Adopt approval-engine's outbox wire as Gate House doctrine, specify the heartbeat-and-reconciliation detection surface, and settle consumption ordering: the PEP consumes by CAS before the side effect. T05's §11 check is written here and queued for statute v0.8. Assistant: grok Assistant-Session: 01a04d89-aaa5-7443-945e-b3055cd4b7e4
4.2 KiB
Approval emission detection surface
Owner: gate-house
Source: approval-engine
Archive: audit-core
Observer: kings-guard (silence-as-signal; offered)
Status: normative for GH-WP-0002-T04
Date: 2026-08-29
Statute: net-kingdom/canon/standards/security-layer-model_v0.7.md §9.6
Source declaration: approval-engine/cadence.yaml
A hash chain proves accepted records were not altered or truncated. It proves nothing about an event never emitted. Atomicity (the outbox contract) prevents accidental omission. This surface is what makes a silent loss visible.
It does not prevent a compromised source from suppressing. That residual is stated in §9.6 and is not closed here.
Form
Approval evidence is load-bearing and low-volume. Rate monitoring is forbidden: a handful of revocations a month has no rate to drop below, and suppression is indistinguishable from a quiet month.
The required form is heartbeat plus reconciliation. Reference instance:
approval-engine/cadence.yaml and approval-engine/docs/emission-cadence.md.
Heartbeat
A signed positive claim: nothing to report, together with per-class transition counts since the previous heartbeat (or since process start on the first). The claim can itself go missing, which is the point.
| Field | Value |
|---|---|
| Class | heartbeat |
| Interval | 24 hours (SHOULD also be emittable on demand) |
| Assertion | nothing-to-report |
| Counts | {issuance, use, supersession, revocation} of committed outbox rows |
| Missing heartbeat | finding |
Heartbeat rows use the outbox table and the same at-least-once drain. They are not coupled to an object mutation.
Reconciliation
Compare approval-engine's committed outbox counts per class to audit-core's
accepted event counts for source=approval-engine and the corresponding
action. Divergence is a finding, not a log line.
| Source class | audit-core action |
|---|---|
issuance |
approval.issuance |
use |
approval.use |
supersession |
approval.supersession |
revocation |
approval.revocation |
heartbeat |
approval.heartbeat |
Undrained local rows are lag, not yet a divergence. A row with drained_at set
that audit-core does not hold is the omission case §9.6 names.
Lag bound
| Bound | Default (reference) | Exceed |
|---|---|---|
| Outbox depth | 100 undrained rows | finding |
| Outbox age | 1 hour for the oldest undrained row | finding |
These detect a stuck drain. They are not a completeness proof.
What is a finding
- No heartbeat arrives for more than one interval.
audit-corecount for a class is less than the source's drained count for that class.- Outbox depth or age exceeds the lag bound.
None of these are rate drops. None of these are informational logs.
kings-guard consumes the finding as observation of the stream, not of its
contents. Until it reports that it is watching in production, no argument may
assume this surface is live (§12). The source MUST still publish the
declaration; a detector that is not yet watching does not excuse an undeclared
source.
Who owns which half
| Half | Owner |
|---|---|
| Publish cadence and expose committed counts / lag | approval-engine |
| Hold accepted events and answer per-source per-class counts | audit-core |
| Raise silence, divergence, and lag as findings | kings-guard |
| Name the form and the residual | gate-house |
Conformance check (queued for statute v0.8 §11)
GH-WP-0002-T05. Mechanically checkable, in the same list as the existing §11 bullets:
- every repository catalogued as an evidence source, or that emits
load-bearing evidence, declares its emission guarantee in a
machine-readable form at a path named in its layer declaration:
- load-bearing: local transactional outbox (this contract's shape) and a heartbeat-or-reconciliation cadence declaration;
- attributive, deliberately non-atomic: the named trade, and a statement that completeness is not claimed.
A new engine catalogued under §9.4 / §4 as an evidence source that ships
without this declaration reintroduces the approval omission gap silently.
Until v0.8 lands, this paragraph is doctrine; approval-engine's
cadence.yaml plus layer.yaml is the reference form.