the-custodian/docs/assessments/2026-09-21-layer-declaration-boundaries.md
codex e3d0d13253 Record the Kubernetes change gate in Mode of Authority terms; drop bare 'operator'.
Option C: the gate on ADMINISTER @ realm:kubernetes is tiered by ADR-0006
readiness state. Below production-approved, activation=APPROVED by founder
plan approval; at production-approved, CONSTRUCT via ArgoCD for
external-audited evidence, direct apply only as activation=BREAK_GLASS.
rapp-policy-nexus gets a dated transition to 2026-12-21.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-21 14:07:30 +02:00

304 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Layer declarations: the estate-wide view of flex-auth's boundaries review
flex-auth published `docs/conformance/boundaries-review.md` (FLEX-WP-0030) on
2026-09-20 and corrected its first finding on 2026-09-21. It surveyed twelve
security-relevant counterparts against §11 of the security layer model
(`net-kingdom/canon/standards/security-layer-model_v0.8.md`, proposed). Each of
the five engine repositories received a tailored message; none of them sees the
whole set. This record holds the cross-repo view and adds two findings the
review could not have reached from inside one repository.
## What the review established
**B1 (as corrected) — precedence between two permitted forms.** §11 accepts a
`layer:` key in `INTENT.md` frontmatter *or* an equivalent declaration file, and
does not say which governs when a repository carries both. Nine repositories
carry both and disagree in every case: `INTENT.md` capitalises, `layer.yaml`
does not. A conformance run reading one file and a run reading the other reach
different answers for nine repositories, and both follow §11. Two rulings are
needed: which form governs, and whether the §3 vocabulary is case-sensitive.
The first published B1 claimed the estate spelled `layer:` three ways *across*
repositories. It was produced by a shell pipeline that took the first match per
repository across two files without recording which file it came from. flex-auth
rebuilt it as `tools/survey_layer_declarations.go` with a receipt, and running it
falsified the finding it was built to reproduce. The correction is the stronger
result: the disagreement is *within* each repository and universal rather than
careless.
**B2 — four security-relevant repositories carry no `layer:` key**: gate-house,
key-cape, ops-mason, net-kingdom.
**B3 — an emission guarantee nobody has claimed.** §11 requires every repository
catalogued in §4 as a source of evidence to declare class, cadence and detection
surface, and says a source declaring none is not conforming. flex-auth produces
the decision record and declares none. Whether it is a §4 source, or only the
producer of an artifact audit-core is the source of, is unruled. flex-auth has
declined to take the reading that favours it and holds the gap open as G2.
**B4 — whether a layer declaration should carry a standard version.** flex-auth
removed `0.7` from its own and enforced the absence by test: assent is to a
boundary at a named version, not to current text, so a version in the declaration
makes every revision read as though it invalidated the declaration.
**B5 — canon names `access-engine`; the repository still answers to `flex-auth`**
and the rename (FLEX-WP-0020) has not landed.
## Two findings the review could not see
The review surveyed the twelve counterparts flex-auth has boundaries with. An
estate-wide sweep of every repository carrying a declaration finds fourteen, and
the three it did not cover change two of its conclusions.
**One repository declares a value outside the §3 vocabulary — not two.**
`informed-decision` declares `surface`, which appears nowhere in the model as a
layer. `railiance-master` declares `Taxonomy`, and **`Taxonomy` is §3's first
enumerated layer**, defined in §3.1, carried in §4's catalog, mapped in §7 and
given its own §17. The custodian's first reading of this finding was wrong: it
took flex-auth's validator set `{Staff, Engine, Tooling}` for the §3 vocabulary.
§3 enumerates four layers — Taxonomy, Tooling, Engines, Staff. The correction is
railiance-master's, with the citations, and it is recorded here rather than
quietly amended because the first version was circulated to gate-house.
What remains of the finding is sharper and is aimed at the validator and the
standard, not at the declaring repositories:
- **flex-auth's validator omits §3.1 and misspells §3.3.** It admits `Engine`
where §3's table writes `Engines`, and omits `Taxonomy` altogether. Its set
looks built from §4's role-typed catalog rows rather than from §3.
- **§3 and §4 disagree inside the standard.** §3's table says `Engines`; §4's
catalog types eight rows `Engine`. A conformance run built from §3 and one
built from §4 disagree about every engine repository in the estate. That is
the same defect as B1 — two readings of one standard, both faithful — one
level further in, and B1's precedence ruling does not reach it.
- **`railiance-master`'s casing matches §3's table exactly.** Against the
standard's own spelling, the nine lower-casing `layer.yaml` files are the
divergent ones, which bears on whether case sensitivity is even the question.
`informed-decision`'s `surface` is a genuinely separate case and does not
behave like `railiance-master`'s. The two should not be ruled on together.
**The "two generators, two conventions" reading does not hold estate-wide.**
Nine of nine is true of the repositories flex-auth surveyed, but
`informed-decision` and `railiance-master` agree between their two files. The
split tracks the vocabulary values, not the generators: exactly the repositories
whose value is outside the vocabulary are the ones written by hand and
internally consistent. This does not weaken B1 — precedence is still unruled —
but it removes the inference that a single generator pair explains the estate,
and with it the hope that one generator fix closes the finding.
`whitehat-security` declares `Staff` in `INTENT.md` and has no `layer.yaml`,
which is flex-auth's own shape: a second repository that cannot exhibit the
split for the same reason.
## Where the questions sit
| # | Question | Owner |
|---|---|---|
| 1 | Which §11 form governs when both are present | gate-house |
| 2 | Is the §3 vocabulary case-sensitive | gate-house |
| 3 | Is §3's vocabulary closed — `surface` only; `Taxonomy` is §3.1 | gate-house |
| 4 | gate-house's own layer declaration (B2) | gate-house |
| 5 | Is flex-auth a §4 source of evidence (B3) | gate-house |
| 6 | May a declaration carry a standard version (B4) | gate-house |
| 7 | Which side of the B3 line audit-core holds | audit-core |
| 8 | What `CheckRequest.tenant` denotes on the write API — ANSWERED, TEN-DEC-2026-002 | tenant-engine |
| 9 | Layer declarations for key-cape, ops-mason, net-kingdom (B2) | each owner |
gate-house holds six of the nine, including the ruling that decides whether
flex-auth is non-conformant on its own conformance record today. That
concentration is not an accident of routing: every one of them is a question
about what §11 means, and gate-house authors §11. It is also the repository
flex-auth names as the clearest B2 case — a doctrine owner that has not
discharged its own obligation.
audit-core can state its side of B3 without waiting for anyone, but stating it
does not close G2: flex-auth holds the gap open until gate-house rules *and*
audit-core confirms.
tenant-engine's is the longest-running — asked 2026-09-15, re-asked 2026-09-20,
still unanswered — and the only one of the nine blocking implementation rather
than documentation. FLEX-WP-0022-T02 waits on it by choice: flex-auth can read
`FlexAuthWriteAuthorizer.authorize` copying `tenant_id` onto both
`CheckRequest.tenant` and `resource.id`, and has declined to encode a policy rule
from reading a consumer's code. "None of the nine write actions is refused
cross-tenant" is a complete answer; silence is not, because a deliberate
cross-tenant scope and an omitted rule are indistinguishable in the published
package.
## The custodian's reading
The v0.8 assent round should not close while §11's own mechanical check is
ambiguous. Six of the nine questions are §11 interpretation, and a standard that
cannot tell two conforming conformance runs to agree is not yet mechanically
checkable in the sense §11 claims for itself. gate-house has already been asked
to hold v0.8 over audit-core's §11 review; these belong in the same hold rather
than in a follow-on amendment.
None of this is the custodian's to rule. §11 is net-kingdom canon authored by
gate-house, and the custodian's contribution is the estate-wide survey and the
observation that the questions concentrate in one repository.
## Correction, 2026-09-21
The first version of this record claimed two repositories declared values
outside §3's vocabulary. `Taxonomy` is in §3. The error was the custodian's and
was made in the same shape as the one flex-auth had just corrected: a survey run
against an artifact that stands in for the standard — there, a shell pipeline;
here, another repository's validator — and published without reading §3 itself.
A tenth question follows from the correction: whether §3's `Engines` or §4's
`Engine` governs a declaration.
## Resolution, 2026-09-21
gate-house ruled all six of its questions the same day, in `GH-DEC-2026-017`
(declaration form), `GH-DEC-2026-018` (B3) and `GH-DEC-2026-019` (the v0.8
hold), with the canon changes drafted as gate-house amendments A9A13 and
circulated for assent. No net-kingdom file was edited; publication stays with
net-kingdom.
- **Precedence.** `INTENT.md` governs; a `layer.yaml` is a derived artifact that
must agree. Precedence alone would have made eight of the nine disagreements
invisible rather than settled, so a disagreement between the two forms stays
a reportable finding.
- **Case.** Case-insensitive, ASCII fold, §4's column spelling canonical. No
repository re-spells anything; flex-auth's validator changes, as it offered.
- **Vocabulary.** Closed at four tokens, not three. The validator's omission of
`Taxonomy` is the defect; `railiance-master` is conforming. `surface` is the
only genuine off-vocabulary value.
- **Scope.** §11 binds §4, and both off-vocabulary repositories sit outside §4 —
so neither is a non-conformance, and **a conformance run must now state its
scope**. That rule reaches this record: the sweep below was published without
stating that it ranged over every repository carrying a declaration rather
than over §4, and two of its three findings turned on repositories §11 does
not bind.
- **B2.** Discharged for gate-house in the same commit: `INTENT.md` frontmatter,
`layer: Staff`, no sidecar. The prose `**Layer:** Staff` line had stood since
v0.1 and is exactly what gate-house's own paragraph says does not count.
- **B3.** Ruled against flex-auth: a custodian is never the source of what it
holds, so flex-auth is a §4 source, owes an emission guarantee, has none, and
is non-conforming on §11 today. audit-core's reading is upheld. The finding
under it: §11 says "catalogued in §4 as a source of evidence" and §4
catalogues no such thing, so flex-auth could not have answered from the text.
- **B4.** No standard version in a declaration. Every sidecar in the estate
carries `standard_version: "0.7"` because ops-warden's reference form does —
one change in one repository, not seven.
- **v0.8** stays held, with three stated conditions so the hold cannot drift.
Of the ten questions this record tracked, eight are ruled or answered.
Outstanding: `informed-decision`'s §4 membership (asked, not enrolled) and the
`role:` vocabulary, which needs A9 first.
### What the custodian got wrong, twice
Both errors were the same error. The sweep was run against flex-auth's
validator as a stand-in for §3, and published as an estate property without
stating the scope it ranged over. `Taxonomy` was in §3 all along, and the two
repositories named were never bound by §11. The reviewed repositories caught
both: `railiance-master` supplied the §3 citations, `informed-decision`
narrowed its own request rather than re-litigating, and gate-house's scope rule
names the defect generally. The custodian's contribution that survived is the
§3-`Engines`/§4-`Engine` disagreement, which became amendment A9.
## Application, 2026-09-21
- **ops-warden** applied GH-DEC-2026-017 to the reference form after verifying
it at `gate-house@def0af2`. Its conformance checker listed `standard_version`
as required, so any repository that copied the checker must drop the key from
the checker's required list in the same commit, or a conforming declaration
fails `MALFORMED`. Change set: `ops-warden/wiki/playbooks/netkingdom-layer-declaration.md`.
- **flex-auth** fixed its validator (four tokens, ASCII fold, §4 spelling, scope
stated per run), published per-class emission guarantees in `cadence.yaml`,
and holds G2 as a dated declared gap to 2026-10-19 under FLEX-WP-0031.
FLEX-DEC-2026-015: `resource.system` follows the runtime, not the repository.
- **informed-decision** declares `Staff`/`pep-shaped` and asked for a §4 row with
its guarantee reported as owed. The §3.4 fit — Staff is defined as
non-deterministic; this repository is deterministic by test — stays open as
INFD-IN-0007.
- **secrets-engine** established that its exec reads the ungoverned legacy path
`secret/coulomb/whynot-design/npm/publish` (field `npm_token`), while ops-warden's
runbook rotates the governed path (field `NPM_AUTH_TOKEN`). A rotation per the
runbook would not reach the live publish path. Held by the founder.
Ten repositories still carry the pre-ruling sidecar form.
## Second round, 2026-09-21
GH-DEC-2026-017 is applied in thirteen repositories. No `standard_version` field
remains in any declaration, and no layer value was re-spelled. Six
repositories carried a copy of ops-warden's conformance checker, not five as
first counted; zone-engine's was under `tools/`. Each required
`standard_version`, and several compared layers with plain equality. Every one
changed in the same commit as its field.
Three questions about A12's reach went to gate-house with counts measured on
disk. The repositories' own reports had suggested a 33 split on the versioned
`standard:` path. On disk, only audit-core and user-engine still pin one.
- **flex-auth** closed FLEX-WP-0022. It enforces tenant-engine's invariant
(`tenant` = `resource.id`) as a deny, and states and tests cross-tenant scope.
One exception is named: user-engine's onboarding grant excludes
`tenant:platform`. That was sent back to tenant-engine rather than decided.
v3 is not rolled out.
- **tenant-engine** is admitted as an audit-core sender but cannot deliver:
the egress NetworkPolicy, the URL, and the token projection are missing from
its deploy manifests. TEN-IN-0005; this needs a credential path from custody (OpenBao, railiance-platform).
- **secrets-engine** surfaced a question: the service JWT design names
`tenant:coulomb`, but the approval chain resolved to `tenant:platform`.
## Third round, 2026-09-21: GH-DEC-2026-020
gate-house ruled what A12 reaches (GH-DEC-2026-020, A12 r2):
- **Reached:** a version in the `standard:` path, and `companion_version`.
- **Not reached:** stance, claims and classification maps.
- **Checkers:** a re-runnable checker is sufficient if every run prints the version it checked against and its scope. kings-guard's `VALIDATED_AGAINST` pattern is the reference.
It is applied in eleven repositories. whitehat-security, which never received GH-DEC-2026-017 and which the custodian's rounds had also missed, applied both rulings.
The round produced the same failure a third time, now in the checkers: each wrote its own version detector, and they disagree. Measured:
- **Prose citations:** eight declarations carry a prose version citation, including gate-house's own. Seven carry the same inherited sentence, "Outside §5 by the v0.5 scope rule". The repositories split four ways on handling it while gate-house's ruling is pending.
- **`VALIDATED_AGAINST`:** six checkers name the v0.7 text in force; tenant-engine and flex-auth name the held v0.8.
ops-warden wrote one reference detector into its playbook (0f9ada0). All of this went to gate-house, with a proposed additional v0.8 flip condition.
## Fourth round, 2026-09-21: GH-DEC-2026-021 and B2 closed
gate-house ruled the third round's findings in GH-DEC-2026-021:
- **Prose citations:** the narrow reading. A12 reaches only a version carried as a pin, so no declaration changes. The ruling notes that this reading benefits gate-house. The wording is drafted as A12 r3 and sent for assent.
- **VALIDATED_AGAINST:** checkers name the accepted v0.7 plus the gate-house decisions they enforce. tenant-engine and flex-auth re-point now.
- **Detector:** ops-warden's playbook detector is the estate reference. Each copy converges on it when next edited, and no later than the post-flip commit.
- **Flip:** not added to GH-DEC-2026-019, because it would be circular as a precondition. Instead it is a post-flip task, GH-WP-0004-T11, and the flip notice must name all eight checkers.
- **A11 r2:** permits a single-repository conformance run.
B2 is closed. All four undeclared repositories declared their own layer:
| Repository | Layer |
|---|---|
| gate-house | Staff |
| key-cape | Tooling |
| ops-mason | Staff, pep-shaped |
| net-kingdom | Taxonomy |
Each reading agrees with §4, and GH-DEC-2026-019's third closing condition is met. Three things surfaced:
- **key-cape:** its token endpoint has the shape of a PIP, and its authentication enforcement sits where §3.3 places enforcement boundaries. It read both as Tooling behaviour.
- **ops-mason:** it writes OpenBao policies and auth roles, creates secret_ids and runs `kubectl apply`, gated by the founder approving the plan rather than by an access-engine decision. Its own earlier review note said otherwise. These are declared as dated gaps to 2026-12-21.
- **net-kingdom:** the canon repository carries runtime material, `identity-provisioner/` and `sso-mfa/k8s/`.
Still open: A11 r2 and A12 r3 assent, INFD-IN-0007 (the §3 cut, outside the §11 hold), and the role vocabulary after A9.
## Follow-ups, 2026-09-21
The founder approved A11 r2 and A12 r3, exercising `GOVERN`. The approval was relayed to gate-house under GH-WP-0004-T09 as the return for the four round members that deferred to the founder: audit-core, access-engine, ops-warden and net-kingdom. It does not stand in for approval-engine, kings-guard, informed-decision or railiance-master.
GH-DEC-2026-021's immediate changes are applied:
- **tenant-engine** (`ff0712b`) and **flex-auth** (`067d93a`) now name the accepted v0.7 in `VALIDATED_AGAINST`, and both converged on the reference detector. flex-auth kept one exemption: an empty version key is not flagged. It is justified by a Go struct field rather than by the ruling, and no declaration carries such a key. It is a candidate for removal at flex-auth's next edit of the detector.
- **ops-warden** (`3979152`): the playbook is now titled as the estate reference detector. Prose citations are recorded as not reached, with a note of what widens if A12 r3 is rejected. `intent_version` is named as a key that must not be flagged.
The reference detector flags a versioned path to any document, not only one naming the standard. GH-DEC-2026-021 §3 accepts that. No declaration carries such a path today.
## Terminology, 2026-09-21
This record and the custodian's messages today used bare "operator" for the founder's decisions. SecurityCanon's disambiguation rule forbids that: `Operator` is a CARING lifecycle role, and `OPERATE` is an Auth Mode. The founder's decisions today were authority over authority, which is `GOVERN`. The records are corrected. Messages already sent are not; later messages use the canon's terms.
The Kubernetes change gate is recorded in `docs/kubernetes-change-gate-decision.md` in Mode of Authority terms.