diff --git a/README.md b/README.md index 80682f3..3235040 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ The dynamic, self-optimizing security platform is the long-term direction in ## Orientation - [SCOPE.md](SCOPE.md) — what this repo owns, current state, and when it is relevant -- [Security layer model](canon/standards/security-layer-model_v0.6.md) — how the +- [Security layer model](canon/standards/security-layer-model_v0.7.md) — how the security estate is layered (Taxonomy / Tooling / Engines / Staff) and what each layer may own - [Agent companion](canon/standards/security-layer-model-companion_v0.1.md) — the diff --git a/canon/standards/security-layer-model-companion_v0.1.md b/canon/standards/security-layer-model-companion_v0.1.md index b82f2df..5b5d8fe 100644 --- a/canon/standards/security-layer-model-companion_v0.1.md +++ b/canon/standards/security-layer-model-companion_v0.1.md @@ -5,7 +5,7 @@ title: "NetKingdom Security Layer Model — Agent Companion v0.1" domain: netkingdom status: proposed version: "0.1" -companion_to: canon/standards/security-layer-model_v0.6.md +companion_to: canon/standards/security-layer-model_v0.7.md owner: gate-house publication_owner: net-kingdom created: "2026-08-29" @@ -16,7 +16,7 @@ standard_token: security-layer-model-companion_v0.1 # Security Layer Model — Agent Companion -**This is the operative form of `security-layer-model_v0.6.md`.** Same rules, no +**This is the operative form of `security-layer-model_v0.7.md`.** Same rules, no change log, no review history. The statute governs where the two disagree; if you find a disagreement, report it — that is a finding, not a formatting problem. @@ -187,6 +187,10 @@ Stated so nobody plans around a capability that does not exist: --- -**Statute:** `canon/standards/security-layer-model_v0.6.md`. +**Statute:** `canon/standards/security-layer-model_v0.7.md`. +**Known gap in this version:** §5.3 says publish your stance map but not *where*, +and omits the statute's §6.4 inventory obligation — a repository could satisfy +this document and no register would learn of its stance. Fixed in v0.2; until +then read statute §6.4 and §13.1. **Owner:** gate-house. **Report a disagreement between this and the statute as a finding.** diff --git a/canon/standards/security-layer-model_v0.6.md b/canon/standards/security-layer-model_v0.6.md index b9ef5fa..8c3d2b3 100644 --- a/canon/standards/security-layer-model_v0.6.md +++ b/canon/standards/security-layer-model_v0.6.md @@ -3,7 +3,7 @@ id: netkingdom-security-layer-model-v0.6 type: standard title: "NetKingdom Security Layer Model v0.6" domain: netkingdom -status: proposed +status: superseded version: "0.6" supersedes: canon/standards/security-layer-model_v0.5.md owner: gate-house @@ -14,6 +14,7 @@ last_reviewed: "2026-08-28" review_interval: 3m source_revision: "gate-house@516ed4e" standard_token: security-layer-model_v0.6 +superseded_by: canon/standards/security-layer-model_v0.7.md assented_by: - "flex-auth FLEX-DEC-2026-001" - "kings-guard KG-DEC-2026-001" @@ -33,6 +34,12 @@ related: # NetKingdom Security Layer Model v0.6 +> **Superseded 2026-08-29 by [v0.7](security-layer-model_v0.7.md).** This version +> announced a human/agent principal separation in its change log and never wrote +> it into §3.4 — a silent edit failure found by `kings-guard`. Its §6.4 also +> forbade both the fail-open stance §9.3 sanctions and the session-bound allow +> §9.7.1 permits. Do not cite §3.4 or §6.4 from this version. + ## 1. Purpose This standard states how NetKingdom's IT-security estate is layered, and what diff --git a/canon/standards/security-layer-model_v0.7.md b/canon/standards/security-layer-model_v0.7.md new file mode 100644 index 0000000..e4e162c --- /dev/null +++ b/canon/standards/security-layer-model_v0.7.md @@ -0,0 +1,1387 @@ +--- +id: netkingdom-security-layer-model-v0.7 +type: standard +title: "NetKingdom Security Layer Model v0.7" +domain: netkingdom +status: proposed +version: "0.7" +supersedes: canon/standards/security-layer-model_v0.6.md +owner: gate-house +publication_owner: net-kingdom +created: "2026-08-28" +updated: "2026-08-28" +last_reviewed: "2026-08-28" +review_interval: 3m +source_revision: "gate-house@516ed4e" +standard_token: security-layer-model_v0.7 +# "assented_by" records assent to a BOUNDARY, given at the version named. +# It is not assent to the current text. Revision reviews are listed in §14. +assented_by: + - "flex-auth FLEX-DEC-2026-001" + - "kings-guard KG-DEC-2026-001" + - "ops-warden ADR-0010" + - "audit-core AUDIT-IN-0001, and v0.4 review with three findings" + - "flex-auth FLEX-DEC-2026-002 (v0.4, §9.3 contested)" + - "kings-guard v0.4 review, four findings" + - "ops-warden 2026-08-29 v0.4 review, three findings" +related: + - canon/standards/security-zones_v0.1.md + - canon/standards/tenancy-posture_v0.1.md + - canon/standards/credential-management_v0.2.md + - gate-house/decisions/decisions.md + - net-kingdom/history/2026-08-29-layering-standard-assessment.md + - gate-house/history/2026-08-28-security-layer-model-and-gate-house-recut.md +--- + +# NetKingdom Security Layer Model v0.7 + +## 1. Purpose + +This standard states how NetKingdom's IT-security estate is layered, and what +each layer may and may not do. It answers one question: + +> **Given a repository, which layer is it in, and what does that permit it to +> own?** + +The layers are distinguished by **determinism** and by **the kind of artifact +the layer produces**, not by technical tier, deployment topology, or team. + +It is not an org chart, not a network model, not a deployment topology, and not +a dependency graph. It does not assign work, and it does not replace any +repository's boundary contract; it constrains what such a contract may claim. + +**What changed in v0.7.** v0.6 announced a rule it never wrote: §1 and §15 said +the standard separates human and agent principals inside Staff, and §3.4 was +byte-identical to v0.5. `kings-guard` found it and put it correctly — *a rule +stated about a standard in its own change log is not a rule*, which is §11's own +principle turned on the standard. §3.4 is now written. + +The rest are collisions between rules written for the clean case: §6.4's first +obligation forbade what its third obligation blesses, and its second forbade the +session-bound allow §9.7.1 permits. §9.4's atomicity was described as closing a +threat it does not close. §19 graded the document it lived in. And §20 records +the interaction boundary with Railiance operations, on definitions from +`railiance-master` rather than inference. §15 records the change list. + +**What changed in v0.6.** An independent assessment against industry practice +(`net-kingdom/history/2026-08-29-layering-standard-assessment.md`) found the model +sound as a layering constitution and incomplete as a *self-healing* one: cognition, +authority, and execution are specified, but the two verbs that close a healing +loop — observe in production and actuate through a deterministic surface — are +pending, and one is unstaffed. It also found the Engine layer untyped, so that +"we need an engine for X" drifts toward "X now decides", and the enforcement +point unnamed. + +v0.6 types the engines (§3.3), names the enforcement point (§6.4), replaces the +containment assignment with an actuation surface held at zero (§9.2), separates +human and agent principals inside Staff (§3.4), puts time into the model (§9.7), +requires the Taxonomy artifacts that make §6.2 compileable rather than +reviewable (§17), and composes the sibling standards it had only cited (§18). +Section numbers below §14 are unchanged: the estate cites them. + +**What changed in v0.5.** All four reviewing repositories returned findings on +v0.4, and one contested a rule. §9.3 was wrong: it collapsed *engine reachable +but degraded* with *engine not reachable at all*, and the second case has no +evaluator in the path to express anything. §9.1 collapsed *no route exists* with +*route exists under a declared gap*, which would have forced a false "pending" +onto a production capability. §11 claimed mechanical checkability for a rule +that cannot be checked in prose. §13 filed two opposite conformance states in one +table and recorded proposed owners as owners. §9.6 needed the load-bearing +distinction it implied but never drew. §15 records the change list. + +**What changed in v0.4.** `audit-core` assented to the approval evidence half +and corrected the rationale twice. v0.3 rested §9.4 on that repository's INTENT +principle 6, which is an aspiration; the shipped bound in its `docs/integrity.md` +is weaker and conditional. More consequentially, no append-only archive can prove +**omission at source** — a suppressed revocation leaves the chain intact — which +is now stated as an estate-wide doctrine constraint (§9.6) rather than left +implicit. `audit-core` was also referenced as an owner in v0.3 without appearing +in the §4 catalog at all; it is catalogued here, as an Engine, on its own +declaration. §15 records the change list. + +**What changed in v0.3.** Two engines were seeded to own concepts v0.2 recorded +as unowned: `approval-engine` takes the approval object that §13 left homeless, +and `maturity-engine` takes graded progression — closing a §9.1 defect in +gate-house's own catalog claim, which asserted conformance review with no engine +to act through. §15 records the change list. v0.3 is **proposed**: the two new +engines are seeded by owner direction and have no other side to assent yet, and +the evidence half of the approval split needs `audit-core`'s assent. + +**What changed in v0.2.** v0.1 was assented to by all three repositories whose +boundaries moved, and each returned a finding. v0.1 had one lane for a Staff +repository that legitimately touches Tooling — read-only diagnostics — which is +narrower than the estate as it actually stands, and a rule with no lane for a +real sanctioned case is satisfied by relabelling rather than by closing the gap. +v0.1 also catalogued a capability (§4, containment) that §5 forbade discharging, +and applied its reconstructability test to engines but not to the doctrine +gate-house feeds them. §15 records the full change list. + +## 2. Authority and conformance + +| Fact or rule | Authority | +| --- | --- | +| The layers, their definitions, and the rules between them | This standard, owned by gate-house | +| Which layer a given repository is in | This standard, §4 catalog | +| What a repository owns within its layer | That repository's `INTENT.md` and boundary contract | +| Whether a specific request is permitted | `access-engine` — never this standard | +| Whether a Tooling contact is sanctioned | The declaring repository, under the shapes in §5, reviewable by gate-house | +| Security doctrine and invariants | gate-house | +| Publication | net-kingdom canon | +| Whether an invariant is *watched in practice* | the observing repository's own report — never this standard, and never §12's diagram | + +A repository conforms when its `INTENT.md` declares its layer, its claims fall +within that layer's permissions (§3), and its Tooling contacts take one of the +sanctioned shapes in §5 or are declared as gaps under §5.3. + +**No estate argument may cite observation that has not happened.** §12 lists +`kings-guard` against the loop's fourth step, and that repository has reported +that it has never observed a real event. Until it reports otherwise, no +assessment, review, or decision in this estate may treat an invariant as being +watched in practice on the strength of the diagram. Lifted here from §12 so it +cannot be lost in a summary. + +## 3. The layers + +| Layer | Character | Produces | Deterministic | +| --- | --- | --- | --- | +| **Taxonomy** | cross-cutting language | terms, semantic contracts, standards | n/a — describes | +| **Tooling** | infrastructure and state | data structures, persistence | yes | +| **Engines** | interfaces for a modeled concept | APIs, contracts | yes | +| **Staff** | management, operations, change, controlling | specifications, decisions, workplans, tasks | **no** | + +### 3.1 Taxonomy + +Cross-cutting language. Taxonomy repositories define terms and semantic +contracts so the other layers interoperate without integration by +interpretation. They own no runtime position and no state any layer depends on. + +`info-tech-canon` holds ecosystem-wide semantic contracts. NetKingdom-specific +security architecture — including this standard — is net-kingdom canon's. + +### 3.2 Tooling + +Deterministic infrastructure: data structures, persistence, and the consistent, +performant, scalable keeping of state. Much of it is third-party. + +### 3.3 Engines + +Deterministic APIs for a modeled concept — a user, a tenant, a zone, a secret, +an access rule. An engine's defining property is that **the same authoritative +input state yields the same result**. Engines are where the estate's +deterministic guarantees live, and therefore where every enforcement boundary +MUST sit. + +A repository whose core function is inference or judgment fails this test by +construction and is Staff, however much of its work happens at runtime. + +**Engines are typed.** "Engine" is one layer but four roles, and collapsing them +hides different failure modes. Every §4 Engine row carries a role: + +| Role | Meaning | Outage means | +| --- | --- | --- | +| **PDP** | renders the authorization decision — `access-engine`, and only it (§6) | consumer residue (§9.3) | +| **PIP** | supplies facts a decision consumes as claims — user, tenant, zone, approval, maturity | input degradation, engine's own fallback (§9.3) | +| **Evidence** | records what happened and proves integrity of what it holds — `audit-core` | MUST NOT block the operation being recorded — a default, not a property; see below | +| **Lifecycle** | a deterministic API over Tooling it owns — `secrets-engine` | the owning engine's failure semantics | + +The roles are why *"we need an engine for X"* does not mean *"X now decides"*. +A new engine is a PIP unless this standard is amended to say otherwise, and §6 +means it can never be a second PDP. + +The Evidence row's outage rule is an estate **trade**, not a property of +evidence engines. Choosing availability there means accepting that a compromised +source can suppress a record and that detection is the answer (§9.6). The +opposite shape — *do not proceed unless an independent custodian already holds +the record* — is the only one that puts evidence outside the actor's blast +radius **before** the act. The estate has not needed it, so it is not ruled out +by a table cell: an operation whose control genuinely requires independent +recording before effect is a declared exception, raised when needed. Raised by +`audit-core` against its own row. + +The industry vocabulary is deliberately mirrored here — PDP, PIP, PEP as in +NIST ZTA and XACML — because it is how the estate talks to the outside and how a +PEP is stopped from quietly becoming a PDP. The determinism cut in §3 stays +primary where the two disagree. + +### 3.4 Staff + +Interactive and non-deterministic. Staff is the management layer: operations, +change, innovation, and controlling. It works through agentic capability — +assistants and autonomous agents — and its artifacts are specifications, +decisions, workplans, and tasks. + +Staff repositories MUST NOT hold state that another layer depends on at +runtime, and MUST NOT render or cache any decision an Engine is responsible for. + +Acting at runtime does not make a repository an Engine. Being agentic makes it +Staff, and §5 governs how it acts. + +**Two principals, one layer.** Humans and agents are both non-deterministic and +both Staff, so they share the layer's permissions. They do not share blast +radius. Four rules bind the agent principal specifically: + +1. **No standing credential.** An agent holds no long-lived credential of its + own. Authority is issued per task, time-bounded under §9.7, and attributable + to the principal on whose behalf it acts. +2. **Tool use is a conduit or an Engine API.** An agent acts through §5.2 — the + owner's tool under the caller's identity, presenting no authority of its own + — or through an engine. There is no third route. Tool availability is not + permission: a callable tool means the operation exists, not that this actor + may invoke it. +3. **Agent memory is not a state plane.** Agent memory, tool-call traces, and + prompt caches are the agent's own. They MUST NOT become state another layer + depends on at runtime unless catalogued as Tooling in §4, which subjects them + to §5 like anything else, and to §5's sunset. +4. **Every agent action is reconstructable as the caller's action**, bounded by + §9.6 — the archive shows the actions it received, not that it received all of + them. + +Session semantics — session loops, tool policy, harness routing, model +selection — are **not** governed here. They belong to `glas-harness` and its +`rein-*` backends (§20). This standard governs what an agent may be authorized +to do; `glas-harness` governs how an agent session is conducted. Rule 2 is the +seam between them, and neither side may treat its own half as sufficient. + +v0.6 claimed these rules in its change log and did not write them. Found by +`kings-guard`, which is the repository they bind hardest and which offered to +assent to them sight-unseen. + +## 4. Layer catalog + +| Repository | Layer | Role | Owns | +| --- | --- | --- | --- | +| `info-tech-canon` | Taxonomy | — | ecosystem-wide semantic contracts and terminology | +| `net-kingdom` | Taxonomy | — | NetKingdom standards of record; publication | +| `key-cape` | Tooling | — | packaged identity tooling; IAM profile; authentication | +| `OpenBao` | Tooling | — | secret storage, leases, PKI, dynamic secret engines | +| `user-engine` | Engine | PIP | users, accounts, memberships | +| `tenant-engine` | Engine | PIP | tenant-as-an-entity facts | +| `zone-engine` | Engine | PIP | zone identity and membership — offline reference conformance per its 2026-08-23 disposition | +| `secrets-engine` | Engine | Lifecycle | credential abstraction, custody, lifecycle | +| `audit-core` | Engine | Evidence | audit event custody, retention, integrity verification, export — explicitly not a decision point (§9.6) | +| `access-engine` | Engine | **PDP** | **the policy decision** — the only decision point (§6) | +| `approval-engine` | Engine | PIP | the approval object — durable, authenticated, consumable, atomically supersedable (§9.4) | +| `maturity-engine` | Engine | PIP | graded progression against declared criteria and evidence; the gap register; capability readiness (§9.5) | +| `gate-house` | Staff | — | security doctrine, authority context, curriculum; **conformance review — through `maturity-engine` (§9.5)** | +| `ops-mason` | Staff | PEP-shaped | building and tearing down access routes and perimeters | +| `ops-warden` | Staff | PEP-shaped | operational access lanes, stewardship, runbooks; SSH certificate issuance — **declared-gap** (§9.1, §13) | +| `kings-guard` | Staff | — | adaptive defence and judgment; observation of Staff-reachable sources — identity and secret observation **pending**; **proposes** containment, which it does not own (§9.2) | +| `whitehat-security` | Staff | — | offensive validation | + +An **actuation surface** — reduce authority, require step-up, isolate a workload +— is catalogued nowhere because it does not exist. See §9.2: it is an Engine +concept held at zero, not a Staff capability. + +`access-engine` is the ruled name for the repository currently called +`flex-auth`; both denote the same authority until the governed rename completes. +Execution conditions for that rename are recorded in its migration decision, not +here. + +## 5. The binding rule + +> **Staff never touches Tooling directly. It acts only through Engine APIs.** + +A Staff repository MUST NOT hold a direct client for a Tooling-layer system — +no direct database connection, no direct OpenBao client, no direct cluster +mutation — outside the shapes below. This is the architectural form of *no +privilege from cognition*, and it is deliberately mechanically checkable. + +**Scope.** "Tooling-layer system" means a system catalogued as Tooling in §4. +Infrastructure the estate runs but has not catalogued — the State Hub, +`llm-connect`, and similar — is outside this rule, because a rule that silently +covered them would put every Staff repository in undeclared violation on +adoption day: they all write progress events. Such clients SHOULD be recorded +in the repository's declaration as non-Tooling for completeness of the check, +and the way to bring one under §5 is to catalogue it in §4, deliberately. + +Raised by `ops-warden`, which held clients for both and declined to resolve the +scope question on gate-house's behalf. + +**The carve-out sunsets.** It is a pressure valve, and a valve left open becomes +a second persistence plane under the Staff layer — which §3.4 forbids in spirit. +Three rules bound it: every non-Tooling client MUST be listed in the +repository's declaration; an uncatalogued store that another layer **reads** +MUST, within two review intervals, either be catalogued as Tooling in §4 or be +declared a gap under §5.3; and a Staff-owned event bus or memory store MUST NOT +become the estate's de facto state plane. Today's instances are the State Hub +and `llm-connect`; tomorrow's are agent memory, tool-call traces, and prompt +caches (§3.4). + +Three shapes are sanctioned. Everything else is a violation. + +### 5.1 Read-only diagnostic observation + +A Staff repository MAY read Tooling state for diagnostics where the owning +engine exposes no equivalent. It MUST be declared in the repository's +`INTENT.md`. It grants no write, and it is an engine gap to close, not a +standing arrangement. + +### 5.2 Conduit + +A Staff repository MAY run the **owner's** tool under the **caller's** identity, +supplying no authority of its own. The test is the supplied-authority property: +the conduit MUST NOT present its own credential, MUST NOT widen what the caller +could already do, and MUST be reconstructable as the caller's action in audit. + +A conduit that presents its own token is not a conduit; it is §5.3 or a +violation. This shape MUST be declared, and the no-authority property SHOULD be +covered by a test. + +The reconstructability requirement is an audit-dependent claim and is therefore +bounded by §9.6: the archive shows the conduit actions it received, not that it +received all of them. + +### 5.3 Declared engine gap + +Where a Staff repository must contact Tooling directly and no engine exposes the +capability, it MUST declare the contact rather than take an exemption. A +declared gap carries, machine-readably: + +| Field | Meaning | +| --- | --- | +| `capability` | what the contact does | +| `intended_owner` | the engine that should own it | +| `blocked_on` | why it cannot move today | +| `review` | a date, not "when convenient" | + +A declared gap is **tracked non-conformance**, not conformance. It does not +expire on its own and it is not a licence to add more. It exists because a rule +offering no lane for a real sanctioned case gets satisfied by relabelling rather +than by closing the gap — and a tracked gap is visible, whereas a relabelled one +is not. + +Prior art: `ops-warden` runs equivalent machinery for delegated lanes (27 +catalog entries carrying `delegation:`, queryable via `warden route gaps`), and +has offered it as reusable. + +**No fourth "operator of third-party Tooling" shape.** It has been proposed, on +the argument that someone must operate `OpenBao` and every operational necessity +otherwise looks like a gap. Declined: §5.3 already sanctions the operation while +keeping it visible, and a clean "operator" shape would convert a tracked gap +into a permanent allowance — the relabelling failure this standard exists to +prevent. A permanent operational necessity is a declared gap whose review +interval keeps returning, which is the correct amount of friction. If the review +becomes ceremonial, that is an argument for closing the gap, not for renaming +it. + +## 6. One decision point + +`access-engine` is the only policy decision point in NetKingdom. No other +repository, in any layer, may render or cache authorization decisions. + +First ruled in `zone-engine/INTENT.md` §5 — *"flex-auth is the policy decision +point. It stays the only one."* The failure mode, from the same source: *"It +becomes a second decision point… it would arrive as a small convenience."* + +### 6.1 Compiled data that determines an outcome is still deciding + +A registry, cache, or schema that resolves a result before the engine runs has +decided early. Provenance MUST remain reconstructable from the engine's decision +record. + +### 6.2 Doctrine reaches the decision as an input, or it is not applied + +This rule binds gate-house on the same terms. **An authority ceiling, mandate +constraint, or operating-mode restriction that determines an outcome MUST reach +the decision either as an input claim on the request or as a rule in the +versioned policy package**, so that its application is reconstructable from the +decision record. + +Doctrine that influences outcomes by any other route is a second decision point +wearing an author's hat. This is not a limit on gate-house's authorship; it is +what keeps that authorship auditable at decision time. + +### 6.3 No Staff repository may host a decision point + +A deterministic authority boundary inside a non-deterministic layer contradicts +the invariant the estate is built on. gate-house was re-cut on this ground. + +### 6.4 The enforcement point + +The standard has been precise about the decision and silent about the gate. A +decision that nothing refuses to proceed without is advice. + +A **PEP** is any runtime that causes a protected side effect. It is a *shape*, +not a repository: `ops-warden` issuing a certificate, `ops-mason` opening a +route, and any protected system acting on a verdict are all PEP-shaped. Being +PEP-shaped does not move a repository out of its layer. + +Four obligations, and they are normative: + +1. **No side effect without a decision record, or a recorded stance.** A PEP + MUST NOT perform the protected action unless it holds a decision from + `access-engine` identifying the request it was rendered for, **or** its + declared §9.3 stance for the applicable scope permits proceeding without one + **and the application of that stance is recorded in place of the decision**. + The second limb is stricter than silence, not looser: a fail-open result is + metadata, never an absent record. `ops-warden` `ca.py` writes the zone, the + failure mode, and a decision id present only where a decision was rendered. + + v0.6's unqualified form made the shipped stance §9.3 sanctions into a + violation — the same defect as v0.5's §9.1, a rule written for the clean case + producing a false result on the adjacent case already sanctioned elsewhere. + Raised by `ops-warden`, which is the reference shape for limb two. + +2. **No recaching of the verdict beyond its own binding.** A stored verdict + replayed **outside the decision's stated binding and lifetime** is a second + decision point deciding early (§6.1). Within them it is the decision being + used as issued — a session-bound allow under §9.7.1 is used across later + requests by construction, and v0.6 forbade what §9.7.1 permits. + + The test is mechanical, not a matter of implementer judgement: replay is + permitted **iff the canonical request digest matches and the decision's + lifetime holds**. `access-engine` computes that digest over normalised + subject, action, resource, and context, and it is already in every decision + binding. A retry after a transport failure is therefore the same request; a + different resource is not. + + **Negative caching is permitted, narrowly.** A cached DENY cannot manufacture + authority — §8's asymmetry holds — and protects against retry storms. It is + permitted where the refusal is itself recorded against the request that was + refused (obligation 4), and where the cache lifetime is declared alongside + the stance map. A stale deny is an availability failure and will be + misdiagnosed as a policy one, so it must be visible as what it is. Ruled + explicitly because it is the first thing an implementer under load reaches + for. Raised by `access-engine`. + +3. **A declared unreachable-engine stance** (§9.3): total, per zone or + equivalent scope, no implicit default, no per-call discretion, published + rather than held in code comments or in a dataclass default. `ops-warden` + `ADR-0009` and its `pep-stance.yaml` are the reference shape. + + The published map MUST equal the shipped behaviour, and that equality SHOULD + be asserted by a test. A published map free to drift from the code is worse + than none, because it invites reliance it cannot support. Raised by + `ops-warden`, which found its own map unpublished while being cited as the + reference for this obligation. + +4. **Reconstructability**, bounded by §9.6. + +Every PEP-shaped consumer MUST publish its stance map at a path named in its +layer declaration, and those maps MUST be inventoried in the §13.1 register +until `maturity-engine` can hold them. §9.3 is otherwise a ruling with no +register behind it, and *"`z0`–`z2` and unknown fail open"* becomes the estate's +real policy without anyone having compiled it into a versioned package. + +v0.6 named a register that did not exist — a requirement whose register is +missing is a capability catalogued without a surface, by §9.1's own logic. +Raised independently by `ops-warden` and `access-engine`; §13.1 now exists, and +its first inventory has one row, which is itself the finding. + +Raised by the 2026-08-29 independent assessment: NIST ZTA splits decide from +enforce, and this standard had only the first half. + +## 7. Relationship to the Active Secrets Management Canon + +```text +Staff interactive, non-deterministic ≈ Cognitive Plane +Engines deterministic APIs ≈ Authority Plane +Tooling deterministic state ≈ Execution Plane +Taxonomy cross-cutting language +``` + +*Cognition proposes. Authority disposes. Infrastructure executes.* is therefore +NetKingdom's layering rule, not only its security maxim. §5 and §6 are that +principle applied to repositories rather than to requests. + +## 8. Vocabulary demarcations + +| Term | Belongs to | Not | +| --- | --- | --- | +| **access lane** | ops-warden, ops-mason (Staff) — how a worker reaches a host | the decision whether they may | +| **access rule** | access-engine (Engine) — whether an actor may act | the route by which they arrive | +| **control plane** | Engine layer | a Staff repository's self-description | +| **doctrine** | gate-house | a lane owner's runbook | +| **runbook** | the Staff repository stewarding the lane | a substitute for doctrine | +| **posture** | kings-guard publishes; gate-house defines its authority meaning; access-engine renders it | a privilege source | + +Posture carries an asymmetry that MUST hold: adaptive systems may reduce +authority, require step-up, or request containment. They MUST NOT +probabilistically manufacture additional authority. + +The asymmetry is what bounds the damage when observation is incomplete (§9.6): +suppressed evidence can only prevent a tightening that should have happened, never +engineer a loosening. That is an argument for keeping it absolute rather than +situational. + +## 9. Capability assignment + +### 9.1 The catalog may not assign what the rules forbid discharging + +A Staff repository MUST NOT be catalogued in §4 as owning a capability it cannot +discharge under these rules. Two marks distinguish the two ways that happens, and +they are not interchangeable: + +| Mark | Meaning | +| --- | --- | +| **pending** | No route exists. No engine exposes the capability, the repository makes no Tooling contact, and the capability is **zero** — not degraded. | +| **declared-gap** | A route exists through a §5.3 declared gap. The capability **works** and is tracked, with an intended owner and a review date in §13. | + +v0.4 had only `pending`, which forced a false choice. `ops-warden` holds +production-verified SSH certificate issuance through a declared OpenBao contact; +marking it `pending` would have told readers the repository does not do the one +thing it demonstrably does daily, while leaving it unmarked left §4 disagreeing +with §13. Neither is acceptable, and the defect was in this section rather than +in the catalog. + +`pending` was written for `kings-guard`'s containment — no route, capability +zero — and remains correct there. `declared-gap` is the case §5.3 was added to +sanction. Raised by `ops-warden`. + +Both marks apply per capability, not per repository. A repository may hold one +capability outright, another under a declared gap, and a third pending. + +### 9.2 Actuation does not exist, and containment is not Staff's to own + +Self-healing needs four verbs: observe, evaluate, decide, actuate. Observation is +`kings-guard` and is unstaffed (§12). Evaluation is `maturity-engine` and is +seeded. Decision is `access-engine` and works. **Actuation has no surface at +all**, and a model with no actuation surface describes a diagnosis machine +rather than a healing one. + +v0.5 marked containment `pending` against `kings-guard`, which was the right +mark on the wrong repository. Containment is not a Staff capability that happens +to lack a route: **reduce authority, require step-up, isolate a workload** are +authority-changing operations, and under §6 an authority-changing operation is +rendered by an Engine and enforced by a PEP (§6.4). A Staff repository proposes +containment; it never performs it. + +The **actuation surface** is therefore an Engine concept — likely a small +surface on `access-engine` together with runtime PEPs — carrying the same +reconstructability rules as any other decision: a containment action is a +decision record, not a side channel. + +It is **unowned and held at zero**. `access-engine` is recorded in §13 as a +*proposed* owner and has explicitly not reviewed it (`FLEX-DEC-2026-002`). No +repository may be catalogued as owning containment until the surface exists — +§9.1 applied to the estate's most operationally tempting gap, and the standard's +own medicine. + +Until then `kings-guard` proposes and judges, its containment claim stays at +zero rather than degraded, and no argument may assume the estate can contain +anything automatically. + +### 9.3 Degraded mode: two failure cases, two owners + +v0.4 collapsed two failures into one rule. They have different owners because +one has an evaluator in the path and the other does not. + +**Input degradation — the engine's.** Where `access-engine` is reachable but +cannot reach its own inputs, the deterministic *fail to reduced authority* +default belongs to the engine. This keeps the decision at the decision point and +keeps the fallback deterministic, which a Staff-layer fallback could never be. + +**Engine unreachable — necessarily the consumer's.** Where `access-engine` is +not reachable at all, it applies nothing, because it is not running. Whatever +happens next is the consumer's behaviour by construction: fail-open is not +expressible by a policy decision point, since there is no evaluator in the path +to express it. A standard that assigns this to the engine assigns it to nobody. + +The consumer's residue is bounded rather than free. A protected system MUST +declare its unreachable-engine stance ahead of time, per zone or equivalent +scope, and that stance MUST be auditable and total — no implicit default, no +per-call discretion. `ops-warden` `ADR-0009` already satisfies this: a total +per-zone map, open for `z0`–`z2` and unknown, closed for `z3-critical`, +replacing the global `policy.enabled` / `policy.fail_closed` switches it +superseded. + +**Unchanged: engine-unavailable is not grounds for a Staff break-glass path.** +The distinction is whether an engine is there to ask. A bypass around a +*reachable* engine is a second decision point, and an incident is when an +attacker most wants that shortcut. A consumer choosing its declared behaviour +when there is no engine to ask is not a bypass; it is the only thing left. + +Contested by `flex-auth` (`FLEX-DEC-2026-002`), which has held since 2026-08-19 +that fail-open is not expressible by a PDP, and which noted v0.4 collided with +shipped behaviour in a repository that had assented to this standard. + +### 9.4 Approvals are an engine concept, not a Staff or audit concern + +The approval object — durable, authenticated entries, distinct-approver +counting, atomic supersession, single consumption, revocation without holder +cooperation — is owned by `approval-engine`. + +It is not Staff's: §3.4 forbids Staff holding state another layer depends on at +runtime. It is not the decision point's: an evaluator that owns the object it +evaluates is self-dealing. It is not the audit fabric's: an approval needs +mutable, in-path, current-state semantics, and an append-only archive is built +for the opposite property. + +`access-engine` consumes approvals as **input claims** under §6.2 and never +mutates them. Every issuance, use, supersession, and revocation is emitted to +`audit-core`: the operative state and the evidence record are different +artifacts with different owners. + +The evidence guarantee is bounded, and the bound is `audit-core`'s +`docs/integrity.md`, not its INTENT principle 6. An in-database hash chain +detects a rewritten payload only if the attacker does not also recompute the +suffix — which a database owner can. Detection against that class requires the +external chain-head attestation, and even with it the store is not WORM, object +lock, or archival custody. `tamper_evidence` is therefore conditional on live +preconditions, not a property of the store at rest, and approval events receive +exactly the guarantee every other source receives. + +**Emission atomicity is `approval-engine`'s obligation.** An approval MUST NOT be +issued, consumed, superseded, or revoked without the corresponding event being +durably queued in the same transaction. + +**The queue MUST be local.** The durable queue MUST live in `approval-engine`'s +own transactional store, and **no synchronous dependency on `audit-core` may sit +inside the state-change transaction**. With a genuine local outbox, fail-closed +triggers only when `approval-engine`'s own store is unavailable — where the +change could not have been recorded anyway — and an `audit-core` outage does not +block a revocation. Satisfying the requirement by emitting synchronously to +`audit-core` inside the transaction is also atomic, and turns an audit outage +into an inability to revoke: the operation least tolerable to block during an +incident, and the same coupling this section rejects for reads. Raised by +`audit-core`. +`audit-core` reports what it received and does not imply it is everything that +happened; without atomic emission the evidence half is silently incomplete and +nothing detects the gap. This is a condition of `audit-core`'s assent +(`AUDIT-IN-0001`) and belongs in `approval-engine`'s contract before the evidence +half is treated as load-bearing. + +`audit-core` MUST NOT expose an approval-validity query. Records, yes; a verdict +on whether an approval is still valid, never — a consumer branching on that +answer would route an authorization decision through the audit fabric, which is +what this section exists to prevent. Callers needing current state ask +`approval-engine`. + +### 9.5 Graded progression is an engine concept + +Maturity — how far a subject has progressed against declared criteria and +submitted evidence — is owned by `maturity-engine`. 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. + +The division with Staff: **gate-house judges and proposes; maturity-engine +computes and remembers.** Interpretation is inference and stays Staff. A +criterion that cannot be evaluated by rule is not yet a criterion. + +This closes a defect in v0.2's own catalog: `gate-house` was assigned +conformance review with no engine to act through, which is exactly the §9.1 +problem raised against the containment claim. Staff acts only through Engine +APIs, including gate-house. + +**A maturity level MUST NOT be compiled into registry content.** Until +`access-engine`'s decision provenance carries a registry-snapshot digest — a gap +it self-declared in §13 — a level reaching a decision through the registry is not +reconstructable from the decision record. Levels arrive as request claims or as +versioned policy rules. Same constraint, and same reason, as zone stance. + +**A maturity level MUST NOT gate a decision directly.** Under §6.1, compiled +data that determines an outcome is still deciding. If a level determines whether +an action is permitted, it MUST reach `access-engine` as an input claim or a +versioned policy rule under §6.2, never by a consumer branching on a fetched +level. + +Approvals and maturity are deliberate opposites — a closed binary state machine +against an open graded ladder — and neither engine may drift toward the other. + +### 9.6 Evidence proves alteration and truncation, not omission at source + +An append-only archive with a verified hash chain proves that records were not +**altered or truncated after arrival**. It cannot prove that a record was never +sent. Against a compromised or buggy source, a suppressed event leaves the chain +perfectly intact and verification reports intact. + +This bound is estate-wide. Statements of the form *"the audit record proves it +happened"* are unsound; the sound form is *"the archive proves the records it +holds were not altered or truncated after arrival"*. Its mirror is equally +unsound: **absence of a record is not evidence of non-occurrence**, and no +control may read it as such. + +**Load-bearing versus attributive evidence.** The atomicity obligation attaches +to the first, not to both: + +| Kind | Test | Obligation | +| --- | --- | --- | +| **Load-bearing** | a control's soundness depends on the event being present or absent — an approval revocation, a containment action, a denial | emission MUST be atomic with the state change (§9.4) | +| **Attributive** | the event supports forensic reconstruction and attribution, and no control branches on its presence | atomicity SHOULD be sought; where it is deliberately traded away, the trade MUST be declared and completeness MUST NOT be claimed | + +Where a repository deliberately makes emission non-atomic — `ops-warden`'s +`# audit must not block signing` is the estate's live example, chosen so that an +audit-store failure cannot remove production host access — the trade is +legitimate for attributive evidence, MUST be declared where the trail is +documented, and MUST NOT be described in terms that imply completeness. The +availability argument is real in both directions: making it atomic gives the +estate's operational access lane a new dependency on its own evidence store. + +**Consequence for adaptive systems.** Suppression does not degrade observation +neutrally, it biases it optimistic, and silently: an event never emitted is never +evaluated, so no finding is raised and the last posture stands. A confidence +score computed from the richness of the record in hand cannot express doubt about +the completeness of the stream — a well-formed observation from a 90%-suppressed +stream scores high. That is this section's failure reproduced one layer up, in +the consumer. + +Two things follow. + +**Which control covers which threat.** v0.6 read as though emission atomicity +closed this section's opening sentence. It does not, and the decomposition is +owed to the reader: + +| Threat | Covered by | When | +| --- | --- | --- | +| **Accidental omission** — process dies between mutation and emit | emission atomicity, local outbox (§9.4) | prevented | +| **Adversarial omission** — a compromised source declines to insert, deletes before drain, or drains to nowhere | cadence and reconciliation | **detected, after the fact** | +| Adversarial omission at a compromised source | — | **nothing in this model prevents it** | + +The outbox sits inside the blast radius of the component whose compromise this +section posits, so it makes emission atomic against crash and partial failure +and nothing more. That residual is real and is stated rather than implied. +Raised by `audit-core`, correcting a remedy it had itself proposed. + +1. **The §8 asymmetry bounds the damage, and this is its clearest payoff.** + Because an adaptive system may only reduce authority and never manufacture it, + suppression can only prevent a tightening that should have happened. It cannot + be used to engineer a loosening. The harm is a missed reduction, not an + invented privilege — which is an argument for keeping the asymmetry absolute. +2. **Silence is a signal, and for load-bearing evidence it is the only control + in its class.** A source of **attributive** evidence SHOULD declare an + expected emission cadence; a source of **load-bearing** evidence **MUST**. + A drop below the declared rate is a finding in its own right — the stream + observed, not only its contents — and needs no Tooling contact, because the + source publishes its own stream. + + **Rate monitoring is the wrong form for rare events**, and rare is exactly + where the stakes are highest: the most valuable event to suppress is the + negative one, and revocations, denials, and containment actions are + infrequent by nature. A source emitting a handful of revocations a month has + no rate to drop below, and suppression is indistinguishable from a quiet + month. For **low-volume load-bearing classes** the required form is therefore + **positive reconciliation or a heartbeat**: compare the source's own state + transitions against the evidence engine's event count per class and treat + divergence as a finding, or assert *nothing to report* as a signed positive + claim that can itself go missing. Rate monitoring never produces a claim that + can be missing; a heartbeat does. `GH-WP-0002-T04` is the reference instance. + Raised by `audit-core`. + +Raised by `audit-core` against its own principle; extended by `kings-guard` from +its own evaluator and confidence model. + +### 9.7 Decisions have a lifetime + +A single decision point deciding on stale claims is a single decision point +deciding wrongly. The model has had no temporal law, and the approval race in +§16 was its first symptom. + +1. **Every allow has an explicit lifetime** — a TTL, or a binding to a session + or obligation that ends. An allow with no stated end is a standing grant, and + standing grants are what this estate exists to remove. +2. **Revocation and supersession have a visibility deadline**, and its shape + differs by role. A **PEP** has one boundary and MUST state one deadline. A + **PDP** MUST state a deadline **per input class**, because a decision is a + join over sources with unrelated refresh behaviour — approval-claim freshness, + registry snapshot cadence, policy package activation, directory ETag. A single + number at a PDP is either a fiction or the worst case, and the worst case is + the slowest and least visible input. "Eventually" is not a stance; an unstated + deadline is an unbounded replay window. + + A consequence worth naming: a stated deadline for a fact carried by a + registry snapshot is unfalsifiable while decision provenance holds no snapshot + digest, since nobody can determine afterwards which snapshot a decision read. + The deadline and the digest are one gap seen from two sides, which promotes + `access-engine`'s self-declared provenance gap (§13) from housekeeping to a + conformance prerequisite. Raised by `access-engine` against its own backlog. +3. **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 — the decision precedes the action + and the action precedes consumption, so a decision record proves an intent to + act, not an act. +4. **Three failure modes are named, and each needs an owner**: an allow rendered + then never consumed; a double consumption by racing callers; consumption + after the authorized action has already failed. Neither engine closes these + alone. Recorded in §16 and `GH-WP-0002-T06`. + +### 9.8 Partition is not one-dimensional + +§9.3 handles *engine unreachable*. A real estate spends most of its incident +time in the band between reachable and gone: partial PIP reachability, clock +skew across a decision and its enforcement, and two consumers with different +declared stances seeing different worlds at the same moment. + +Two rules hold today, and the rest is open (§16). A PEP MUST resolve its own +stance from its declared map without consulting another consumer — divergent +views are expected and are not a coordination problem to be solved at enforcement +time. And where clock skew could extend a lifetime under §9.7, the shorter +reading governs. + +## 10. Changing layer + +A repository's layer is not permanent. `zone-engine` changed layer in practice +when its runtime hypothesis was falsified. + +A layer change MUST be recorded as a decision, MUST update the repository's +`INTENT.md`, and MUST obtain assent from the repositories whose boundaries move. +A repository MUST NOT acquire a new layer's permissions by gradual practice. + +"No gradual practice" needs a check rather than a sentence. A layer change MUST +carry six artifacts, written from the `zone-engine` case that the procedure +should have been derived from in the first place: + +| Artifact | Why | +| --- | --- | +| before/after `INTENT.md` | the declaration is the conformance surface (§11) | +| client inventory | what the repository holds against Tooling, before and after | +| gap inventory | which §5.3 gaps close, open, or transfer | +| assent list | every repository whose boundary moves | +| state-migration decision | what happens to live state and to consumers reading it | +| permission freeze | no new permissions of the target layer are exercised until the cut completes | + +The freeze is the one that makes the rule checkable: a repository mid-change +holds its old permissions, not the union of both. + +## 11. Conformance + +Conformance has four states, and the distinction between the last two is the +point: + +| State | Meaning | +| --- | --- | +| **Conforming** | no Tooling contact, or only §5.1/§5.2 shapes, declared | +| **Blocked-clean** | the capability does not exist because no engine exposes it, and the repository makes **no** Tooling contact — §9.1 `pending`, and not a non-conformance | +| **Declared gap** | a §5.3 contact with owner, blocker, and review date — tracked non-conformance | +| **Undeclared violation** | anything else — a finding | + +**Blocked-clean is not a lesser state than conforming.** A repository that +declined a break-glass path and left a capability at zero has complied at cost; +a repository that quietly opened a direct client and declared nothing has not. +Any downstream scoring — `maturity-engine` included (§9.5) — MUST NOT rank the +first below the second. Raised by `kings-guard`, whose three gaps are all of +this kind and which would otherwise have been graded down three times for +having taken the standard seriously. + +**Who must declare.** A repository the estate authors declares its layer in its +own `INTENT.md`. For a component the estate catalogues but does not author — +third-party or vendored, such as `OpenBao` — the §4 catalog row **is** the +declaration, and no `INTENT.md` obligation attaches. A rule that assigns an +obligation the holder cannot discharge is the §9.1 defect applied to conformance +rather than capability. + +A layer stated *about* a repository by another repository is not a declaration. +Review notes, catalog rows, and correspondence record an intent to adopt; only +the repository's own file conforms. + +**Declaration form.** Because prose cannot distinguish a declaration from a +transcribed review, a declaration MUST carry a machine-readable form: a `layer:` +key in the `INTENT.md` frontmatter, or an equivalent declaration file. Without +it this section asserts a property it cannot deliver — the defect this standard +has now corrected three times elsewhere. `ops-warden` has implemented a reference +form (`layer.yaml`, a conformance script, and a test covering the §5.2 +no-authority property) and offered it to the repositories that have yet to +declare. Raised by `audit-core`, which noted that `flex-auth`'s conforming +declaration is legible as one only by following its decision trail. + +Mechanically checkable: + +- every estate-authored repository in §4 carries a machine-readable layer + declaration; +- every direct Tooling client in a Staff repository maps to a declared §5.1, + §5.2, or §5.3 entry, and non-Tooling clients are recorded so the check is + total; +- no repository other than `access-engine` exposes an authorization decision + surface; +- no §4 capability is catalogued without an engine surface, a `pending` mark, or + a `declared-gap` mark. + +Requires review: whether claims stay inside layer permissions; whether compiled +or cached data has become an early decision (§6.1); whether doctrine is reaching +decisions as declared inputs (§6.2); whether the §8 vocabulary is used correctly. + +## 12. The conformance loop + +Doctrine no engine implements is fiction. The loop is normative, not +aspirational: + +```text +gate-house asserts an invariant + → the engines implement it, or declare a gap + → whitehat-security tries to break it + → kings-guard observes it in operation + → findings return to gate-house as doctrine change +``` + +A finding that a rule is unsatisfiable is a **success** of this loop, not a +failure of the reporting repository. Four of this standard's five versions exist +because a reviewing repository used it. + +**Step four is currently aspiration.** `kings-guard` has disclosed that it has +never observed anything in operation: the pilot is specified and scaffolded, every +input is a hand-built fixture, and no test has met a real event. Until it reports +otherwise, no argument in this estate may assume an invariant is being watched in +practice because §12 lists a repository against that step. + +## 13. Open gaps + +Two different things are recorded here, and they are opposite conformance states +(§11). A **declared contact** means the repository touches Tooling because no +engine exposes the capability. An **unowned capability** means no route exists +and the repository makes no contact at all. Reading them as one list would grade +restraint as though it were non-conformance. + +An `intended owner` is a **proposal to** the named repository, not an assignment +**onto** it. §2 keeps ownership in the repository's own `INTENT.md`, so the +register distinguishes proposed from assented. + +| Gap | State | Declared by | Owner | Owner status | +| --- | --- | --- | --- | --- | +| SSH-CA signing write (`VaultCA`, `bao kv put`) | declared-contact | ops-warden | secrets-engine | proposed | +| Authentication / assurance evidence | unowned-capability | kings-guard | identity layer + audit-core | **access-engine declined** | +| Secret-use evidence | unowned-capability | kings-guard | secrets-engine | proposed | +| Actuation / containment surface | unowned-capability | **gate-house (estate-wide)** | access-engine + runtime engines | proposed | +| Identity and secret observation | unowned-capability | kings-guard | as above | proposed | +| Stance-map register had no implementation | declared-contact | ops-warden, access-engine | gate-house | resolved in §13.1 | +| Registry-snapshot digest in decision provenance | declared-contact | flex-auth | flex-auth | self-declared | +| Approval storage and lifecycle | — | flex-auth | approval-engine | assigned (§9.4) | +| Approval evidence | — | gate-house | audit-core | **assented** (`AUDIT-IN-0001`) | +| Approval evidence custody stronger than the shipped bound — WORM, object lock, transparency log | unowned-capability | audit-core | — | unassigned | +| Emission atomicity for approval state changes | — | audit-core | approval-engine | assigned (§9.4) | +| Non-atomic audit emission on the SSH signing lane | declared-contact | ops-warden | ops-warden | self-declared, attributive (§9.6) | + +The actuation row is no longer attributed to `kings-guard`. §9.2 ruled that +containment is not a Staff capability lacking a route, so `kings-guard` is not +its declarer: the gap is estate-wide and blocks every repository's ability to +act. Raised by `kings-guard`, which asked not to carry a row for a capability +the standard had just ruled was never theirs. + +`access-engine` declined authentication and assurance evidence +(`FLEX-DEC-2026-002`): it consumes assurance claims as input and never redefines +them, so evidence of authentication belongs to the identity layer and +`audit-core`. It owns evidence of the decision, which it already emits. The +containment surface is recorded as proposed and remains `pending` under §9.2. + +Whether approvals warrant custody stronger than every other source is doctrine +work not yet done; until it is, approval evidence carries the same guarantee as +any other source and §9.6 bounds what may be claimed from it. + +**What is normative here, and what is a snapshot.** Three rules are part of this +standard and survive wherever the register lives: + +1. the two marks — `pending` and `declared-gap` (§9.1); +2. the owner-status rule — a proposed owner is not an assigned one (§2); +3. the scoring rule — `blocked-clean` MUST NOT rank below conforming (§11). + +**The table above is a snapshot, not statute.** It moves into `maturity-engine` +as soon as that engine can store state, and the `state` and owner-status columns +MUST survive the migration. A standard that is also a backlog keeps attracting +findings that belong in the register, and its review interval is far slower than +the register's real rate of change. + +### 13.1 PEP stance-map register + +Every PEP-shaped consumer publishes an unreachable-engine stance map (§6.4, +obligation 3). This is the inventory until `maturity-engine` can hold it. + +| Consumer | Stance map | Shape | +| --- | --- | --- | +| `ops-warden` | `ops-warden/pep-stance.yaml` | total per-zone; open `z0`–`z2` and unknown, closed `z3-critical`; test asserts the published map equals the shipped default (`ADR-0009`) | +| `ops-mason` | — | **not published**; catalogued PEP-shaped in §4 | + +**One row is the finding.** The aggregate of consumer stances is the estate's +real authorization behaviour, and it is currently one published map and one +absence. `access-engine` has noted it is the repository positioned to notice +when that aggregate diverges from what the policy packages say — which it cannot +do while the register is nearly empty. + +## 14. Adoption + +Status is **proposed** — the frontmatter is authoritative, and v0.2 was the last +version to reach `accepted`. Four repositories have assented, each with a record, +and all four returned findings on the versions since: + +| Repository | Record | Outcome | +| --- | --- | --- | +| flex-auth | `FLEX-DEC-2026-001` | assent to all three items; one self-declared non-conformance; two rename conditions | +| kings-guard | `KG-DEC-2026-001` | assent; declined the offered §5 relaxation; raised §9.1 | +| ops-warden | `ADR-0010` | assent to all three; veto not exercised; offered the §5.3 amendment | +| audit-core | `AUDIT-IN-0001` | assent to the evidence half with conditions; corrected the rationale twice; raised §9.6 | + +Adoption for a repository means its `INTENT.md` declares its layer, its +ownership claims fall inside that layer, its Tooling contacts are declared under +§5, and any shared boundary has been assented to by the other side. + +**Adoption status as of 2026-08-29: seven of sixteen** estate-authored §4 +repositories have declared in their own voice — `gate-house`, `flex-auth`, +`kings-guard`, `ops-warden`, `audit-core`, `approval-engine`, `maturity-engine`. +The remaining nine — `info-tech-canon`, `net-kingdom`, `key-cape`, +`user-engine`, `tenant-engine`, `zone-engine`, `secrets-engine`, `ops-mason`, +`whitehat-security` — carry a layering review note authored by `gate-house` and +have not answered it. Those notes state a layer but do not constitute a +declaration, and this standard does not claim estate-wide adoption on their +basis. Declaration requests are open as intakes in each. + +## 15. Change log + +v0.1 → v0.2: + +1. **§5 restructured** into three sanctioned shapes. Added §5.2 conduit + (ops-warden's question, ruled) and §5.3 declared engine gap (ops-warden's + amendment, accepted). +2. **§6.2 added** — doctrine must reach the decision as an input claim or a + versioned policy rule (flex-auth's boundary drawn back, accepted). +3. **§9 added** — the catalog may not assign a capability the rules forbid + discharging; containment marked pending; degraded-mode fallback ruled into + the engine (kings-guard's finding). +4. **§11 restructured** — conformance now has three states, distinguishing a + tracked gap from an undeclared violation. +5. **§12 made normative**, with the explicit statement that an + unsatisfiability finding is a success of the loop. +6. **§13 added** — open gaps register, including the unowned approval storage + and lifecycle capability. +7. §4 catalog gained the pending mark and ops-warden's SSH certificate lane. + +v0.2 → v0.3: + +1. **§9.4 added** — approvals assigned to `approval-engine`, with the operative + state and the evidence record separated between it and `audit-core`. +2. **§9.5 added** — graded progression assigned to `maturity-engine`, closing + the §9.1 defect in gate-house's own conformance-review claim, and carrying + the guardrail that a level may never gate a decision directly. +3. §4 catalog gained both engines; gate-house's conformance-review claim now + names the engine it acts through. +4. §13 register updated: the approval hole is assigned, two new entries added. + +v0.6 → v0.7, from four reviews: + +1. **§3.4 is written.** v0.6 announced the human/agent principal separation in + §1 and §15 and left §3.4 byte-identical to v0.5 — a silent edit failure. A + rule stated about a standard in its own change log is not a rule. Found by + `kings-guard`. The same failure had also dropped two §16 entries, restored + here. +2. **§6.4 obligation 1 rewritten** — it forbade what obligation 3 blesses. A PEP + may proceed under its declared §9.3 stance provided the application of that + stance is *recorded in place of* the decision. Stricter than v0.6 where it + counts: a fail-open result is metadata, never silence. Raised by `ops-warden`. +3. **§6.4 obligation 2 rewritten** — it forbade the session-bound allow §9.7.1 + permits. Scoped to replay outside the decision's own binding and lifetime, + with the canonical request digest as the mechanical test, and negative + caching ruled permitted where the refusal is recorded and the cache lifetime + declared. Raised by `access-engine`. +4. **§6.4 obligation 3** gained the requirement that the published stance map + equal shipped behaviour, asserted by test. **§13.1** now exists as the + register §6.4 mandated and v0.6 did not implement. +5. **§9.6 gained a threat decomposition** — atomicity prevents accidental + omission; cadence and reconciliation detect the adversarial case after the + fact; nothing prevents it at a compromised source. Raised by `audit-core` + against its own proposed remedy. +6. **§9.6 cadence is now MUST for load-bearing sources**, with positive + reconciliation or a heartbeat as the required form for low-volume classes, + because rate monitoring fails exactly where the stakes are highest. +7. **§9.7.2 splits by role** — a PDP states a deadline per input class, a PEP one + at its boundary. Promotes `access-engine`'s provenance gap to a conformance + prerequisite. +8. **§3.3's Evidence row** is stated as an estate trade rather than a property, + leaving independent-recording-before-effect raisable as a declared exception. +9. **§17** moves the decision-record schema to `access-engine`, which argued it + against its own interest; `kings-guard` drafts the emission-cadence schema. +10. **§13** no longer attributes the actuation gap to `kings-guard`; it is + estate-wide. **§19 removed** — a verdict inside a standard grades the + document it lives in. **§17/§18** demoted from H1 to H2. +11. **§20 added** — the Railiance interaction boundary, on `railiance-master`'s + definitions, including that `rein-*` is not a fifth axis. + +v0.5 → v0.6, from the independent assessment of 2026-08-29: + +1. **§3.3 types the engines** — PDP, PIP, Evidence, Lifecycle, with a role + column in §4. A new engine is a PIP unless this standard says otherwise, so + "we need an engine for X" cannot drift into "X now decides". +2. **§6.4 names the enforcement point** — a PEP shape with four obligations: no + side effect without a decision record, no local recaching of the verdict, a + declared unreachable-engine stance, reconstructability. The standard had the + decision and not the gate. +3. **§9.2 replaced** — containment was marked pending against the wrong + repository. Actuation is an Engine concept, unowned, held at zero; Staff + proposes containment and never performs it. +4. **§3.4 separates the two Staff principals** — human and agent share the layer + but not blast radius: no standing credential, conduit or engine API only, + agent memory is not a state plane, every action reconstructable as the + caller's. +5. **§9.7 puts time into the model** — explicit lifetimes, revocation visibility + deadlines, consumption as a state change never inferred, and the three race + modes named. **§9.8** states what holds under partition and leaves the rest + open. +6. **§17 requires the Taxonomy artifacts** — claim, decision-record, gap-record, + and emission-cadence schemas — without which §6.2 and §11 are reviewable but + not compileable. Ownership proposed, not assigned. +7. **§18 composes the sibling standards** — how zone stance, tenancy posture, + and a credential lifecycle event each enter a decision as a claim. They were + cited in frontmatter and nowhere in the rules. +8. **§5 gained a sunset** on the uncatalogued-infrastructure carve-out, and + §5.3 **declines** a proposed fourth "operator of third-party Tooling" shape: + it would convert a tracked gap into a permanent allowance. +9. **§10 gained the six artifacts** a layer change must carry, written from the + `zone-engine` case, including a permission freeze during the cut. +10. **§2 lifts the observation rule** — no estate argument may cite observation + that has not happened. **§13** separates its three normative rules from the + table, which is now a snapshot due to move into `maturity-engine`. +11. **§16** the approval custody question is **decided: no**, rather than left + open. **§19** records the fitness verdict, including that the estate can + propose and decide but cannot yet watch or act. + +v0.4 → v0.5, all from review findings: + +1. **§9.1 split into two marks** — `pending` (no route, capability zero) and + `declared-gap` (route exists under §5.3, capability works and is tracked). + v0.4's single mark would have forced a false `pending` onto ops-warden's + production SSH issuance. Raised by `ops-warden`. +2. **§9.3 rewritten** — input degradation is the engine's; engine-unreachability + is necessarily the consumer's, bounded by a declared, auditable, total stance. + Contested by `flex-auth`: fail-open is not expressible by a PDP, and v0.4 + collided with `ops-warden` `ADR-0009`. +3. **§5 gained a scope rule** — "Tooling-layer system" means a §4 Tooling row; + uncatalogued infrastructure is outside §5 and recorded rather than policed. + Without it every Staff repository was in undeclared violation for writing + progress events. Raised by `ops-warden`. +4. **§9.4 requires a local outbox** — no synchronous dependency on `audit-core` + inside the state-change transaction, so an audit outage cannot block a + revocation. Raised by `audit-core`. +5. **§9.5 forbids compiling maturity levels into registry content** until + decision provenance carries a registry-snapshot digest. Raised by `flex-auth`. +6. **§9.6 gained the load-bearing / attributive distinction**, the mirror rule + that absence is not evidence of non-occurrence, the optimistic-bias + consequence for adaptive systems, and silence-as-signal. Raised by + `kings-guard` on top of `audit-core`'s original. +7. **§11 gained a fourth state** — blocked-clean, which MUST NOT rank below + conforming — and a machine-readable declaration form. Raised by `kings-guard` + and `audit-core`. +8. **§13 gained state and owner-status columns** — declared-contact versus + unowned-capability, proposed versus assented owner. `access-engine`'s + decline of authentication evidence is recorded. Raised by `kings-guard` and + `flex-auth`. +9. **§8** records the asymmetry's payoff under incomplete observation; **§12** + records that its fourth step is unstaffed; **§14** corrects the adoption + arithmetic and the status contradiction. + +Amended in place while `proposed`, 2026-08-28: §11 gained the who-must-declare +rule after a conformance sweep found the standard required an `INTENT.md` +declaration from `OpenBao`, which the estate does not author; and §14 gained the +honest adoption count. + +v0.3 → v0.4: + +1. **§4 catalog gained `audit-core`** as an Engine, on its own declaration. v0.3 + named it as an owner in §9.4 and §13 without cataloguing it — a §11 defect in + the standard itself, raised by `audit-core`. +2. **§9.4 evidence rationale rewritten** to cite `audit-core`'s shipped + `docs/integrity.md` bound rather than its INTENT principle 6, and to state + that `tamper_evidence` is conditional on live preconditions. +3. **§9.4 gained emission atomicity** as `approval-engine`'s obligation, and the + prohibition on `audit-core` exposing an approval-validity query. +4. **§9.6 added** — evidence proves alteration and truncation, not omission at + source. Estate-wide; the sound and unsound forms of the claim are stated. +5. **§13** — evidence half recorded as assented with conditions; two new gaps: + stronger approval custody (unassigned) and emission atomicity + (`approval-engine`). + +## 16. Open questions + +- ~~Whether approvals warrant archival custody stronger than every other audit + source.~~ **Decided (§13): no.** Approval evidence carries the same bound as + every other source. The acute risk for approvals is *omission* — a suppressed + revocation — and archival custody does not address omission at all; emission + atomicity with a local outbox (§9.4) and a detection surface + (`GH-WP-0002-T04`) do. Leaving it open while calling the evidence half + load-bearing created a promise the archive cannot cash. If a future + requirement genuinely needs WORM or a transparency log, that is a different + store with a different owner, raised then. +- Whether SSH certificate issuance evidence is load-bearing or attributive + (§9.6). Ruled attributive here on the argument that no control branches on the + presence of a signing record; `ops-warden` asked for the ruling and the trade + is genuinely two-sided, so it is flagged rather than settled. +- Who marks an approval consumed, and at what point relative to the decision + (§9.4). `flex-auth` notes the decision precedes the action and the action + precedes consumption, so an allow rendered against an approval then never + consumed, or consumed twice by a racing caller, is a gap neither engine closes + alone. Needed before `FLEX-WP-0017` T05. +- Whether other §4 repositories are missing layer declarations; `audit-core` + flagged its own absence and asked whether the catalog needs the same + correction elsewhere. +- Whether the gap register migrates from this standard into `maturity-engine` + once that engine exists, leaving the standard to state the rules only. +- Whether Tooling warrants subdivision between third-party and homegrown. +- How a future `role-engine` divides responsibility with `access-engine`. +- Whether declared gaps need an estate-wide register rather than per-repository + declarations; ops-warden's `warden route gaps` is candidate machinery. +- Whether non-security repositories adopt the same model. The determinism cut is + not security-specific; if non-security Staff also may not hold + runtime-dependent state, the estate gets one constitution rather than a + security ghetto. +- The rest of §9.8: split brain, partial PIP reachability, and clock skew beyond + the two rules stated. +- Publication integrity of the Taxonomy layer itself. This standard demands + reconstructability of decisions while its own publication path has no digest, + freeze, or rollback discipline. +- The fitness verdict formerly at §19 now lives in + `net-kingdom/history/2026-08-29-layering-standard-assessment.md`. A grade + inside a standard of record becomes normative by adjacency and ages against the + text it grades. Raised by `access-engine`. Its two substantive points remain + live: observation in production is unstaffed (§12) and actuation has no surface + (§9.2). +- The **agent companion** (`security-layer-model-companion_v0.1.md`) is the + operative form of this statute. The statute governs on disagreement, and a + disagreement is a finding. Its §5.3 omits where a stance map is published and + omits the §6.4 inventory obligation entirely — a repository could satisfy the + companion faithfully, publish into its own repo, believe itself conforming, and + no register would learn of it. Raised by `access-engine` in answer to the + question of what would show the companion insufficient. To be fixed in + companion v0.2. +- How the Railiance operational axes meet this model beyond §20's first + statement, which is deliberately minimal. + +--- + +## 17. Taxonomy artifacts + +§6.2 says doctrine reaches a decision as an input claim or a versioned policy +rule. As prose that is a rule a reviewer can apply. As an interface it does not +exist, because nothing defines what a claim *is*. §11 calls itself mechanically +checkable while resting on that gap. + +Four artifacts are therefore required, owned by Taxonomy and versioned like any +standard: + +| Artifact | Contents | +| --- | --- | +| **request-claim schema** | identity, tenant, zone stance, posture, approval, maturity, assurance — each with its issuer and freshness rule | +| ~~decision-record schema~~ | **moved to `access-engine`** — see below | +| **gap-record schema** | the §5.3 fields — `capability`, `intended_owner`, `blocked_on`, `review` — plus the §13 `state` and owner-status | +| **emission-cadence declaration** | the expected rate a source publishes, so silence is a finding (§9.6) | + +Until these exist, §6.2 and §11 are reviewable but not compileable, and every +engine invents its own claim shape at its own boundary. + +**The decision-record schema is not Taxonomy's.** A decision record is the PDP's +output artifact — the one thing in the estate only `access-engine` produces — and +§2 keeps ownership in the producing repository's own `INTENT.md`. Taxonomy +authoring the schema for an artifact only one engine emits would invert the +ownership rule this standard applies everywhere else. `access-engine` publishes +it as a contract; Taxonomy holds only the shared field vocabulary the claim +schema references. + +Raised by `access-engine` **against its own interest** — the same §2 argument it +used to decline authentication evidence, applied where it takes work on rather +than off. Symmetry of that kind is what makes the ownership rule credible. + +**The emission-cadence declaration has a drafter.** `kings-guard` is its only +consumer, cannot implement silence-as-signal without it, and has offered to draft +it against `qonto-assistant` and hand it to whichever Taxonomy repository takes +ownership — rather than inventing a local shape, which is the drift §17 exists to +prevent. Accepted as a draft; ownership still rests with Taxonomy. + +**Ownership is proposed, not assigned.** `info-tech-canon` holds ecosystem-wide +semantic contracts and `net-kingdom` holds NetKingdom standards of record; the +split between them for these four artifacts is theirs to draw, and §2 keeps +ownership in the owning repository's `INTENT.md`. Neither has assented. + +## 18. Composition with the sibling standards + +The related-standards list has been frontmatter and little else. If the +following sentences cannot be written, the list is decoration — so they are +written here rather than in the siblings. + +**Zone stance** (`security-zones_v0.1`). A zone answers which scrutiny a +workload has qualified for; membership is `zone-engine`'s. The *effect* of a +zone on a decision belongs in a versioned `access-engine` policy package, never +in registry content — that ruling is zone-engine's §5, and §6.1 is its +generalization. Zone stance therefore enters a decision as a **claim on the +request or a rule in the package**, and a decision that turned on a zone must +name the package version that read it. + +**Tenancy posture** (`tenancy-posture_v0.1`). Posture is a bounded security-state +input, published by its owner and never a privilege source (§8). It enters as a +**claim**, carries its own freshness, and the §8 asymmetry binds it: posture may +tighten a decision and may never loosen one. A posture too stale to trust is a +missing claim, and a missing claim is not permission. + +**Credential lifecycle** (`credential-management_v0.2`). Issuance, rotation, and +revocation are `secrets-engine`'s and `OpenBao`'s, downstream of a decision — a +credential is an artifact of authority, never its source. A lifecycle event +becomes an **input** to a later decision as a claim (this credential is current, +this lease is bound to this task), never a side channel that changes an outcome +without appearing in the decision record. Revocation visibility is bounded by +§9.7. + +Each of the three composes the same way, which is the point: **facts arrive as +claims, effects live in versioned policy, and anything that changes an outcome +appears in the decision record.** + +--- + +## 20. The Railiance interaction boundary + +Operations is not NetKingdom's. Workload operations are organized by +**Railiance**, whose framework repository is `railiance-master`, and NetKingdom +provides the security and approval framework those operations consume. This +section states the boundary as it stands today. It is expected to evolve, and it +is written here so that evolution is visible rather than inferred. + +Definitions are `railiance-master`'s and are restated, not authored, here. + +### 20.1 What Railiance organizes + +A **workload** is a managed running deployable. Human commands, credential +patterns, broker actions, approvals, and infrastructure resources that are not +themselves deployables **are not workloads** — which is why an approval object +(§9.4) is not a Railiance axis and never becomes one. + +Every workload is operated through four composable axes, each answering a +different question about the same workload: + +| Prefix | Axis | Question | +| --- | --- | --- | +| `railiance-*` | ownership | Who owns this capability? | +| `rail-*` | execution contract | How does this workload run? | +| `rapp-*` | managed package | What exactly is packaged and operated? | +| `reef-*` | substrate | Where is it bound, and as what operational reality? | + +`rein-*` is **not a fifth axis**. Reins are `glas-harness` agent-harness +backends; the name echoes `rail-*` analogically, not taxonomically. Agentic +session semantics — session loops, tool policy, harness routing, model selection +— belong to `glas-harness`. When a rein is installed and operated as a managed +service it is a workload like any other, packaged and bound through the four +axes above. + +### 20.2 What holds today + +For any Railiance consumer of NetKingdom security, without exception: + +1. Authorization decisions come from `access-engine` and from nowhere else (§6). +2. Approvals are objects in `approval-engine`, consumed as claims (§9.4). +3. Credentials are materialized by `secrets-engine` **after** a decision, never + as a substitute for one. +4. Evidence goes to `audit-core` under the bound in §9.6. +5. Anything causing a protected side effect is **PEP-shaped** and owes the four + obligations in §6.4 — including a published unreachable-engine stance in the + §13.1 register. + +### 20.3 What is not settled + +The mapping between the axes and this model is deliberately thin, because +guessing it would be worse than admitting it: + +- A **`rapp-*`** is the most likely *resource* a decision is rendered about, but + nothing states its identity form in a request claim. +- A **`rail-*`** describes how a workload runs and is therefore where PEP shape + is most likely to live — but §6.4 obligations attach to repositories, and a + rail is a contract, so whether a rail can *carry* an obligation is unwritten. +- A **`reef-*`** answers where a workload is bound, which is adjacent to a + security zone (`security-zones_v0.1`) without being one. `zone-engine` records + that a reef capping availability for everything bound to it is a canon + composition problem. That composition is unwritten. +- The **`railiance-*` ownership axis** names who owns a capability, which is + adjacent to the principal a decision is rendered for. Adjacent is not equal, + and no rule connects them. +- **`glas-harness` and reins** hold tool policy and session semantics for agents, + while §3.4 rule 2 holds that an agent acts only through a conduit or an engine + API. Those two must compose, and neither side may treat its own half as + sufficient. That seam is the most consequential of the five, because it is + where "tool availability is not permission" is actually enforced or lost. + +### 20.4 How this boundary changes + +An interaction boundary between two frameworks is owned by neither alone. +Changes to §20 require assent from `railiance-master` for the axis definitions +and from `glas-harness` for the session and tool-policy seam, on the same terms +as any other boundary in this standard (§10). NetKingdom states what a consumer +owes; it does not define what a rail, rapp, reef, or rein *is*.