Align action audit redaction contract docs

This commit is contained in:
rcourtman
2026-05-13 21:59:25 +01:00
parent d3670d7882
commit bc307b01a8
4 changed files with 45 additions and 26 deletions
@@ -953,8 +953,10 @@ runtime-Failed, or refused-before-dispatch with stable
`plan_drift:` / `resource_remediation_locked:` error-token
prefixes preserved verbatim; successful dispatches carry a
`verification` block — the agent-stable projection of the
broker's read-after-write probe — so agents close the
"did it actually work?" loop without polling /api/actions/{id}),
broker's read-after-write probe, with verification command/note
details redacted to stable markers at the action-audit readback
boundary — so agents close the "did it actually work?" loop without
polling /api/actions/{id}),
and a 15-second heartbeat keepalive.
The broadcaster drops real published events for slow subscribers
rather than blocking publishers, so the patrol-finding runtime, the
@@ -1006,12 +1006,16 @@ the canonical monitored-system blocked payload.
`ran`, `command`, `output`, `success`, `ranAt`, and `note`. API
consumers (specifically the Resource Action History on the
infrastructure detail drawer) must round-trip the verification
block verbatim and render it as a distinct outcome row alongside
the dispatch `result`. Operators see what command Pulse ran as the
read-after-write check, what it returned, and whether it confirmed
the intended state — not just "command exit 0." When `ran=false`
(no derivable check, or feature disabled for the action class)
nothing must be rendered, matching the no-fabrication rule.
block as the action-audit readback API returns it and render it as a
distinct outcome row alongside the dispatch `result`. The `command`,
`output`, and `note` fields are redacted to stable markers at
persistence/readback boundaries, including migrated legacy rows, so
consumers must not expect or re-expose raw historical verification
details. Operators see whether Pulse ran the read-after-write probe
and whether it confirmed the intended state, not raw command output.
When `ran=false` (no derivable check, or feature disabled for the
action class) nothing must be rendered, matching the no-fabrication
rule.
The patrol-status response (`PatrolStatusResponse`) carries an
optional `trust` block of type `ai.FindingsTrustSummary` that
surfaces the trust-metrics snapshot for the Patrol page. The block
@@ -1417,8 +1421,10 @@ dispatches carry a `verification` block — the agent-stable
projection of the broker's read-after-write probe — with `ran`,
`success`, `command`, `note`, `ranAt` so agents close the
"did it actually work?" loop without a follow-up audit fetch;
raw action and verification commands follow the same `ai:execute`
redaction rule on the stream;
action command disclosure follows the governed `ai:execute` rule, while
verification command/note details in the action-audit projection remain
stable redaction markers; stable error-token prefixes remain verbatim
for agent branching;
refused dispatches omit `verification` because the probe never
runs) — and `heartbeat` every 15 seconds so an idle connection
can confirm the stream is alive. Each event carries a monotonic ID
@@ -1612,8 +1618,9 @@ with their stable token prefixes (`resource_remediation_locked:`,
(shared `AgentResourceActionVerification` projection, shared
`projectAgentResourceVerification` helper) so the bundle's depth
view and the doorbell speak the same vocabulary on probe outcomes;
action and verification command text follows the same `ai:execute`
redaction rule.
action and verification command/note text follows the same stable-marker
redaction rule as action-audit readback, while stable status/error
prefixes remain verbatim.
The shape is intentionally narrower than the full internal types
so agents see a stable agent-paradigm contract, decoupled from
internal type evolution.
@@ -259,9 +259,12 @@ bypass the API fail-closed execution gate.
context boundary: monitoring/read API tokens receive redacted approval,
action, and verification command payloads (`commandRedacted:true`) unless
they also hold action execution scope. Storage and recovery consumers may
display those redacted records as status or evidence, but must not derive
backup, restore, storage remediation, or execution authority from the event
stream or resource-context bundle.
display those redacted records as status or evidence, and action-audit
verification command/output/note details read back from migrated legacy rows
must remain stable redaction markers rather than raw historical details.
Storage and recovery consumers must not derive backup, restore, storage
remediation, or execution authority from the event stream or resource-context
bundle.
The `previous_resolved_fix_summary` operational-memory field carried on
findings across regressions follows the same scope: storage and recovery
surfaces may render it as adjacent finding context but must not
@@ -518,12 +518,17 @@ AI-only summary payloads, or page-local heuristics.
intentionally narrower than the patrol-failure redactor: arbitrary
URLs are preserved so operators can reference runbooks, ticket
links, and GitHub issues in audit reasons.
Verification command output is part of the same persistence
boundary: `ActionVerificationResult.Command`, `Output`, and `Note`
must be redacted both on top-level `ActionAuditRecord.Verification`
and nested `ExecutionResult.Verification`, while `Ran=false`
normalization remains responsible for clearing verification details
rather than persisting redaction markers for unrun checks.
Verification command output is part of the same persistence and
readback boundary: `ActionVerificationResult.Command`, `Output`,
and `Note` must be replaced with stable redaction markers both on
top-level `ActionAuditRecord.Verification` and nested
`ExecutionResult.Verification`. Migrated legacy rows follow the same
contract when rehydrated, so API and frontend readers never surface
raw historical verification command, output, or note details. Stable
status and error-token prefixes such as `plan_drift:` remain
verbatim where agents depend on them. `Ran=false` normalization
remains responsible for clearing verification details rather than
persisting redaction markers for unrun checks.
21. Keep post-execution verification outcome on the canonical execution
result. `ExecutionResult.Verification` carries
`ActionVerificationResult` with `Ran`, `Command`, `Output`,
@@ -564,11 +569,13 @@ AI-only summary payloads, or page-local heuristics.
surfaces verification as a distinct outcome row alongside the
dispatch result, with emerald tone for verified and amber for
failed (matching the trust palette already used on the findings
panel). The render must show the verification command verbatim,
the captured output, and the optional broker note, so the
operator sees exactly what Pulse read back rather than a yes/no
summary. When `verification.ran` is false (no derivable check, or
feature disabled for the action class) nothing is rendered —
panel). The render must show the stable redaction markers returned
by the action-audit readback API for verification command, output,
and note fields, not raw command or historical output details; the
operator still sees whether Pulse ran the read-after-write probe and
whether it confirmed the intended state. When `verification.ran` is
false (no derivable check, or feature disabled for the action class)
nothing is rendered —
operators must not see fabricated "verified" claims for actions
where Pulse cannot read back.