Rule on unknown and the scoping axis as GH-DEC-2026-009
access-engine exercised the divergence capability it claimed in the v0.6 round, on the first occasion §13.1 held two rows. ops-warden resolves unknown to fail_open, secrets-engine to fail_closed; both conformant, both total, both test-pinned, disagreeing about the one case that by construction nobody planned for. They also scope over different axes, so the register cannot answer what an inventory exists to answer. Ruling 1: unknown is not a zone and MUST fail closed. §9.3 permits trading availability for openness per zone — and that trade requires knowing the zone. Where the scope is unknown the trade cannot have been made for it, so a permissive unknown does not extend a considered decision, it invents the most permissive one. An unreachable engine is a known request in a degraded system; an unclassified subject is not. unknown is the cheapest state for an attacker to induce, so failing open on it makes being unclassifiable a privilege escalation requiring no credential, which §8's asymmetry forbids wherever it appears. Ruling 2: each map declares its scoping axis and its relation to zone. Forcing everyone onto zones would make secrets-engine assert a zone it cannot know, and a fiction in a runtime-read test-pinned file is worse than an honest incommensurability. The register records the axes and states that cross-axis aggregation is unavailable. ops-warden acquires one non-conformant cell at v0.8. It did everything asked — published first, built the reference form, offered it estate-wide — so this goes to the assent round rather than being imposed quietly. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WtJBr77gMFLrN93iEevqQJ Assistant: claude-code Assistant-Model: opus Assistant-Process: 425128@bnt-lap001 Assistant-Session: f5944d8b-dac4-4e1a-87eb-8b3d8f314a63
This commit is contained in:
parent
45a65c0748
commit
22915cf2a0
3 changed files with 187 additions and 6 deletions
|
|
@ -30,6 +30,7 @@ Assembly and circulation are `GH-WP-0003-T06`.
|
|||
| A5 | §6.4, §8 | `GH-DEC-2026-005`, `GH-DEC-2026-008` | T05 |
|
||||
| A6 | §17 | `GH-DEC-2026-004` | T07 |
|
||||
| A7 | §11, §12 | four observed instances; proposed by `approval-engine` | T08 |
|
||||
| A8 | §6.4, §13.1 | `GH-DEC-2026-009` | T09 |
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -130,12 +131,13 @@ one.
|
|||
|
||||
**§13.1 rows to transcribe at the cut** — carried here so the cut is mechanical:
|
||||
|
||||
| Consumer | Stance map | Shape |
|
||||
| --- | --- | --- |
|
||||
| `ops-warden` | `ops-warden/pep-stance.yaml` | total per zone; `fail_open` for `z0`–`z2` and unknown, sanctioned by §9.3 and recorded per §6.4 obligation 1 limb two; test asserts published map equals shipped default |
|
||||
| `user-engine` | `user-engine/pep-stance.yaml` | total per zone; `fail_closed` for `z0`–`z3`, unknown, and not-applicable; test asserts published map equals `user_engine.pep_stance` |
|
||||
| `tenant-engine` | `tenant-engine/pep-stance.yaml` | total; `fail_closed` for unset, unreachable, non-allow, unknown; test asserts file equals shipped behaviour |
|
||||
| `ops-mason` | — | **unpublished**; PEP-shaped under §6.4 (opening a route). Recorded as a gap, not a stance |
|
||||
| Consumer | Stance map | Axis | Shape |
|
||||
| --- | --- | --- | --- |
|
||||
| `ops-warden` | `ops-warden/pep-stance.yaml` | security zone | total per zone; `fail_open` for `z0`–`z2` and unknown, sanctioned by §9.3 and recorded per §6.4 obligation 1 limb two; test asserts published map equals shipped default |
|
||||
| `user-engine` | `user-engine/pep-stance.yaml` | security zone | total per zone; `fail_closed` for `z0`–`z3`, unknown, and not-applicable; test asserts published map equals `user_engine.pep_stance` |
|
||||
| `tenant-engine` | `tenant-engine/pep-stance.yaml` | security zone | total; `fail_closed` for unset, unreachable, non-allow, unknown; test asserts file equals shipped behaviour |
|
||||
| `secrets-engine` | `secrets-engine/pep-stance.yaml` | catalog stage — interim, pending zone membership as a claim | total over stage plus unknown; no implicit default; runtime-read; pinned to `SHIPPED_STANCE` by test |
|
||||
| `ops-mason` | — | — | **unpublished**; PEP-shaped under §6.4 (opening a route). Recorded as a gap, not a stance |
|
||||
|
||||
Three of four are total and fail-closed. The `ops-mason` row is the finding §6.4's
|
||||
closing paragraph anticipated, and it is more useful in the register than absent from
|
||||
|
|
@ -338,6 +340,58 @@ as stronger than it is, which would be the same defect one layer up.
|
|||
|
||||
---
|
||||
|
||||
## A8 — §6.4 and §13.1, `unknown` and the scoping axis (T09)
|
||||
|
||||
Settled by `GH-DEC-2026-009`, on the first occasion §13.1 held enough rows to diverge.
|
||||
|
||||
**Add to §6.4 obligation 3:**
|
||||
|
||||
> **`unknown` is not a zone and MUST resolve to `fail_closed`.** §9.3 permits trading
|
||||
> availability for openness *per zone* — knowingly, for a named scope, at a declared
|
||||
> cost. That trade requires knowing the zone. Where the scope is unknown it cannot
|
||||
> have been made for this request, so resolving `unknown` permissively does not extend
|
||||
> a considered decision, it invents the most permissive one available.
|
||||
>
|
||||
> An unreachable engine and an unclassified subject are different failure cases. The
|
||||
> first is a known request in a degraded system and the trade is available for it. The
|
||||
> second is not: `unknown` is the cheapest state for an attacker to induce — an
|
||||
> unregistered workload, a malformed label, a resource created before classification,
|
||||
> a race against registry propagation — and a permissive `unknown` makes being
|
||||
> unclassifiable a privilege escalation requiring no credential. §8's asymmetry
|
||||
> forbids that wherever it appears.
|
||||
>
|
||||
> Zone stances are untouched by this. Raised by `access-engine` as an observation on
|
||||
> two conformant maps that disagree, and explicitly not as a request that either
|
||||
> consumer change its stance — a PDP does not set a consumer's stance.
|
||||
|
||||
**Add to §6.4 obligation 3, and to the §13.1 register columns:**
|
||||
|
||||
> A published map MUST name the **axis** it scopes over and state its relationship to
|
||||
> security zone: either a mapping, or an explicit declaration that none exists yet and
|
||||
> why. §13.1 carries the axis per row.
|
||||
>
|
||||
> "Per zone **or equivalent scope**" permits axes that cannot be aggregated, and the
|
||||
> register cannot then answer *"what is the estate's stance for a `z2`-protected
|
||||
> workload"* — the question an inventory exists to answer. Forcing every consumer onto
|
||||
> zones is the wrong repair where zone membership is not yet available as a claim;
|
||||
> asserting a zone one cannot know is a fiction, and a fiction in a runtime-read,
|
||||
> test-pinned file is worse than an honest incommensurability. **The register therefore
|
||||
> records the axes and states that cross-axis aggregation is unavailable**, rather than
|
||||
> implying an answer it does not have. An inventory that silently cannot answer its own
|
||||
> question is §9.1's defect in another place.
|
||||
>
|
||||
> The convergence path is zone membership reaching the decision as a claim, after
|
||||
> which a stage-scoped map converges onto zones without either side inventing a
|
||||
> mapping. Until then the axes are recorded, not reconciled.
|
||||
|
||||
**Register impact at the cut.** `ops-warden`'s `unknown` → `fail_open` cell becomes
|
||||
non-conformant under this amendment; its `z0`–`z2` stances do not. That is a real cost
|
||||
to the repository that published first, built the reference form, and offered it
|
||||
estate-wide, and it is put to the assent round rather than imposed — the A3 row stays
|
||||
as written until v0.8 is accepted.
|
||||
|
||||
---
|
||||
|
||||
## Not in this set
|
||||
|
||||
Recorded so the omissions are deliberate rather than forgotten.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue