Align INTENT and SCOPE to security layer model v0.7; plan conformance work
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

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
This commit is contained in:
tegwick 2026-08-29 14:43:49 +02:00
parent 5753b47ccb
commit 0e2efa8fcf
6 changed files with 492 additions and 64 deletions

View file

@ -0,0 +1,136 @@
---
id: flex-auth-2026-08-29-layer-model-alignment
type: history
title: "Layer model v0.7 alignment: INTENT, SCOPE, and the gap between them"
domain: infotech
repo: flex-auth
owner: flex-auth
created: "2026-08-29"
standard: net-kingdom/canon/standards/security-layer-model_v0.7.md
records: decisions/decisions.md FLEX-DEC-2026-001, FLEX-DEC-2026-002, FLEX-DEC-2026-003
workplan: 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
1. **A machine-readable layer declaration** in frontmatter — `layer: Engine`,
`role: PDP` — which §11 requires and flex-auth did not have. `audit-core`
named 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.
2. **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.
3. **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.
4. **A `Layer Conformance` section** stating the conformance state honestly:
conforming with one declared gap, no Tooling client, not PEP-shaped.
5. **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`.