gate-house/decisions/decisions.md
repo-manager 23cbefcb7b repo.work.resolve_decision GH-DEC-2026-002
correlation_id: 75014e3f-ab3f-4038-9e2a-719f2da53abc
reason: GH-WP-0002-T03: record the revocation failure mode
source: repo-manager

Assistant: grok
Assistant-Session: 01a04d89-aaa5-7443-945e-b3055cd4b7e4
2026-08-29 14:50:58 +02:00

14 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: open
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:50:06.944092Z'

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.