Four repositories returned text reviews. Every substantive finding was about a rule that read as satisfied by a check that did not satisfy it, which is the failure mode this repo is structurally prone to: doctrine is graded on whether it is right and consumed on whether it is checkable, and only the implementers can tell those apart. GH-DEC-2026-010 — attribution is not identity. Obligation 1 said a PEP must hold a decision from access-engine; obligation 2 supplied a digest test emphatic that it was mechanical rather than a matter of judgement. That test establishes which request a decision is for and nothing about who issued it, and it cannot: every input to it is either sent by the caller or published, so a responder knowing a published package id and version returns a well-formed allow. Fail-closed protects against a decision point that is absent, not against one that lies. Section 9.4 required authenticated entries of the approval object and nothing required it of the decision, so obligation 5 was written over a pair a PEP could only half validate. The mechanism is access-engine's under section 17 and it is not the standard's to choose, so the condition is a declared section 13 gap rather than a rule invented here. Raised by access-engine against its own artifact, which had already recorded it as its own defect before reading our text. GH-DEC-2026-011 — ops-warden assented to GH-DEC-2026-009 on the falsifier's own terms, went looking for the section 5.1 escape hatch the reversal clause predicted, and reported it does not have one. Then it priced adoption: 0 of 3 signing targets and 3 of 21 routing lanes resolve to a zone, so the cell adopted today fails closed on nearly every certificate it issues whenever the engine is unreachable — including the continuity path an operator needs to repair that unreachability. Its ask for a dated transitional unknown: fail_open is declined; it is indistinguishable at runtime from the stance the rule forbids and would make the rule optional at the only moment it costs anything. Its second preference is adopted instead: 13.1 records a dated coverage figure beside each stance, so a strict consumer and an unclassified one stop reading alike. Coverage is disclosure and does not soften the stance — the record says so, and says what would make the column come out again. The round record is closed and carries the rest: totality by catch-all, absent versus unknown (closing the section 16 question this version opened), the drift test promoted to MUST, ops-mason marked, and approval-engine's four editorial-but-load-bearing findings. Its own finding ids are used rather than renumbered. kings-guard and audit-core did not return a review. Section 14 records that as not claimed rather than counting silence as assent, and names the sections that therefore carry no assent from the repository best placed to test them. Standard amended at net-kingdom@64394e9; it stays proposed, and publication and the acceptance flip are net-kingdom's. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012viPor8WJNCbV64ipwewrm Assistant: claude-code Assistant-Model: opus Assistant-Process: 1754332@bnt-lap001 Assistant-Session: 9c8ac536-ff5e-46a3-8ab1-a548bde25fc0
18 KiB
v0.8 assent round — findings and dispositions
Repository: gate-house
Project family: NetKingdom security layer
Status: closed — all findings dispositioned; publication handed to net-kingdom
Version: 0.2
Date: 2026-09-09
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
F-numbers are this record's own, assigned in the order findings arrived;
F-A numbers are approval-engine's. Where a reporter's own finding id is cited it is
named as theirs. F1–F4 arrived before the round properly opened; F5 onward came
from the full text reviews.
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 obligations stand (this record said "its four
obligations stand" in v0.1, written after obligation 5 was added — the propagation
approval-engine cites in F-A2b below, corrected here rather than only at the source); 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.
F5 — attribution is not identity · adopted, GH-DEC-2026-010
Reported by access-engine (FLEX-DEC-2026-011, ranked blocking for calling §6.4's
obligations complete, explicitly not blocking adoption), against its own artifact and
recorded on its own side as FLEX-DEC-2026-010 before it read this text. Framed
independently by secrets-engine and carried into the correspondence chain by
approval-engine.
§6.4 obligation 1 required a PEP to hold "a decision from access-engine", and
obligation 2 supplied a digest test emphatic that it was mechanical rather than a
matter of implementer judgement. That test establishes which request a decision is
for and nothing about who issued it, and it cannot: every input is either sent by
the caller or published, so a responder knowing a published package id and version
returns a well-formed allow. Publishing more digests makes a forgery look more
authenticated, not less.
Fail-closed protects against a decision point that is absent, not against one that lies. And §9.4 requires authenticated entries of the approval object while nothing required it of the decision, so obligation 5 was written over a pair of artifacts whose authenticity a PEP could validate for only one half.
Disposition. Adopted. Obligation 1 now requires attribution and states that the
digest comparison does not discharge it; the mechanism is the owner's under §17 and the
condition is a declared §13 gap with access-engine as owner. Ruled in
GH-DEC-2026-010. Note that §16 had already recorded this observation one layer up,
against this standard's own publication path — the gap was visible from inside and
recorded against the wrong artifact.
F6 — totality by catch-all; absent is not unknown · adopted, GH-DEC-2026-011 §3
access-engine, as its own F2. A map carrying unknown → fail_closed satisfies obligation 3's
totality requirement vacuously: every scope never enumerated lands in the catch-all,
fails closed, and nobody learns which those were, while the drift test passes by
exercising the default rather than the axis. Recognised from its own
FLEX-DEC-2026-008 — a package shipped with no tenant rule while 29 fixtures passed,
because every fixture carried the same tenant.
Disposition. Adopted. A map MUST enumerate its axis; an absent hit MUST be
distinguishable in the record from an unknown hit and MUST surface as a conformance
failure. Runtime behaviour is unchanged — absent fails closed too, for the stronger
reason. This closes the §16 question opened at the cut.
F7 — the drift test was a SHOULD · adopted
access-engine, as its own F3. The strongest obligation in §6.4 had the weakest verification, in
a paragraph arguing that a map free to drift is worse than none. Promoted to MUST;
already met by four of five §13.1 rows, so it costs nothing.
F8 — §13.1 marked one violation and not the plainer one · adopted
access-engine, as its own F4. ops-warden's row was bolded non-conformant for a wrongly-valued
cell; ops-mason's "not published" was stated as bare fact, though an unpublished map
is the plainer violation of the same obligation. Gate House's own §11 marking
obligation applied to its own register, returned unchanged by the repository it had
made the same argument to. ops-mason is now marked.
F9 — the adoption cost of GH-DEC-2026-009 · split: ask 1 declined, ask 2 adopted
ops-warden, assenting to the rule on the falsifier's own terms — it went looking for
the §5.1 read-only escape hatch the reversal clause predicted and reported that it does
not have one, since the map governs warden sign, a credential-issuing side effect.
Then it priced adoption: 0 of 3 signing targets and 3 of 21 routing lanes resolve to a zone, so the cell adopted today fails closed on essentially every certificate it issues whenever the engine is unreachable — including the continuity path an operator needs to repair that unreachability. Eighteen of eighteen unknown lanes are unknown because another repository has published no workload-identity declaration.
Disposition. Ask 1 (a dated transitional unknown: fail_open) declined: it is
indistinguishable at runtime from the stance the rule forbids and makes the rule
optional at the only moment it costs anything. Ask 2 adopted: §13.1 records a dated
coverage figure beside each stance. Ruled in GH-DEC-2026-011, which also records that
ADR-0009 rule 3's prohibition on inferring membership holds under this pressure.
ops-warden also confirmed §12's derived-artifact rule against its own
catalog_revision / catalog_dirty practice, and agreed with refusing a forced
migration onto zones. No change requested for either.
F-A1 — §15 item 2b's numbering made §14's tally uncheckable · adopted
approval-engine. The change list contained an item numbered 2b, and §14 claimed "ten
of this version's eleven changes were requested by another repository" with §17 as the
single exception — a tally that only holds if 2b is a sub-clause rather than a change,
and 2b is the one item explicitly described as not a request. So if 2b counts, both
halves move: ten of twelve, two exceptions.
Disposition. Adopted, promoted. 2b counts as a change in its own right and is the
second exception; §14 restates the ratio. The label 2b is retained rather than
renumbered so that references written against this list do not silently repoint. The
finding is well aimed: §14 offers the ratio as the argument for circulating rather
than accepting, and invites the reader to count.
approval-engine also recorded two candidates it checked and dropped — §15 change
9's "+3 rows" (correct against v0.7's two) and §11's "three times"/"four times"
(different corrections in sequence). A finding count means nothing without the count
checked and discarded.
F-A2 — §6.4 announced four obligations and listed five · adopted
approval-engine. v0.7 said "Four" and listed 1–4; v0.8 added obligation 5 and left the
count. Not a typo with cosmetic consequences: obligation 5 carries
correspondence-by-identity, the PIP/PDP separation, the replay-identity property, and
the summary-predicate trust rule — the obligation the whole GH-DEC-2026-003 / -005 /
-008 chain rests on. An implementer reading "the four obligations of §6.4" has a
defensible reading under which it implements 1–4 and omits the one governing how an
approval is compared to a decision. Corrected.
F-A2b — the miscount had already propagated · adopted, corrected in place
approval-engine observed that Gate House's own 2026-09-06 message said "the ruling
stands and its four obligations stand" — written after obligation 5 was added, by the
section's author. That is the evidence the count sentence was doing work rather than
decorating. The same sentence appeared in v0.1 of this record and is corrected above.
An estate-wide grep for other references found only historical ones, in the v0.6 and
v0.7 change logs where "four" is accurate for those versions.
F-A3 — §17's artifact count contradicted its own body · adopted
approval-engine. §17 said "four artifacts are therefore required, owned by
Taxonomy" while its body says plainly that the decision-record schema is not
Taxonomy's, and a second — the emission-cadence declaration — is assigned to
info-tech-canon and net-kingdom and accepted in their own voice. The closing
paragraph then called three artifacts' ownership "still proposed" and settled one of
them in the same sentence. v0.8's own change item 10 claimed §17's stale paragraph was
corrected; the correction reached the emission-cadence paragraph and not the count.
Disposition. Adopted. Exactly two artifacts are unsettled — request-claim and
gap-record. The finding matters because access-engine took the decision-record schema
on against its own interest, and a stale paragraph was quietly undoing that.
F-A4 — the §19 hole is explained where nobody looks · adopted
approval-engine, marked minor. Headings ran §18 → §20 with the explanation in a §16
bullet. The removal was right and is not asked back — a grade inside a standard of
record becomes normative by adjacency — but a reader scanning structure cannot tell
whether an edit dropped a section. A stub now sits at the boundary.
N1 — net-kingdom corrected §11 in its own voice · accepted as landed
§17 confirmed unchanged: the profile assigns info-tech-canon the generic
EmissionCadenceDeclaration contract and net-kingdom the MUST/SHOULD split, the
rare-class rate-monitoring prohibition, and the heartbeat-plus-reconciliation
obligation. The ITC-WP-0018 / NK-WP-0035 acceptance record is accurate.
§11 diverged in both directions and was corrected in place at net-kingdom@da7747d, as
invited. As cut it required "heartbeat or reconciliation" of every load-bearing
source: that withholds from a volume class the expected-rate form the profile
permits, and accepts for a rare class either control alone where the profile
requires both. The conjunction is load-bearing — a rare class with a heartbeat alone has
no reconciliation to catch divergence, and one with reconciliation alone produces no
claim that can itself go missing, which is why §9.6 rejects rate monitoring there. §11
also contradicted its own next paragraph. The item now defers form to the governing
profile and adds that classification is the source's published inventory, never the
checker's to infer from an event name, payload, or observed rate — without which
omission detection is circular.
Implementation ahead of acceptance
Both engines implemented against the ruling before the round closed.
access-engine—FLEX-DEC-2026-007,dd3ce4c: publishesbinding.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 declarespdp_path;create()refusespdp_path: truewithout apdp_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 tofalserather than being back-filled, and a successor inherits its predecessor's declaration. Back-filling would have manufactured a statement no requester made, which isGH-DEC-2026-008's own objection to translation in another form.
Round closed
All findings above are dispositioned. Nine corrections landed in the text during
circulation (§15 items 12–20 at net-kingdom@64394e9); one request was declined with
its reasons stated in §6.4 rather than only here.
Two circulated repositories did not return a text review: kings-guard and
audit-core. The sections each was asked to attack — §9.5's criteria-grounding clause
and whether §12's step-four paragraph is now stale for the first, whether §11's
emission-guarantee wording lets a source imply completeness for the second — therefore
carry no assent from the repository best placed to test them. §14 records that as not
claimed rather than treating silence as assent. approval-engine did the same thing
voluntarily, naming the sections it did not read (§1–§4, §7, §8, §9.1–§9.2,
§9.5–§9.6, §9.8, §10, §18, §20) so a three-finding review would not read as a clean
bill.
Publication and the acceptance flip are net-kingdom's and were handed over on round
close. v0.7 stays accepted and in force until then, unpatched.
What the round showed
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.
Closed, the round says something narrower and worse. Every substantive finding was about a rule that read as satisfied by a check that did not satisfy it. Obligation 1 read as discharged by a digest comparison establishing something else. Obligation 3's totality read as satisfied by a catch-all that measured nothing. Obligation 3's drift test read as required and was optional. §17's status paragraph read as open on a question its own body had settled. §6.4's count sentence read as complete at four while five were listed. None was a wrong rule; each was a correct rule a careful implementer could satisfy without doing the thing it exists to require.
That is a failure mode this repository is structurally prone to, because doctrine is graded on whether it is right and consumed on whether it is checkable. Only the implementers can tell the two apart, and every one of these came back from a repository reading the text against its own code rather than against its own opinion.
Two repositories did not return one, and the standard now says so in §14 rather than counting silence as assent. A round whose value is that it catches this class is worth exactly what it covers, and it did not cover §9.5 or §11's emission wording.