Four findings returned so far, all from access-engine and approval-engine. F1 is the serious one: GH-DEC-2026-008 as written mandated a comparison that could never pass, because a claim travelling inside a hashed request cannot name the digest of the request containing it. A fail-closed consumer obeying it would have denied destroy permanently — the ruling and its own fail-closed requirement compounded rather than cancelled. Ruling and its four obligations stand; the comparison target is corrected to the PDP's published exclusion-scoped digest, verified in flex-auth's schema and canonical.go before amending. A consumer must not guess the exclusion rule, and until a PDP publishes one the path is fail-closed rather than complete. F2 adds the general property access-engine flagged as a near miss it was not asking to have written: an evidence-bearing input may be excluded from a correspondence digest but never from the replay identity. The round record notes what this says about the process. GH-DEC-2026-008 was correct in substance, argued from doctrine, and verified against another repository's schema before issue — and none of that caught a defect three repositories found within hours of building on it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WtJBr77gMFLrN93iEevqQJ Assistant: claude-code Assistant-Model: opus Assistant-Process: 425128@bnt-lap001 Assistant-Session: f5944d8b-dac4-4e1a-87eb-8b3d8f314a63
112 lines
5.7 KiB
Markdown
112 lines
5.7 KiB
Markdown
# v0.8 assent round — findings and dispositions
|
|
|
|
**Repository:** gate-house
|
|
**Project family:** NetKingdom security layer
|
|
**Status:** open — round in progress
|
|
**Version:** 0.1
|
|
**Date:** 2026-09-06
|
|
**Subject:** `net-kingdom/canon/standards/security-layer-model_v0.8.md` (proposed)
|
|
**Workplan:** `GH-WP-0003-T06`
|
|
|
|
*Derived artifact: this record states the round's status as of the date above, not
|
|
current state. Authoritative bodies are the decision records and the cut itself.*
|
|
|
|
## Circulated
|
|
|
|
`ops-warden`, `approval-engine`, `access-engine`, `kings-guard`, `audit-core`, and
|
|
`net-kingdom` (publisher). Each was told what the version costs them and what to
|
|
attack, rather than sent a summary to nod at.
|
|
|
|
## Findings returned
|
|
|
|
### F1 — `GH-DEC-2026-008` was unimplementable as written · **adopted, corrected**
|
|
|
|
Reported by `access-engine`, independently by `approval-engine`, originally found by
|
|
`secrets-engine` re-verifying a replay fixture — within hours of the ruling and before
|
|
the assent round had properly opened.
|
|
|
|
The ruling required `claim.binding.pdp_digest` to equal the decision's
|
|
`NewDecisionBinding.request_digest`. `access-engine` hashes context into that digest
|
|
and the dual-control pattern carries the claim in `context.approval`, so embedding the
|
|
claim changes the digest of the request carrying it. A hash cycle: a claim cannot name
|
|
the digest of a document containing that claim.
|
|
|
|
**A fail-closed consumer obeying the rule would have denied `destroy` permanently.**
|
|
The ruling's own fail-closed requirement is what would have made it harmful rather
|
|
than merely wrong — the rule and the failure mode compounded instead of cancelling.
|
|
|
|
**Disposition.** Ruling stands; its four obligations stand; obligation 1's comparison
|
|
target is corrected to the PDP's published exclusion-scoped digest
|
|
(`binding.approval_binding_digest`, `FLEX-DEC-2026-007`). v0.8 §9.7.3 rewritten. A
|
|
consumer MUST NOT guess the exclusion rule, and until a PDP publishes one the path is
|
|
fail-closed rather than complete — a gap in a dependency, not in the ruling.
|
|
|
|
Verified independently against `flex-auth/schemas/decision_envelope.schema.json` and
|
|
`pkg/api/canonical.go` before amending.
|
|
|
|
### F2 — replay identity versus correspondence digest · **adopted, added**
|
|
|
|
Flagged by `access-engine` explicitly as a near miss it was *not* asking to have
|
|
written down. The obvious fix to F1 is to drop `context.approval` from the request
|
|
digest entirely, and that is unsafe: two requests differing only in which approval was
|
|
presented decide differently, so collapsing them lets an allow obtained with a valid
|
|
claim be replayed against a request carrying none.
|
|
|
|
**An evidence-bearing input may be excluded from a correspondence digest but never
|
|
from the replay identity.** Added to v0.8 §6.4 obligation 5. A property discovered by
|
|
nearly getting it wrong is worth more written down than remembered, and the shape
|
|
recurs wherever evidence travels inside a hashed request.
|
|
|
|
### F3 — `GH-DEC-2026-009` adopted, with a reason we had not stated
|
|
|
|
`access-engine` records that the `unknown` ruling is right for the adversarial reason
|
|
— `unknown` is the cheapest state to induce, so failing open on it makes being
|
|
unclassifiable a credential-free escalation — and notes it had reported the divergence
|
|
without reaching that reading. No change; recorded because the reasoning, not the
|
|
conclusion, is what a later reader needs.
|
|
|
|
It also endorses sending `ops-warden`'s non-conformant cell to the round rather than
|
|
imposing it.
|
|
|
|
### F4 — A7 accepted by its own worked example
|
|
|
|
`access-engine` accepts its dual-control instance as the one carrying the argument,
|
|
and notes the §11 marking obligation would have caught the source: the stale G3 row in
|
|
its own 2026-08-29 review, handed on as current. No change.
|
|
|
|
## Implementation ahead of acceptance
|
|
|
|
Both engines implemented against the ruling before the round closed.
|
|
|
|
- `access-engine` — `FLEX-DEC-2026-007`, `dd3ce4c`: publishes
|
|
`binding.approval_binding_digest`, and asserts by test that the two digests
|
|
**disagree** on a claim-bearing request, so a later refactor cannot collapse them.
|
|
- `approval-engine` — `7e75677`, 102 tests: schema v3 declares `pdp_path`; `create()`
|
|
refuses `pdp_path: true` without a `pdp_digest`, so an approval that would be
|
|
unusable on the path fails **at issue** rather than at the protected side effect.
|
|
Intent is declared and never inferred — a digest that happens to be present is not a
|
|
declaration, legacy rows migrate to `false` rather than being back-filled, and a
|
|
successor inherits its predecessor's declaration. Back-filling would have
|
|
manufactured a statement no requester made, which is `GH-DEC-2026-008`'s own
|
|
objection to translation in another form.
|
|
|
|
## Still outstanding
|
|
|
|
`ops-warden` (the `unknown` cell it acquires), `kings-guard` (the criteria-grounding
|
|
clause, and whether §12's step-four paragraph is now stale), `audit-core` (whether
|
|
§11's emission-guarantee wording lets a source imply completeness), `net-kingdom`
|
|
(whether §17 says what it would say in its own voice, and whether §11 tracks its
|
|
published profile).
|
|
|
|
## What the round has shown so far
|
|
|
|
The first finding against v0.8 was a rule that was **right and unimplementable**, and
|
|
it was found by the repository that would have been broken by it, then reported by two
|
|
others under no obligation to look. That combination is only survivable because the
|
|
implementers read the ruling against their own fixtures instead of accepting it — the
|
|
behaviour §12 describes, arriving without being asked for.
|
|
|
|
It is also an argument for the round itself. `GH-DEC-2026-008` was correct in
|
|
substance, argued from doctrine, and verified against another repository's schema
|
|
before it was issued. None of that caught a defect that three repositories found in
|
|
hours of trying to build on it.
|