Audit exact-bound owner-native lifecycle receipts (#126082)

* feat(audit): add owner-native lifecycle receipts

* fix(audit): store lifecycle bindings additively

* test(cron): isolate execution binding fixtures

* fix(audit): reject stale lifecycle owners

* fix(acp): gate parent flow binding on retained task

* fix(audit): reject pruned owner cursors
This commit is contained in:
Josh Avant
2026-08-24 17:49:25 -07:00
committed by GitHub
parent 05a2a593f7
commit 2e9c8f8d3f
58 changed files with 3802 additions and 318 deletions
+13 -2
View File
@@ -115,7 +115,8 @@ view renders these sections:
3. **Lineage**: parent context or an explicit absent, unknown, or unsupported
state.
4. **Decisions**: bounded run-admission and authoritative action-decision
receipts, including terminal operator approvals.
receipts, including terminal operator approvals and exact-bound cron, task,
and task-flow lifecycle rows.
5. **Missing evidence** and **Next steps**.
Every field includes `present`, `absent`, `unknown`, or `unsupported`; the CLI
@@ -125,6 +126,15 @@ ingress, an absent invoker, and
`unattributed` coverage. Its admission receipt says `not-applicable` because no
identity-aware policy or grant evaluation was proven.
Lifecycle rows from `cron_run_receipts`, `task_runs`, and `flow_runs` appear as
owner-native, attribution-only receipts when their keyed lifecycle metadata
carries the exact inspected context and execution ids. They contain status and
bounded record references, not prompts, task goals, hook payloads, paths, or raw
errors. Their decision is `not-applicable` because lifecycle attribution does
not prove authorization.
Treat every decision cursor as opaque: numeric and `a:`, `m:`, and `g:` values
remain compatible, while cron/task/flow pages may return `c:`, `t:`, or `f:`.
For Gateway runs, a resolved authenticated profile can make the invoker
`present` and coverage `attribution-only`. Paired devices and shared credentials
do not establish a person: without a durable profile the invoker stays absent,
@@ -340,7 +350,8 @@ and no identity context; its required `decisionDisplays` array is empty until
the caller selects an execution id.
For one selected context, receipt paging starts with admission, then reads
owner-native terminal approvals, merges outbound progress and terminal records,
and finally reads generic facts for boundaries without a native durable record.
then reads generic facts and the cron, task, and flow lifecycle owners. The
complete order is admission, approval, message, generic, cron, task, then flow.
The merge is deterministic across restart and rejects a cursor whose exact
owner row has expired. Approval and message selectors use the opaque
`approval-decision:` and `message-decision:` namespaces minted from the same