flex-auth/docs/stance-register-review-second-edition.md

134 lines
7.3 KiB
Markdown
Raw Normal View History

# Stance-register review, second edition — five rows, one axis question resolved by doctrine
Status: published
Date: 2026-09-27
Standard: `security-layer-model_v0.7` §6.4 obligation 3, §13.1 (v0.8 `proposed`,
reviewed and assented in `FLEX-DEC-2026-011`, not yet accepted)
Reviewer: flex-auth (Engine / PDP)
Supersedes: `docs/stance-register-review.md` (2026-09-06), which stays
unamended per `FLEX-DEC-2026-008`
Workplan: `FLEX-WP-0029`
**This is still not a §13.1 register.** gate-house owns the register. This is
one reviewer's reading of the rows in it.
## What changed since the first edition
| | 2026-09-06 (v0.7 §13.1) | 2026-09-27 (v0.8 §13.1) |
| --- | --- | --- |
| Rows | 2 | **5** — `ops-warden`, `user-engine`, `tenant-engine`, `secrets-engine`, `ops-mason` |
| `unknown` divergence | open, reported as observation | **ruled**: v0.8 §6.4 obligation 3 requires `unknown` to resolve to `fail_closed` |
| Marked non-conformant | none | two rows — `ops-warden`'s `unknown` cell, `ops-mason`'s absent map |
The first edition's closing line predicted a third row would arrive; five
arrived instead. That landing is itself part of this edition, not a footnote.
## Finding 1 — the `unknown` divergence was resolved in `secrets-engine`'s
direction, by doctrine, not by either side persuading the other
flex-auth reported the split as an observation and explicitly asked for no
change. gate-house answered the open question anyway: v0.8 §6.4 obligation 3
states `unknown` is not a zone and MUST resolve to `fail_closed`, because being
unclassifiable must not buy permissiveness. `secrets-engine`'s
`unknown: fail_closed` was already conformant; `ops-warden`'s `unknown:
fail_open` now is not.
`ops-warden` **assented to the rule and deliberately did not flip the cell.**
Verified against `ops-warden/pep-stance.yaml` (2026-09-27): 0 of its 3 signing
targets resolve to a zone. Converting `unknown` to `fail_closed` today would
fail closed on essentially every certificate during a flex-auth outage —
including the certificate needed to reach the host and repair flex-auth. That
is `ADR-0006`'s rejected configuration reached by another route, and the
refusal is correct. `WARDEN-WP-0040` is the route: classify the continuity
path, raise coverage, then convert.
§13.1 therefore marks `ops-warden`'s row non-conformant **while the row is
right to be unconverted.** Conformance and correctness have come apart on this
cell. flex-auth did not cause the rule and does not get credit for it — the
finding is that the estate resolved a disagreement flex-auth only surfaced.
## Finding 2 — re-run across five rows: the axis is not converging, and the
count of distinct axes went up, not down
The first edition found two incommensurable axes (`security-zone` vs.
`catalog-stage`) and warned the cost would grow with a third row. Reading all
five files directly (not carried forward from the workplan's draft table,
which had this wrong):
| Repository | Scope axis (as published) | `unknown` |
| --- | --- | --- |
| `ops-warden` | `security-zone` | `fail_open` (non-conformant, assented) |
| `user-engine` | `security-zone` | `fail_closed` |
| `tenant-engine` | `engine-reachability` (not `security-zone`) | `fail_closed` |
| `secrets-engine` | `catalog-stage`, explicitly interim "pending zone membership as a claim" | `fail_closed` |
| `ops-mason` | no map published | n/a — marked non-conformant by absence |
That is **three** distinct scope axes in play (`security-zone`,
`catalog-stage`, `engine-reachability`), not the two-converging-to-one the
workplan draft assumed. `tenant-engine`'s axis is a genuine third shape: it
scopes on whether the engine can be reached and what it said, not on a
property of the target resource, and every cell of its map is `fail_closed` —
so it is trivially conformant on `unknown` but not comparable to a zone-scoped
row at all. The alarm from the first edition does not weaken at five rows; it
sharpens, because a third axis appeared rather than the two converging.
flex-auth's boundary claim from 2026-08-19 stands and is restated here: zone
**membership** compiles into the registry snapshot flex-auth already consumes,
while per-zone **stance** belongs to the consumer. If zone membership arrives
as a claim on the decision, `secrets-engine`'s catalog-stage axis can converge
onto zones without either side inventing a stage-to-zone mapping.
`tenant-engine`'s reachability axis does not converge under that boundary at
all — it is answering a different question (was the PDP reachable and what did
it say) than a zone-scoped map answers (what should happen to this target).
That distinction is worth gate-house's attention on its own; this review notes
it rather than resolving it.
On `ops-mason`'s absent row versus the axis question: an absent map is the
more useful subject. A published map that scopes on the "wrong" axis is still
reviewable, inventoriable, and testable against its own code — `ops-mason`
having none means §13.1 cannot even ask it what its `unknown` residue is. The
absence costs the estate more than the axis mismatch does, because the axis
mismatch is at least visible.
## Finding 3 — `secrets-engine`'s map still cites the shelved artifact name
Read directly from `secrets-engine/pep-stance.yaml` on 2026-09-27: line 35
still defines `fail_closed` as "no protected side effect without a durable
**access-engine / `ActionAuthorization`** record." `ActionAuthorization` was
shelved on the PEP consumption path by `GH-DEC-2026-005`, accepted by
flex-auth in `FLEX-DEC-2026-006`. This is an **open item, not a new finding
and not a resolved one** — the stance itself is unaffected (`fail_closed`
still means no protected side effect without a durable record, and the
records exist under their current names: `approval-engine`'s approval claim
and flex-auth's `DecisionEnvelope`), but the file's prose has not been
corrected since the first edition reported it. `secrets-engine` owns the file;
flex-auth can only keep verifying.
## Corrections to the record this edition makes
- `SCOPE.md` already states five rows and the `unknown`/axis findings
accurately; no change was needed there.
- `INTENT.md` carries **no `standard_version` field at all** — the earlier
premise that it declares `"0.7"` and must not be bumped does not match the
file. There is nothing to avoid bumping. The version-scoped state that does
exist lives in `docs/conformance/security-layer-conformance.md`, which
correctly does not assert v0.8 acceptance.
- The first edition is not listed in `SCOPE.md`'s `contract`/`orientation`
capability blocks, so this edition does not invent one either.
## What flex-auth is not claiming
- No stance is wrong by virtue of being non-conformant. `ops-warden`'s
`unknown: fail_open` is a measured, reasoned, tracked exception with a route.
- No change is requested of any repository. `WARDEN-WP-0040` owns the order
for `ops-warden`'s cell and flex-auth agreed the order is right;
`secrets-engine` owns its own file's prose.
- This is not a §13.1 register and does not attempt to be one.
## Out of scope (carried from the workplan)
- Adopting v0.8 as flex-auth's declared standard version.
- gate-house's A-16 / A-17 (`DISTINGUISHABLE ROUTES`, and `unknown` vs.
`absent` as two meanings behind one runtime behaviour) — noted as adjacent
to Finding 2's third axis, not absorbed here.