You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[Decision] ADR-0049's declaration surface has two halves and only one is governed — platform-object row columns on security objects have no liveness ledger, and both #8894 ground-truth instances live there #9054
Filed by the domain:devx PM seat (#6023, session session_011RB4waLuNbdruCo6X9oobm) from the #8894 measurement. Unassigned. ⛔ No domain:* set — triage's field, and the landing package depends on which option is chosen.
This is not the question #8894 asked, which is why it is not being closed inside it.#8894 was ruled "a measurement, not a gate", the measurement was taken, and it closed on its own terms: the enumeration oracle is not mechanizable in the read-determination half (measured by ablation — the oracle stays green across sys_permission_set.active's entire inert life; 2 of 4 ground-truth instances missed, and they are the two the card was filed about). Full numbers in #8894 comment 5306337804.
What the measurement surfaced on the way is a governance gap that is bigger than the card, and it needs its own ruling.
The gap, as measured
ADR-0049's "declared = enforced" surface has two halves:
Spec schema properties (field.type, object.enable.clone, …) — governed by check:liveness, with a ratchet, evidence-path resolution, verifiedAt, evidenceScope and authorWarn.
Measured size of the ungoverned half: 10 security objects (plugin-security + plugin-sharing, off the curated PLATFORM_OBJECTS_BY_PACKAGE registry), 88 candidate security keys and 9 actions. Widening to identity takes it to 29 objects / ~240 keys.
⭐ Both of #8894's ground-truth instances live in the ungoverned half — that is not a coincidence, it is the reason the class keeps recurring. Recurrence is measured, not asserted: #8613, #8811, #8535 inside one week, and #9046 was found within an hour of simply pointing an enumerator at the surface. The class is not exhausted.
Options
A — Nothing. Close with the measurement; the class keeps being found by hand, roughly as it has been.
B — Extend the existing packages/spec/liveness ledger to platform-object row columns on security objects. One ledger, one vocabulary, reuses live machinery. Cost: 88 verdicts with evidence to backfill, and the boundary (10 security objects, or 29 with identity) becomes a ruling of its own.
C — A new, narrower ledger for just the RBAC grant catalogues (sys_permission_set, sys_position, sys_user_*), ~40 keys.
Measured business pull — cuts both ways, honestly. Four instances in a week is real recurrence. But the consumer of a ledger is a human reading it, and the implementing dev reports this repo has a hard number for how well that goes: 10 of 13 re-verified entries in the sibling ledger were wrong (77%). ⚠️ That figure is the dev's measurement and I have not independently re-derived it — it is load-bearing enough that it should be re-checked before it decides anything.
AI-agent error-resistance — this is the prism that stops me short of recommending B. The failure mode is an agent declaring a key the runtime never enforces. A ledger catches that only if the verdict is right, and a ledger row is a comfortable place for an agent to write a confident wrong sentence with a citation attached. The local proof is sys_capability.active: its Deactivate prose asserted an enforcement that never existed, so a row written from the declaration would have read "live" — the ledger would have certified the exact falsehood it exists to catch. Compare what did work: a bare enumeration with no verdict attached found [finding] The ADR-0091 D5 recertification columns (last_certified_at / certified_by) are declared on both grant tables and nothing writes or reads them #9046 in minutes, because "here are 88 keys, four have no reader at all" is checkable and "this key is live because X" is not.
Startup scope discipline — for A. 88 hand-written verdicts is a real backfill, and a permanent maintenance obligation on every future card.
Recommendation: A now, and B only if you want it — ⛔ never C
The prisms do not align and I am not going to manufacture agreement between them: coherence wants B, error-resistance wants the enumerator without the ledger, business pull splits. That disagreement is the finding, not a failure to decide.
What I would do absent an instruction: keep the enumeration halves alive as an on-demand instrument (they are mechanical, they are already written, and they are the part that demonstrably works), and not build a verdict ledger over them. A gate addition is a standing obligation on every future card, which both the triage seat and the 2026-08-16 ruling placed with you.
⚠️ If you rule B, the boundary question (10 objects vs 29) needs answering in the same stroke, or it becomes a second decision six weeks from now.
Refs: #8894 (the measurement + the fork) · #9046 (the fourth instance, found by enumeration) · #8613 · #8811 · #8535 · #8711 (the ledger-divergence precedent) · ADR-0049 · ADR-0091 D5.
Filed by the
domain:devxPM seat (#6023, sessionsession_011RB4waLuNbdruCo6X9oobm) from the #8894 measurement. Unassigned. ⛔ Nodomain:*set — triage's field, and the landing package depends on which option is chosen.This is not the question #8894 asked, which is why it is not being closed inside it.#8894 was ruled "a measurement, not a gate", the measurement was taken, and it closed on its own terms: the enumeration oracle is not mechanizable in the read-determination half (measured by ablation — the oracle stays green across
sys_permission_set.active's entire inert life; 2 of 4 ground-truth instances missed, and they are the two the card was filed about). Full numbers in #8894 comment5306337804.What the measurement surfaced on the way is a governance gap that is bigger than the card, and it needs its own ruling.
The gap, as measured
ADR-0049's "declared = enforced" surface has two halves:
field.type,object.enable.clone, …) — governed bycheck:liveness, with a ratchet, evidence-path resolution,verifiedAt,evidenceScopeandauthorWarn.sys_permission_set.activeandsys_position.activeare unenforced too — both Deactivate dialogs promise access stops, and it does not #8613's own changeset says so verbatim: "activeis a ROW property of asys_permission_setrecord, not a key onPermissionSetSchema".Measured size of the ungoverned half: 10 security objects (
plugin-security+plugin-sharing, off the curatedPLATFORM_OBJECTS_BY_PACKAGEregistry), 88 candidate security keys and 9 actions. Widening to identity takes it to 29 objects / ~240 keys.⭐ Both of #8894's ground-truth instances live in the ungoverned half — that is not a coincidence, it is the reason the class keeps recurring. Recurrence is measured, not asserted: #8613, #8811, #8535 inside one week, and #9046 was found within an hour of simply pointing an enumerator at the surface. The class is not exhausted.
Options
packages/spec/livenessledger to platform-object row columns on security objects. One ledger, one vocabulary, reuses live machinery. Cost: 88 verdicts with evidence to backfill, and the boundary (10 security objects, or 29 with identity) becomes a ruling of its own.sys_permission_set,sys_position,sys_user_*), ~40 keys.Four-prism
activeflag, and its completeness check cannot notice #8711 just spent a whole card narrowing, so C is dominated by B on this prism and should not be chosen for cheapness alone.sys_capability.active: its Deactivate prose asserted an enforcement that never existed, so a row written from the declaration would have read "live" — the ledger would have certified the exact falsehood it exists to catch. Compare what did work: a bare enumeration with no verdict attached found [finding] The ADR-0091 D5 recertification columns (last_certified_at/certified_by) are declared on both grant tables and nothing writes or reads them #9046 in minutes, because "here are 88 keys, four have no reader at all" is checkable and "this key is live because X" is not.Recommendation: A now, and B only if you want it — ⛔ never C
The prisms do not align and I am not going to manufacture agreement between them: coherence wants B, error-resistance wants the enumerator without the ledger, business pull splits. That disagreement is the finding, not a failure to decide.
What I would do absent an instruction: keep the enumeration halves alive as an on-demand instrument (they are mechanical, they are already written, and they are the part that demonstrably works), and not build a verdict ledger over them. A gate addition is a standing obligation on every future card, which both the triage seat and the 2026-08-16 ruling placed with you.
Refs: #8894 (the measurement + the fork) · #9046 (the fourth instance, found by enumeration) · #8613 · #8811 · #8535 · #8711 (the ledger-divergence precedent) · ADR-0049 · ADR-0091 D5.