audit-core/workplans/AUDIT-WP-0018-bounded-executor-receipt-custody.md
tegwick 2b8c9097ad
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 3s
AUDIT-WP-0018-T03: report bounded-executor runs that started without a receipt
A sender may declare closing_classes; nk-bounded-executor declares
execution.run.started closed by execution.attribution.receipt within
7200s. GET /v1/stream-findings reports opening_without_closing past the
bound, counted from the receiver's accepted_at plus the heartbeat grace
allowance; a per-run data.window.not_after tightens but never extends.
Identifiers and timing only. The overlay may add or shorten, never
remove, rebind or lengthen. Both backends: 403 passed (1 unrelated
live-catalog env failure).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 482098@bnt-lap001
Assistant-Session: 9643c95a-a398-4f4a-b56a-6119be4e845e
2026-11-03 22:04:14 +01:00

5 KiB

id type title domain repo status flavor owner topic_slug created updated related state_hub_workstream_id
AUDIT-WP-0018 workplan Hold bounded-executor execution-attribution receipts infotech audit-core active implementation audit-core audit-evidence-dependencies 2026-10-31 2026-11-03
NK-WP-0056
NK-WP-0040
AUDIT-WP-0014
932c94fc-2e7c-55eb-b6d5-70832d3996b5

AUDIT-WP-0018 — Hold bounded-executor execution-attribution receipts

NetKingdom's Bounded Execution Admission v0.1 makes a non-human executor (service:nk-bind-executor, namespace sso) emit one execution-attribution receipt per run. Audit-core holds those receipts. The owner answer and the event mapping are in docs/bounded-executor-receipts.md. Canonical schema validation is still AUDIT-WP-0014-T02 and is not duplicated here.

Answer the NK-WP-0056-T02 owner request

id: AUDIT-WP-0018-T01
status: done
priority: high
state_hub_task_id: "7c1fb849-ddb3-558f-8a50-5c711e2c7b56"

Hub message 755cbeed-ecbd-46d9-883e-958fbd88378b. Audit-core accepts custody. Each run produces one receipt event that carries the per-step outcomes, check results, reverted and budget. Each run also produces an execution.run.started event, correlated with the receipt by run_id. Event ids are deterministic from run_id. The proposed secret_policy is reject. NetKingdom has to decide how a singular target/action relates to per-step targets and actions, and has to make decision_refs typed.

Prepare sender registration and ingress for the executor

id: AUDIT-WP-0018-T02
status: done
priority: high
state_hub_task_id: "3f251d30-e62d-5849-88d9-d033097b4f7d"

Prepare the following:

  • a non-secret registry entry (nk-bounded-executor: exact source, exact tenants, write only, secret_policy: reject, and either evidence_kind load-bearing or attributive with a completeness_trade);
  • a NetworkPolicy that admits only the executor's pods in sso.

Then test on synthetic fixtures:

  • accept on 202;
  • a retry returns a 200 duplicate;
  • a reused run_id with a different body is a 409 conflict;
  • wrong source or tenant is refused;
  • a secret-shaped step check is refused with 400.

The live registry seed and the rollout are founder-run.

Done 2026-10-31, from NetKingdom hub messages ed03ba30 and deea5bf8. Scope entry: deploy/senders-scope.{json,yaml}. The overlay may now tighten secret_policy but never relax it. Ingress: audit-core-nk-bounded-executor-ingress. Tests: tests/test_bounded_executor_sender.py. Nothing is applied.

  • Founder-run: mint the Secret entry, seed it, and roll out the ConfigMap and the NetworkPolicy.
  • Still owed by NetKingdom: NK-WP-0040-T02 (schema and fixtures). Also the executor must accept 202: clients.AuditCore.emit accepts only 200 and 201 today.
  • Still owed by railiance-platform: bearer custody.

See docs/bounded-executor-receipts.md, "Status 2026-10-31".

Detect runs that started without a receipt

id: AUDIT-WP-0018-T03
status: done
priority: medium
state_hub_task_id: "ec2cd9b7-be65-5792-b546-ffd0b3937856"

Report every execution.run.started that has no execution.attribution.receipt with the same correlation_id after the declared window. Reuse the existing stream-completeness/cadence surface (docs/stream-completeness.md, docs/cadence-registration.md) instead of adding a new monitor. The report is a finding for the verifier and the founder. Audit-core does not infer what the run did.

Unblocked 2026-10-31. NetKingdom adopted the started event and set the bound: the admission's window.not_after. Pilot windows are 2 h. The receipt also carries time_interval.end.

Done 2026-11-03. A sender may declare closing_classes. For nk-bounded-executor, execution.run.started must be closed by execution.attribution.receipt with the same correlation_id within 7200 s. GET /v1/stream-findings reports opening_without_closing past that bound.

  • Deadline: counted from the receiver's own accepted_at, with the heartbeat grace allowance added, so a finding appears after 3 h at the latest. A per-run data.window.not_after tightens the deadline but never extends it.
  • Lookback: 30 days.
  • Disclosure: identifiers and timing only.
  • Overlay: may add a pair or shorten its bound; may never remove, rebind or lengthen.

Code: audit_core/stream_findings.py (evaluate_closing) and unclosed_openings on both backends. Tests: tests/test_run_receipt_findings.py (30 tests, both backends). Docs: docs/stream-completeness.md.

  • Asked of NetKingdom: put window.not_after in the started body.
  • Founder-run: release an image from this commit and apply the ConfigMap.

Founder decision 2026-10-31

Approved by the founder (proposed -> ready) after the NK-WP-0056-T02 owner answers (hub decision 19afd15e). Founder adopted the execution.run.started event plus one receipt per run with an admission-level target/action, steps[] detail and labelled decision_refs.