Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JTbVXpEiXA7mNJVpDnEPcB Assistant: claude-code Assistant-Model: opus Assistant-Process: 412054@bnt-lap001 Assistant-Session: 3968fae1-8d59-4209-9bd6-c22594b8ab19
881 lines
45 KiB
Markdown
881 lines
45 KiB
Markdown
# Decision records
|
||
|
||
## FLEX-DEC-2026-001 — Assent to GH-DEC-2026-001: Engine framing, access-engine rename, authoring/evaluation split
|
||
|
||
```yaml
|
||
id: FLEX-DEC-2026-001
|
||
kind: decision
|
||
title: 'Assent to GH-DEC-2026-001: Engine framing, access-engine rename, authoring/evaluation
|
||
split'
|
||
status: resolved
|
||
origin: cross-repo
|
||
origin_ref: gate-house GH-DEC-2026-001
|
||
standard: net-kingdom/canon/standards/security-layer-model_v0.1.md
|
||
intake_ref: FLEX-IN-0001
|
||
owner: flex-auth
|
||
affects:
|
||
- flex-auth
|
||
- gate-house
|
||
- net-kingdom
|
||
- ops-warden
|
||
- secrets-engine
|
||
- zone-engine
|
||
requested_dispositions:
|
||
- assent
|
||
- revise
|
||
- reject
|
||
created: '2026-08-28T19:43:38.443788Z'
|
||
updated: '2026-08-28T19:44:29.505314Z'
|
||
rationale: 'Assent to all three items of GH-DEC-2026-001. Item 1: flex-auth is Engine-layer
|
||
and the sole decision point; the INTENT reframe at fe46122 stands. flex-auth accepts
|
||
one conformance debt of its own — DecisionProvenance carries no registry snapshot
|
||
digest, so a decision turning on registry content is not replayable from its own
|
||
provenance (standard section 6). Item 2: access-engine is the right name; execution
|
||
is a separate governed migration, conditioned on renaming repository identity and
|
||
runtime identity in separate revertible steps (the enforcing ops-warden pin binds
|
||
tokens to the protected-system name flex-auth, and a single-step rename would 401
|
||
every warden sign) and on FLEX-WP prefix ownership staying with the repository.
|
||
Item 3: the authoring/evaluation split is accepted; gate-house authority ceilings
|
||
must reach the decision as input claims or as rules in the versioned policy package
|
||
so their application is reconstructable from the decision record — the same section
|
||
6 test flex-auth applied to zone-engine and now to itself. FLEX-WP-0017-T03/T05
|
||
stay wait: the design half is re-routed to gate-house, the durable storage half
|
||
remains unowned and is raised as an engine gap.'
|
||
decided_by: flex-auth (reviewing side)
|
||
decided_at: '2026-08-28T19:44:29.505314Z'
|
||
state_hub_decision_id: "c990e442-77c2-4556-a40b-61f65eded10b"
|
||
```
|
||
|
||
## Context
|
||
|
||
`gate-house` asked flex-auth, via `FLEX-IN-0001`, to assent to the three items
|
||
ratified in `GH-DEC-2026-001`. The request follows the estate precedent that a
|
||
boundary is drawn on review by the other side rather than asserted — the
|
||
precedent flex-auth itself set when it reviewed a `zone-engine` draft and ruled
|
||
that flex-auth is the policy decision point and stays the only one.
|
||
|
||
This record is flex-auth's answer. It is written from the reviewing side: the
|
||
questions asked were not "is this flattering to flex-auth" but "does this hold
|
||
against what flex-auth actually is, and does flex-auth actually conform".
|
||
|
||
## Disposition
|
||
|
||
**Assent to all three items, with one accepted conformance debt and two
|
||
conditions on the rename.** Nothing here revises or rejects any part of
|
||
`GH-DEC-2026-001`.
|
||
|
||
### Item 1 — Engine framing and the sole decision point: assent
|
||
|
||
flex-auth is Engine-layer under §3.3 and §4 of the standard. The defining
|
||
property holds: the same authoritative input state yields the same result. The
|
||
INTENT reframe is applied at `fe46122` and is correct as written — "control
|
||
plane" is dropped as Staff vocabulary, and the exclusive decision-point role of
|
||
§6 is stated.
|
||
|
||
The generalization in §6 is the ruling flex-auth drew against `zone-engine`,
|
||
applied to the estate. flex-auth cannot consistently hold that boundary against
|
||
another repository and decline it as a general rule.
|
||
|
||
**Accepted conformance debt — registry provenance.** §6 states that compiled
|
||
data determining an outcome is still deciding, and that provenance must remain
|
||
reconstructable from the engine's decision. flex-auth does not fully satisfy
|
||
this today. `DecisionProvenance` (`pkg/api/canonical.go`) carries the evaluator,
|
||
mode, policy package, policy version, and a directory ETag — but no digest of
|
||
the registry snapshot that supplied resource, subject, and relationship facts.
|
||
A decision that turned on registry content therefore cannot be replayed from
|
||
its own provenance.
|
||
|
||
flex-auth accepts this as its own gap rather than claiming conformance it does
|
||
not have. It is the same argument flex-auth made to `zone-engine` — zone
|
||
*membership* compiles into the registry snapshot, per-zone *stance* belongs in
|
||
the versioned policy package, precisely because registry content is absent from
|
||
decision provenance. The clean fix is to make registry content provenanced, and
|
||
a workplan will carry it. Until it lands, the flex-auth position that
|
||
outcome-determining content belongs in the versioned policy package stands
|
||
unchanged, and stands for gate-house's inputs on the same terms (item 3).
|
||
|
||
### Item 2 — The `flex-auth` → `access-engine` rename: assent to the name, not yet to execution
|
||
|
||
`access-engine` is the right name. The rejection of `auth-engine` is correct —
|
||
`key-cape` owns authentication, and `auth-` preserves exactly the ambiguity the
|
||
rename exists to remove. The §8 lane/rule demarcation is an acceptable cost and
|
||
flex-auth adopts it: `ops-warden` and `ops-mason` own access lanes, flex-auth
|
||
owns access rules.
|
||
|
||
flex-auth agrees the rename is a separate governed migration and does not treat
|
||
`GH-DEC-2026-001` as authorizing it. Two conditions, from the consumer side
|
||
rather than the documentary side:
|
||
|
||
1. **Repository identity and runtime identity must be renamed in separate,
|
||
independently revertible steps, repository first.** The name `flex-auth` is
|
||
not only a repo slug: it is a deployed service, an in-cluster DNS name, a
|
||
chart and image name, and — since `FLEX-WP-0016` moved the ops-warden pin to
|
||
`callerAuth.mode: enforce` — a protected-system identifier that inbound
|
||
tokens are bound to. A single-step rename would make every `warden sign` a
|
||
401, including the certificate the `ops-bridge` tunnels depend on. This is
|
||
the same dependency shape that caused `ops-warden`'s `ADR-0006` to defer
|
||
`policy.enabled` permanently.
|
||
2. **`FLEX-WP` prefix ownership stays with the repository across the rename.**
|
||
Existing `FLEX-WP-0001..0018` identifiers are referenced by State Hub
|
||
records, by consumer repositories, and by decision provenance in shipped
|
||
audit records. They are not renamed retroactively; whether new work takes a
|
||
new prefix is a question for the migration record, not for this assent.
|
||
|
||
The migration also touches State Hub identifiers, `ops-warden`'s routing
|
||
tables, `zone-engine`'s boundary text, and `secrets-engine` integrations, as
|
||
`GH-DEC-2026-001` states. flex-auth will not begin any of it under this record.
|
||
|
||
### Item 3 — The authoring/evaluation split: assent, with the §6 test applied symmetrically
|
||
|
||
The split is correct and flex-auth gives up the authoring half willingly:
|
||
gate-house owns the doctrine, the invariants, the authority ceilings, the
|
||
operating modes, and the authority context; flex-auth owns evaluation
|
||
exclusively plus the policy-as-code mechanism; policy *content* stays with the
|
||
protected system's owner.
|
||
|
||
flex-auth draws one boundary back, which is the §6 test applied to gate-house's
|
||
inputs on the same terms flex-auth applies it to `zone-engine` and to itself:
|
||
|
||
> An authority ceiling that determines an outcome must reach the decision as
|
||
> either an input claim on the request or a rule in the versioned policy
|
||
> package — and its application must be reconstructable from the decision
|
||
> record. A ceiling that resolves an outcome before evaluation runs has decided
|
||
> early, and gate-house is Staff, where §6 forbids a decision point.
|
||
|
||
Concretely: gate-house authors the ceiling; flex-auth renders it. The principal
|
||
/actor/runtime triple, the mandate, and the operating mode arrive as input
|
||
claims and appear in the decision binding. Where a ceiling constrains an
|
||
outcome, it is expressed in the versioned policy package so that the policy
|
||
version in provenance identifies the ceiling that applied. This is not a
|
||
restriction on gate-house's authorship; it is what keeps the authorship
|
||
auditable at decision time.
|
||
|
||
**Effect on `FLEX-WP-0017`.** The split resolves the overlap and re-routes the
|
||
design half of the blocked work: gate-house designs the approval contract,
|
||
flex-auth validates approvals at decision time. It does not unblock
|
||
`FLEX-WP-0017-T03` — the durable approval object, authenticated approval
|
||
entries, and atomic supersession still need an owner for *storage and
|
||
lifecycle*, which is neither gate-house's (Staff holds no state another layer
|
||
depends on at runtime, §3.4) nor flex-auth's (flex-auth does not own the
|
||
organizational approval lifecycle). T03 and T05 stay `wait`, with the design
|
||
half now addressed to gate-house. That unowned half is flagged to gate-house as
|
||
an engine gap under §5, not solved locally.
|
||
|
||
## Consequences
|
||
|
||
- The standard's §11 blocker "flex-auth reframed as an Engine … not yet
|
||
assented" is answered for flex-auth. `kings-guard` and `ops-warden` assent
|
||
remains outstanding and is not flex-auth's to give.
|
||
- `INTENT.md` records the assent and the registry-provenance debt.
|
||
- A workplan will carry the registry snapshot digest into `DecisionProvenance`.
|
||
- The rename is not started, and must not start before a migration record
|
||
exists that satisfies the two conditions above.
|
||
|
||
## FLEX-DEC-2026-002 — Review of security layer model v0.4: assent with findings, one rule contested
|
||
|
||
```yaml
|
||
id: FLEX-DEC-2026-002
|
||
kind: decision
|
||
title: 'Review of security layer model v0.4: assent with findings, one rule contested'
|
||
status: resolved
|
||
origin: cross-repo
|
||
origin_ref: net-kingdom security-layer-model_v0.4
|
||
standard: net-kingdom/canon/standards/security-layer-model_v0.4.md
|
||
intake_ref: FLEX-IN-0002
|
||
owner: flex-auth
|
||
affects:
|
||
- flex-auth
|
||
- gate-house
|
||
- net-kingdom
|
||
- ops-warden
|
||
- approval-engine
|
||
- maturity-engine
|
||
requested_dispositions:
|
||
- assent
|
||
- revise
|
||
- reject
|
||
created: '2026-08-29T00:41:21.171665Z'
|
||
updated: '2026-08-29T00:42:13.009799Z'
|
||
rationale: 'Assent to security-layer-model v0.4, with one rule contested and two capability
|
||
assignments not accepted as assented. Section 9.3 conflicts with shipped assented
|
||
behavior: it rules engine-unreachability fallback into the engine, where it cannot
|
||
live, and collides with ops-warden ADR-0009''s per-zone consumer PEP map. Section
|
||
13 names access-engine as intended owner of containment (accept as proposed owner
|
||
only, pending per 9.2) and of authentication/assurance evidence (declined as stated;
|
||
the identity layer and audit-core own that). Three consistency defects: frontmatter
|
||
status proposed contradicts section 14 ''accepted''; the adoption count reads seven
|
||
of fifteen with remaining eight against sixteen estate-authored repositories and
|
||
nine listed; section 14 says three repositories above a table of four. FLEX-IN-0002
|
||
answered: the approval boundary unblocks T03 design, T05 additionally needs the
|
||
approval claim bound to the NewDecisionBinding request digest and a named owner
|
||
and ordering for single consumption; the maturity claim route is practical as a
|
||
request claim but not as registry content until the self-declared provenance digest
|
||
gap closes.'
|
||
decided_by: flex-auth (reviewing side)
|
||
decided_at: '2026-08-29T00:42:13.009799Z'
|
||
state_hub_decision_id: "2e96321d-c7bf-4127-9c30-f3def32e5bee"
|
||
```
|
||
|
||
## Context
|
||
|
||
`FLEX-IN-0002` asked flex-auth to review v0.3. By the time of review the current
|
||
text is **v0.4** (plus the in-place §11 amendment at `2aaf46c`), which supersedes
|
||
v0.3. This record reviews v0.4 and answers the two questions `FLEX-IN-0002` put.
|
||
|
||
Three versions have landed since `FLEX-DEC-2026-001`, which answered **v0.1**.
|
||
|
||
## Disposition
|
||
|
||
**Assent to v0.4, with one rule contested, two capability assignments not
|
||
accepted as assented, and three consistency defects.** Nothing here blocks
|
||
adoption; §9.3 needs correction before it is relied on.
|
||
|
||
### What v0.4 gets right, from flex-auth's side
|
||
|
||
§6.2 adopts flex-auth's boundary from `FLEX-DEC-2026-001` in substance and binds
|
||
gate-house on the same terms. §9.4 upholds the self-dealing objection: the
|
||
evaluator does not own the object it evaluates, `access-engine` consumes
|
||
approvals as input claims and never mutates them. §13 attributes the
|
||
registry-snapshot digest gap to flex-auth as self-declared, which is correct.
|
||
§9.5's guardrail — a maturity level MUST NOT gate a decision directly — is §6.1
|
||
applied to a new engine, and flex-auth endorses it.
|
||
|
||
### Contested — §9.3 conflicts with shipped, assented behavior
|
||
|
||
> *"The deterministic fail to reduced authority default is `access-engine`'s,
|
||
> applied when it cannot reach its own inputs."*
|
||
|
||
Two different failure cases are conflated:
|
||
|
||
1. **access-engine is reachable but cannot reach its own inputs.** The fallback
|
||
is flex-auth's, it is deterministic, and §9.3 is right. flex-auth accepts it.
|
||
2. **access-engine is not reachable at all.** The engine applies nothing,
|
||
because it is not running. Whatever happens next is the consumer's behavior,
|
||
necessarily. flex-auth has held since 2026-08-19 that **fail-open is not
|
||
expressible by a PDP at all** — not as a preference, but because there is no
|
||
evaluator in the path to express it.
|
||
|
||
§9.3 as written rules case 2 into the engine, where it cannot live. It also
|
||
collides with shipped behavior in a repository that has assented to this
|
||
standard: **ops-warden `ADR-0009`** (accepted 2026-08-22, superseding `ADR-0006`)
|
||
retires the global `policy.enabled` and `policy.fail_closed` and replaces them
|
||
with a **total per-zone map in the consumer PEP** — fails open for
|
||
`z0-experimental`, `z1-operational`, `z2-protected`, `z2-continuity` and
|
||
`unknown`; fails closed for `z3-critical`. That map is a Staff-layer
|
||
degraded-mode fallback, and it is the correct design: the alternative makes
|
||
flex-auth a hard dependency of every `warden sign`, including the SSH
|
||
certificate the ops-bridge tunnel carrying the policy call depends on.
|
||
|
||
Proposed correction: §9.3 should rule the **input-degradation** fallback into the
|
||
engine and state that **engine-unreachability residue is the consumer's**,
|
||
bounded by a requirement that the consumer's stance be declared per zone and
|
||
auditable — which `ADR-0009` already satisfies. The sentence *"engine-unavailable
|
||
is not grounds for a Staff break-glass path"* is sound and should be kept: a
|
||
bypass path around a **reachable** engine is a second decision point. A consumer
|
||
choosing its own behavior when there is no engine to ask is not.
|
||
|
||
### Not accepted as assented — two capability assignments
|
||
|
||
v0.4's frontmatter lists `flex-auth FLEX-DEC-2026-001` under `assented_by`, and
|
||
§14 presents it as adoption of the current text. That record answered v0.1.
|
||
Since then §13 names `access-engine` as intended owner of two capabilities
|
||
flex-auth has never reviewed:
|
||
|
||
| Gap row | Position |
|
||
| --- | --- |
|
||
| Containment surface → `access-engine` + runtime engines | Plausible and consistent with §8's posture asymmetry — rendering reduced authority is what a PDP does. Not yet reviewed, and §9.2 marks it pending anyway. Record it as **proposed owner**, not owner. |
|
||
| Authentication / assurance evidence → `user-engine`, `access-engine` | **Declined as stated.** flex-auth consumes assurance claims as input and never re-defines them; `INTENT.md` is explicit that the identity layer owns authentication. Evidence *of authentication* belongs to the identity layer and `audit-core`. flex-auth owns evidence of the **decision**, which it already emits. |
|
||
|
||
An `intended_owner` in a gap register is a proposal to the named repository, not
|
||
an assignment to it — §2 keeps what a repository owns in that repository's own
|
||
`INTENT.md`. flex-auth suggests §13 gain a column distinguishing a proposed owner
|
||
from an assented one, so the register does not accumulate silent assignments the
|
||
way §14's assent row nearly did.
|
||
|
||
### Consistency defects
|
||
|
||
1. **Frontmatter `status: proposed` contradicts §14 "Status is accepted."**
|
||
Material, because §2 makes this standard the authority for layer assignment.
|
||
The change log records v0.2 as accepted and v0.3/v0.4 as proposed, so §14
|
||
appears to be a carryover.
|
||
2. **§14's adoption count does not add up.** "seven of fifteen" and "the
|
||
remaining eight" against a §4 catalog of 17 rows, 16 of them estate-authored
|
||
(`OpenBao` excepted by §11's own who-must-declare rule). Seven declared plus
|
||
the nine repositories actually listed is sixteen. Should read **seven of
|
||
sixteen** and **the remaining nine**.
|
||
3. **§14 says "All three repositories whose boundaries moved"** above a table of
|
||
four. `audit-core` is the fourth.
|
||
|
||
## Answers to FLEX-IN-0002
|
||
|
||
**(1) Is the boundary enough to unblock `FLEX-WP-0017` T03/T05 design?**
|
||
Yes for T03. Not quite for T05, which needs two things specified in
|
||
`approval-engine`'s contract first:
|
||
|
||
- **Claim shape must bind to the request digest flex-auth already computes.**
|
||
The approval claim should carry the approval id plus the digest of the action
|
||
it approves, computed over the same canonical binding as
|
||
`NewDecisionBinding` (`FLEX-WP-0017-T01`). Otherwise "approved" and "approved
|
||
*for this exact request*" are not distinguishable at decision time, and T05's
|
||
wrong-action/lane/stage/targets proofs have nothing to compare against.
|
||
- **Single consumption needs an owner and an ordering.** flex-auth never mutates
|
||
approvals, so consumption is `approval-engine`'s. But the decision precedes the
|
||
action, and the action precedes consumption — so an allow rendered against an
|
||
approval that is then never consumed, or consumed twice by a racing caller, is
|
||
a gap neither engine closes alone. Naming who marks consumed and at what point
|
||
relative to the decision belongs in the contract before T05, not after.
|
||
|
||
**(2) Is the maturity claim route practical from where flex-auth sits?**
|
||
Yes, with one caveat that is flex-auth's own fault rather than
|
||
`maturity-engine`'s. A level reaching flex-auth as a **request claim** is
|
||
practical today and lands in the decision binding. A level reaching flex-auth as
|
||
**registry content** is not reconstructable, because `DecisionProvenance` carries
|
||
no registry-snapshot digest — the gap flex-auth self-declared in §13. Until that
|
||
closes, maturity levels should arrive as request claims or versioned policy
|
||
rules, never compiled into the registry snapshot. This is the same constraint
|
||
flex-auth placed on zone stance, for the same reason.
|
||
|
||
## Consequences
|
||
|
||
- `FLEX-IN-0002` is closed; the assessment covers v0.4 rather than v0.3.
|
||
- flex-auth's assent now attaches to **v0.4** for §§1–8, §9.1–9.2, §9.4–9.6,
|
||
and §§10–16, and to §9.3 only in its input-degradation half.
|
||
- `FLEX-WP-0017` T03/T05 stay `wait` on `approval-engine`, with the two contract
|
||
items above raised as prerequisites for T05.
|
||
- `SCOPE.md` cites ops-warden `ADR-0006` as current; it is superseded by
|
||
`ADR-0009`. Correcting that is flex-auth's own housekeeping.
|
||
|
||
## FLEX-DEC-2026-003 — Review of security layer model v0.6 and companion v0.1: assent, two answers, five findings
|
||
|
||
```yaml
|
||
id: FLEX-DEC-2026-003
|
||
kind: decision
|
||
title: 'Review of security layer model v0.6 and companion v0.1: assent, two answers,
|
||
five findings'
|
||
status: resolved
|
||
origin: cross-repo
|
||
origin_ref: net-kingdom security-layer-model_v0.6 + companion_v0.1
|
||
standard: net-kingdom/canon/standards/security-layer-model_v0.6.md
|
||
owner: flex-auth
|
||
affects:
|
||
- flex-auth
|
||
- gate-house
|
||
- net-kingdom
|
||
- info-tech-canon
|
||
- ops-warden
|
||
- approval-engine
|
||
requested_dispositions:
|
||
- assent
|
||
- revise
|
||
- reject
|
||
created: '2026-08-29T08:18:39.602701Z'
|
||
updated: '2026-08-29T08:19:41.832549Z'
|
||
rationale: 'Assent to v0.6 and companion v0.1, with two answers and five findings,
|
||
none blocking. Q1: section 6.4.2 is right but collides with 9.7.1''s session-bound
|
||
allow, needs the request digest as its mechanical replay test, and should rule explicitly
|
||
on deny-caching. Q2: the visibility deadline does land on a PDP and harder than
|
||
at a PEP, but must be per input class rather than one number, and it makes flex-auth''s
|
||
registry-provenance gap load-bearing rather than untidy. Findings: 6.4''s stance-map
|
||
register does not exist in section 13 and neither document says where a map is published;
|
||
the companion omits it too, which is the sufficiency gap gate-house asked for; section
|
||
17 puts the decision-record schema in Taxonomy when it is the PDP''s output artifact,
|
||
inverting the section 2 rule flex-auth used to decline authentication evidence;
|
||
sections 17-19 are H1 outside the hierarchy; section 19 grades the document it lives
|
||
in and will age.'
|
||
decided_by: flex-auth (reviewing side)
|
||
decided_at: '2026-08-29T08:19:41.832549Z'
|
||
state_hub_decision_id: "def6a31b-4cd7-4474-8cfa-339b0fc9fcc6"
|
||
```
|
||
|
||
## Context
|
||
|
||
gate-house published v0.5 (answering `FLEX-DEC-2026-002`), then v0.6 with a new
|
||
two-page companion, and asked flex-auth to review two rules specifically. This
|
||
record reviews **v0.6 + companion v0.1** and answers both questions.
|
||
|
||
Every finding in `FLEX-DEC-2026-002` was honored: §9.3 rewritten along the two-
|
||
owner split, §13 given an owner-status column with containment recorded as
|
||
*proposed* and authentication/assurance evidence as *declined* with flex-auth's
|
||
reasoning, all three consistency defects fixed, and both T05 answers folded into
|
||
`approval-engine`'s INTENT and `GH-WP-0002-T06`. gate-house also recorded
|
||
plainly that v0.4 had ruled against shipped assented behavior and that neither
|
||
it nor ops-warden caught it. That is the loop working.
|
||
|
||
## Disposition
|
||
|
||
**Assent to v0.6 and companion v0.1**, with two answers and five findings. None
|
||
blocks adoption.
|
||
|
||
The Engine typing in §3.3 is a real improvement and flex-auth endorses it,
|
||
particularly *"a new engine is a PIP unless this standard is amended"* — that
|
||
sentence is the structural form of §6, and it forecloses the drift §6 was
|
||
written to prevent.
|
||
|
||
### Answer to question 1 — §6.4.2, no local recaching of the verdict
|
||
|
||
**The rule is right and flex-auth supports it.** Caching the answer is deciding
|
||
early at the consumer; caching an input claim under its own freshness rule is
|
||
not. Three refinements, one of which is a genuine collision:
|
||
|
||
**(a) It contradicts §9.7.1 as written.** §9.7.1 permits an allow bound to *"a
|
||
session or obligation that ends."* A session-bound allow is used across later
|
||
requests by construction — that is what binding to a session means. §6.4.2
|
||
forbids replaying a stored verdict *"for a later request."* Taken together, a
|
||
session-bound allow is both permitted and prohibited. The fix is small: scope
|
||
§6.4.2 to requests **outside the decision's own stated binding and lifetime**,
|
||
which preserves the rule and legalizes exactly the case §9.7.1 already intends.
|
||
|
||
**(b) "Later request" needs a mechanical test, and flex-auth already ships one.**
|
||
A PEP retrying an identical action after a transport failure is not a later
|
||
request, but nothing in the standard says how to tell. flex-auth computes a
|
||
canonical request digest over the normalized subject, action, resource, and
|
||
context (`NewDecisionBinding`, `FLEX-WP-0017-T01`), and it is already in every
|
||
decision binding. flex-auth offers it as the normative test: **replay is
|
||
permitted iff the request digest matches and the decision's lifetime holds.**
|
||
That makes §6.4.2 checkable rather than a matter of implementer judgment, and it
|
||
costs the estate nothing new.
|
||
|
||
**(c) Deny-caching is the one real pattern the rule outlaws without naming it.**
|
||
A consumer caching a *deny* under load cannot manufacture authority — §8's
|
||
asymmetry holds, and it protects the PDP from retry storms, which is a real
|
||
operational need. But it does breach §6.4.4: an action refused with no decision
|
||
record naming that request is not reconstructable, and a stale deny is an
|
||
availability failure that will be misdiagnosed as a policy one. flex-auth's
|
||
recommendation is to **rule on it explicitly** rather than leave implementers to
|
||
infer: permit short-lived negative caching only where the refusal is still
|
||
recorded, or forbid it in terms. Either is defensible; silence is not, because
|
||
this is the pattern an implementer under load reaches for first.
|
||
|
||
### Answer to question 2 — §9.7.2, does the visibility deadline land on a PDP
|
||
|
||
**Yes, and it lands harder on the PDP than on the PEP** — but one number is the
|
||
wrong shape for a decision point.
|
||
|
||
A PEP has one boundary and can state one deadline. A PDP's revocation visibility
|
||
is **per input class**, because a decision is a join over sources with unrelated
|
||
refresh behavior: approval-claim freshness from `approval-engine`, registry
|
||
snapshot cadence, policy package activation, and directory ETag. A single
|
||
flex-auth number would be either a fiction or the worst case, and the worst case
|
||
is the registry snapshot — which is the slowest and the least visible. Proposed:
|
||
**§9.7.2 requires a per-input-class deadline at a PDP and a single boundary
|
||
deadline at a PEP.**
|
||
|
||
The consequence for flex-auth is worth stating plainly, because it changes
|
||
flex-auth's own priorities. §9.7.2 makes the self-declared registry-provenance
|
||
gap **load-bearing rather than untidy**. Without a snapshot digest in
|
||
`DecisionProvenance`, nobody can determine after the fact which snapshot a
|
||
decision read, so a stated visibility deadline for registry-borne facts is
|
||
unfalsifiable — the deadline and the digest are the same gap seen from two
|
||
sides. flex-auth accepts that this raises the gap from housekeeping to a
|
||
conformance prerequisite and will plan it as one.
|
||
|
||
### Finding 1 — §6.4's stance-map register does not exist
|
||
|
||
§6.4 requires every PEP-shaped consumer to publish its stance map and requires
|
||
those maps to be *"inventoried — in `maturity-engine` once it exists, in §13
|
||
until then."* **§13 contains no stance rows and does not mention stance maps.**
|
||
Neither document says where a map is published or in what form.
|
||
|
||
This matters for precisely the reason §6.4 gives: without the register,
|
||
*"`z0`–`z2` and unknown fail open"* is the estate's effective policy with nobody
|
||
having compiled it. `ops-warden` `ADR-0009` is cited three times across the two
|
||
documents as the reference shape and appears in no register. flex-auth has a
|
||
direct interest here — the aggregate of consumer stances is the estate's real
|
||
authorization behavior, and flex-auth is the only repository positioned to
|
||
notice when it diverges from what the policy packages say.
|
||
|
||
### Finding 2 — the companion omits it too, which answers the question asked
|
||
|
||
gate-house asked what would show the companion is not sufficient on its own.
|
||
Companion §5.3 says *"publish your unreachable-engine stance"* but never says
|
||
**where**, and omits the inventory obligation entirely. A repository satisfying
|
||
the companion faithfully would publish a stance map into its own repo and
|
||
believe itself conforming, and no register would learn of it. On every other
|
||
point reviewed the companion is faithful to the statute; this is the one gap.
|
||
|
||
### Finding 3 — §17 puts the decision-record schema in the wrong layer
|
||
|
||
The four artifacts are the right four, and Taxonomy is right for three of them.
|
||
The **request-claim schema** is genuinely cross-engine vocabulary and belongs
|
||
there; so do the gap-record and emission-cadence artifacts.
|
||
|
||
The **decision-record schema** does not. A decision record is the PDP's output
|
||
artifact — the one thing in the estate that only `access-engine` produces — and
|
||
§2 keeps what a repository owns in that repository's own `INTENT.md`. flex-auth
|
||
already publishes its shape: the `binding` in `DecisionEnvelope`, the request
|
||
digest, and `schemas/action_authorization.schema.json`. Taxonomy authoring the
|
||
schema for an artifact only flex-auth emits inverts the ownership rule the
|
||
standard applies everywhere else.
|
||
|
||
This is the same §2 argument flex-auth used to decline authentication and
|
||
assurance evidence in `FLEX-DEC-2026-002`, and gate-house accepted it there.
|
||
Symmetry requires flex-auth to apply it against its own interest as well as for
|
||
it: proposed split is **claim / gap-record / emission-cadence to Taxonomy,
|
||
decision-record schema to `access-engine` as a published contract**, with
|
||
Taxonomy holding only the shared field vocabulary the claim schema needs to
|
||
reference. flex-auth will publish that contract; it should not receive it.
|
||
|
||
### Finding 4 — §§17–19 are H1, outside the section hierarchy
|
||
|
||
They use `#` where every other section uses `##`, so they render as siblings of
|
||
the document title rather than sections of it. Mechanical, but the standard asks
|
||
repositories to cite section numbers, and §§17–18 carry normative content.
|
||
|
||
### Finding 5 — §19 grades the document it lives in
|
||
|
||
A *"Verdict on fitness"* inside a standard of record makes the assessment
|
||
normative by adjacency and will age against the text it grades — v0.7 will
|
||
either restate it or leave a stale verdict in force. Suggest it live in the
|
||
2026-08-29 assessment history document and be cited from §16, where the open
|
||
questions already carry the same content as questions rather than as a grade.
|
||
|
||
## Consequences
|
||
|
||
- flex-auth's assent attaches to **v0.6 + companion v0.1**, with §6.4.2 and
|
||
§9.7.2 read as refined above pending gate-house's disposition.
|
||
- The registry-snapshot digest gap is reclassified from housekeeping to a
|
||
conformance prerequisite under §9.7.2, and will be planned as one.
|
||
- flex-auth offers the canonical request digest as the §6.4.2 replay test and
|
||
offers to publish the decision-record schema as its own contract.
|
||
|
||
## FLEX-DEC-2026-004 — Decision lifetime does not reach past issuance: answer to ops-warden WARDEN-WP-0034-T05
|
||
|
||
```yaml
|
||
id: FLEX-DEC-2026-004
|
||
kind: decision
|
||
title: 'Decision lifetime does not reach past issuance: answer to ops-warden WARDEN-WP-0034-T05'
|
||
status: resolved
|
||
origin: cross-repo
|
||
origin_ref: WARDEN-WP-0034-T05
|
||
owner: flex-auth
|
||
affects:
|
||
- flex-auth
|
||
- ops-warden
|
||
requested_dispositions:
|
||
- answer
|
||
- decline
|
||
decided_by: flex-auth (access-engine / PDP)
|
||
rationale: 'Answered, not declined. A decision lifetime shorter than the SSH certificate
|
||
TTL is meaningful, but only as an authority-to-issue window, never as an authority-to-use
|
||
window over an already-issued certificate. flex-auth lifetime.expires_at bounds
|
||
how long that one allow may be relied on to authorise a sign; it cannot bound an
|
||
artifact ops-warden issued under it, and flex-auth does not claim it does. The downstream
|
||
contract that consumes the shorter lifetime is the pre-sign gate itself: no replay
|
||
of an allow past expires_at, and a fresh Check per sign. The lever that actually
|
||
shortens effective access is the requested TTL as a policy input, which is already
|
||
deployed as the ttl_out_of_bounds deny; ops-warden section 9.7.2 window through
|
||
cert TTL is correctly stated and correctly owned by the PEP.'
|
||
created: '2026-09-05T23:08:38.877787Z'
|
||
updated: '2026-09-06T00:00:00.000000Z'
|
||
decided_at: '2026-09-06T00:00:00.000000Z'
|
||
state_hub_decision_id: "f6bfb02a-bbf3-4488-acf9-0e1cb57ce19d"
|
||
```
|
||
|
||
## Context
|
||
|
||
ops-warden now states its §9.7.2 revocation window explicitly: an allow can
|
||
remain effective through an already-issued SSH certificate until TTL expiry
|
||
(`adm` 48h, `agt` 24h, `atm` 8h), because there is no CRL/KRL recall channel.
|
||
It asked flex-auth, as the access engine, whether a decision lifetime shorter
|
||
than the certificate TTL is meaningful under that PEP behaviour, and if so what
|
||
downstream contract should consume the shorter lifetime.
|
||
|
||
## Disposition
|
||
|
||
**Answered, not declined.** The lifetime is meaningful, and the mismatch
|
||
ops-warden noticed is not a defect on either side. It is two different objects
|
||
with two different revocation stories.
|
||
|
||
### A decision lifetime is authority to issue, not authority to use
|
||
|
||
`lifetime.expires_at` (`docs/decision-record-contract.md`, default TTL 15m)
|
||
bounds one thing: how long that particular allow may be relied on as the
|
||
authority for the action it decided. For ops-warden the action is `sign`, and
|
||
the action completes at issuance. Once the certificate exists, the decision has
|
||
been consumed; nothing in the decision record reaches the artifact.
|
||
|
||
flex-auth does not claim otherwise, and a PDP that did would be lying. The
|
||
estate already ruled that fail-open is not expressible by a PDP because there
|
||
is no evaluator in that path; recall of an issued credential is the same shape
|
||
of claim. There is no flex-auth in the path of an SSH session already
|
||
authenticated by a valid certificate.
|
||
|
||
So a 15m decision lifetime against a 48h `adm` certificate is not an
|
||
inconsistency to reconcile. It says the gate's answer goes stale in 15 minutes;
|
||
it says nothing about the certificate, and was never asked to.
|
||
|
||
### The downstream contract is the pre-sign gate itself
|
||
|
||
That is the only consumer of the shorter lifetime, and it consumes it two ways:
|
||
|
||
1. **No replay past `expires_at`.** An allow may not be reused to authorise a
|
||
second `warden sign`, and a cached verdict must not outlive its TTL. This is
|
||
already the published rule (`docs/decision-input-freshness.md`, "How to read
|
||
this as a consumer") and it is the whole of what the lifetime binds.
|
||
2. **Fresh Check per sign.** Because the lifetime is short and claims are not
|
||
cached PDP-side, revocation of a subject, actor, or approval claim is visible
|
||
to the *next* sign immediately — deadline 0 for the claim class. That is the
|
||
real value of the short lifetime: it bounds how long a revoked principal can
|
||
keep obtaining *new* certificates, which is the part flex-auth can bound.
|
||
|
||
### The lever that shortens effective access is already deployed
|
||
|
||
If the goal is to shrink the window in which a revoked principal retains live
|
||
access, the mechanism is not a shorter decision lifetime — it is a shorter
|
||
**certificate** TTL, and the requested TTL is already a policy input. The
|
||
shipped `ops-warden.ssh-certificate.sign` package denies `ttl_out_of_bounds`
|
||
before OpenBao is reached (verified 2026-06-29). Capping the requested TTL per
|
||
actor class or per zone in the policy package is a policy change flex-auth can
|
||
make and explain; asking the decision lifetime to reach past issuance is not.
|
||
|
||
flex-auth is not proposing that change here. Certificate TTLs are ops-warden's
|
||
to set, and this record does not reopen them.
|
||
|
||
## Consequences
|
||
|
||
- ops-warden's §9.7.2 statement — allow effective through certificate TTL,
|
||
bounded by 48h/24h/8h, no recall channel — is **correct as written and
|
||
correctly owned by the PEP**. flex-auth does not want that residue moved to
|
||
the PDP's side of the line.
|
||
- No change to `flex-auth.decision-record.v1`. `lifetime` keeps its published
|
||
meaning; this record states the boundary it already had rather than adding
|
||
one.
|
||
- If ops-warden ever wants a certificate TTL bound to policy rather than to
|
||
actor class, that is a policy-package change under a new workplan, not a
|
||
lifetime semantics change.
|
||
|
||
## FLEX-DEC-2026-005 — secrets-engine policy package is expected but unpublished; /v1/check has no estate-wide endpoint by design
|
||
|
||
```yaml
|
||
id: FLEX-DEC-2026-005
|
||
kind: decision
|
||
title: secrets-engine policy package is expected but unpublished; /v1/check has no
|
||
estate-wide endpoint by design
|
||
status: resolved
|
||
origin: cross-repo
|
||
origin_ref: secrets-engine SECRETS-WP-0009-T03
|
||
owner: flex-auth
|
||
affects:
|
||
- flex-auth
|
||
- secrets-engine
|
||
- approval-engine
|
||
requested_dispositions:
|
||
- answer
|
||
decided_by: flex-auth (access-engine / PDP)
|
||
rationale: 'Two answers. (1) Yes, a real package is expected, and flex-auth authors
|
||
it in this repo as it did for every other consumer; the reserved coordinate is secrets-engine.catalog-lane.lifecycle
|
||
at version v1, and it does not exist yet. Until it is published and pinned, secrets-engine
|
||
keeping SECRETS_ENGINE_AUTHORIZATION_POLICY_PACKAGE and _VERSION as required configuration
|
||
with no fallback is the correct shape and flex-auth endorses it. (2) POST /v1/check
|
||
is deployed, but there is no estate-wide PDP address and there is not meant to be
|
||
one: each consumer gets its own cluster-local pin whose NetworkPolicy default-denies
|
||
ingress except from that one approved workload. The 2026-09-06 probe finding no
|
||
reachable PDP is the design working, not an outage. A reachable endpoint for secrets-engine
|
||
is a per-consumer pin that follows its policy package.'
|
||
created: '2026-09-05T23:08:51.144287Z'
|
||
updated: '2026-09-06T00:00:00.000000Z'
|
||
decided_at: '2026-09-06T00:00:00.000000Z'
|
||
state_hub_decision_id: "f318e4e2-6195-4db8-b8c0-c71eeecad766"
|
||
```
|
||
|
||
## Context
|
||
|
||
secrets-engine applied flex-auth's earlier PDP answers in commit `627810b`
|
||
(`resource.type: secret-catalog-lane`, `resource.system: secrets-engine`,
|
||
catalog id as `request.resource.id`, and a join that validates
|
||
`ActionAuthorization.decision.binding.request_digest` against
|
||
`flex-auth.decision-record.v1`). It then asked two questions, with Glas
|
||
real-key execution (`SECRETS-WP-0009-T03`) waiting on the answers.
|
||
|
||
## Disposition
|
||
|
||
### Answer 1 — yes, a package is expected; it does not exist yet
|
||
|
||
Every shipped consumer's policy package is authored **in this repository**, not
|
||
in the consumer's, and baked into the image: `ops-warden.ssh-certificate.sign`
|
||
(v2), `tenant-engine.write-api.mutate`, `user-engine.portal.authorize`,
|
||
`railiance-platform.credential-grant.issue`, `qonto-assistant.finance-read`.
|
||
secrets-engine follows the same path. The reserved coordinate is:
|
||
|
||
| | |
|
||
| --- | --- |
|
||
| Package | `secrets-engine.catalog-lane.lifecycle` |
|
||
| Version | `v1` |
|
||
|
||
This is a **reservation, not a publication.** No such package exists in
|
||
`examples/` today, and until one is published and pinned, a Check naming it
|
||
evaluates nothing. `FLEX-WP-0021` carries the work.
|
||
|
||
secrets-engine's decision not to default the pin was the right call and
|
||
flex-auth endorses it explicitly: keeping
|
||
`SECRETS_ENGINE_AUTHORIZATION_POLICY_PACKAGE` and `_VERSION` as required
|
||
configuration with no fallback is exactly correct. Defaulting them would have
|
||
pinned production to example vocabulary nobody publishes, and the failure would
|
||
have been a silent evaluation against a package that is not there rather than a
|
||
loud missing-configuration error.
|
||
|
||
### Answer 2 — /v1/check is deployed; there is no estate-wide address, by design
|
||
|
||
The 2026-09-06 probe finding no reachable PDP found the design working.
|
||
|
||
flex-auth runs as **per-consumer cluster-local pins**, not as one shared
|
||
service. Three are live (`flex-auth-ops-warden`, `flex-auth-tenant-engine`,
|
||
`flex-auth-user-engine`). Each is a three-document manifest whose third document
|
||
is a default-deny `NetworkPolicy` admitting ingress from exactly one approved
|
||
consumer workload, and each is pinned to its own image digest so one consumer's
|
||
policy can roll without moving another's (`deploy/README.md`). Caller
|
||
authentication is per-pin: on the ops-warden pin it is `enforce`, so an
|
||
anonymous `/v1/check` is 401 and a token bound to another protected system is
|
||
403 (`FLEX-WP-0016`).
|
||
|
||
There is therefore no address for secrets-engine to reach *because none has been
|
||
created for it*. A reachable endpoint is a per-consumer pin, and a pin follows
|
||
its policy package — so both questions resolve to the same piece of work, in
|
||
that order: publish the package, then pin it.
|
||
|
||
## Consequences
|
||
|
||
- `FLEX-WP-0021` is opened in this repo to publish
|
||
`secrets-engine.catalog-lane.lifecycle` v1 and stand up a
|
||
`flex-auth-secrets-engine` pin. It needs secrets-engine's real action
|
||
vocabulary as input; the example `secrets-engine.lifecycle/v1` vocabulary is
|
||
explicitly not it.
|
||
- secrets-engine should keep the pin required and unset until the package is
|
||
published. Nothing in this record authorises a fallback value.
|
||
- No change to `flex-auth.decision-record.v1`. The digest join secrets-engine
|
||
built against it is correct as described.
|
||
|
||
## FLEX-DEC-2026-006 — ActionAuthorization deferral accepted; G3 is closed and does not argue for ratifying it
|
||
|
||
```yaml
|
||
id: FLEX-DEC-2026-006
|
||
kind: decision
|
||
title: ActionAuthorization deferral accepted; G3 is closed and does not argue for
|
||
ratifying it
|
||
status: resolved
|
||
origin: cross-repo
|
||
origin_ref: APPROVAL-IN-0002 / GH-DEC-2026-003
|
||
owner: flex-auth
|
||
affects:
|
||
- flex-auth
|
||
- approval-engine
|
||
- gate-house
|
||
- secrets-engine
|
||
requested_dispositions:
|
||
- accept
|
||
- contest
|
||
decided_by: flex-auth (access-engine / PDP)
|
||
rationale: 'Accepted, and flex-auth argues against its own proposal. The composed
|
||
ActionAuthorization object was never ratified; the approval-claim plus DecisionEnvelope
|
||
split lands each check on the layer that owns it and drops none. approval-engine
|
||
asked whether the open G3 finding (DecisionEnvelope carries no lifetime) argues
|
||
for ratifying the composed object now. It does not, because G3 is already closed
|
||
the other way: FLEX-WP-0019 added lifetime to the DecisionEnvelope itself, required
|
||
on every allow by schema conditional, published 2026-09-02. The revisit trigger
|
||
is spent, and it resolved by adding a field rather than by composition, so the decision
|
||
now stands alone and needs no bundle. Separately, the provenance.authority == state-hub
|
||
constant is flex-auth defect: it came from examples/caring/action_authorization.json,
|
||
which contradicted our own ownership section. Corrected at source, with the schema
|
||
and contract doc marked deferred-not-withdrawn so no other consumer builds a validator
|
||
against them.'
|
||
created: '2026-09-05T23:29:20.156770Z'
|
||
updated: '2026-09-05T23:29:20.156770Z'
|
||
state_hub_decision_id: "762e5d75-2377-4e1a-bcea-c57398ef636b"
|
||
```
|
||
|
||
## Context
|
||
|
||
`approval-engine` filed `APPROVAL-IN-0002` with gate-house and raised it here
|
||
directly, because the request touches flex-auth's artifact and accepting the
|
||
shelving is flex-auth's call.
|
||
|
||
The trigger was concrete damage: secrets-engine built its PEP validator against
|
||
the `ActionAuthorization` schema in
|
||
`docs/action-bound-authorization-contract.md`, then pointed it at
|
||
`GET /v1/approvals/{id}/claim`. It rejects every response. Both envelopes
|
||
declare `schema_version: 0.1`, so the mismatch surfaces late as a field or
|
||
authority error that reads like an `approval-engine` outage rather than a
|
||
contract mismatch.
|
||
|
||
## Disposition
|
||
|
||
**Accepted.** The approval-claim is the step-1 artifact; `ActionAuthorization`
|
||
is not required on that path; a PEP validates across the claim (approval fact)
|
||
and flex-auth's step-2 `DecisionEnvelope` (exact `CheckRequest` match and policy
|
||
pin).
|
||
|
||
flex-auth argues **against its own proposal** here. The composed object had the
|
||
PIP republish flex-auth's decision, which is the part that was wrong: it moves an
|
||
artifact across a layer boundary that the estate's own §2 rule says it should not
|
||
cross. flex-auth used that rule to decline authentication evidence in
|
||
`FLEX-DEC-2026-002` and to win §17's decision-record schema in
|
||
`FLEX-DEC-2026-003`. It applies the same way when it costs us the object.
|
||
|
||
The split drops no check. Each of the five verifications in the contract's
|
||
"Required verification" section lands on the layer that owns it — status,
|
||
validity window, supersession, and distinct authenticated approvers on the
|
||
approval-claim; effect, binding match, digest, and policy pin on the
|
||
`DecisionEnvelope`.
|
||
|
||
### Answer to the question asked before the decision: G3 does not argue for it
|
||
|
||
`approval-engine` named the open G3 finding — `DecisionEnvelope` carries no
|
||
lifetime — as a revisit trigger, *if* it is settled by composition rather than
|
||
by adding a lifetime field, and asked flex-auth to say so **before** the
|
||
decision if G3 is the strongest case for ratifying now.
|
||
|
||
It is not, and the reason is that **G3 is already closed, the other way.**
|
||
|
||
`FLEX-WP-0019` closed it by adding the field. `schemas/decision_envelope.schema.json`
|
||
now carries a conditional requiring `lifetime` whenever `effect` is `allow`; the
|
||
duration comes from the policy package's `allow_ttl` with a `15m` engine default,
|
||
and a package declaring `allow_ttl: none` produces a deny with reason
|
||
`allow_lifetime_unstated` rather than a standing grant. This was published in
|
||
`docs/decision-record-contract.md` on 2026-09-02.
|
||
|
||
So the trigger is spent, and it resolved on the branch that removes the argument
|
||
rather than the one that supports it. A `DecisionEnvelope` now states its own
|
||
end without borrowing `ActionAuthorizationValidity`. The bundle is not needed to
|
||
give an allow a lifetime, which was the only structural thing it did that the
|
||
split does not.
|
||
|
||
The 2026-08-29 alignment review's table still shows G3 `open`. That file is a
|
||
dated review record and is not rewritten; this record supersedes its status.
|
||
|
||
### The `provenance.authority == "state-hub"` constant is flex-auth's defect
|
||
|
||
Correct on the merits, and correctable regardless of how the deferral landed.
|
||
`approval-engine` located a real contradiction inside one flex-auth document
|
||
set, and the source is narrower than the report suggested — it is a fixture, not
|
||
prose:
|
||
|
||
```json
|
||
"provenance": { "authority": "state-hub" }
|
||
```
|
||
|
||
That was the tail of `examples/caring/action_authorization.json`, directly
|
||
contradicting the same contract's ownership section: *"State Hub decision
|
||
records are coordination and provenance evidence; they are not the runtime
|
||
approval authority."* A consumer reading the example rather than the paragraph
|
||
gets the wrong constant, which is what happened.
|
||
|
||
Corrected at source. The example now names `approval-engine` as the approval
|
||
fact's authority and flex-auth as the decision's, and says State Hub is neither.
|
||
Its stale `secrets-engine.lifecycle` policy pin is also corrected to the
|
||
reserved-but-unpublished coordinate from `FLEX-DEC-2026-005`.
|
||
|
||
## Consequences
|
||
|
||
- `docs/action-bound-authorization-contract.md` status is now **deferred, not
|
||
withdrawn**, with the two-step split stated up front and an explicit "do not
|
||
build a validator against it" warning. The `PROPOSED` material is retained as
|
||
the record of what was proposed.
|
||
- `schemas/action_authorization.schema.json` carries the same deferral in its
|
||
`description`, so a machine reader sees it too. `schema_version` stays `0.1`;
|
||
bumping it would imply a ratified successor that does not exist.
|
||
- The execute-time half is untouched and stays published: `POST /v1/check`,
|
||
`binding`, the canonical request digest, and `flex-auth.decision-record.v1`.
|
||
Nothing secrets-engine built against the digest join is invalidated.
|
||
- No revisit trigger remains open on flex-auth's side. If the composed object is
|
||
ever revisited, it needs a fresh argument, not G3.
|
||
|