--- id: FLEX-WP-0019 type: workplan title: "Layer model v0.7 conformance: provenance, lifetimes, deadlines, and the decision contract" domain: infotech repo: flex-auth status: ready owner: codex topic_slug: netkingdom planning_priority: P1 planning_order: 119 created: "2026-08-29" updated: "2026-08-29" --- # FLEX-WP-0019 - Layer model v0.7 conformance The NetKingdom Security Layer Model was accepted at v0.7 on 2026-08-29 and `INTENT.md`/`SCOPE.md` were aligned to it. The alignment review (`history/2026-08-29-layer-model-v0.7-alignment-review.md`) identified six gaps between what flex-auth now states and what it implements. This workplan closes them. Two are conformance obligations rather than features: the registry-snapshot digest (§9.7.2 promotes it from housekeeping to a prerequisite, on flex-auth's own argument) and the per-input-class visibility deadlines that depend on it. Ordering is load-bearing. **T02 precedes T04** — publishing a visibility deadline for registry-borne facts before provenance can identify the snapshot would publish a number nobody can check. ## Assert the layer declaration mechanically ```task id: FLEX-WP-0019-T01 status: todo priority: medium ``` `INTENT.md` frontmatter carries `layer: Engine`, `role: PDP` per §11. Add a conformance check and test asserting the declaration parses, states a layer in the §3 vocabulary, states a role because the layer is Engine, and that no Tooling client exists in the tree — the Engine-side analogue of ops-warden's `scripts/check_layer_conformance.py`, which is offered estate-wide as a reference form. Closes G1's remaining half. Wire it into `make test`. ## Add the registry-snapshot digest to decision provenance ```task id: FLEX-WP-0019-T02 status: todo priority: high ``` `DecisionProvenance` carries no digest of the registry snapshot that supplied resource, subject, and relationship facts, so a decision that turned on registry content cannot be replayed from its own record (§6.1). This is flex-auth's one declared gap in §13 and a conformance prerequisite under §9.7.2. Reuse the canonical-JSON plus SHA-256 pattern already in `pkg/api/canonical.go` over `registry.Snapshot`, which is already deterministic and has a test asserting it (`TestStoreLoadsAndSavesDeterministicSnapshot`). Thread the digest into `DecisionProvenance`, through the standalone engine and through every delegated adapter that shares the canonical constructor, and into `schemas/decision_envelope.schema.json`. Add regression coverage that a changed snapshot changes the digest and that two decisions over the same snapshot agree. ## Give every allow an explicit lifetime ```task id: FLEX-WP-0019-T03 status: todo priority: high ``` §9.7.1 requires every allow to carry an explicit lifetime — a TTL, or a binding to a session or obligation that ends. `DecisionEnvelope` has no lifetime field; `ActionAuthorizationValidity` has one but belongs to the durable approval object, not the decision. The struct field is trivial; the semantics are not. flex-auth has no session concept, so the first honest shape 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: it needs package schema support, fixtures covering declared TTL, defaulted TTL, and the no-stated-end deny, and it must appear in the decision record and the published schema. ## State revocation visibility deadlines per input class ```task id: FLEX-WP-0019-T04 status: todo priority: high ``` §9.7.2 requires a PDP to state a deadline **per input class**, because a decision is a join over sources with unrelated refresh behaviour. Enumerate the classes flex-auth actually joins — approval-claim freshness, registry snapshot cadence, policy package activation, directory ETag — and state a deadline for each, with the mechanism that bounds it rather than an aspiration. Depends on **T02**: the registry deadline is unfalsifiable until provenance can identify the snapshot a decision read. Publish as `docs/decision-input-freshness.md` and reference it from `INTENT.md`. ## Publish the decision-record schema as flex-auth's contract ```task id: FLEX-WP-0019-T05 status: todo priority: medium ``` §17 moves the decision-record schema from Taxonomy to `access-engine`, on flex-auth's own argument that a decision record is the PDP's output artifact. `schemas/decision_envelope.schema.json` exists and describes `binding` and `provenance`, but carries no lifetime (T03), no snapshot digest (T02), no policy-package **digest** — name and version only — and no input-claim digests. Complete it, version it as a published contract rather than an internal shape, and document it in `docs/` as the artifact consumers may rely on. Taxonomy holds only the shared field vocabulary the claim schema references; this schema is flex-auth's. ## Publish the request digest as the replay test ```task id: FLEX-WP-0019-T06 status: todo priority: medium ``` §6.4.2 makes replay permitted **iff the canonical request digest matches and the decision's lifetime holds**, and names flex-auth's digest as the mechanical test. The digest is computed and regression-tested but is documented nowhere a consumer would look. Publish what it is computed over, what normalization applies, its stability guarantees across versions, and worked examples of a permitted retry and a refused replay. Consumers cannot honour §6.4.2 against an undocumented digest, and negative caching under §6.4.2 needs the same guidance.