Align INTENT and SCOPE to security layer model v0.7; plan conformance work
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:
parent
5753b47ccb
commit
0e2efa8fcf
6 changed files with 492 additions and 64 deletions
136
history/2026-08-29-layer-model-v0.7-alignment-review.md
Normal file
136
history/2026-08-29-layer-model-v0.7-alignment-review.md
Normal 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`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue