B2: key-cape (Tooling), net-kingdom (Taxonomy) and ops-mason (Staff) now declare in their own files. Verified by the survey rather than taken on report: 14 of 14 counterparts declared, 0 undeclared. ops-mason sent no reply and needed none — under §11 the file is the declaration. Every T04 finding is answered, so FLEX-WP-0030 is finished. B5's residual ping belongs to FLEX-WP-0020. key-cape stated the identity boundary from its side for the first time and cautioned that principal_type must not be read as authentication-derived until GH-DEC-2026-013/-016 §5 is answered. Checked against every published package: only the two informed-decision packages gate on a human subject, and both also require principal_type_source == "authentication-derived", which informed-decision derives from the verified code-flow MFA event rather than from key-cape's claim. No change needed; the assessment and a warning about the legacy "otherwise -> human" fallback are in docs/iam-profile-consumption.md. tenant-engine confirmed FLEX-DEC-2026-016's reading of commitment (b): the fixed-record exclusion is consistent with it. Recorded under point 3; v3 stands. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 28468@bnt-lap001 Assistant-Session: c76569b2-6056-4dad-aea4-49cd7a018f5d
178 lines
12 KiB
Markdown
178 lines
12 KiB
Markdown
# Boundaries review — flex-auth against its security-relevant counterparts
|
||
|
||
> **Derived artifact** (§11). Derives from
|
||
> `net-kingdom/canon/standards/security-layer-model_v0.8.md`
|
||
> (`status: proposed`, `source_revision: gate-house@516ed4e`), from each
|
||
> counterpart's `INTENT.md` / `layer.yaml` as of the date below, and from
|
||
> flex-auth's own `decisions/decisions.md`.
|
||
> Derived at: **2026-09-21**. Reviewer: `flex-auth` (Engine / PDP).
|
||
> Carried by `FLEX-WP-0030`.
|
||
|
||
## Why this exists
|
||
|
||
`INTENT.md` was carrying a standard version it should not (`FLEX-WP-0030` T01).
|
||
Fixing one line meant reading what the declaration actually asserts, and the
|
||
declaration asserts a boundary — which is only half of a boundary. The other half
|
||
is held by someone else, and flex-auth had never checked whether the other halves
|
||
were stated at all.
|
||
|
||
They are not, in four cases. That is the finding of this review, and it was not
|
||
the one being looked for.
|
||
|
||
## The rule this review holds itself to
|
||
|
||
§11 is explicit: *"A layer stated **about** a repository by another repository is
|
||
not a declaration."* So nothing below grades a peer. flex-auth reports what it can
|
||
observe from outside, names the owner, and says which of three states the boundary
|
||
is in. **`unstated` is not recorded as `agreed`** — that conflation is the whole
|
||
reason the four cases below went unnoticed.
|
||
|
||
## Boundary status
|
||
|
||
| Counterpart | Boundary | State |
|
||
| --- | --- | --- |
|
||
| `gate-house` | owns invariants, authority ceilings, operating modes; flex-auth authors no doctrine and consumes authority context as claims | **agreed in substance, undeclared in form** — no `layer:` key (B2) |
|
||
| `key-cape` / NetKingdom SSO | identity source; flex-auth consumes verified claims as normative input and never redefines them | **asserted from one side only** — no `layer:` key (B2) |
|
||
| `ops-warden` | consumer / PEP; owns SSH CA, OpenBao signing, actor inventory and its own stance map. flex-auth owns the decision, never the credential | **agreed, and the most exercised boundary in the estate** |
|
||
| `secrets-engine` | consumer / PEP; owns credential lifecycle downstream of a decision | **agreed** |
|
||
| `approval-engine` | owns the approval object, its storage and lifecycle; flex-auth validates approvals as input claims and never mutates them | **agreed** — `GH-DEC-2026-005`, accepted in `FLEX-DEC-2026-006` against flex-auth's own proposal |
|
||
| `zone-engine` | zone **membership** compiles into the registry snapshot flex-auth consumes; per-zone **stance** is the consumer's | **held by flex-auth since 2026-08-19; not contested, not confirmed** |
|
||
| `user-engine` | PIP; supplies subject facts | **agreed** |
|
||
| `tenant-engine` | PIP and consumer. What `CheckRequest.tenant` denotes on the write API — caller, target, or guardrail scope — is **unanswered since 2026-09-15** | **unclear, and live** — `FLEX-WP-0022`, re-asked 2026-09-20 |
|
||
| `audit-core` | holds custody of evidence; flex-auth **emits** the decision record | **ruled 2026-09-21, against flex-auth** — flex-auth is the §4 source; custody is never source (`GH-DEC-2026-018`); `audit-core` confirmed independently and declined the role (`AUDIT-IN-0005`). G2 is now a dated gap |
|
||
| `maturity-engine` | PIP; supplies maturity claims. §9.5 forbids ranking blocked-clean below conforming | **agreed** |
|
||
| `kings-guard` | Staff; raised the authentication/assurance evidence gap that flex-auth **declined** (§13, `FLEX-DEC-2026-002`) | **agreed, by mutual declining** |
|
||
| `ops-mason` | catalogued PEP-shaped in §4 | **undeclared twice over** — no stance map (§13.1 marks it), no `layer:` key (B2) |
|
||
|
||
## Findings raised for resolution
|
||
|
||
Full statements in `workplans/FLEX-WP-0030-boundary-declaration-cleanup.md` T04.
|
||
|
||
| # | Finding | Owner | Outcome |
|
||
| --- | --- | --- | --- |
|
||
| B1 | **Corrected 2026-09-21.** Nine of nine repositories carrying both §11 forms declare a different `layer:` value in each. §11 does not say which form governs | `gate-house` | **Ruled** `GH-DEC-2026-017` §1–§2: `INTENT.md` governs, sidecar is derived and must agree, the disagreement is still reported; comparison folds ASCII case. flex-auth's validator changed |
|
||
| B2 | `gate-house`, `key-cape`, `ops-mason`, `net-kingdom` carry no machine-readable layer declaration | each named repository | `gate-house` declared `Staff` in the ruling commit; three remain |
|
||
| B3 | flex-auth declares no emission guarantee; whether it owes one turns on an unruled boundary with `audit-core` | `gate-house`, `audit-core` | **Ruled against flex-auth** `GH-DEC-2026-018`; per-class inventory published in `cadence.yaml`; delivery is dated gap G2 |
|
||
| B4 | a layer declaration should not pin a standard version; if §11 agrees it should say so generally | `gate-house` | **Ruled as asked** `GH-DEC-2026-017` §5, A12 |
|
||
| B5 | canon names `access-engine`; the repository still answers to `flex-auth` and the rename has not landed | `gate-house` to note | A13 notes it; ping when `FLEX-WP-0020` lands |
|
||
|
||
## What flex-auth is not claiming
|
||
|
||
- **Not a conformance finding against anyone.** B1 and B2 are observations about
|
||
form. A repository may be entirely conformant in substance and simply not have
|
||
written the key; `gate-house` is the clearest case.
|
||
- **Not a request that any peer change casing.** B1 may equally be resolved by
|
||
ruling the vocabulary case-insensitive, which would make flex-auth's validator
|
||
the thing that changes. *(It was, and it did — see the second correction.)*
|
||
- **Not a grade.** §9.3's two-owner split is flex-auth's own finding and it cuts
|
||
here: the PDP does not get to score the repositories whose facts it consumes.
|
||
|
||
## Correction — B1, 2026-09-21
|
||
|
||
**The first published version of B1 was wrong, and it was wrong in a way this
|
||
review exists to prevent.**
|
||
|
||
It reported that the estate spelled `layer:` three ways *across* repositories,
|
||
and named eight as non-conformant on casing. That came from an ad-hoc shell
|
||
survey run while writing this document. The survey took the first `^layer:` match
|
||
per repository across two files without recording which file it came from, so it
|
||
reported one value where there were two.
|
||
|
||
Re-run mechanically (`tools/survey_layer_declarations.go`, receipt at
|
||
`docs/evidence/2026-09-21-layer-declaration-survey.json`), the finding is
|
||
different and stronger:
|
||
|
||
| | |
|
||
| --- | --- |
|
||
| Repositories carrying **both** §11 forms | 9 |
|
||
| Of those, forms that **disagree** | **9 of 9** |
|
||
| Shape | `INTENT.md` says `Engine` / `Staff`; `layer.yaml` says `engine` / `staff` |
|
||
| Repositories with only one form | 1 — `flex-auth`, which has no `layer.yaml` |
|
||
|
||
The disagreement is **within** each repository, between the two forms §11
|
||
permits, and it is universal rather than sloppy — two generators, two
|
||
conventions, no repository mixing them. Nobody is inconsistent with anybody else.
|
||
|
||
That relocates the question. §11 accepts *"a `layer:` key in the `INTENT.md`
|
||
frontmatter, **or** an equivalent declaration file"* and does not say which
|
||
governs when a repository carries both and they disagree. A conformance run
|
||
reading `INTENT.md` and one reading `layer.yaml` reach different answers for nine
|
||
repositories, and both are following §11.
|
||
|
||
flex-auth is the only declared repository that cannot exhibit this, and only
|
||
because it never wrote the second file — not a virtue.
|
||
|
||
**What this cost.** The wrong version went to `gate-house` and five engine
|
||
repositories before it was checked. Corrections were sent the same day. The
|
||
review had already said a mechanical check nobody can re-run is an assertion, and
|
||
then asserted B1 from a shell pipeline — which is why B1 is now a command with
|
||
tests and a receipt, and why this correction is recorded here rather than edited
|
||
away. A published review corrected silently is `FLEX-DEC-2026-008`'s defect, and
|
||
that rule does not have an exception for the reviewer.
|
||
|
||
|
||
## Correction — the validator, 2026-09-21
|
||
|
||
**This review treated flex-auth's validator as the §3 vocabulary. It was not,
|
||
and it was wrong.**
|
||
|
||
`internal/layer` admitted `{Staff, Engine, Tooling}`. §3 enumerates **four**
|
||
layers — Taxonomy, Tooling, Engines, Staff — and §3.1 defines Taxonomy, which
|
||
§4 catalogues twice (`info-tech-canon`, `net-kingdom`) and which the standard
|
||
itself is an instance of. The three-token set was built from §4's role-typed
|
||
catalog rows rather than from §3's layer table, so it took §4's spelling
|
||
(`Engine`) and lost §3's fourth row. Where this review and its survey said
|
||
"outside the §3 vocabulary as written", they meant "outside flex-auth's
|
||
validator", and the difference is the finding.
|
||
|
||
**`railiance-master`'s `Taxonomy` declaration was conforming all along; the
|
||
validator was the divergent artifact.** `railiance-master` said so with the
|
||
citations (§3.1, §4, §7, §17) against a record that had named it
|
||
non-conformant. `GH-DEC-2026-017` §3 ruled the same.
|
||
|
||
How it happened is §11's derived-artifact rule inverted: an artifact derived
|
||
from canon came to stand in for canon, because canon left the token set to be
|
||
inferred from two tables that disagree and the validator was the only
|
||
executable statement of one. flex-auth wrote that artifact.
|
||
|
||
**Fixed** in `internal/layer`, per `GH-DEC-2026-017` §2–§4 and A9, A11:
|
||
|
||
- four tokens, closed: `Taxonomy`, `Tooling`, `Engine`, `Staff`;
|
||
- ASCII case folded before comparing; a lowercase declaration is conforming;
|
||
- §4's column spelling is canonical, so `engine` reports as `Engine` and
|
||
`Engines` (§3's plural heading) is not the token;
|
||
- `INTENT.md` governs; a disagreement between the two forms is still reported,
|
||
and a spelling-only disagreement is distinguished from a disagreement about a
|
||
layer (there are nine of the first and none of the second);
|
||
- **a run states its scope.** §11 binds §4. The survey now leads with its scope
|
||
(`estate-wide` or `§4 catalog`, `--catalog-only`), and reports a repository
|
||
outside §4 that declares as *declared voluntarily, outside catalog scope* —
|
||
never as a non-conformance. This review's own survey was estate-wide over
|
||
fourteen counterparts and said nothing about which question it answered.
|
||
|
||
A second defect surfaced while fixing the first: the survey decoded peers'
|
||
files into flex-auth's own declaration struct, so a peer field sharing a name
|
||
with one of flex-auth's in a different shape (`audit-core`'s list-shaped
|
||
`emission_guarantee`) made that peer's `layer.yaml` silently disappear. Peers
|
||
are now read for `layer` and `role` only. A surveyor's schema is a house rule
|
||
too. Receipt: `docs/evidence/2026-09-21-layer-declaration-survey-after-ghdec017.json`.
|
||
|
||
## Addendum — B2 closed, 2026-09-21
|
||
|
||
The status table above is left as derived. Three rows have since moved, each
|
||
verified in the counterpart's own file (receipt
|
||
`docs/evidence/2026-09-21-layer-declaration-survey-b2-closed.json`):
|
||
|
||
| Counterpart | Was | Now |
|
||
| --- | --- | --- |
|
||
| `key-cape` | asserted from one side only | **agreed, stated from both sides** — declares `Tooling` (`key-cape@9cb9507`); expects nothing of flex-auth beyond standard token verification |
|
||
| `ops-mason` | undeclared twice over | declares `Staff` (`ops-mason@0ff263a`); the §13.1 stance-map mark is gate-house's and unchanged |
|
||
| `net-kingdom` | undeclared | declares `Taxonomy` (`net-kingdom@0b10b4b`) |
|
||
|
||
`gate-house` declared earlier the same day. Fourteen of fourteen counterparts now
|
||
declare. The `tenant-engine` row closed under `FLEX-WP-0022` (`TEN-DEC-2026-002`,
|
||
`FLEX-DEC-2026-016`); the `audit-core` row was ruled against flex-auth
|
||
(`GH-DEC-2026-018`), and delivery is `FLEX-WP-0031`.
|
||
|
||
One boundary remains held by flex-auth alone: `zone-engine` has confirmed the
|
||
casing ruling but not the membership/stance boundary it was asked about.
|