The standard was accepted at v0.7 on 2026-08-29. Four of flex-auth's review findings are in the accepted text: 9.3's two-owner split, 6.4.2 scoped to the decision's own binding with our canonical request digest as its mechanical test, 9.7.2 split by role, and 17 moving the decision-record schema to access-engine. INTENT.md - Machine-readable layer declaration in frontmatter (layer: Engine, role: PDP), which section 11 requires and we did not have. audit-core noted our declaration was legible only by following the decision trail. - PDP failure semantics stated: our outage is consumer residue, not input degradation; fail-open is not expressible by a PDP at all. - Four owned obligations added: the decision-record schema as our contract, the request digest as the published replay test, a lifetime on every allow, and visibility deadlines per input class. - A Layer Conformance section stating the state honestly: conforming with one declared gap, no Tooling client, not PEP-shaped. - Vocabulary correction: earlier text dropped "control plane" as Staff vocabulary. Section 8 binds it to the Engine layer, which is why kings-guard was asked to release it. The term is ours; we prefer "decision engine" for precision, not boundary. SCOPE.md - Layer and role in the one-liner; the four obligations In Scope; five boundaries established in review but never written down Out of Scope. - Three capability blocks marked planned for workplans completed in May are now current; two blocks added. - Superseded ADR-0006 citation corrected to ADR-0009, which retires the global flag outright rather than deferring it. history/2026-08-29-layer-model-v0.7-alignment-review.md checks each obligation against the code and finds six gaps. FLEX-WP-0019 closes them, with T02 before T04 because a visibility deadline for registry-borne facts is unfalsifiable until provenance can identify the snapshot a decision read. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012sgN4GH5ZYT8pJVkCR6dcP Assistant: claude-code Assistant-Model: opus Assistant-Process: 4014348@bnt-lap001 Assistant-Session: a993abda-65a0-4ea8-8ccd-0fcd78c92ac0
8.1 KiB
| id | type | title | domain | repo | owner | created | standard | records | workplan |
|---|---|---|---|---|---|---|---|---|---|
| flex-auth-2026-08-29-layer-model-alignment | history | Layer model v0.7 alignment: INTENT, SCOPE, and the gap between them | infotech | flex-auth | flex-auth | 2026-08-29 | net-kingdom/canon/standards/security-layer-model_v0.7.md | decisions/decisions.md FLEX-DEC-2026-001, FLEX-DEC-2026-002, FLEX-DEC-2026-003 | workplans/FLEX-WP-0019-layer-model-conformance.md |
Layer model v0.7 alignment review
The NetKingdom Security Layer Model was accepted at v0.7 on 2026-08-29.
INTENT.md and SCOPE.md were aligned to it in the same session. This document
records what changed, then asks the question the alignment exists to answer:
where does the stated scope now outrun the implementation, and what has to be
built to close it.
1. How flex-auth arrived at v0.7
flex-auth reviewed three versions and holds three records. Four of its findings became text in the accepted standard:
| Finding | Adopted as |
|---|---|
| §9.3 collapsed two failures with different owners | §9.3 rewritten: input degradation is the engine's, engine-unreachability is necessarily the consumer's |
| §6.4.2 forbade the session-bound allow §9.7.1 permits | §6.4.2 scoped to the decision's own binding and lifetime, with flex-auth's canonical request digest as the mechanical test, and negative caching ruled permitted where the refusal is recorded |
| A PDP's visibility deadline is per input class, not one number | §9.7.2 split by role |
| The decision-record schema is the PDP's output, not Taxonomy's | §17 moves it to access-engine |
The last of those was argued against flex-auth's own interest — it takes work on rather than off — and the standard says so, because that is what makes the §2 ownership rule credible when flex-auth also uses it to decline work.
Two of flex-auth's positions were recorded rather than adopted: containment surface ownership stays proposed (§13, pending under §9.2), and authentication/assurance evidence is recorded as declined.
2. What changed in INTENT.md
- A machine-readable layer declaration in frontmatter —
layer: Engine,role: PDP— which §11 requires and flex-auth did not have.audit-corenamed this precisely: flex-auth's declaration was "legible as one only by following its decision trail." Prose cannot distinguish a declaration from a transcribed review. - The PDP role stated with its failure semantics: flex-auth's outage is consumer residue, not input degradation. Fail-open is not expressible by a PDP at all.
- Four obligations added to what flex-auth owns: the decision-record schema as its own contract, the canonical request digest as the published replay test, a lifetime on every allow, and revocation visibility deadlines per input class.
- A
Layer Conformancesection stating the conformance state honestly: conforming with one declared gap, no Tooling client, not PEP-shaped. - A vocabulary correction. Earlier versions dropped "control plane" as Staff vocabulary. That reason was wrong on the standard's own terms — §8 binds control plane to the Engine layer, which is why kings-guard was asked to release it. The term is flex-auth's to use. This file prefers "decision engine" as a matter of precision, not boundary.
3. What changed in SCOPE.md
The one-liner now states the layer and role. In Scope gained the four v0.7
obligations. Out of Scope gained five boundaries flex-auth had established in
review but never written down: fail-open, enforcement, the approval object,
authentication evidence, and doctrine authoring. Three capability blocks were
still marked planned for workplans completed in May and are now current, and
two capability blocks were added. A superseded citation of ops-warden ADR-0006
was corrected to ADR-0009, which retires the global flag outright rather than
deferring it.
4. Scope versus implementation — the gap
This is the operative section. Each row is checked against the code, not against the documents.
| # | Obligation | Standard | Implementation today | Gap |
|---|---|---|---|---|
| G1 | Machine-readable layer declaration | §11 | INTENT.md frontmatter, added in this session |
closed, needs a conformance test |
| G2 | Registry-snapshot digest in decision provenance | §6.1, §9.7.2, §13 | DecisionProvenance carries evaluator, mode, policy package, policy version, directory ETag, decision time — no snapshot digest |
open — conformance prerequisite |
| G3 | Every allow carries an explicit lifetime | §9.7.1 | DecisionEnvelope has no lifetime field. ActionAuthorizationValidity has not_before/expires_at, but that is the durable approval object, not the decision |
open |
| G4 | Revocation visibility deadline per input class | §9.7.2 | Not stated anywhere — no document, no field | open |
| G5 | Decision-record schema published as flex-auth's contract | §17 | schemas/decision_envelope.schema.json exists and describes binding and provenance via $defs. It carries no lifetime, no policy-package digest (name and version only), and no input-claim digests |
partial |
| G6 | Canonical request digest as the §6.4.2 replay test | §6.4.2 | NewDecisionBinding computes it over normalized subject, action, resource, context; it is in every binding and regression-tested |
closed in code, unpublished as consumer guidance |
| G7 | Doctrine reaches the decision as claim or versioned rule | §6.2 | Context claims and versioned policy packages both exist | closed |
| G8 | Approvals consumed as input claims, never mutated | §9.4 | flex-auth mutates no approval. FLEX-WP-0017 T03/T05 wait on approval-engine |
closed on flex-auth's side; blocked externally |
Why G2 is the one that matters most
G2 and G4 are the same gap seen from two sides, and the standard now says so in flex-auth's own words. A stated visibility deadline for a fact carried by a registry snapshot is unfalsifiable while provenance holds no snapshot digest, because nobody can determine afterwards which snapshot a decision read. Publishing G4 without closing G2 would be publishing a number nobody can check.
G2 is also cheap. registry.Snapshot is already a deterministic,
JSON-serializable struct with a test asserting that determinism
(TestStoreLoadsAndSavesDeterministicSnapshot), and pkg/api/canonical.go
already carries the canonical-JSON-plus-SHA-256 pattern that
NewDecisionBinding uses. The work is to reuse that pattern over the snapshot
and thread the result into DecisionProvenance, including through the delegated
adapters, which already share the canonical binding constructor.
Why G3 is larger than it looks
Adding a lifetime field is trivial. Deciding what the lifetime is is not: a TTL, a session binding, or an obligation binding, per §9.7.1. flex-auth has no session concept, so the honest first step is a policy-package-declared TTL with an explicit default, and a deny for any allow that would otherwise have no stated end. That is a policy-surface change and needs fixtures, not just a struct field.
A capability flex-auth claimed and cannot yet exercise
flex-auth told gate-house it is the repository positioned to notice when the
aggregate of consumer stances diverges from what the policy packages say. §13.1
now exists as the register, and it has one row — ops-warden, with
ops-mason catalogued PEP-shaped and unpublished. The claim is sound and the
data is not there yet. This is not a flex-auth gap to close alone, but flex-auth
should be able to read the register once it is populated, and should say so
rather than let the claim sit unexercised.
5. What this does not change
flex-auth's boundaries are unchanged by v0.7. It still does not author doctrine,
own approvals, own enforcement, or own authentication evidence. The rename to
access-engine remains a separate governed migration under the two conditions
in FLEX-DEC-2026-001, and nothing in the alignment starts it.
6. Outcome
FLEX-WP-0019 carries G1's test, G2, G3, G4, G5, and G6. G7 needs nothing.
G8 stays with FLEX-WP-0017, blocked on approval-engine.