Follow-up to #10773 / PR #10934, which registered eleven dogfood proof tags in proof-registry.mts and — per that card's triage ruling (13:11Z) — proposed ledger bindings without adopting any. Every entry landed bound: false with a blockedReason, so nothing is mis-cited today; this card carries the ledger edits that were deliberately held out of a registration PR.
The judgment half is already done. The spec seat adjudicated the proposals as reviewer of record in the ACCEPT comment on PR #10934 (issuecomment-5376518715) before the shift closed. This card is the execution, not a re-litigation — but ⛔ re-verify each binding against the file on the merged ref before writing it, since the adjudication was made against 23e27af370.
① ADOPT — showcase-fls-read-mask-strip → permission.fields.readable
The strongest of the three. packages/qa/dogfood/test/showcase-fls-read-mask-strip.dogfood.test.ts authors a scratch permission set carrying readable: false and asserts the runtime outcome both ways — key-absence on the wire ('budget' in record is false, not toBeUndefined(), which cannot distinguish stripped from masked) and the entitled contrast on the same field, row and request. That is exactly the property whose live status the entry claims.
⛔ Do not also bind permission.fields.editable. The file authors that key but asserts its refusal as a consequence of unreadability rather than as the write-deny axis — showcase-permission-zoo already pins that half. Binding it would repeat the owner-anchor / allowTransfer mistake: a proof cited for a property it does not exercise.
② ADOPT — showcase-crud-persona-matrix → all four permission.objects.allow{Create,Read,Edit,Delete}
The four cells map one-to-one onto the four entries, exercised in both directions per cell. The scope worry the dev raised — one breadth proof anchoring four properties — is answered by the file's own shape: the exact allow/deny split is asserted, so a narrowing sweep (or a persona silently failing to provision) breaks the build rather than quietly shrinking what four entries cite. Multi-entry binding has precedent in semantic-roles, which binds three.
Note the ADR-0090 D5 subtlety the file already handles: cells are judged as a union with the everyone-baseline set, because capability is additive — judging against the raw access-matrix.json row turns 9 correctly-allowed cells into fabricated violations.
③ DO NOT BIND YET — sharing-rule-org-less-caller → permission.systemPermissions
Blocked on a measurement, not on a preference. The file authors system_permissions: ['manage_sharing'] and proves it acts as a real data-layer boundary (ADR-0111 D6, at the sharing service). But that ledger entry's note reads "PARTIAL — app-entry/nav visibility only, not a general capability gate", with evidence pointing at hono-plugin.ts:1222 — i.e. the note describes a narrower consumer than the proof measures.
Binding onto a stale note propagates the staleness into a citation, which is worse than no citation. So: re-verify the note against the sharing-service path first. If it is stale, correct the note and bind in the same PR; if the note is accurate and the two really are different consumers, leave the proof unbound and record why on this card.
Acceptance
check:liveness green, and BOUND_PROOF_PATHS in proof-registry.test.ts updated to match the new bindings (that pin is what catches a silent binding).- Each adopted binding flips its registry entry from
bound: false + blockedReason to the bound shape — ⛔ leaving a stale blockedReason next to a live binding is a contradiction the next reader will trust. - ③ resolved either way, in writing.
Back-links: #10773, PR #10934, #9220 (the multi-entry precedent discussion), ADR-0090 D5, ADR-0111 D6.
Follow-up to #10773 / PR #10934, which registered eleven dogfood proof tags in
proof-registry.mtsand — per that card's triage ruling (13:11Z) — proposed ledger bindings without adopting any. Every entry landedbound: falsewith ablockedReason, so nothing is mis-cited today; this card carries the ledger edits that were deliberately held out of a registration PR.The judgment half is already done. The spec seat adjudicated the proposals as reviewer of record in the ACCEPT comment on PR #10934 (issuecomment-5376518715) before the shift closed. This card is the execution, not a re-litigation — but ⛔ re-verify each binding against the file on the merged ref before writing it, since the adjudication was made against
23e27af370.① ADOPT —
showcase-fls-read-mask-strip→permission.fields.readableThe strongest of the three.
packages/qa/dogfood/test/showcase-fls-read-mask-strip.dogfood.test.tsauthors a scratch permission set carryingreadable: falseand asserts the runtime outcome both ways — key-absence on the wire ('budget' in recordis false, nottoBeUndefined(), which cannot distinguish stripped from masked) and the entitled contrast on the same field, row and request. That is exactly the property whoselivestatus the entry claims.⛔ Do not also bind
permission.fields.editable. The file authors that key but asserts its refusal as a consequence of unreadability rather than as the write-deny axis —showcase-permission-zooalready pins that half. Binding it would repeat the owner-anchor /allowTransfermistake: a proof cited for a property it does not exercise.② ADOPT —
showcase-crud-persona-matrix→ all fourpermission.objects.allow{Create,Read,Edit,Delete}The four cells map one-to-one onto the four entries, exercised in both directions per cell. The scope worry the dev raised — one breadth proof anchoring four properties — is answered by the file's own shape: the exact allow/deny split is asserted, so a narrowing sweep (or a persona silently failing to provision) breaks the build rather than quietly shrinking what four entries cite. Multi-entry binding has precedent in
semantic-roles, which binds three.Note the ADR-0090 D5 subtlety the file already handles: cells are judged as a union with the everyone-baseline set, because capability is additive — judging against the raw
access-matrix.jsonrow turns 9 correctly-allowed cells into fabricated violations.③ DO NOT BIND YET —
sharing-rule-org-less-caller→permission.systemPermissionsBlocked on a measurement, not on a preference. The file authors
system_permissions: ['manage_sharing']and proves it acts as a real data-layer boundary (ADR-0111 D6, at the sharing service). But that ledger entry's note reads "PARTIAL — app-entry/nav visibility only, not a general capability gate", with evidence pointing athono-plugin.ts:1222— i.e. the note describes a narrower consumer than the proof measures.Binding onto a stale note propagates the staleness into a citation, which is worse than no citation. So: re-verify the note against the sharing-service path first. If it is stale, correct the note and bind in the same PR; if the note is accurate and the two really are different consumers, leave the proof unbound and record why on this card.
Acceptance
check:livenessgreen, andBOUND_PROOF_PATHSinproof-registry.test.tsupdated to match the new bindings (that pin is what catches a silent binding).bound: false+blockedReasonto the bound shape — ⛔ leaving a staleblockedReasonnext to a live binding is a contradiction the next reader will trust.Back-links: #10773, PR #10934, #9220 (the multi-entry precedent discussion), ADR-0090 D5, ADR-0111 D6.