gate-house/decisions/decisions.md
tegwick 42e9bcc747 Adopt the recomputability boundary as GH-DEC-2026-007
GH-WP-0003-T04. kings-guard's answer to KG-IN-0003 is adopted: the
posture/maturity line is recomputability, not volatility. Their argument
holds — volatility describes the two categories without partitioning
them, and every case it does not obviously cover becomes an argument at
exactly the boundary §6 exists to keep out of argument. The test is
§9.5's own determinism clause pointed where it had not been pointed.

Added one clause they did not propose, because their framing opens a
loophole: recomputability is assessed over the stated criteria, so a
criterion that dereferences a judgment is deterministic in form and
inferential in substance, and would put an opinion inside an engine
wearing a rule's clothes. A criterion MUST bottom out in evidence about
the subject, not in another party's conclusion about it. A recorded
judgment is evidence that the judgment was made, never that the thing
judged is so — the same distinction §9.6 draws about archives and
GH-DEC-2026-005 draws about valid_now.

All three kings-guard consequences carried, including the constraint they
volunteered against themselves (readiness is not an input to posture) and
their honest limit, which makes §17 load-bearing for the rule.

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 08:08:32 +02:00

43 KiB

Decision records

GH-DEC-2026-001 — NetKingdom security layer model, the gate-house re-cut, and the access-engine reframing

id: GH-DEC-2026-001
kind: decision
title: NetKingdom security layer model, the gate-house re-cut, and the access-engine
  reframing
status: resolved
owner: Bernd Worsch
repo: gate-house
standard: net-kingdom/canon/standards/security-layer-model_v0.1.md
source_note: history/2026-08-28-security-layer-model-and-gate-house-recut.md
requested_dispositions:
- approved
- revised
- rejected
affects:
- gate-house
- flex-auth
- ops-warden
- ops-mason
- kings-guard
- whitehat-security
- net-kingdom
- zone-engine
created: '2026-08-28T19:15:15.607849Z'
updated: '2026-08-28T19:16:01.456127Z'
rationale: 'Approved in session on 2026-08-28. The three rulings were taken interactively:
  Staff as the layer name, net-kingdom canon as the model''s home, and access-engine
  as the rename target with the lane/rule demarcation accepted as its cost. Approval
  covers the doctrine and documents only; the flex-auth rename remains a separate
  governed migration, and the standard stays proposed pending assent from flex-auth,
  kings-guard, and ops-warden.'
decided_by: Bernd Worsch
decided_at: '2026-08-28T19:16:01.456127Z'
state_hub_decision_id: "2d6509d0-ffd2-4209-89ab-bf68a4945ada"

Context

The security estate acquired overlapping claims to the same responsibility, and the overlap was invisible in each repository's own documents. gate-house was seeded as a deterministic authority plane — a policy decision point with an /authorize API, grant storage, and a revocation service — while flex-auth already described itself as the authorization control plane and was actively delivering FLEX-WP-0017, an approval contract binding approvals to action, actor, target, and validity window. Neither repository's INTENT named the other. zone-engine had already been ruled against on the same question.

Full review and evidence: history/2026-08-28-security-layer-model-and-gate-house-recut.md.

Decision requested

Ratify three linked rulings. They are one decision because the second does not hold without the first, and the third is the first applied to the repository that was already right.

Ruling 1 — Adopt the NetKingdom security layer model

The estate is layered Taxonomy → Tooling → Engines → Staff, distinguished by determinism and by the kind of artifact each layer produces. The top layer is named Staff — the general-staff sense of plans and doctrine without execution — not "Helpers", which undersold a layer holding architecture, controlling, and change.

The model is published as net-kingdom/canon/standards/security-layer-model_v0.1.md, owned by gate-house, status proposed. It belongs in net-kingdom canon rather than info-tech-canon because it is NetKingdom-flavored security architecture, not general semantic contract.

It carries two normative rules:

  • Staff never touches Tooling directly. It acts only through Engine APIs.
  • access-engine is the only policy decision point, generalizing to the whole estate the ruling first drawn in zone-engine/INTENT.md §5.

Ruling 2 — Re-cut gate-house as the doctrine council

Gate House is Staff: the council where NetKingdom's security and defence doctrine is established, documented, taught, and supervised. It holds no runtime position.

The decisive argument is gate-house's own: a decision point inside gate-house would place the deterministic authority boundary inside the non-deterministic management layer, violating INV-02 — the first invariant the repository exists to defend. The repository would have been the clearest available counterexample to the canon it hosts.

Boundary: the mandate and the operating mode are gate-house's; the decision is access-engine's; the credential is secrets-engine's; the perimeter is ops-mason's and ops-warden's.

gate-house keeps what no other repository owns — the operating modes, the principal/actor/runtime triple, mandates and authority ceilings, the change dynamics envelope, the MCP doctrine, the posture asymmetry, the assurance specifications, and the curriculum. It gives up /authorize, policy evaluation, policy engine selection, grant storage, and revocation.

Ruling 3 — Reframe flex-auth as an Engine and rename it access-engine

flex-auth is Engine-layer and remains the only policy decision point. It is renamed access-engine. auth-engine was rejected: key-cape owns authentication, and auth- preserves the ambiguity the rename exists to remove. permission-engine was rejected as ageing badly against a future role-engine.

The name's one cost is that "access" is already spoken for operationally by ops-warden and ops-mason. It is paid by a demarcation, now normative in §8 of the standard: ops-warden and ops-mason own access lanes — how a worker reaches a host; access-engine owns access rules — whether they may.

Sequence is binding: reframe the INTENT first, rename second, as a governed migration. The rename touches FLEX-WP prefix ownership, State Hub identifiers, ops-warden's routing tables, zone-engine's binding boundary text, and secrets-engine integrations.

The reframing also splits a responsibility flex-auth currently holds whole: authoring and governing policy is Staff work (gate-house); evaluating it deterministically and in-path is access-engine's, exclusively. This is the constructive resolution of the FLEX-WP-0017 overlap — gate-house designs the approval contract, access-engine validates approvals at decision time.

What approval authorizes

  • Publication of the layer model as a proposed net-kingdom standard.
  • The gate-house INTENT re-cut, already applied at 7f13f72.
  • The layering review notes placed at the top of twelve estate INTENT files.
  • Starting the flex-auth INTENT reframe.
  • Retiring the gate-house artifacts that describe an engine: ADR-003 (policy engine selection), milestones M0, M3, and M4, and GH-WP-0001-T04 (/authorize skeleton). GH-WP-0001 is rewritten against the re-cut before it is promoted to active.

What approval does not authorize

  • The flex-authaccess-engine rename itself. That is a separate governed migration with its own record, and it must not begin before the INTENT reframe lands.
  • Any change to zone-engine's 2026-08-23 disposition.
  • Promoting the standard from proposed to accepted.
  • Any change to another repository's workplans. Work structure stays with the repository doing the work.

Assent still required

Two adaptations move vocabulary away from repositories that currently use it, and follow the estate's precedent that a boundary is drawn on review by the other side rather than asserted — as flex-auth did to zone-engine:

  1. flex-auth — Engine framing, the rename, and the authoring/evaluation split.
  2. kings-guard and ops-warden — releasing "control plane" and the security curriculum respectively to the layers that own them.

Reversal

The rulings are documents; nothing executable depends on them yet, and no code exists in gate-house. Reversal is reverting the INTENT and standard commits. The falsifiers that should trigger reconsideration are in gate-house/INTENT.md § "What Would Make This Repository Wrong" — principally gate-house becoming a paper generator whose conformance loop never turns, or the estate declining to adopt the authority vocabulary.

GH-DEC-2026-002 — Revocation fails closed only when approval-engine's own store is down

id: GH-DEC-2026-002
kind: decision
title: Revocation fails closed only when approval-engine's own store is down
status: resolved
owner: Bernd Worsch
repo: gate-house
standard: net-kingdom/canon/standards/security-layer-model_v0.7.md
source_note: history/2026-08-29-approval-evidence-integrity-contracts.md
requested_dispositions:
- approved
- revised
- rejected
affects:
- gate-house
- approval-engine
- audit-core
- flex-auth
created: '2026-08-29T12:50:04.747439Z'
updated: '2026-08-29T12:50:58.873684Z'
rationale: 'Approved as GH-WP-0002-T03. Local-outbox fail-closed is the only remaining
  closed path: if approval-engine cannot insert the outbox row, the revocation does
  not commit. An audit-core outage must not block a revocation. Synchronous emission
  inside the mutation is forbidden even though it is atomic. Proceed-with-gap is rejected
  for load-bearing approval evidence.'
decided_by: Bernd Worsch
decided_at: '2026-08-29T12:50:58.873684Z'

Context

GH-IN-0001 (from audit-core) required that the revocation failure mode be a recorded decision rather than an implementation accident. Both sides are defensible on their own: fail-closed makes an audit dependency into an availability risk on the revocation path; proceed-with-gap needs a detectable marker so the gap is visible rather than silent.

v0.5's local-outbox rule already narrowed this. With the queue in approval-engine's own store, fail-closed triggers only when that store is down — where the change could not have been recorded anyway — and an audit-core outage does not block a revocation. Satisfying atomicity by emitting synchronously to audit-core inside the mutation is also atomic, and turns an audit outage into an inability to revoke: the operation least tolerable to block during an incident.

The statute states the locality rule at §9.4. This record is the decision the workplan still owed, so an implementer cannot pick the other side by accident.

Wire: docs/contracts/approval-outbox.md.

Decision

If the local outbox insert cannot commit, the revocation does not commit. The same rule applies to issuance, use, and supersession.

An audit-core outage MUST NOT block a revocation. Drain is asynchronous and at-least-once. audit-core dedupes on event_id.

Synchronous emission to audit-core inside the state-change transaction is forbidden, even though it is atomic.

Proceed-with-gap is rejected for load-bearing approval evidence. A revocation that succeeds while its event is lost is the exact case AUDIT-IN-0001 conditioned assent on.

What this authorizes

  • approval-engine failing a revoke (and any other mutation) when its own store cannot insert the outbox row.
  • Continuing to revoke while audit-core is down, with the row draining later.
  • Treating emit-after-commit, a second non-local queue, or a sync audit-core call inside BEGINCOMMIT as out of contract.

What this does not authorize

  • Claiming the outbox closes adversarial omission. Atomicity prevents crash; cadence and reconciliation detect suppression after the fact (§9.6).
  • A validity query on audit-core.
  • Any change to another repository's workplans.

Reversal

Revert this record and the outbox contract. The falsifier is operational: if failing closed on the local store removes the ability to revoke during the incidents this engine exists for, the trade needs revisiting — but the alternative is a silent evidence gap on the event an attacker most wants missing, which is worse.

GH-DEC-2026-003 — The PEP consumes an approval before the protected side effect

id: GH-DEC-2026-003
kind: decision
title: The PEP consumes an approval before the protected side effect
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
requested_dispositions:
- approved
- revised
- rejected
affects:
- gate-house
- approval-engine
- flex-auth
- secrets-engine
- ops-warden
created: '2026-08-29T12:50:06.944092Z'
updated: '2026-08-29T12:51:01.355583Z'
rationale: Approved as GH-WP-0002-T06. The PEP consumes by compare-and-swap before
  the protected side effect; the PDP never mutates; there is no unconsume. Same request
  digest is idempotent success; a different digest against a consumed object is conflict.
  This closes the three named races and unblocks APPROVAL-WP-0001-T05 and FLEX-WP-0017-T05.
decided_by: Bernd Worsch
decided_at: '2026-08-29T12:51:01.355583Z'

Context

Statute §16 left open who marks an approval consumed, and at what point relative to the decision. flex-auth named three failure modes neither engine closes alone: an ALLOW never consumed; a double consumption by racing callers; consumption after a failed action. approval-engine performs the mutation because access-engine never mutates, and refused to wire a public consume by guessing the contract. APPROVAL-WP-0001-T05 and FLEX-WP-0017-T05 are wait on this record.

§9.7.3 forbids inferring consumption from a decision record. That stands. The same paragraph currently reads as if the action must precede the consume call. That reading cannot enforce single use: two racing PEPs can both act, and CAS then prevents only the second record.

Decision

The PEP-shaped consumer consumes, by compare-and-swap, before the protected side effect. The PDP never mutates. Staff never calls consume.

There is no unconsume and no reserve/release. An approval authorizes one attempt, not one success. A consume followed by a failed action spends the object; retry is a new approval.

Same request_digest against an already-consumed object is idempotent success (a retry of one logical request). A different digest is conflict, and the PEP MUST NOT act.

The three failure modes have owners:

  1. Allow never consumed — PEP duty to consume; PDP lifetime bounds the window; a stale ALLOW without a matching use is a finding, not a consume.
  2. Double consumptionapproval-engine CAS; the PEP that receives conflict does not act.
  3. Consumed then the action fails — accepted as the cost of closing (2).

Protocol: docs/contracts/approval-consumption.md. Statute v0.8 will replace the §9.7.3 implication that action precedes the consume call; until then this record governs the blocked implementers.

What this authorizes

  • approval-engine exposing POST /v1/approvals/{id}/consume against this contract, including the digest column the internal CAS does not yet store.
  • FLEX-WP-0017-T05 requiring the PEP (secrets-engine, for that task) to consume before the OpenBao call.
  • Canon T-06 consume-side replay (a second, different digest against a consumed object) becoming in-scope once the endpoint exists.

What this does not authorize

  • The PDP consuming, or inferring consumption from a decision record.
  • Unconsume, reserve, or any path that returns a consumed object to approved.
  • A consume that is a decision ("may this actor do X").
  • Any change to another repository's workplans. Work structure stays with the repository doing the work.

Reversal

Revert this record and the consumption contract. The falsifier is operational: if spending an approval on a failed attempt makes the estate unable to complete the actions this object exists for, a reserve/commit protocol can be raised then. Unconsume is not the alternative — it reopens replay.

GH-DEC-2026-004 — Layer emission-cadence ownership between Info Tech Canon and Net Kingdom

id: GH-DEC-2026-004
kind: decision
title: Layer emission-cadence ownership between Info Tech Canon and Net Kingdom
status: resolved
owner: Bernd Worsch
repo: gate-house
standard: net-kingdom/canon/standards/security-layer-model_v0.7.md
source_note: kings-guard/specs/EmissionCadenceDeclaration.md
requested_dispositions:
- approved
- revised
- rejected
affects:
- gate-house
- info-tech-canon
- net-kingdom
- kings-guard
- qonto-assistant
created: '2026-09-04T00:55:29Z'
updated: '2026-09-04T00:55:29Z'
rationale: >-
  Approved interactively on 2026-09-04. The layered split gives each artifact
  one owner: ecosystem-wide semantics belong to info-tech-canon; NetKingdom-
  specific MUST/SHOULD rules and the low-volume load-bearing heartbeat-plus-
  reconciliation profile belong to net-kingdom. This avoids both a Staff-local
  consumer schema and competing Taxonomy definitions.
decided_by: Bernd Worsch
decided_at: '2026-09-04T00:55:29Z'
state_hub_decision_id: "89c73f45-d07b-40ea-b428-5a7375ce4b09"

Context

Security-layer-model v0.7 §§9.6 and 17 require evidence sources to declare an expected emission cadence so silence can become a finding. King's Guard is the only current consumer and drafted EmissionCadenceDeclaration.md against the real qonto-assistant source, but correctly declined to keep a Staff-local schema. The standard left ownership between the two Taxonomy repositories: info-tech-canon for ecosystem-wide semantic contracts and net-kingdom for NetKingdom standards of record.

Treating that as joint ownership would leave version authority ambiguous. Giving the entire artifact to either repository would instead conflate a reusable evidence/observability contract with the security obligations of one estate. The split is therefore made by artifact, with one owner for each.

Decision

info-tech-canon owns the versioned, ecosystem-wide EmissionCadenceDeclaration semantic contract. It owns the generic forms, fields, vocabulary, validation semantics, compatibility rules, and evolution of the contract.

net-kingdom imports that contract and owns the NetKingdom security profile. It owns which evidence classes MUST or SHOULD declare cadence, the rule that rate monitoring is forbidden for rare load-bearing classes, and the heartbeat-plus-reconciliation obligations that satisfy security-layer-model §9.6.

The remaining ownership boundaries are unchanged:

  • each source repository owns its declaration instance and emission behavior;
  • kings-guard owns stream evaluation and silence findings, not the schema;
  • Gate House owns doctrine and conformance supervision, not publication or runtime behavior.

The King's Guard draft remains the provenance and handover input. Once the Taxonomy artifacts are published, it becomes historical rather than a second contract.

What this authorizes

  • Requesting info-tech-canon to adopt, revise, or contest the generic contract and create its own owning work record.
  • Requesting net-kingdom to adopt, revise, or contest the security profile and create its own owning work record.
  • Sources such as qonto-assistant, approval-engine, and secrets-engine publishing instances against the eventual canonical contract and profile.
  • King's Guard replacing its draft-shaped fixture with the published contract without changing its consumer ownership.

What this does not authorize

  • Joint ownership or two independently versioned definitions of the generic schema.
  • Gate House or King's Guard retaining the schema as a local contract.
  • Gate House creating workplans in either Taxonomy repository.
  • Treating ownership as source conformance: qonto-assistant remains incomplete until it publishes and emits the required positive claim.

Assent and completion

The ownership ruling is resolved. Publication is complete only when both Taxonomy owners reply in their own voice and publish or explicitly schedule their respective artifacts. Until then the prior handover residual remains open, now with an unambiguous requested disposition.

Reversal

Supersede this record if the generic contract proves inseparable from the NetKingdom security profile, or if Info Tech Canon cannot provide a stable cross-domain contract boundary. Reversal must still name one owner for every artifact; returning to undifferentiated "Taxonomy ownership" is not an acceptable outcome.

GH-DEC-2026-005 — The approval-claim is the step-1 artifact on the PEP consumption path

id: GH-DEC-2026-005
kind: decision
title: The approval-claim is the step-1 artifact on the PEP consumption path
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
origin: GH-IN-0002
requested_dispositions:
- approved
- revised
- rejected
affects:
- gate-house
- approval-engine
- flex-auth
- secrets-engine
- ops-warden
rationale: 'Confirmed, with one addition. GH-DEC-2026-003 already named step 1 by
  endpoint and by field; the approval-claim is what that endpoint serves and valid_now
  is its field. ActionAuthorization is a proposed, unratified shape carrying no doctrine
  standing here. The addition is that the split validation is stated as doctrine rather
  than left implicit: each artifact is checked by the consumer against the layer that
  owns its data, and no PIP republishes a PDP decision. The state-hub authority requirement
  in the secrets-engine validator is struck because State Hub is a read model and
  holds no runtime approval authority.'
decided_by: Bernd Worsch
created: '2026-09-05T23:28:23.931441Z'
updated: '2026-09-05T23:28:23.931441Z'

Context

GH-DEC-2026-003 settled the consumption sequence and named step 1 by endpoint and by field: GET /v1/approvals/{id}/claimvalid_now (a fact, not permission). approval-engine serves the approval-claim at that endpoint (approval-engine/docs/approval-claim.md). secrets-engine's PEP validator (validate_action_authorization, src/secrets_engine/authorization.py) calls the same endpoint but expects a flex-auth ActionAuthorization. Two different objects were being assumed on one path, and the divergence would have surfaced at first live consume rather than at deployment.

ActionAuthorization originates in flex-auth/docs/action-bound-authorization-contract.md as a proposed shape for durable approval storage that the same document assigns to approval-engine. It was never ratified, appears nowhere in this repository's doctrine, and has no valid_now field. GH-DEC-2026-003 was issued after it without reference to it. There is therefore nothing to reconcile: the claim was the step-1 artifact all along, and this record says so where implementers will find it.

approval-engine raised the question rather than guessing, which is the behaviour §12 asks for. The three substantive assertions in the request were checked here independently before confirmation.

Decision

1. The approval-claim is the step-1 artifact on the GH-DEC-2026-003 path. It carries the approval fact: binding digest, validity window, consumption state, observation freshness, and issuer. Holding one with valid_now: true remains not authority to act.

2. ActionAuthorization is not required on that path. approval-engine is not expected to serve it and MUST NOT serve it from the claim endpoint. A step-1 response cannot contain a step-2 decision; any composed post-decision artifact would be a new artifact at a new endpoint. The proposal is shelved on this path, not withdrawn.

3. A PEP validates across the two artifacts it already fetches. The claim is checked for the approval fact; the flex-auth DecisionEnvelope from step 2 is checked for exact CheckRequest match and policy package/version pin. This is doctrine, not merely an implementation convenience: each artifact is validated against the layer that owns its data. A PIP republishing the PDP's decision would put a copy of the authority decision in a repository that did not render it — the same shape of error the re-cut removed from Gate House itself. No safety property is lost, because ActionAuthorization is a bundle of exactly these two checks.

4. The provenance.authority == "state-hub" requirement is struck. State Hub is a read model. It is not the runtime approval authority and never was; flex-auth's own contract says so. A validator that requires it would fail closed against every correctly issued claim. secrets-engine removes the constant with the validator split.

Consequent changes: approval-engine none — the claim schema stands as published; secrets-engine splits its validator and drops the authority constant; flex-auth records that the proposal is shelved on this path. Nothing here gates APPROVAL-WP-0002-T03secrets-engine is fail-closed until its own gates land, and this record governs first live consume, not deployment.

Deferred

A ratified post-decision ActionAuthorization — one composed, signed, forwardable object — remains coherent and is recorded here so it is not rediscovered as new. It is not adopted now because it has no named issuer or lifecycle owner and the sequence is already settled without one. Revisit on any of: a third or fourth PEP-shaped consumer; a requirement for a single signed forwardable artifact (offline verification, or an audit that must replay one object rather than a join); resolution of flex-auth's open G3 finding by composition rather than by adding a lifetime to the envelopestruck, see the amendment below; or assent of the statute §17 Taxonomy request-claim schema (APPROVAL-IN-0001) — in which case converge there and do not revive this separately.

Also rejected, so they are not re-proposed: serving ActionAuthorization at the claim endpoint (structurally impossible for step 1, and it would assert an authority approval-engine does not hold); and extending the claim with approvals.required_count or entries (publishing approver identities is a deliberate least-disclosure non-goal, and it would still not satisfy the validator).

Amendment, 2026-09-06 — the G3 trigger is struck

Recorded the day after this decision, on corrections volunteered independently by approval-engine and access-engine, and verified here against flex-auth/schemas/decision_envelope.schema.json.

FLEX-WP-0019 closed G3 on 2026-09-02 by adding the field: the schema requires lifetime whenever effect is allow, sourced from the policy package's allow_ttl with a 15-minute engine default, and allow_ttl: none renders a DENY with reason allow_lifetime_unstated rather than a standing grant.

The trigger was therefore already spent when this decision was written, and it resolved on the branch that removes the argument rather than the one that supports it. This is not bookkeeping. Carrying its own end was the one structural thing the composed bundle did that the split does not, so the strongest available case for ratifying option D is not merely unspent — it is answered, and the answer is no. A DecisionEnvelope now states its own lifetime without borrowing an ActionAuthorizationValidity.

Three revisit triggers remain: a third or fourth PEP-shaped consumer; a requirement for a single signed forwardable artifact; and assent of the §17 request-claim schema, where the instruction is to converge rather than revive.

The error came from sourcing the trigger from a 2026-08-29 alignment record rather than from current state — the same class of mistake as reading a change log for what the body says, which the v0.6 findings audit hit on the same day (docs/conformance/2026-09-06-v06-findings-audit.md). Both repositories reported it against their own interest, which is why it was caught within a day.

Stated consequence, 2026-09-06 — what the PEP stopped checking

Raised by secrets-engine on implementing the split, against its own position, and recorded here rather than left in a commit message.

The distinct-approver threshold is no longer verified independently at the PEP. The claim exposes no approver entries — publishing approver identities is the deliberate least-disclosure non-goal this decision upheld — so approval-engine folds the threshold into valid_now. That is the correct layer under this doctrine and it is also a genuine reduction in what the PEP checks on its own, and the second thing does not stop being true because the first one is.

The estate should hold this consciously. valid_now is a summary predicate, and a consumer of a summary trusts the issuer's evaluation of everything folded into it. The compensating property is not a second check at the PEP — that is the duplication the split removes — but reconstructability at the issuer: approval-engine's state transitions and its use outbox row must make the threshold evaluation recoverable after the fact under §9.6. Detection, not prevention, and it should be named as such in the same register as §9.6's other residual.

A second consequence, also from secrets-engine and also correct: two digests now cover the same proposed action and are never compared — approval-engine's binding digest over {action, actor, principal, purpose, target} and the flex-auth CheckRequest digest, with claim.binding.pdp_digest preferred where the issuer recorded one. They answer different questions at different layers and collapsing them would be a layer violation wearing the costume of a refactor. secrets-engine holds a test asserting the two functions disagree, which is the right way to defend a distinction that looks like duplication.

Reversal

Revert this record and the amendment to docs/contracts/approval-consumption.md. The falsifier is a demonstrated check that two-artifact validation cannot perform and a single composed artifact can — most plausibly offline or forwarded verification with no access to the PDP. That is a trigger for the deferred option above, not for returning ActionAuthorization to the claim endpoint, which stays forbidden on structural grounds regardless.

GH-DEC-2026-006 — The §13 registers become pointers only once maturity-engine publishes a readable export

id: GH-DEC-2026-006
kind: decision
title: The §13 registers become pointers only once maturity-engine publishes a readable
  export
status: resolved
owner: Bernd Worsch
repo: gate-house
standard: net-kingdom/canon/standards/security-layer-model_v0.7.md
source_note: workplans/GH-WP-0003-statute-v08-amendment-set.md (T03)
requested_dispositions:
- approved
- revised
- rejected
affects:
- gate-house
- net-kingdom
- maturity-engine
- ops-warden
- ops-mason
- user-engine
- tenant-engine
- access-engine
rationale: 'A statute of record should not carry state, and §13 and §13.1 are state:
  they change without the doctrine changing, and a hand-maintained table inside a
  standard is a register that drifts. maturity-engine is the right holder. But a pointer
  is only an improvement once there is something readable to point at — a standard
  that can only be understood by querying a live engine has traded one defect for
  a worse one, and it would make the statute unreadable to exactly the auditor it
  exists for. The migration is therefore conditioned on a committed, versioned export
  rather than declared outright. Until that export exists the tables stay and rows
  are transcribed, so no repository is left without an answer while the condition
  is outstanding.'
decided_by: Bernd Worsch
created: '2026-09-05T23:38:49.777532Z'
updated: '2026-09-05T23:38:49.777532Z'

Context

security-layer-model v0.7 §13 holds the open-gap register and §13.1 the PEP stance-map register. Both were created because the obligations above them named a register that did not exist — §9.1's own logic, that a requirement whose register is missing is a capability catalogued without a surface. They did their job.

maturity-engine (MAT-WP-0001) now holds both as queryable data: the §13 snapshot with state and owner-status intact, the §13.1 inventory, ASM-0ASM-6 registered as data owned by gate-house, pep-stance-publication owned by ops-warden, and blocked-clean scored equal to conforming by test. It proposes that the statute table become a pointer.

Four repositories are waiting behind the answer. user-engine and tenant-engine have published stance maps and asked for §13.1 rows; ops-warden is published and ops-mason is not. §6.4 obliges every PEP-shaped consumer to publish and obliges those maps to be inventoried. Each week the question stays open, the register either accumulates transcription or accumulates silence.

Decision

§13 and §13.1 become pointers to maturity-engine, and not before it publishes a committed, versioned export of both registers that is readable without a live query.

Two things are true at once and the ruling holds both.

A statute should not carry state. §13 and §13.1 change without the doctrine changing. A table maintained by hand inside a standard of record drifts, and every row transcribed into it is the manual step maturity-engine exists to remove. This is the same rule as GH-DEC-2026-005: the artifact is held by the layer that owns its data, and a repository that neither computes nor owns a fact should not be its register of record.

A standard must be readable on its own. A pointer to a live engine is not a register an auditor can read; it is an instruction to run software. Whatever else the statute is, it must be legible in git, at a version, to a reader with no cluster access — including a reader auditing the estate precisely because they do not trust its running systems. Replacing a drifting table with an unreadable reference trades a known defect for a worse one.

The condition reconciles them. maturity-engine computes and remembers; it also publishes the result as a committed artifact at a stated path and version, and the statute cites that path. The rows are then computed rather than transcribed, and still readable without a query. Publication is the migration's precondition, not its follow-up.

What happens meanwhile

The tables stay, and rows continue to be transcribed into §13.1 at each version cut. No repository waits on the export to get an answer. user-engine, tenant-engine, ops-warden and ops-mason are inventoried in v0.8 whether or not the export has landed by then.

This is deliberately the slower path. The alternative — strike the tables now and point at the engine — would close four open requests immediately and leave the statute stating an obligation whose register no reader can open, which is the exact defect §13.1 was created to fix. Repeating a defect in the other direction is not progress.

What is asked of maturity-engine

Not a new capability, a published form of one it has. The export must be a file in the repository, versioned, generated rather than hand-edited, carrying the same fields the statute tables carry today (§13: capability, kind, declarer, owner, state, owner-status; §13.1: consumer, stance map path, shape), and regenerable so drift between the export and the engine's own state is detectable. layer.yaml and pep-stance.yaml are the shape to follow: published, machine-readable, and asserted equal to shipped behaviour by a test. §6.4 obligation 3 already requires that equality of every PEP; a register of those maps should not hold itself to less.

When it exists, the §13 and §13.1 tables are replaced by a citation of it, and maturity-engine becomes the register of record.

Reversal

Revert to tables if the export proves to drift from the engine's computed state faster than a hand-maintained table drifted from reality — that is, if generation and publication decouple. The falsifier is mechanical: a regeneration that changes the committed export without any underlying evidence having changed, or an underlying change that does not reach the export.

GH-DEC-2026-007 — The posture/maturity boundary is recomputability, bounded by a criteria-grounding rule

id: GH-DEC-2026-007
kind: decision
title: The posture/maturity boundary is recomputability, bounded by a criteria-grounding
  rule
status: resolved
owner: Bernd Worsch
repo: gate-house
standard: net-kingdom/canon/standards/security-layer-model_v0.7.md
source_note: kings-guard/docs/PostureMaturityBoundary.md (KG-DEC-2026-002, KG-COM-0001)
requested_dispositions:
- approved
- revised
- rejected
affects:
- gate-house
- net-kingdom
- kings-guard
- maturity-engine
- access-engine
rationale: 'Adopted with one addition. kings-guard is right that volatility describes
  the two categories without partitioning them, and right that the discriminator is
  already in §9.5''s determinism clause rather than being a new rule. The addition
  closes the loophole the test leaves open: recomputability is assessed over the stated
  criteria, so any judgment can be made to look recomputable by writing a criterion
  that dereferences it. Criteria must bottom out in evidence about the subject, not
  in another party''s opinion recorded as evidence. Without that clause the test is
  satisfiable in form by exactly the inference it exists to exclude.'
decided_by: Bernd Worsch
created: '2026-09-06T06:07:34.017316Z'
updated: '2026-09-06T06:07:34.017316Z'

Context

GH-WP-0003-T04. v0.7 §9.5 states the maturity half of the boundary — "Given the same criteria and the same evidence it MUST return the same level; that determinism is what makes it an Engine rather than an opinion", and "A criterion that cannot be evaluated by rule is not yet a criterion." It does not state the posture half.

Gate House had proposed drawing the line on volatility: posture is fast-moving, maturity is slow. kings-guard answered KG-IN-0003 with a proposed revision (KG-DEC-2026-002, argued in kings-guard/docs/PostureMaturityBoundary.md) rejecting that line and offering recomputability instead. The commentary was also sent to maturity-engine.

The concern behind the original question stands and is why the line has to be exact: a second grading authority would be the same shape of mistake as a second decision point, and §6 says it would arrive the same way — gradually, each time for a good local reason.

Decision

The boundary 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.

The volatility line is withdrawn. kings-guard's argument against it is accepted in full: volatility is an observation about how a value has behaved, not a definition of what it is. It fails at both edges — a maturity criterion moves fast when evidence lands in a burst, and a posture sits unchanged for months on a healthy subject — and, more seriously, it describes the two categories without partitioning them. Every case it does not obviously cover becomes an argument, and arguments at a boundary are the mechanism §6 exists to prevent.

Recomputability is not a new rule. It is §9.5's own determinism clause pointed at the one boundary where it had not been pointed, which is why it can be adopted without enlarging the standard. §9.5 already states the maturity half; the posture half is its mirror, and the pair partitions: a criterion that cannot be evaluated by rule is not yet a criterion; a judgment that can be evaluated by rule is not posture — it is a criterion sitting in the wrong repository.

The addition — criteria must be grounded

Adopted with one clause kings-guard did not propose, and the reason is the loophole their own framing opens.

Recomputability is assessed over the stated criteria. That makes it mechanical, which is its virtue, and it also makes it satisfiable in form by the thing it exists to exclude. Any judgment can be made to look recomputable by writing a criterion that dereferences it: "level 2 iff the reviewer marked the control adequate" is perfectly deterministic — recompute it and you get the same answer every time — and it has smuggled an opinion into an engine wearing a rule's clothes. The engine would then be grading, deterministically, on someone's judgment, which is precisely the second grading authority the boundary is drawn to prevent.

Therefore:

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.

This is the same distinction §9.6 draws between what an archive proves and what it is read as proving, and the same one this repository applies to valid_now in GH-DEC-2026-005: a summary predicate is a fact about the issuer's evaluation, not a substitute for the evaluation. Without the clause the test is mechanical and circumventable; with it, the test is mechanical and the circumvention is itself checkable.

Consequences carried

The three kings-guard names are adopted as stated.

  1. The migration direction is permanent. Anything called posture that turns out to be recomputable moves to maturity-engine as a criterion; anything in maturity-engine that needs judgment is not yet a criterion and moves back to Staff. The boundary maintains itself under change because the test applies to each item rather than to the category.
  2. Two authorities cannot grade the same subject property, because a property is either recomputable or it is not, and that fact does not depend on which repository claims it. The failure becomes structurally prevented rather than conventionally avoided.
  3. Capability readiness MUST NOT be an input to posture. Readiness is deterministic; posture is not; feeding one into the other would make posture partly recomputable and blur the boundary from the kings-guard side. Volunteered by kings-guard as a constraint on itself and accepted as normative.

Consequence 3 also answers the second half of KG-IN-0003: tracking kings-guard's own gaps in maturity-engine creates no incident-time dependency, because posture evaluation never consults readiness. The dependency would exist only if the mistake consequence 3 forbids had already been made.

The limit is recorded, not resolved

kings-guard flagged, against its own proposal, that "the same evidence" is not well defined anywhere in the estate, so until §17's request-claim and gap-record schemas exist, recomputability is a thought experiment rather than a check. That is recorded in the statute alongside the test rather than left in the commentary. A boundary that is correct but not yet mechanically checkable does beat one that is checkable and wrong — but a reader is entitled to know which of the two they are holding. It makes §17 load-bearing for this rule.

The caution is also recorded: "posture" has the drift profile "control plane" had — it sounds specific and quietly absorbs whatever sits next to it. §8 exists because the estate has been bitten by exactly that, and this repository described itself as a control plane before the re-cut. The recomputability test is a defence against that drift because it can be applied to a candidate before the word is stretched to cover it. kings-guard asked to be held to it rather than trusted about it, and that is the standing it gets.

No change to §8's three-way split and no §4 catalog change. Posture stays non-deterministic and stays Staff; the test explains why, which is what was missing.

Reversal

Revert if the grounding clause proves to exclude criteria the estate needs — that is, if a legitimate maturity criterion cannot be expressed without dereferencing a judgment. The falsifier is a concrete criterion, not an argument that one might exist. The likely candidates are human-attested controls (a policy was reviewed, a drill was 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.