One row, no doctrine change. key-cape has no adapter populating the directory user tenant, so a client registration supplies a human principal's tenant. gate-house ruled that admissible as a declared bounded gap rather than as the answer, on the ground that its distinguishing case fails closed: where registration and directory disagree, issuance is refused rather than resolved either way. Registered here because condition 3 of that ruling requires it — a transitional shape not held in a register becomes the permanent answer by nobody minding it. Intended owner is left unnamed per 13's own rule that an intended owner is a proposal to a repository rather than an assignment onto it. The standard stays proposed and this changes no normative text. 21 tests pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012viPor8WJNCbV64ipwewrm Assistant: claude-code Assistant-Model: opus Assistant-Process: 1754332@bnt-lap001 Assistant-Session: 9c8ac536-ff5e-46a3-8ab1-a548bde25fc0
2015 lines
120 KiB
Markdown
2015 lines
120 KiB
Markdown
---
|
||
id: netkingdom-security-layer-model-v0.8
|
||
type: standard
|
||
title: "NetKingdom Security Layer Model v0.8"
|
||
domain: netkingdom
|
||
status: proposed
|
||
version: "0.8"
|
||
supersedes: canon/standards/security-layer-model_v0.7.md
|
||
owner: gate-house
|
||
publication_owner: net-kingdom
|
||
created: "2026-08-28"
|
||
updated: "2026-09-09"
|
||
last_reviewed: "2026-09-09"
|
||
review_interval: 3m
|
||
source_revision: "gate-house@516ed4e"
|
||
standard_token: security-layer-model_v0.8
|
||
# "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"
|
||
- "kings-guard v0.6 review, four findings; KG-DEC-2026-002 (§9.5 boundary)"
|
||
- "ops-warden v0.6 review, two findings"
|
||
- "access-engine FLEX-DEC-2026-003 (v0.6), five findings and two answers"
|
||
- "audit-core v0.6 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.8
|
||
|
||
## 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.8.** v0.7 was accepted, and eight rulings were made against
|
||
it in the eight days that followed. Each was correctly kept out of the accepted
|
||
text; together they are a version.
|
||
|
||
Three correct a rule that was unsafe or unfalsifiable as written. §9.7.3 stated
|
||
that the action precedes consumption, which leaves the compare-and-swap able to
|
||
prevent only the second *record* and never the second *side effect* — single
|
||
consumption was theatre. §9.5's boundary with posture rested on volatility, which
|
||
describes the two categories without partitioning them. §6.4 let `unknown`
|
||
resolve permissively, which makes being unclassifiable a privilege escalation
|
||
requiring no credential.
|
||
|
||
Three close a gap between rules already made. §6.4 gains validation by owning
|
||
layer and the rule that correspondence between two artifacts is established by
|
||
identity rather than translation. §11 gains an emission-guarantee declaration, so
|
||
`GH-IN-0001` cannot recur unnoticed. §13.1 gains three rows, a scoping axis, a
|
||
coverage figure, and an honest statement of what it cannot answer.
|
||
|
||
Nine more corrections landed during circulation, listed as §15 items 12–20 and
|
||
dispositioned in `gate-house/docs/conformance/2026-09-06-v08-assent-round.md`. The
|
||
load-bearing one is §6.4 obligation 1: a PEP must be able to *attribute* a
|
||
decision to `access-engine`, and no digest comparison does that. Fail-closed
|
||
protects against a decision point that is absent, not against one that lies.
|
||
|
||
One is a defect of the same kind this standard has now corrected repeatedly: §17
|
||
stated that emission-cadence ownership was unassigned and unassented after it had
|
||
been assigned and both owners had accepted. And §11 and §12 gain the general form
|
||
of the failure that produced it — six instances in one week, across four
|
||
repositories, of a repository acting on a derived summary rather than the
|
||
authoritative body. Four were self-reported and one was committed by the
|
||
repository proposing the rule, which is the argument that the publishing shape
|
||
makes the error the default rather than that four repositories were careless.
|
||
|
||
§15 records the change list. Section numbers are unchanged: the estate cites them.
|
||
|
||
**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.
|
||
|
||
Five 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.
|
||
|
||
**Held is not attributed, and this obligation requires both.** The decision a
|
||
PEP holds MUST be *attributable to* `access-engine`, not merely present and
|
||
well-formed. Obligation 2's digest test establishes **which request** a
|
||
decision was rendered for; it establishes nothing about **who rendered it**,
|
||
and it cannot. Every input to that comparison is either sent by the caller or
|
||
published: the request material is what the PEP transmitted, and the policy
|
||
and registry digests are computable from a public repository. A responder
|
||
knowing a published package id and version reproduces all of it and returns a
|
||
well-formed allow, and each further digest published makes a forged envelope
|
||
look more authenticated rather than less.
|
||
|
||
**Fail-closed protects against a decision point that is absent, not against
|
||
one that lies.** §9.3's whole apparatus — two failure cases, two owners,
|
||
published stance maps — addresses absence. An unreachable PDP denies; a
|
||
responder impersonating one allows. The asymmetry with obligation 5 is the
|
||
sharp form: §9.4 requires the approval object to have durable, authenticated
|
||
entries, so a PEP can validate the approval artifact's authenticity and
|
||
cannot yet validate the decision artifact's. Obligation 5 is written over
|
||
both halves of that pair and is today satisfiable for only one of them.
|
||
|
||
This obligation is therefore **not discharged by a digest comparison**, and an
|
||
implementer MUST NOT read obligation 2's mechanical test as discharging it.
|
||
The channel is unauthenticated today — `flex-auth.decision-record.v1` carries
|
||
no signature and pins serve plain HTTP — so the obligation stands with a
|
||
declared gap in §13 rather than with a shipped mechanism, owner
|
||
`access-engine` (`FLEX-DEC-2026-010`, `FLEX-WP-0024`). The signature scheme is
|
||
the owner's under §17; the standard names the property, not the mechanism. A
|
||
declared gap is honest; an unstated assumption inside a test called mechanical
|
||
is not. Raised by `access-engine` against its own artifact, having recorded it
|
||
as its own defect before reviewing this text; put the same way independently by
|
||
`secrets-engine`, whose posture *"silently assumes the PDP is the PDP"*, and
|
||
carried forward by `approval-engine`, which observed that an approval whose
|
||
`pdp_digest` matches a **forged** decision matches perfectly.
|
||
|
||
§16 had already recorded this observation one layer up, against this
|
||
standard's own publication path having no digest, freeze, or rollback
|
||
discipline. Applied to the artifact the standard regulates rather than to the
|
||
standard, it is this paragraph: the gap was visible from inside and was
|
||
recorded against the wrong artifact.
|
||
|
||
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 MUST 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.
|
||
|
||
The test was a `SHOULD` through v0.8's circulation, which left the strongest
|
||
obligation in this section with the weakest verification: a paragraph arguing
|
||
that drift is worse than no publication, whose only detector of drift was
|
||
optional, sanctioning the failure exactly where the argument says it is worst.
|
||
Promotion costs nothing — §13.1's `Shape` column already records such a test
|
||
for four of five rows. Raised by `access-engine`.
|
||
|
||
**`unknown` is not a zone and MUST resolve to `fail_closed`.** §9.3 permits
|
||
trading availability for openness *per zone* — knowingly, for a named scope,
|
||
at a declared cost. That trade requires knowing the zone. Where the scope is
|
||
unknown it cannot have been made for this request, so resolving `unknown`
|
||
permissively does not extend a considered decision; it invents the most
|
||
permissive one available.
|
||
|
||
An unreachable engine and an unclassified subject are different failure
|
||
cases. The first is a known request in a degraded system, and the trade is
|
||
genuinely available for it. The second is not: `unknown` is the cheapest
|
||
state for an attacker to induce — an unregistered workload, a malformed
|
||
label, a resource created before classification, a race against registry
|
||
propagation — and a permissive `unknown` makes being unclassifiable a
|
||
privilege escalation requiring no credential. §8's asymmetry forbids that
|
||
wherever it appears. Zone stances are untouched by this rule.
|
||
|
||
**A map MUST enumerate its axis, and an `unknown` cell MUST NOT be what makes
|
||
it total.** Totality satisfied by a catch-all is satisfied *vacuously*: every
|
||
scope the author never enumerated lands in `unknown`, fails closed, and nobody
|
||
ever learns which those were. The map is then total by having a default rather
|
||
than by covering its axis, and the drift test above passes by exercising the
|
||
catch-all instead of the axis. `access-engine` recognised the shape because it
|
||
published it — a policy package shipped with no tenant rule at all while 29
|
||
fixtures passed, because every fixture carried the same tenant
|
||
(`FLEX-DEC-2026-008`). A suite that never varies an input cannot report on it,
|
||
however many assertions pass; a stance map with a catch-all cannot report which
|
||
scopes were never enumerated, however green its test.
|
||
|
||
**`unknown` and `absent` are one runtime behaviour and two meanings, and the
|
||
record MUST distinguish them.** A scope value the map classifies as `unknown`
|
||
and a scope value the map does not enumerate at all both fail closed —
|
||
`absent` for a stronger reason than `unknown`, since it is the branch reached
|
||
by discovering that the author's model of their own axis was wrong, and §8's
|
||
asymmetry forbids being more permissive on surprise. But an `unknown` hit is
|
||
normal operation under a considered stance, while an `absent` hit is evidence
|
||
that this obligation is violated. An `absent` hit MUST therefore be
|
||
distinguishable in the record from an `unknown` hit, and MUST surface as a
|
||
conformance failure rather than be absorbed by the catch-all. This answers the
|
||
question §16 opened at the v0.8 cut, and closes it. Raised by `access-engine`.
|
||
|
||
**Classification coverage is published alongside the stance, and does not
|
||
soften it.** A row reading `unknown` → `fail_closed` while most of that
|
||
consumer's targets resolve to no scope at all is conformant and materially
|
||
misleading: a reader cannot distinguish a strict consumer from an unclassified
|
||
one, and the map becomes accurate about itself while inaccurate about its
|
||
effect — §11's published-map-equals-shipped-behaviour rule one level up.
|
||
§13.1 therefore records a dated coverage figure beside each stance.
|
||
|
||
Coverage is disclosure, **not** a transitional licence. `ops-warden` asked
|
||
whether this obligation could name a dated, published transitional
|
||
`unknown: fail_open` converting on coverage rather than on calendar, having
|
||
measured zero of three signing targets and three of twenty-one routing lanes
|
||
resolved to a zone: adopting the cell today would fail closed on essentially
|
||
every certificate it issues whenever `access-engine` is unreachable, including
|
||
the continuity path an operator needs in order to repair that unreachability.
|
||
**Declined.** A sanctioned transitional `fail_open` is indistinguishable at
|
||
runtime from the stance this rule forbids, and would make the rule optional at
|
||
exactly the moment of adoption — the only moment it costs anything. §11's
|
||
declared-gap mark already expresses *"correct rule, adoption not yet
|
||
affordable"* without inverting the rule's effect, and `ops-warden` proposed
|
||
that outcome as its own second preference. The deadlock it names is real, and
|
||
is closed by classifying continuity paths into a scope whose stance is open:
|
||
that is classification work, not a reason to hold the axis open. A stricter
|
||
stance is equally not a licence to manufacture the membership that makes it
|
||
survivable — where a scope is unknown because another repository has published
|
||
no workload-identity declaration, the consumer MUST NOT infer one.
|
||
|
||
**A published map MUST name the axis it scopes over**, and state its
|
||
relationship to security zone: either a mapping, or an explicit declaration
|
||
that none exists yet and why. *"Per zone or equivalent scope"* permits axes
|
||
that cannot be aggregated, and the register cannot then answer *"what is the
|
||
estate's stance for a `z2`-protected workload"* — the question an inventory
|
||
exists to answer. Forcing every consumer onto zones is the wrong repair where
|
||
zone membership is not yet available as a claim: asserting a zone one cannot
|
||
know is a fiction, and a fiction in a runtime-read, test-pinned file is worse
|
||
than an honest incommensurability. §13.1 therefore records the axes and
|
||
states that cross-axis aggregation is unavailable.
|
||
|
||
Raised by `access-engine` on the first occasion §13.1 held enough rows to
|
||
diverge, and explicitly not as a request that either consumer change its
|
||
stance — a PDP does not set a consumer's stance. Settled in
|
||
`GH-DEC-2026-009`.
|
||
|
||
4. **Reconstructability**, bounded by §9.6.
|
||
|
||
5. **Validation by owning layer.** Where a PEP's decision to act rests on more
|
||
than one artifact, each artifact MUST be validated against the layer that
|
||
owns its data, and a PIP MUST NOT republish the PDP's decision. A PEP MUST
|
||
NOT accept the approval fact from the decision artifact, nor the decision
|
||
from the approval artifact.
|
||
|
||
A composed object bundling both is not forbidden as an artifact, but it is
|
||
post-decision by construction: it cannot be served from a pre-decision call,
|
||
and it needs a named issuer and lifecycle owner before anyone may rely on it.
|
||
|
||
The live instance is the `GH-DEC-2026-003` consumption path: the
|
||
approval-claim carries the approval fact (binding digest, validity window,
|
||
consumption state, freshness, issuer) and the `DecisionEnvelope` carries the
|
||
decision (exact `CheckRequest` match, policy package and version pin). Two
|
||
digests may cover the same proposed action without being compared to each
|
||
other; they answer different questions at different layers, and collapsing
|
||
them is a layer violation in the shape of a refactor.
|
||
|
||
**Correspondence is established by identity, not by translation.** Where two
|
||
artifacts use different vocabularies for the same request, the consumer
|
||
compares a digest one layer computed and the other recorded. It MUST NOT
|
||
recompute one layer's binding from the other's vocabulary, and no
|
||
cross-engine mapping is published for it to use: a mapping can be wrong in a
|
||
way that still produces a confident answer, it fails open, and it would be a
|
||
third authority on what a request *is*.
|
||
|
||
**An evidence-bearing input may be excluded from a correspondence digest, but
|
||
never from the replay identity.** These are two digests over one request and
|
||
they are deliberately different. A correspondence digest answers *"is this the
|
||
action the approval was granted for"* and must exclude the evidence, or it
|
||
cannot be computed before the evidence exists. A replay identity answers *"is
|
||
this the same request"* and MUST cover every input the decision depends on,
|
||
evidence included — two requests differing only in which approval was
|
||
presented decide differently, one allowing and one denying, so collapsing them
|
||
would let an allow obtained with a valid claim be replayed against a request
|
||
carrying none. That is a fail-open hole reached by a refactor that looks like
|
||
simplification, which is why the property is stated rather than left to be
|
||
rediscovered. The shape recurs wherever evidence travels inside a hashed
|
||
request. Raised by `access-engine`, which nearly took the unsafe simplification
|
||
and reported the near miss.
|
||
|
||
**A consumer of a summary predicate trusts the issuer's evaluation of
|
||
everything folded into it.** Where the split reduces what a PEP verifies
|
||
independently — as `valid_now` does for an approver threshold the claim
|
||
deliberately does not expose — the compensating property is
|
||
reconstructability at the issuer under §9.6, not a second check at the
|
||
consumer. That is detection, not prevention, and it belongs in the same
|
||
register as §9.6's other residual.
|
||
|
||
Raised by `approval-engine`, and by `access-engine` twice against its own
|
||
interest — once on its proposed artifact and once on a gap it declined to
|
||
close locally. Settled in `GH-DEC-2026-005` and `GH-DEC-2026-008`.
|
||
|
||
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 |
|
||
| **validating a fact** | the consumer checking an artifact against its issuer | **re-issuing it** — serving another layer's conclusion as your own output is deciding early (§6.1), whatever the field is named |
|
||
|
||
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.
|
||
|
||
**The boundary with posture is recomputability, not volatility.** Given the same
|
||
criteria and the same evidence, recompute. If you MUST get the same answer, it is
|
||
maturity and it belongs in an engine. If you CANNOT promise the same answer, it is
|
||
posture and it belongs in Staff.
|
||
|
||
This is not a new rule — it is the determinism clause above, pointed at the one
|
||
boundary where it had not been pointed. This section already states the maturity
|
||
half: a criterion that cannot be evaluated by rule is not yet a criterion. The
|
||
posture half is its mirror and completes the pair: **a judgment that CAN be
|
||
evaluated by rule is not posture — it is a criterion sitting in the wrong
|
||
repository.** Together they partition rather than describe, which a "fast-moving
|
||
versus slow-moving" line cannot: volatility is an observation about how a value
|
||
has behaved, and every case it does not obviously cover becomes an argument at
|
||
exactly the boundary §6 exists to keep out of argument.
|
||
|
||
**A criterion MUST bottom out in evidence about the subject, not in another
|
||
party's conclusion about the subject.** A recorded judgment may be evidence *that
|
||
the judgment was made* — a fact with an issuer and a timestamp. It MUST NOT be
|
||
evidence *that the thing judged is so*. Without this the test is satisfiable by
|
||
the inference it exists to exclude: *"level 2 iff the reviewer marked the control
|
||
adequate"* recomputes identically every time and has placed an opinion inside an
|
||
engine wearing a rule's clothes. For human-attested controls, grade on the
|
||
attestation event's existence, freshness, and issuer — never on its verdict.
|
||
|
||
Three consequences follow. **The migration direction is permanent**: anything
|
||
called posture that proves recomputable becomes a criterion in `maturity-engine`;
|
||
anything in `maturity-engine` that needs judgment is not yet a criterion and
|
||
returns to Staff. **Two authorities cannot grade the same subject property**,
|
||
because a property is either recomputable or it is not, and that does not depend
|
||
on which repository claims it. **Capability readiness MUST NOT be an input to
|
||
posture** — readiness is deterministic and posture is not, so feeding one into the
|
||
other would make posture partly recomputable and blur the boundary from the Staff
|
||
side.
|
||
|
||
**A limit, stated rather than implied.** *"The same evidence"* is not yet well
|
||
defined in this estate. Until §17's request-claim and gap-record schemas exist,
|
||
two parties can disagree about whether they hold the same evidence, and
|
||
recomputability is a thought experiment rather than a check. This makes §17
|
||
load-bearing for this rule. A boundary that is correct but not yet mechanically
|
||
checkable is better than one that is checkable and wrong; a reader is entitled to
|
||
know which they are holding.
|
||
|
||
Raised by `kings-guard` against the volatility line `gate-house` had proposed, and
|
||
against its own convenience — the readiness constraint is one it volunteered.
|
||
Settled in `GH-DEC-2026-007`.
|
||
|
||
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: a decision record proves an intent
|
||
to act, not an act.
|
||
|
||
**The PEP MUST obtain a successful consume before the protected side
|
||
effect.** Holding a claim with `valid_now: true`, or an ALLOW rendered
|
||
against that claim, is not authority to act; the consume is. In-flight
|
||
duplicate ALLOWs are expected and the CAS serializes use — a later
|
||
`CheckRequest` sees `valid_now: false` and cannot mint a new ALLOW against
|
||
the same object.
|
||
|
||
v0.7 stated the opposite order. Acting first leaves the CAS able to prevent
|
||
only the second *record*, never the second *side effect*, which makes single
|
||
consumption theatre. This is a protocol correction and not a retraction of
|
||
the forensic claim: consumption is still never inferred from a decision.
|
||
|
||
An approval authorizes one **attempt**, not one success. There is no
|
||
unconsume and no reserve/release; a consumed approval spent on a failed
|
||
action is spent. Reversibility would reopen replay, which is the failure the
|
||
mutation exists to close.
|
||
|
||
**The correspondence is a digest, and it is the PDP's to define.** A consumer
|
||
on this path MUST verify that the approval's recorded PDP digest equals the
|
||
digest the PDP publishes **for the request with the approval evidence
|
||
excluded** — `binding.approval_binding_digest` in `access-engine` — and MUST
|
||
NOT use a claim that carries no such digest. Recomputing the approval engine's
|
||
native binding from a `CheckRequest` is not a permitted fallback: it requires
|
||
translating between two vocabularies, no mapping is published, and a wrong
|
||
translation fails open by silently accepting a claim approved for something
|
||
else. Without this, `valid_now: true` plus an ALLOW establishes *approved* and
|
||
*permitted* but never *approved for this request*.
|
||
|
||
**The comparison cannot be against the full request digest.** Where a claim
|
||
travels inside the hashed request — the dual-control pattern — embedding it
|
||
changes the digest of the request carrying it, so a digest recorded at issue
|
||
can never equal the final one. That is a hash cycle and the resolution is
|
||
forced, not chosen: the recorded digest is necessarily of the underlying
|
||
action before any claim was embedded. A standard that mandates the naive
|
||
comparison mandates a check that can never pass, and a fail-closed consumer
|
||
then denies the action permanently.
|
||
|
||
**The exclusion rule is the PDP's to publish, and until it does the path is
|
||
incomplete rather than complete.** A consumer MUST NOT guess which fields are
|
||
excluded: a digest computed under an assumed rule produces a confident wrong
|
||
answer, and comparing two digests derived under different rules fails open
|
||
toward accepting a claim bound to a different request — the same failure
|
||
direction as an invented vocabulary mapping, reached by another road.
|
||
|
||
Settled in `GH-DEC-2026-008`, amended on an implementability defect found by
|
||
`secrets-engine` and reported independently by `access-engine` and
|
||
`approval-engine` within hours of the ruling.
|
||
|
||
Settled in `GH-DEC-2026-003`; the protocol is
|
||
`gate-house/docs/contracts/approval-consumption.md`.
|
||
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;
|
||
- every repository catalogued in §4 as a source of evidence declares its
|
||
**emission guarantee** in its machine-readable layer declaration: for a
|
||
**load-bearing** source, a local transactional outbox (§9.4), its declared
|
||
cadence, and the detection surface the governing cadence profile requires for
|
||
that class — under `net-kingdom`'s
|
||
`emission-cadence-security-profile_v0.1.md`, a **volume** load-bearing class
|
||
MAY be covered by rate monitoring where the source has classified it as
|
||
suitable, with a positive window and a positive minimum; a **rare**
|
||
load-bearing class MUST NOT be, and MUST carry a heartbeat **and**
|
||
reconciliation, not either alone; for an **attributive** source, the trade it
|
||
makes and an explicit statement that completeness is not claimed. Which class
|
||
an event falls in, and whether it is rare, is the source's published
|
||
classification: a conformance run is supplied that inventory and MUST NOT
|
||
infer it from an event name, payload, or observed rate, or the check becomes
|
||
circular;
|
||
- every published example, fixture, or sample document validates against the
|
||
schema it exemplifies, and where a field is optional but load-bearing, the
|
||
examples cover both its presence and its absence rather than leaving one shape
|
||
to be inferred from the other;
|
||
- every derived artifact — a summary, example, change log, or review record that
|
||
restates a normative body — is marked as derived, names the artifact it
|
||
derives from, and carries the version or commit it was derived at.
|
||
|
||
A source that declares no emission guarantee is not conforming, and neither is
|
||
one that declares load-bearing emission with rate monitoring alone where its
|
||
event class is rare (§9.6). The declaration is what makes §9.6 checkable rather
|
||
than reviewable; without it the section states an obligation whose satisfaction
|
||
cannot be observed, which is the §9.1 defect this standard has now corrected four
|
||
times. Drafted in `gate-house/docs/contracts/approval-emission-detection.md`,
|
||
which `approval-engine`'s `cadence.yaml` implements as the reference instance.
|
||
The check states no MUST/SHOULD split of its own: which evidence classes must
|
||
declare cadence, and in which form, is the governing profile's to say (§17), and
|
||
this item follows it rather than restating it.
|
||
Raised by `audit-core` as the general form of `GH-IN-0001`, so the finding that
|
||
produced `GH-WP-0002` cannot recur unnoticed.
|
||
|
||
The example-validation check is the mechanical half of §12's derived-artifact
|
||
rule; `approval-engine` reports it at fifteen lines. Its second clause is the
|
||
non-obvious one: an example set that silently omits an optional field teaches
|
||
every reader that the field does not exist.
|
||
|
||
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.
|
||
|
||
**A derived artifact is not evidence of what the body says.** A repository acting
|
||
on another repository's contract, schema, or standard MUST read the authoritative
|
||
artifact. Where a derivative exists — a summary, example, change log, or review
|
||
record — it MUST be marked as derived, name the artifact it derives from, and
|
||
carry the version or commit it was derived at. A **dated review record** MUST
|
||
carry an explicit marker that it states status as of that date and not current
|
||
state. Where a derivative is unmarked, treat it as stale.
|
||
|
||
This is not a counsel of care. The estate produced six instances in a single
|
||
week, across four repositories: a validator built against a fixture rather than
|
||
its prose; a revisit trigger sourced from a dated alignment table; a change log
|
||
read for section text; a dual-control policy rule written against an assumed
|
||
claim shape, under which every live destroy would have denied; a fixture
|
||
declaring a contract version while omitting fields published since; and a
|
||
published example set contradicting its own schema. Four were self-reported, and
|
||
one was committed by the repository arguing for this rule. Diligence prevented
|
||
none of them, and a control that depends on repositories volunteering corrections
|
||
is not a control.
|
||
|
||
The obligation on the publishing side is §11's marking and example-validation
|
||
checks. The limit is worth stating: the mechanical half catches example-versus-
|
||
schema drift, and the convention half makes prose staleness visible without
|
||
detecting it. A marked derivative can still be wrong; claiming otherwise would be
|
||
this same defect one layer up. Proposed by `approval-engine`, which asked to own
|
||
none of 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 |
|
||
| Decision-record authenticity — a PEP cannot attribute a decision to `access-engine` (§6.4 obligation 1); unsigned envelope, plain-HTTP pins | declared-contact | flex-auth | flex-auth | self-declared (`FLEX-DEC-2026-010`, `FLEX-WP-0024`) |
|
||
| Human principal's tenant is unresolvable from the directory, so a client registration supplies it (`GH-DEC-2026-013`) | declared-contact | key-cape | directory adapter — unnamed | proposed |
|
||
| 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 | Axis | Coverage | Shape |
|
||
| --- | --- | --- | --- | --- |
|
||
| `ops-warden` | `ops-warden/pep-stance.yaml` | security zone | signing targets 0/3 resolved; routing lanes 3/21 resolved (2026-09-09, self-measured) | total per zone; open `z0`–`z2`, closed `z3-critical`; test asserts the published map equals the shipped default (`ADR-0009`). **`unknown` → `fail_open` is non-conformant under §6.4 obligation 3 as of this version**; route `WARDEN-WP-0040` |
|
||
| `user-engine` | `user-engine/pep-stance.yaml` | security zone | not reported | total per zone; `fail_closed` for `z0`–`z3`, unknown, and not-applicable; test asserts the published map equals `user_engine.pep_stance` |
|
||
| `tenant-engine` | `tenant-engine/pep-stance.yaml` | security zone | not reported | total; `fail_closed` for unset, unreachable, non-allow, unknown; test asserts the file equals shipped behaviour |
|
||
| `secrets-engine` | `secrets-engine/pep-stance.yaml` | catalog stage — interim, pending zone membership as a claim | not reported | total over stage plus unknown; no implicit default; runtime-read; pinned to `SHIPPED_STANCE` by test |
|
||
| `ops-mason` | — | — | — | **not published — non-conformant under §6.4 obligation 3**; catalogued PEP-shaped in §4; no route recorded |
|
||
|
||
**Two rows are marked, and the marking is the point.** `ops-warden`'s cell is
|
||
wrongly valued in a published map; `ops-mason` has published no map at all, which
|
||
is the plainer violation of the same obligation and read as a bare statement of
|
||
fact through v0.8's circulation. A reader scanning for the bold marks would have
|
||
found one row and concluded the other four were fine. That is §11's marking
|
||
obligation applied to this standard's own register, and it was returned to
|
||
`gate-house` unchanged by `access-engine`, which had received the same argument
|
||
about a stale row of its own.
|
||
|
||
**Coverage is reported by the consumer and is not inferred here.** A blank is
|
||
"not reported", never "complete": the register does not compute another
|
||
repository's classification coverage, and a stance with no coverage figure beside
|
||
it says less than it appears to. §6.4 obligation 3 states why the figure belongs
|
||
next to the stance, and why it does not soften it.
|
||
|
||
**Cross-axis aggregation is unavailable.** Three maps scope by security zone and
|
||
one by catalog stage, which §6.4 permits as an equivalent scope. The register
|
||
therefore cannot answer *"what is the estate's stance for a `z2`-protected
|
||
workload"* for every consumer, and it states that rather than implying it can.
|
||
The convergence path is zone membership reaching the decision as a claim, after
|
||
which a stage-scoped map converges onto zones without either side inventing a
|
||
mapping.
|
||
|
||
**The register earned itself at two rows.** `access-engine` said in the v0.6
|
||
round that it was the repository positioned to notice when the aggregate of
|
||
consumer stances diverges from the policy packages, and recorded that the claim
|
||
was sound while one row could not diverge from anything. The second row produced
|
||
two findings on first inspection: two conformant maps taking opposite stances on
|
||
`unknown`, and two incommensurable axes. Both are settled in `GH-DEC-2026-009`.
|
||
|
||
This register moves to `maturity-engine` when — and not before — that engine
|
||
publishes a committed, versioned export of §13 and §13.1 readable without a live
|
||
query, generated rather than hand-edited, and regenerable so drift between the
|
||
export and its computed state is detectable. A standard of record must stay
|
||
legible in git, at a version, to a reader with no cluster access, including one
|
||
auditing the estate precisely because they do not trust its running systems; a
|
||
pointer to a live engine is an instruction to run software, not a register.
|
||
`maturity-engine` holds both registers as queryable data already (`MAT-WP-0001`),
|
||
so what remains is publication — the migration's precondition, not its
|
||
follow-up. Settled in `GH-DEC-2026-006`.
|
||
|
||
## 14. Adoption
|
||
|
||
Status is **proposed**. v0.7 remains **accepted** and in force until this version
|
||
is accepted in its place; it is not patched.
|
||
|
||
Two things that acceptance does and does not mean, kept apart because
|
||
`ops-warden` asked for the distinction:
|
||
|
||
| | |
|
||
| --- | --- |
|
||
| **Boundary assent** | given by the four repositories below, at the version named in each record, and undisturbed since |
|
||
| **Revision review** | v0.7's changes were each the adopted remedy of a v0.6 finding. All fifteen v0.6 findings were subsequently audited against the v0.7 body — not against its change log — and confirmed dispositioned (`gate-house/docs/conformance/2026-09-06-v06-findings-audit.md`) |
|
||
| **Reviewed as text** | v0.8's circulated round returned findings from `access-engine`, `approval-engine`, `ops-warden`, and `net-kingdom`, and every finding is dispositioned in `gate-house/docs/conformance/2026-09-06-v08-assent-round.md`. Nine corrections landed in this text during circulation (§15 items 12–20) and one request was declined with its reasons in §6.4 |
|
||
| **Not claimed** | `kings-guard` and `audit-core` have not returned a text review; the sections each was asked to attack — §9.5's criteria-grounding clause and §12's step-four paragraph for the first, §11's emission-guarantee wording for the second — carry no assent from the repository best placed to test them. `approval-engine` named the sections it did **not** read (§1–§4, §7, §8, §9.1–§9.2, §9.5–§9.6, §9.8, §10, §18, §20) rather than let a three-finding review read as a clean bill |
|
||
|
||
|
||
**Ten of this version's twelve changes as cut were requested by another
|
||
repository**, seven of them by a repository arguing against its own interest or
|
||
reporting its own error. There are two exceptions, not one: §17's ownership
|
||
correction, which `gate-house` found by auditing its own accepted text, and item
|
||
2b, which `access-engine` flagged as a near miss it was explicitly *not* asking to
|
||
have written down. The count was stated as ten of eleven until `approval-engine`
|
||
observed that item 2b's numbering left a reader unable to tell whether it was a
|
||
change or a sub-clause — and that the ambiguity moved both halves of a ratio §14
|
||
calls the argument rather than the background. The nine corrections applied during
|
||
circulation (items 12–20) were all requested by another repository. That ratio is the reason the standard is
|
||
circulated rather than accepted on the owner's decision as v0.7 was: this version
|
||
imposes costs on named repositories — `ops-warden` acquires a non-conformant
|
||
stance cell, `approval-engine` acquires an issue-time obligation — and a cost
|
||
imposed without a review round is the kind of rule §12 exists to catch late.
|
||
|
||
Findings against this text are §12's normal business. Two are anticipated and
|
||
would be welcome: whether §6.4's `unknown` ruling is too broad for a genuinely
|
||
low-consequence unclassified scope, and whether a maturity criterion exists that
|
||
cannot be expressed without dereferencing a judgment. Both are written into the
|
||
reversal clauses of their decision records as the falsifiers that would revert
|
||
them.
|
||
|
||
| 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.7 → v0.8:
|
||
|
||
1. **§9.7.3 corrected** — the PEP MUST consume before the protected side effect.
|
||
v0.7's stated order left the CAS able to prevent only the second record, never
|
||
the second side effect. Protocol correction, not a retraction of the forensic
|
||
claim (`GH-DEC-2026-003`).
|
||
2. **§9.7.3 gains the binding correspondence** — the approval's recorded PDP
|
||
digest MUST equal the digest the PDP publishes for the request with the
|
||
approval evidence excluded, and a claim without one is unusable on that path.
|
||
No cross-engine vocabulary mapping is published: a translation can be
|
||
confidently wrong and fails open, where a digest is identity. The comparison
|
||
is against an exclusion-scoped digest because a claim travelling inside a
|
||
hashed request cannot name the digest of the request containing it — a hash
|
||
cycle, found by `secrets-engine` and reported independently by two engines
|
||
within hours of the ruling, which as first written mandated a check that could
|
||
never pass (`GH-DEC-2026-008`, raised by `access-engine`, which declined to
|
||
close it locally).
|
||
2b. **A change in its own right, not a sub-clause of 2** — the label is retained
|
||
rather than renumbered so that references written against this list do not
|
||
silently repoint. §14's tally counts it. **§6.4 obligation 5 gains the
|
||
replay-identity property** — an evidence-bearing
|
||
input may be excluded from a correspondence digest but never from the replay
|
||
identity, because two requests differing only in which approval was presented
|
||
decide differently. Flagged by `access-engine` as a near miss rather than a
|
||
request.
|
||
3. **§6.4 obligation 5 added** — validation by owning layer, and correspondence
|
||
by identity rather than translation. A PIP MUST NOT republish the PDP's
|
||
decision. Carries the consequence that a consumer of a summary predicate
|
||
trusts the issuer's evaluation of what is folded into it, with
|
||
reconstructability at the issuer as the compensating property
|
||
(`GH-DEC-2026-005`).
|
||
4. **§6.4 obligation 3 — `unknown` is not a zone** and MUST resolve to
|
||
`fail_closed`; and every published map MUST name its scoping axis and its
|
||
relation to zone. `ops-warden`'s `unknown` cell becomes non-conformant, and
|
||
the register records it as such (`GH-DEC-2026-009`, raised by `access-engine`
|
||
on two conformant maps that disagree).
|
||
5. **§9.5 gains the posture boundary** — recomputability, not volatility, with
|
||
the clause that a criterion MUST bottom out in evidence about the subject
|
||
rather than another party's conclusion about it. Three consequences, including
|
||
that capability readiness MUST NOT be an input to posture. The limit is stated:
|
||
*"the same evidence"* is undefined until §17 (`GH-DEC-2026-007`, raised by
|
||
`kings-guard` against the line this standard's owner had proposed).
|
||
6. **§11 gains the emission-guarantee declaration**, so a source catalogued as
|
||
evidence declares what its emission actually guarantees rather than
|
||
reintroducing `GH-IN-0001` silently. The check defers the form to the
|
||
governing profile instead of restating it: as first cut it required a
|
||
heartbeat *or* reconciliation of every load-bearing source, which both
|
||
over- and under-stated
|
||
`emission-cadence-security-profile_v0.1.md` — it withheld from a volume class
|
||
the rate monitoring the profile permits, and accepted for a rare class either
|
||
control alone where the profile requires both. It also contradicted its own
|
||
following paragraph. Corrected by `net-kingdom` on review of the ownership
|
||
§17 assigns it (`NK-WP-0035`).
|
||
7. **§11 and §12 gain the derived-artifact rules** — examples validate against
|
||
the schema they exemplify and cover both shapes of an optional load-bearing
|
||
field; derivatives are marked with source and derivation version; dated review
|
||
records are marked as status-as-of-date. Six instances in one week across four
|
||
repositories (proposed by `approval-engine`).
|
||
8. **§8 gains a demarcation** — validating a fact is not re-issuing it.
|
||
9. **§13.1 gains three rows, an axis column, and two statements of limit** — that
|
||
cross-axis aggregation is unavailable, and that the migration to
|
||
`maturity-engine` waits on a published export (`GH-DEC-2026-006`).
|
||
10. **§17 corrected** — emission-cadence ownership is assigned, not proposed, and
|
||
both owners have accepted (`GH-DEC-2026-004`).
|
||
11. **§16 reconciled** against the decision log; two questions closed, one opened
|
||
on whether an absent scope differs from an unknown one.
|
||
|
||
Applied during circulation, after the round returned findings against this text
|
||
(`gate-house/docs/conformance/2026-09-06-v08-assent-round.md`). The version stayed
|
||
`proposed` throughout, so these are corrections to an uncut standard rather than
|
||
amendments to an accepted one:
|
||
|
||
12. **§6.4 obligation 1 gains attribution** — a decision MUST be attributable to
|
||
`access-engine`, and obligation 2's mechanical digest test does not discharge
|
||
that. Fail-closed protects against a decision point that is absent, not
|
||
against one that lies, and obligation 5 was written over a pair of artifacts
|
||
whose authenticity only one half of could be validated. Carried as a declared
|
||
§13 gap with `access-engine` as owner rather than as a shipped mechanism
|
||
(raised by `access-engine` against its own unsigned envelope, having recorded
|
||
it as `FLEX-DEC-2026-010` before reviewing this text).
|
||
13. **§6.4 obligation 3's drift test promoted `SHOULD` → `MUST`** — the strongest
|
||
obligation in the section had the weakest verification, in a paragraph arguing
|
||
that drift is worse than no publication. Already met by four of five §13.1
|
||
rows (raised by `access-engine`).
|
||
14. **§6.4 obligation 3 forbids totality by catch-all**, and requires an `absent`
|
||
scope to be distinguishable in the record from an `unknown` one and to surface
|
||
as a conformance failure. This closes the question item 11 opened (raised by
|
||
`access-engine`, from its own 29-fixture tenant defect).
|
||
15. **§6.4 obligation 3 and §13.1 gain classification coverage** — published
|
||
beside the stance, because `unknown` → `fail_closed` over a population that is
|
||
entirely unclassified is conformant and misleading. A transitional
|
||
`unknown: fail_open` was asked for and **declined**: it is indistinguishable at
|
||
runtime from the stance the rule forbids (requested by `ops-warden`, which
|
||
proposed the declared-gap outcome as its own second preference and measured the
|
||
coverage figure now in the register).
|
||
16. **§13.1 marks `ops-mason`** — an unpublished map is a plainer violation of
|
||
obligation 3 than a wrongly-valued cell in a published one, and was stated as
|
||
bare fact while the other was bolded (raised by `access-engine`, returning
|
||
`gate-house`'s own §11 marking argument unchanged).
|
||
17. **§14's tally corrected and §15 item 2b clarified** — 2b is a change in its own
|
||
right and is the second item not requested by another repository, so the ratio
|
||
is ten of twelve with two exceptions (raised by `approval-engine`).
|
||
18. **§6.4's count sentence corrected** — it announced four obligations and listed
|
||
five, leaving a defensible reading under which an implementer omits the one
|
||
governing how an approval is compared to a decision (raised by
|
||
`approval-engine`).
|
||
19. **§17's artifact count and closing status corrected** — v0.8's item 10 reached
|
||
the emission-cadence paragraph and not the count sentence, which still called
|
||
ownership of the decision-record schema unsettled after `access-engine` took it
|
||
on (raised by `approval-engine`).
|
||
20. **§19 gains a stub** — the heading gap was explained in a §16 bullet, where a
|
||
reader checking whether an edit had dropped a section does not look (raised by
|
||
`approval-engine`).
|
||
|
||
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).~~ **Decided (§9.7.3): the PEP, by compare-and-swap, before the
|
||
protected side effect.** The PDP never mutates and Staff never consumes. The
|
||
three failure modes have owners in
|
||
`gate-house/docs/contracts/approval-consumption.md`; there is no unconsume.
|
||
`GH-DEC-2026-003`, and `GH-DEC-2026-008` for the binding correspondence.
|
||
- 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.~~
|
||
**Decided (§13.1): yes, conditioned on a published export.** The engine holds
|
||
both registers as data; the migration waits on a committed, versioned export
|
||
readable without a live query, because a standard must stay legible in git to a
|
||
reader with no cluster access. `GH-DEC-2026-006`.
|
||
- ~~Whether §6.4's `unknown` ruling should extend to other total-map scopes that
|
||
are absent rather than unknown.~~ **Closed** during v0.8's circulation. It
|
||
extends, and the distinction is not a distinction in the stance: `absent` fails
|
||
closed too, for the stronger reason that it is the branch reached by discovering
|
||
the author's model of their own axis was wrong. The distinction is in the
|
||
record — an `absent` hit is a conformance failure and MUST be distinguishable
|
||
from an `unknown` hit, or obligation 3's totality requirement is satisfied
|
||
vacuously by a catch-all. §6.4 obligation 3; answered by `access-engine`, which
|
||
raised the question's real cost from its own 29-fixture tenant defect.
|
||
- 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. `access-engine` observed during v0.8's
|
||
circulation that the same observation applied to the artifact this standard
|
||
*regulates* is §6.4 obligation 1's attribution gap — the defect was visible from
|
||
inside and had been recorded against the wrong artifact. That half is now a
|
||
declared §13 gap; this entry is the half that remains open, and it is this
|
||
standard's own.
|
||
- 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 **working companion** (`net-kingdom/SECURITY-COMPANION.md`, v0.2, root of
|
||
the repository for onboarding) is the operative form of this statute. The statute governs on disagreement, and a
|
||
disagreement is a finding. The v0.1 gap `access-engine` found — publish
|
||
your stance map, but nowhere saying where, and no inventory obligation — is
|
||
fixed in v0.2 §5.3.
|
||
- 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 and versioned like any standard. **Two of
|
||
the four are not Taxonomy's**, and each is settled below rather than open: the
|
||
decision-record schema is `access-engine`'s, and the emission-cadence declaration
|
||
is split between `info-tech-canon` and `net-kingdom`. The table names all four
|
||
because §6.2 needs all four to exist, not because Taxonomy owns all four.
|
||
|
||
| 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 of the emission-cadence declaration is assigned.** `info-tech-canon`
|
||
owns the versioned, ecosystem-wide `EmissionCadenceDeclaration` semantic contract
|
||
— generic forms, fields, vocabulary, validation semantics, compatibility, and
|
||
evolution. `net-kingdom` imports it and owns the NetKingdom security profile:
|
||
which evidence classes MUST or SHOULD declare cadence, the prohibition on rate
|
||
monitoring for rare load-bearing classes, and the heartbeat-plus-reconciliation
|
||
obligations that satisfy §9.6. Each source repository owns its declaration
|
||
instance and its emission behaviour; `kings-guard` owns stream evaluation and
|
||
silence findings, not the schema.
|
||
|
||
The split was made by artifact so each has one owner: joint ownership would leave
|
||
version authority ambiguous, and giving the whole artifact to either repository
|
||
would conflate a reusable evidence contract with the security obligations of one
|
||
estate. Settled in `GH-DEC-2026-004`; both repositories accepted in their own
|
||
voice (`ITC-WP-0018`, publishing `ITC-EMISSION-CADENCE 0.1` in canon `0.7.0`;
|
||
`NK-WP-0035`, publishing `emission-cadence-security-profile_v0.1.md`). The
|
||
`kings-guard` draft is frozen as assimilation provenance.
|
||
|
||
**Exactly two artifacts are unsettled: the request-claim schema and the
|
||
gap-record schema.** Both sit between `info-tech-canon` and `net-kingdom` on the
|
||
same line, and neither has an owner in its own voice yet. The other two are
|
||
settled above — the decision-record schema is `access-engine`'s, and the
|
||
emission-cadence declaration is assigned and accepted by both its owners. §2 keeps
|
||
ownership in the owning repository's `INTENT.md`.
|
||
|
||
This paragraph read *"the remaining three artifacts is still proposed"* while
|
||
settling one of the three in its own next clause, so a reader checking whether the
|
||
decision-record schema needed an owner found it listed among the unsettled — after
|
||
`access-engine` had taken it on against its own interest. Raised by
|
||
`approval-engine`; v0.8's item 10 corrected the emission-cadence paragraph and did
|
||
not reach this one.
|
||
|
||
## 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.**
|
||
|
||
---
|
||
|
||
## 19. *(retired)*
|
||
|
||
There is no §19. It held a maturity grade for `qonto-assistant`, removed because a
|
||
grade inside a standard of record becomes normative by adjacency — it is an
|
||
assessment, and assessments belong in `maturity-engine` and in dated review
|
||
records. The number is not reused, so references written against earlier versions
|
||
do not silently repoint. Retirement recorded in §16 and in
|
||
`gate-house/history/`; raised by `access-engine`, and the stub added because a
|
||
reader who sees §18 followed by §20 cannot otherwise tell whether an edit dropped
|
||
a section (raised by `approval-engine`).
|
||
|
||
## 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*.
|