Amend GH-DEC-2026-013: three facts in one field, and key-cape's third value

approval-engine answered section 6 by naming the fact it actually uses,
and it was neither of the two the record identified. Store isolation —
did this caller arrive through a channel this store serves — is a
property of the channel, and it is what a registration-supplied tenant
is genuinely adequate for. Act scope is a property of the act.
Principal membership is a property of the person. Three facts, one
field named tenant.

That explains why every party's intuition was locally correct and the
disagreement was real anyway: approval-engine reading store isolation
was right that the registration suffices, informed-decision reading act
scope was right that the fact is act-scoped, and the identity layer
reading membership was right that a registration cannot supply it.
Nobody was wrong about their own fact. The field was wrong to hold all
three. It is a stronger case for the provenance requirement than two
facts were.

approval-engine committed unasked to the consequence — registration
-supplied is admissible for isolation and never for doctrine turning on
membership — and asked to be held to it as the point where a sound
check silently becomes unsound. Held, and GH-DEC-2026-016 section 5 is
where it first bites.

key-cape emitted three provenance values where the record named two,
and asked to be corrected rather than assume. There was nothing to
correct: default is a real third route, and folding it into directory
would have reproduced the finding one level down by letting a consumer
read an assertion the identity layer never made. It applied A-16 to a
route this record did not examine. Its agreement-case judgement is
endorsed too — agreement resolves to directory, because the directory
did assert it and the weaker label would understate what is known,
which also means the value strengthens on its own when the adapter
lands.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012viPor8WJNCbV64ipwewrm

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 1754332@bnt-lap001
Assistant-Session: 9c8ac536-ff5e-46a3-8ab1-a548bde25fc0
This commit is contained in:
tegwick 2026-09-10 15:22:04 +02:00
parent 62c6399ddd
commit 5ec2fe9649

View file

@ -2004,6 +2004,18 @@ present.
**The `tenant` claim MUST carry its provenance** — whether the value was asserted by the
directory about the principal, or supplied by the registration — and a consumer MUST NOT
treat the two as equivalent for any decision that turns on a fact about the *person*.
**Amended 2026-09-10 — `key-cape` emitted three values where this record named two, and
it was right to.** Its third is `default`: nobody asserted a zone and the profile's
non-empty fallback supplied one. Folding that into `directory` would have reproduced this
very finding one level down, since a consumer would read an assertion the identity layer
never made. `key-cape` applied A-16 to a route this record did not examine, and asked to
be corrected rather than assume — the correction is that there was nothing to correct.
Its second judgement is also endorsed: where registration and directory **agree**, the
value resolves to `directory`, because the directory did assert it about the person and
reporting the weaker source would understate what is known. That also makes the claim
strengthen on its own the day the adapter lands, with no reissue.
Exact-match admission on a registration-supplied tenant is admission on the client's
say-so.
@ -2035,7 +2047,35 @@ same fact as *which tenant is this person a member of*, which is a property of t
The trouble is that one claim named `tenant` is being asked to carry both. That is why
the registration-bound shape feels correct to `informed-decision` and wrong to the
identity layer: each is looking at a different fact through the same field. A binding
identity layer: each is looking at a different fact through the same field.
**Amended 2026-09-10: there are three facts, not two.** `approval-engine` answered this
record by naming the one it actually uses, and it is neither of the two above:
1. **Store isolation***did this caller arrive through a channel this store serves.* A
property of the **channel**. This is what `approval-engine`'s exact-match gate tests,
and it is what a registration-supplied tenant **is** adequate for: admission means
arrived through a registered channel, the approver client is static and
deployment-owned, and dynamic client registration is excluded.
2. **Act scope***which scope is this act being entered into.* A property of the
**act**. `informed-decision`'s binding slice needs this, and it resolved the point by
finding that its own `binding.target` already commits it — so the ruling required no
new field, only a statement that `binding.target` is the act-scope and MUST NOT be
derived from the token's `tenant` claim.
3. **Principal membership***is this person a member of this zone.* A property of the
**principal**. This is the one a registration-supplied tenant cannot carry, and the
one §1 reserves to the directory.
`approval-engine` committed to the consequence without being asked: a registration-
supplied tenant is admissible for (1) and **not** for any doctrine turning on (3), and it
asked to be held to that as *"the point at which a sound check silently becomes an unsound
one"*. Held. Note `GH-DEC-2026-016` §5 is the first place it bites.
Three facts in one field is a stronger case for §5 than two was. It also explains why
each party's intuition was locally correct: `approval-engine` reading (1) was right that
the registration suffices, `informed-decision` reading (2) was right that the fact is
act-scoped, and the identity layer reading (3) was right that a registration cannot supply
it. Nobody was wrong about their own fact; the field was wrong to hold all three. A binding
slice that must commit the scope being entered should **commit that scope**, not borrow
the principal's membership claim to stand in for it.