docs(remediation): bank D-15 — token scope is not repository permission

f10-coder holds gitea-mosaicstack-f10-coder.token with write:repository scope and was
verified at mint by 'repo access returns 200'. It cannot push: collaborator lookup
404s and its own token reports push:false, pull:true.

Capability has three independent layers — token file (raw-API auth), tea login (tea
path), repository permission (actual write authority) — and satisfying two proves
nothing about the third. Scope bounds what a token may ATTEMPT; repository permission
decides what the user may DO.

The charter principle failing on the check meant to confirm capability: a 200 on a
READ was accepted as evidence of WRITE. written-unverified treated as verified, by
both provisioner and orchestrator, one layer above D-12.

RM-50's pre-dispatch check must assert effective permission for the intended operation
(permissions.push == true as that seat), not token existence or a read returning 200.
A capability check that cannot fail on a seat lacking write permission is itself an
inert gate.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
mos-dt-0
2026-07-31 18:32:27 -05:00
co-authored by Claude Opus 5
parent d0ad6e942b
commit 3477e933df
+38
View File
@@ -93,6 +93,44 @@ and must not be cited as merge evidence. Rely on reviewer clearance + real CI.
Three independent live instances in a single session — format gate, agent context reset, queue guard — Three independent live instances in a single session — format gate, agent context reset, queue guard —
is the class confirmed, not anecdote. is the class confirmed, not anecdote.
### D-15 — token scope is not repository permission (a THIRD capability layer)
`f10-coder` was provisioned with `gitea-mosaicstack-f10-coder.token`, scopes `write:repository` +
`write:issue`, and the mint was verified by "repo access returns 200". It then failed to push:
```
remote: error: User permission denied for writing.
remote: error: pre-receive hook declined
```
Verified objectively rather than inferred (per the charter principle):
| probe | result |
| ------------------------------------------------------ | ------------------------------------------- |
| `GET /repos/mosaicstack/stack/collaborators/f10-coder` | **404** — not a collaborator |
| repo permissions as seen by **its own token** | `admin: false`, `push: false`, `pull: true` |
**Capability has at least three independent layers, and satisfying two proves nothing about the third:**
1. **Token file exists** → raw-API authentication works (D-11b).
2. **`tea` login exists** → tea-dependent wrapper paths work (D-13).
3. **Repository permission granted** (collaborator/team membership) → _writes_ are actually authorised.
A token can carry `write:repository` scope and still be refused, because **scope bounds what a token
may attempt; repository permission decides what the user may do.** They are different systems.
**This is the charter principle failing on the very check meant to confirm capability.** The mint was
validated by an HTTP 200 on a _read_. A 200 proves reachability; it does not prove the property that
was required, which was **write**. Both the provisioner and I accepted it — the same
`written-unverified` treated as `verified` as D-12, one layer up, on a check whose entire purpose was
verification.
**Requirements.** RM-50's pre-dispatch capability check must probe the **effective permission for the
operation intended** — for push authority, assert `permissions.push == true` as that seat, not token
existence and not a 200 on a read. RM-04's registry reconciliation covers all three layers, with a
must-fail control for each. A capability check that cannot fail on a seat lacking write permission is
itself an inert gate.
### D-14 — a ruled decision did not propagate to the authoritative record ### D-14 — a ruled decision did not propagate to the authoritative record
DECISION-1 (the corrected choke-point wire-in target) was ruled by the coordinator and applied to DECISION-1 (the corrected choke-point wire-in target) was ruled by the coordinator and applied to