GH-DEC-2026-005 moved the distinct-approver check off the PEP onto this
engine's valid_now. secrets-engine has implemented the split and reports
it no longer verifies the threshold independently. Gate House accepted
that as correct on layering AND as a genuine reduction in defence in
depth, and named the compensating control: not a second check at the PEP,
which is the duplication the split removes, but reconstructability at the
issuer under §9.6.
The emitted events could not support that. approval.issuance carried
required_count but never who satisfied it, and approval.use carried no
threshold evidence at all, so an auditor replaying the stream could not
recompute the evaluation without reading live rows -- rows that may since
have been superseded, revoked, or expired.
Both events now carry a threshold object: required_count,
distinct_approver_count, threshold_met, and approvers with approved_at
plus assurance and evidence_ref when recorded. Tests prove reconstruction
from the use row alone, and that the claim still discloses no approver
identities -- they are evidence for audit-core, not consumer-facing, and
the claim keeps disclosing the least it can.
Writing the tests showed distinctness is already a storage invariant:
entries is UNIQUE on (approval_id, subject_id), so a repeat approver is
refused at insert and a separate entry_count could never differ from the
distinct count. Dropped that field rather than ship a number that cannot
vary, and the test now asserts the refusal instead.
88 tests pass (4 new).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TvyJPAaVCGsVheVhcCwNND
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 411227@bnt-lap001
Assistant-Session: d566f6d3-bcaf-43c3-bc5e-3ddd0f64b535
Contracts first (T02–T04): approval claim schema with issuer, freshness,
and binding digest; local transactional outbox wire; load-bearing cadence
as heartbeat or reconciliation (layer.yaml declared).
Then the object (T06–T08): SQLite closed state machine, CAS supersession,
distinct-approver fail-closed, revocation without holder cooperation,
outbox insert in the same transaction. Tests fail the mutation when
emission fails, and revoke while the drain sink is down.
Introspection GET /v1/approvals/{id}/claim is a PIP fact, not a decision.
No public consume (T05 waits on GH-WP-0002-T06). Canon T-06 coverage for
wrong binding, expiry, revoke, and supersede.
FLEX-WP-0017 T03 is unblocked on this object; T05 remains blocked only on
consumption ordering.
Assistant: grok
Assistant-Session: 01a04ceb-2057-7e20-b0f9-c282964d5dd9