From 865bab395581d806182355126a69ce7554cd553d Mon Sep 17 00:00:00 2001 From: repo-manager Date: Sun, 6 Sep 2026 09:30:42 +0200 Subject: [PATCH] repo.work.create_decision GH-DEC-2026-008 correlation_id: 9ea5a1bd-1f00-4069-b6bf-a59a29327415 reason: rmgr CLI source: repo-manager Assistant: claude-code Assistant-Model: opus Assistant-Process: 425128@bnt-lap001 Assistant-Session: f5944d8b-dac4-4e1a-87eb-8b3d8f314a63 --- decisions/decisions.md | 70 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/decisions/decisions.md b/decisions/decisions.md index 90fe484..a685782 100644 --- a/decisions/decisions.md +++ b/decisions/decisions.md @@ -485,6 +485,7 @@ rationale: 'Confirmed, with one addition. GH-DEC-2026-003 already named step 1 b in the secrets-engine validator is struck because State Hub is a read model and holds no runtime approval authority.' decided_by: Bernd Worsch +state_hub_decision_id: "b606e8ce-f1fa-4b39-bfe9-c11e88a3cde6" created: '2026-09-05T23:28:23.931441Z' updated: '2026-09-05T23:28:23.931441Z' ``` @@ -621,6 +622,37 @@ would be a layer violation wearing the costume of a refactor. `secrets-engine` h a test asserting the two functions disagree, which is the right way to defend a distinction that looks like duplication. +**Narrowed, 2026-09-06, by `approval-engine` on implementing the §9.6 obligation.** +The framing above was too broad. `entries` is UNIQUE on `(approval_id, subject_id)`, +so a repeat approver is refused at insert: distinctness is a **storage invariant** in +that engine, not something a consumer or an auditor recomputes. What the PEP stopped +checking is therefore that *this engine applied its own invariant correctly* — not +whether dual control could be forged by a repeated signature, which the schema +forecloses. The reduction is real and it is narrower than "the threshold is now +unverified". `approval-engine` found this by writing a test that expected duplicate +entries to collapse to one distinct approver, watching it fail, and reporting the +result against its own earlier framing; it also dropped an `entry_count` field rather +than ship a number that by construction can never differ from the distinct count. + +The compensating property is now implemented rather than asserted: `approval.issuance` +and `approval.use` both carry a `threshold` object — `required_count`, +`distinct_approver_count`, `threshold_met`, and approver `subject_id`, `approved_at` +and evidence reference — with tests asserting reconstruction from the `use` row +**alone**, performing the recomputation an auditor would. The disclosure boundary is +pinned by test: identities are on the outbox, never on the claim. The evidence path +carries them because that is what audit is for; the consumer-facing artifact discloses +the least it can. The split did not push identities to consumers by another route. + +**Hub row provenance.** `approval-engine`'s `fix-consistency` C-32 check registered +the drafted record block in its own request document as a hub decision +(`b606e8ce-f1fa-4b39-bfe9-c11e88a3cde6`), which it then resolved rather than leave an +open row for a settled question. Gate House **adopts that row as canonical** and +records its id above, rather than registering a second one — the row's content is +correct and a duplicate would be worse than an imperfectly-provenanced single row. A +drafted decision block inside a requesting repository's document is machine-readable +to that repository's own consistency checks, which is a trap in this workflow; the +disposition is recorded here so the next request does not rediscover it. + ## Reversal Revert this record and the amendment to `docs/contracts/approval-consumption.md`. The @@ -908,3 +940,41 @@ The likely candidates are human-attested controls (a policy was reviewed, a dril run); the expected resolution is that the *attestation event* is the evidence and the criterion grades on its existence, freshness, and issuer rather than on its verdict. If that resolution does not hold for some real criterion, this clause is wrong. + +## GH-DEC-2026-008 — The PDP digest is the binding correspondence; no cross-engine vocabulary mapping is published + +```yaml +id: GH-DEC-2026-008 +kind: decision +title: The PDP digest is the binding correspondence; no cross-engine vocabulary mapping + is published +status: resolved +owner: Bernd Worsch +repo: gate-house +standard: net-kingdom/canon/standards/security-layer-model_v0.7.md +source_note: docs/contracts/approval-consumption.md; approval-engine/docs/approval-claim.md +requested_dispositions: +- approved +- revised +- rejected +affects: +- gate-house +- approval-engine +- access-engine +- secrets-engine +- ops-warden +rationale: 'Raised by access-engine. approval-claim verification item 4 is a disjunction: + the consumer recomputes approval-engine''s native binding from the proposed action, + OR compares binding.pdp_digest to the decision''s request digest. The first limb + needs a cross-engine vocabulary mapping nobody owns and nobody has published; the + second is optional in the schema. Together that leaves ''approved for THIS request'' + unestablished whenever the PDP digest is absent, while the claim still reads valid_now + true. The mapping is rejected because a translation between two engines'' vocabularies + can be silently wrong and would be owned by neither, and because recomputing another + layer''s binding is the re-derivation GH-DEC-2026-005 forbids. The digest is identity + rather than translation, so it is made required on the PDP path and consumers fail + closed without it.' +decided_by: Bernd Worsch +created: '2026-09-06T07:30:42.213794Z' +updated: '2026-09-06T07:30:42.213794Z' +```