feat(operation-trace): workspace-wide integrity counters, drill-down and resource identity

- Count hash mismatches / broken links over the whole filtered history instead
  of only the returned page, so the badges no longer reset to zero on page 2.
- Classify failing record ids during the same scan and expose them through an
  integrity=all|issues|hash_mismatch|chain_broken listing filter.
- Report scanned_count / scan_truncated so an approximate (row-capped) summary
  is never mistaken for a clean one.
- Resolve the acted-on resource identity from route params or the request body,
  giving every resource family a "which plugin/skill/knowledge base" trace.
- Render resource types and the two counters through i18n, keeping all eight
  locale files key- and line-aligned.
This commit is contained in:
TyperBody
2026-09-26 03:23:24 +08:00
parent abca2e7bff
commit 6981b6643f
13 changed files with 470 additions and 29 deletions
@@ -387,6 +387,28 @@ class RouterGroup(abc.ABC):
if candidate is not None:
resource_id = str(candidate)
# Routes without an explicit resource_param still name the resource
# they act on, either as a URL parameter or inside the payload of an
# install-style endpoint. Resolving that identity here gives every
# resource family a "which plugin/skill/knowledge base" trace without
# touching each handler. The body is read defensively: an audit path
# must never fail (or block) because a request carries no JSON.
try:
# Imported lazily so the base controller never participates in an
# import cycle with the service layer at module load time.
from ..service import settings as settings_service
request_body: dict[str, typing.Any] | None = None
if str(quart.request.method or '').upper() not in ('GET', 'HEAD', 'OPTIONS'):
raw_body = await quart.request.get_json(silent=True)
if isinstance(raw_body, dict):
request_body = raw_body
identity = settings_service.resolve_resource_identity(kwargs, request_body)
if identity:
resource_id = identity
except Exception: # pragma: no cover - identity resolution is best effort
pass
# Handlers may publish request-local traceability facts when a
# static route declaration cannot describe the runtime diff, e.g.
# the previous and the new role of a member. ``quart.g`` is