gate-house/docs/amendments/v0.8-amendment-set.md
tegwick f0f888ca7e Close the binding-correspondence gap as GH-DEC-2026-008
access-engine raised, and declined to solve locally, a hole in the split
GH-DEC-2026-005 ruled on. approval-claim verification item 4 is a
disjunction and neither limb delivers "approved for THIS request" on the
PDP path: limb one requires translating between two engines' vocabularies
and no mapping is published, limb two (pdp_digest) is optional. Where the
digest is absent a consumer can hold valid_now true, receive an ALLOW,
consume and act with nothing establishing that approval and decision
concern the same action and target.

Ruled: the PDP digest is the correspondence and is required on that path;
a claim without one fails closed; the native limb survives only for
consumers already in approval-engine's vocabulary, including T-06. No
mapping is published — a translation can be wrong while still producing a
confident answer, it fails open, it would be owned by neither engine, and
recomputing another layer's binding is the re-derivation GH-DEC-2026-005
already forbids. The cost is stated: an approval issued without a bound
CheckRequest is unusable on this path, which is correct behaviour.

Also: adopted hub row b606e8ce as canonical for GH-DEC-2026-005 rather
than registering a duplicate; recorded approval-engine's narrowing of the
approver-threshold consequence (distinctness is a UNIQUE storage
invariant, so the PEP stopped checking that the engine applied its own
invariant, not whether dual control could be forged); and drafted A7/T08,
a §11 marking obligation and §12 consumer rule for derived summaries,
after four instances in one week across four repositories.

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
2026-09-06 09:32:20 +02:00

19 KiB
Raw Blame History

Security layer model — v0.8 amendment set

Repository: gate-house (author) Publisher: net-kingdom Project family: NetKingdom security layer Status: draft — normative text proposed, not yet cut Version: 0.1 Date: 2026-09-06 Workplan: GH-WP-0003 Base: net-kingdom/canon/standards/security-layer-model_v0.7.md (accepted)

What this document is

The exact normative text for the amendments GH-WP-0003 collects, section by section, against accepted v0.7. It is the reviewable unit: each amendment can be argued on its own wording here before any of them touch a cut document.

v0.7 is not patched in place. Nothing in this file is in force. Each amendment already governs its implementers through the decision record or contract named as its authority — this document moves them into the statute, it does not decide them again.

Assembly and circulation are GH-WP-0003-T06.

# Section Authority Task
A1 §9.7.3 GH-DEC-2026-003, docs/contracts/approval-consumption.md T01
A2 §11 docs/contracts/approval-emission-detection.md T02
A3 §13, §13.1 GH-DEC-2026-006 T03
A4 §9.5 GH-DEC-2026-007 T04
A5 §6.4, §8 GH-DEC-2026-005, GH-DEC-2026-008 T05
A6 §17 GH-DEC-2026-004 T07
A7 §11, §12 four observed instances; proposed by approval-engine T08

A1 — §9.7.3, consume ordering (T01)

Defect. v0.7 item 3 reads "the decision precedes the action and the action precedes consumption". That clause is a protocol, and it is the wrong one. It was written to support a forensic claim, not to specify an order, but implementers read it as the order — APPROVAL-WP-0001-T05 and FLEX-WP-0017-T05 were both blocked on it.

Why the stated order is unsafe. If the PEP acts and then consumes, two racing PEPs can both observe valid_now, both receive ALLOW, and both act. The CAS then prevents only the second record, not the second side effect. Single consumption becomes theatre — the property the mutation exists to provide is exactly the one the ordering destroys.

Replace item 3 with:

  1. Consumption is a state change, never an inference. An approval is consumed by a mutation in approval-engine (§9.4). It MUST NOT be inferred from the existence of a decision record: a decision record proves an intent to act, not an act.

    The PEP MUST obtain a successful consume before the protected side effect. Holding a claim with valid_now: true, or an ALLOW rendered against that claim, is not authority to act; the consume is. In-flight duplicate ALLOWs are expected and the CAS serializes use — a later CheckRequest sees valid_now: false and cannot mint a new ALLOW against the same object.

    v0.7 stated the opposite order. Acting first leaves the CAS able to prevent only the second record, never the second side effect, which makes single consumption theatre. This is a protocol correction and not a retraction of the forensic claim: consumption is still never inferred from a decision.

    An approval authorizes one attempt, not one success. There is no unconsume and no reserve/release; a consumed approval spent on a failed action is spent. Reversibility would reopen replay, which is the failure the mutation exists to close. Settled in GH-DEC-2026-003; the protocol is gate-house/docs/contracts/approval-consumption.md.

Item 4 stays as written. Its three failure modes now have owners rather than only names, in the same contract; the statute continues to name them and to point at it.


A2 — §11, the emission-guarantee declaration check (T02)

Why. GH-IN-0001 was found by argument, not by a check: audit-core noticed that §9.4 rested on a completeness property no archive can deliver. Nothing in v0.7 stops the next engine catalogued as an evidence source from reintroducing the same gap silently, because the obligation §9.6 creates is not on the conformance list.

Add to §11's "Mechanically checkable" list:

  • every repository catalogued in §4 as a source of evidence declares its emission guarantee in its machine-readable layer declaration: for a load-bearing source, a local transactional outbox (§9.4) plus a detection surface — heartbeat or reconciliation, per §9.6 — and its declared cadence; for an attributive source, the trade it makes and an explicit statement that completeness is not claimed.

Add after the list:

A source that declares nothing is not conforming, and neither is one that declares load-bearing emission with rate monitoring alone where its event class is rare (§9.6). The declaration is what makes §9.6 checkable rather than reviewable; without it the section states an obligation whose satisfaction cannot be observed, which is the §9.1 defect this standard has now corrected four times.

Drafted in gate-house/docs/contracts/approval-emission-detection.md, which approval-engine's cadence.yaml implements as the reference instance. Raised by audit-core as the general form of GH-IN-0001, so that the finding that produced GH-WP-0002 cannot recur unnoticed.


A3 — §13 and §13.1, register disposition (T03)

Settled by GH-DEC-2026-006. The tables stay in v0.8 and the four outstanding stance maps are transcribed into §13.1. The migration to maturity-engine is conditioned on a published export and is therefore a v0.9-or-later change, not this one.

Add to §13.1, after the table:

This register moves to maturity-engine when — and not before — that engine publishes a committed, versioned export of §13 and §13.1 that is readable without a live query, generated rather than hand-edited, and regenerable so drift between the export and the engine's computed state is detectable. A standard of record must stay legible in git, at a version, to a reader with no cluster access, including one auditing the estate precisely because they do not trust its running systems. A pointer to a live engine is an instruction to run software, not a register.

maturity-engine already holds both registers as queryable data (MAT-WP-0001); what remains is publication, which is the migration's precondition rather than its follow-up. Settled in GH-DEC-2026-006.

§13.1 rows to transcribe at the cut — carried here so the cut is mechanical:

Consumer Stance map Shape
ops-warden ops-warden/pep-stance.yaml total per zone; fail_open for z0z2 and unknown, sanctioned by §9.3 and recorded per §6.4 obligation 1 limb two; test asserts published map equals shipped default
user-engine user-engine/pep-stance.yaml total per zone; fail_closed for z0z3, unknown, and not-applicable; test asserts published map equals user_engine.pep_stance
tenant-engine tenant-engine/pep-stance.yaml total; fail_closed for unset, unreachable, non-allow, unknown; test asserts file equals shipped behaviour
ops-mason unpublished; PEP-shaped under §6.4 (opening a route). Recorded as a gap, not a stance

Three of four are total and fail-closed. The ops-mason row is the finding §6.4's closing paragraph anticipated, and it is more useful in the register than absent from it.


A4 — §9.5, the posture/maturity boundary (T04)

Settled by GH-DEC-2026-007, adopting kings-guard's KG-DEC-2026-002 with one added clause.

Append to §9.5, before the approvals/maturity closing paragraph:

The boundary with posture is recomputability, not volatility. Given the same criteria and the same evidence, recompute. If you MUST get the same answer, it is maturity and it belongs in an engine. If you CANNOT promise the same answer, it is posture and it belongs in Staff.

This is not a new rule — it is the determinism clause above, pointed at the one boundary where it had not been pointed. This section already states the maturity half: a criterion that cannot be evaluated by rule is not yet a criterion. The posture half is its mirror and completes the pair: a judgment that CAN be evaluated by rule is not posture — it is a criterion sitting in the wrong repository. Together they partition rather than describe, which a "fast-moving versus slow-moving" line cannot: volatility is an observation about how a value has behaved, and every case it does not obviously cover becomes an argument at exactly the boundary §6 exists to keep out of argument.

A criterion MUST bottom out in evidence about the subject, not in another party's conclusion about the subject. A recorded judgment may be evidence that the judgment was made — a fact with an issuer and a timestamp. It MUST NOT be evidence that the thing judged is so. Without this, the test is satisfiable by the inference it exists to exclude: "level 2 iff the reviewer marked the control adequate" recomputes identically every time and has placed an opinion inside an engine wearing a rule's clothes. For human-attested controls, grade on the attestation event's existence, freshness, and issuer — never on its verdict.

Three consequences follow. The migration direction is permanent: anything called posture that proves recomputable becomes a criterion in maturity-engine; anything in maturity-engine that needs judgment is not yet a criterion and returns to Staff. Two authorities cannot grade the same subject property, because a property is either recomputable or it is not, and that does not depend on which repository claims it. Capability readiness MUST NOT be an input to posture — readiness is deterministic and posture is not, so feeding one into the other would make posture partly recomputable and blur the boundary from the Staff side.

A limit, stated rather than implied. "The same evidence" is not yet well defined in this estate. Until §17's request-claim and gap-record schemas exist, two parties can disagree about whether they hold the same evidence, and recomputability is a thought experiment rather than a check. This makes §17 load-bearing for this rule. A boundary that is correct but not yet mechanically checkable is better than one that is checkable and wrong; a reader is entitled to know which they are holding.

Raised by kings-guard against the volatility line this repository had proposed, and against its own convenience — the readiness constraint is one it volunteered. Settled in GH-DEC-2026-007.


A5 — §6.4 and §8, validation by owning layer (T05)

Why it belongs in the statute. GH-DEC-2026-005 settled it on the approval path, but the property is general: it is a fact about the layer model, not about approvals, and it currently lives only in a decision record and a contract. The next consumer to join two artifacts will re-derive it or get it wrong.

Add as §6.4 obligation 5:

  1. Validation by owning layer. Where a PEP's decision to act rests on more than one artifact, each artifact MUST be validated against the layer that owns its data, and a PIP MUST NOT republish the PDP's decision. A PEP MUST NOT accept the approval fact from the decision artifact, nor the decision from the approval artifact.

    A composed object bundling both is not forbidden as an artifact, but it is post-decision by construction: it cannot be served from a pre-decision call, and it needs a named issuer and lifecycle owner before anyone may rely on it.

    The live instance is the GH-DEC-2026-003 consumption path: the approval-claim carries the approval fact (binding digest, validity window, consumption state, freshness, issuer) and the DecisionEnvelope carries the decision (exact CheckRequest match, policy package and version pin). Two digests may cover the same proposed action without being compared to each other; they answer different questions at different layers, and collapsing them is a layer violation in the shape of a refactor.

    A consumer of a summary predicate trusts the issuer's evaluation of everything folded into it. Where the split reduces what a PEP verifies independently — as valid_now does for an approver threshold the claim deliberately does not expose — the compensating property is reconstructability at the issuer under §9.6, not a second check at the consumer. That is detection, not prevention, and it belongs in the same register as §9.6's other residual.

    Correspondence is established by identity, not by translation. Where two artifacts use different vocabularies for the same request, the consumer compares a digest one layer computed and the other recorded — it MUST NOT recompute one layer's binding from the other's vocabulary, and no cross-engine mapping is published for it to use. A mapping can be wrong in a way that still produces a confident answer, and it would be a third authority on what a request is.

    Raised by approval-engine, and by access-engine twice against its own interest — once on its proposed artifact and once on a gap it declined to close locally. Settled in GH-DEC-2026-005 and GH-DEC-2026-008.

Add to §8's demarcations:

Validating a fact is not re-issuing it. A repository that checks an artifact against its issuer is consuming; a repository that serves another layer's conclusion as its own output is deciding early (§6.1), whatever the field is named.


A6 — §17, ownership is now assigned (T07)

Defect. §17 closes with "Ownership is proposed, not assigned… Neither has assented." That was true at the v0.7 cut and is now false. A reader of the accepted statute is told the estate has not decided something it has.

Replace that closing paragraph with:

Ownership of the emission-cadence declaration is assigned. info-tech-canon owns the versioned, ecosystem-wide EmissionCadenceDeclaration semantic contract — generic forms, fields, vocabulary, validation semantics, compatibility, and evolution. net-kingdom imports it and owns the NetKingdom security profile: which evidence classes MUST or SHOULD declare cadence, the prohibition on rate monitoring for rare load-bearing classes, and the heartbeat-plus-reconciliation obligations that satisfy §9.6. Each source repository owns its declaration instance and its emission behaviour; kings-guard owns stream evaluation and silence findings, not the schema.

The split was made by artifact so that each has one owner: joint ownership would leave version authority ambiguous, and giving the whole artifact to either repository would conflate a reusable evidence contract with the security obligations of one estate. Settled in GH-DEC-2026-004; both repositories accepted in their own voice (ITC-WP-0018, publishing ITC-EMISSION-CADENCE 0.1 in canon 0.7.0; NK-WP-0035, publishing emission-cadence-security-profile_v0.1.md). The kings-guard draft is frozen as assimilation provenance.

Ownership of the remaining three artifacts is still proposed. The request-claim and gap-record schemas sit between info-tech-canon and net-kingdom on the same unsettled line; the decision-record schema is access-engine's, per above. §2 keeps ownership in the owning repository's INTENT.md.


A7 — §11 and §12, derived summaries must be marked (T08)

Why. Four instances in one week, in four repositories, each caught only by another repository reading the authoritative body:

  • gate-house sourced a revisit trigger in GH-DEC-2026-005 from a 2026-08-29 alignment record rather than from flex-auth's current schema;
  • gate-house read a change log for what §3.4 contained, which is the defect kings-guard raised against v0.6 and the reason docs/conformance/2026-09-06-v06-findings-audit.md checked the body instead;
  • access-engine published a dual-control rule written against its own assumption of the approval claim rather than approval-engine's published schema — it required a status field and an approver list that do not exist, and every live destroy would have denied regardless of the approval (failed closed, fixed in 68ad039);
  • secrets-engine read a fixture for its contract's prose, and separately carried two workplans asserting that remaining authorization work was external, which kept an unimplemented local stub invisible.

Different artifact classes — change log, alignment record, fixture, workplan summary — one shape. As approval-engine put it, at four instances this is not coincidence but a property of how this estate publishes: authoritative bodies with derived summaries and examples alongside them, and no staleness marker on the derivatives. A reader cannot tell from the artifact whether it is current, so the diligent and the careless read it the same way.

Three of the four were reported by the repository that had made the error, against its own interest. That is the loop working, and it is also the argument for a check: a control that depends on four repositories volunteering corrections is not a control.

Add to §11's "Mechanically checkable" list:

  • every derived artifact in an estate repository — change log, review record, alignment note, example, fixture, or summary that restates a normative body — is marked as derived, names the authoritative artifact it derives from, and carries the version or commit it was derived at.

Add to §12, as a paragraph of the loop:

A derived summary is not evidence of what the body says. A repository acting on another repository's contract, schema, or standard MUST read the authoritative artifact, not a summary, example, or review record of it. This is not a counsel of care: the estate has produced four instances in a single week, in four repositories, each caught only because a second repository read the body. Diligence did not prevent any of them, and in three the erring repository reported itself.

The obligation on the publishing side is §11's marking rule; this is its consumer half. Where a derivative is unmarked, treat it as stale.

Note on scope. This is the cheap half. It does not detect a derivative that is marked and still wrong, and it should not claim to — the marking makes staleness visible, it does not measure it. Naming that limit here so the check is not later read as stronger than it is, which would be the same defect one layer up.


Not in this set

Recorded so the omissions are deliberate rather than forgotten.

  • §12's fourth step remains unstaffed. Observation in production is still not live; kings-guard's qonto-assistant pilot is fixture-only. That is a status, not an amendment, and §12 already says so.
  • §16's open questions are not re-cut here. Several have been answered by decision records since v0.7. Reconciling §16 against the decision log is T06 work at assembly, not a separate normative amendment.
  • No §4 catalog change. None of these amendments moves a capability between repositories.