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
This commit is contained in:
parent
9fb167871b
commit
2b8c9097ad
13 changed files with 654 additions and 6 deletions
|
|
@ -180,3 +180,48 @@ schema is identical). The result, stated at no more than it is:
|
|||
onto audit-core's evaluation by itself: a source needs `heartbeat_classes` on
|
||||
its registration too, and the two can drift apart. That is fixable on
|
||||
either side and has not been fixed on either.
|
||||
|
||||
## Opening events that never close (AUDIT-WP-0018-T03)
|
||||
|
||||
Some streams come in pairs. The bounded executor emits
|
||||
`execution.run.started` once it has consumed its single approval, and
|
||||
`execution.attribution.receipt` when the run ends. A crash in between leaves
|
||||
only the start in custody, and neither heartbeats nor rate counts can see that.
|
||||
|
||||
A sender's registration may therefore declare `closing_classes`:
|
||||
|
||||
```json
|
||||
"closing_classes": {
|
||||
"execution.run.started": {
|
||||
"closed_by": "execution.attribution.receipt",
|
||||
"within_seconds": 7200
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`GET /v1/stream-findings` then carries an `opening_without_closing` finding
|
||||
for every opening event that has no closing event with the same
|
||||
`correlation_id` from the same source by its deadline.
|
||||
|
||||
- **Clock.** The deadline counts from the receiver's own `accepted_at`, never
|
||||
from a source-supplied time.
|
||||
- **Bound.** The deadline is the declared `within_seconds`. If the opening event
|
||||
carries `data.window.not_after`, the earlier of the two applies (`bound` names
|
||||
which one). A per-run window can tighten the declaration but never extend it.
|
||||
- **Grace.** The same 1.5× allowance as heartbeats is added
|
||||
(`within_seconds × 0.5`), so a receipt accepted moments late does not flap
|
||||
the finding. For the executor that means a finding at 3 h at the latest.
|
||||
- **Lookback.** Opening events accepted in the last 30 days, the operational
|
||||
custody window, are examined.
|
||||
- **No correlation id.** An opening event without a `correlation_id` can never
|
||||
be closed and is always reported.
|
||||
- **Disclosure.** A finding carries identifiers and timing only: event id,
|
||||
correlation id, accepted time, deadline. No payload is disclosed.
|
||||
- **Overlay.** The scope overlay may add a pair or shorten its bound. It may
|
||||
never remove a pair, rebind its closing class, or lengthen the bound.
|
||||
|
||||
The finding's `means` says what it does not prove. The run may have partly
|
||||
executed, failed before emitting, or had its receipt lost or suppressed.
|
||||
Audit-core does not infer which, and does not infer what the run did. It is a
|
||||
finding for the verifier and the founder. As with heartbeats, a compromised
|
||||
emitter that suppresses its start and its receipt together is not covered.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue