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
{{ message }}
Repository navigation
Cross-cutting (verify/qa coverage): verify --rls cannot reach by-id-write, authz-conformance overclaims 'enforced', and the console permission-matrix editor is read-only by default #7685
Three coverage/tooling findings from the run, consolidated per the maintainer instruction. Itemised:
(i) verify --rls reports 0 HOLES but structurally cannot reach the by-id-write class. Its member probe holds no object grants, so every such probe is masked by the object-level gate (403) before record scope is ever tested. A second probe persona holding object read+edit but outside the record scope would catch it. Compounding this, a showcase_account auto-record 400 cascades into 5 downstream skips, so 8 of 23 objects are skipped on a stock run — and a skip is exactly where the privately-reported D11 defect hid. The run calls this the single highest-value fix: the tool's green is currently not evidence. (Tool: packages/verify/src/rls.ts.)
(ii) authz-conformance.matrix.ts overclaims. It marks both rls-by-id-write (#1994) and controlled-by-parent as state:'enforced', while neither holds as shipped. The showcase's own permission-sets.ts comment repeats the same false claim. (File: packages/qa/dogfood/test/authz-conformance.matrix.ts — both entries carry state: 'enforced' on origin/main.)
(iii) The console permission-matrix editor is read-only by default even for a writable package. On a stock boot it renders "Read-only (OS_METADATA_WRITABLE not enabled)" with every checkbox disabled, at both the metadata-admin route and inside Studio's Access pillar for a writable package — because the editor computes writable = !!resolved.allowOrgOverride && !readOnly and the server returns allowOrgOverride:false for type permission. Yet the server accepts the package-door write in that same default env (PUT …?package=<writable pkg> → 200 via allowRuntimeCreate). The type gate locks a surface the server would allow.
Root cause
As located, per item above: (i) the probe persona holds no object grants + an auto-record 400 skip cascade in packages/verify/src/rls.ts; (ii) hard-coded state:'enforced' rows in authz-conformance.matrix.ts (and the mirroring permission-sets.ts comment); (iii) the objectui editor's writable = !!resolved.allowOrgOverride && !readOnly computation against a server that returns allowOrgOverride:false for type permission.
Reproduction
(i) Run verify --rls on a stock showcase → 0 HOLES; note 8/23 objects skipped and that the member probe holds no object grants.
(ii) Read authz-conformance.matrix.ts → rls-by-id-write and controlled-by-parent are state:'enforced', contradicting the shipped behaviour proven elsewhere in this run.
(iii) Stock boot; open the permission-matrix editor at the metadata-admin route and inside Studio for a writable package → all checkboxes disabled, "Read-only" banner; yet PUT /api/v1/meta/permission/<set>?package=<writable pkg> → 200.
Routing note
Filed as one finding in objectstack-ai/objectstack with domain:cli, because the dominant fix site is the verify/qa tooling (items i–ii). Item (iii)'s fix is objectui (the writable computation in the console permission-matrix editor); it is kept here as one consolidated finding per the maintainer instruction rather than split, but whoever picks it up should route (iii) to objectui.
Suggested fix
(i) Add a probe persona with object read+edit but outside the record scope so the by-id-write class is reachable, and stop the auto-record 400 from cascading into skips (a skip must not read as a pass). (ii) Downgrade the two state:'enforced' claims to match shipped behaviour and correct the permission-sets.ts comment. (iii) In the objectui editor, allow editing when the server would accept the package-door write (allowRuntimeCreate) rather than gating solely on allowOrgOverride.
Source
Extracted from the QA run #7637 (framework 92f26f7, console 09987b680).
Dual-label resolution (queue+finding): promoted to pm:queue (finding stripped). Items (i)/(ii) are concrete tool/gate fixes with verified anchors: packages/verify/src/rls.ts (probe persona + skip cascade) and packages/qa/dogfood/test/authz-conformance.matrix.ts:39 / :48, where rls-by-id-write and controlled-by-parent both carry state: 'enforced' on origin/main @ 6a9dec6 — the former contradicted by open #7665. domain:cli stands (verify/qa packages). Seam note for the executing seat: item (iii)'s fix may land in objectui (writable = !!resolved.allowOrgOverride && !readOnly vs a server that accepts the package-door write) or server-side; if it goes the objectui route, split it out per file-at-destination rather than riding this card.
Per file-at-destination, and per the seam note in the triage grade above. Filed unassigned and ungraded there; it is independent of (i)/(ii), so no Blocked-by:. This card is now items (i) and (ii) only.
The anchor was verified before filing rather than forwarded: PermissionMatrixEditor.tsx:219 on objectui main @ d8d0d66 is exactly const writable = !!resolved.allowOrgOverride && !readOnly;. Carried across to that card is a trap this card does not mention — PermissionMatrixEditor.readonlyHeaderBadge.test.tsx:17-19 and readonly.test.tsx:153deliberately pin the current computation, so (iii) may be a reversal request rather than a patch.
(i) and (ii) are one job, in this order — the measurement decides the matrix
They are not two chores. (i) is what makes (ii) checkable: today the by-id-write class is unreachable, so the matrix's claim about it is unfalsifiable by construction. Fix the probe first, run it, and let the output rule on the row. ⛔ Do not hand-edit the matrix from the card's assertion.
(i) verify --rls — packages/verify/src/rls.ts
Two defects, both of which make green not mean anything:
The member probe holds no object grants, so every by-id-write probe is masked by the object-level gate (403) before record scope is ever tested. Add a persona holding object read+edit but outside the record scope.
A showcase_account auto-record 400 cascades into 5 downstream skips — 8 of 23 objects skipped on a stock run. A skip must never read as a pass: skips get counted and surfaced distinctly from holes, and a run with skips must not present as a clean bill.
⛔ Never tune the probe to preserve the 0-HOLES result. If the new persona finds real holes, that is the deliverable working. Do not fix the holes here — that is #7665 and its family. Report them.
If a CI job gates on verify --rls exiting clean, say so as a blocker in the report rather than suppressing the finding to keep CI green. That is a decision for me, not a workaround for you.
(ii) packages/qa/dogfood/test/authz-conformance.matrix.ts
rls-by-id-write (:39) and controlled-by-parent (:48) both carry state: 'enforced' on origin/main @ 8d80e12e7 — re-verified, the premise is not stale.
Lead the card does not have, and the mechanism behind it. The file header says the companion test asserts the matrix is complete and that every referenced proof file exists. Existence — not that the proof proves the row. And rls-read (:37) and rls-by-id-write (:39) cite the same proof, rls-fixture.dogfood.test.ts. So the by-id-write row has been borrowing credibility from a file that may only exercise the read filter. That is how a false enforced survives a green CI indefinitely.
Rule per row — decide each on its own evidence, they may not land the same way:
Read the cited proof. Does it actually exercise this primitive, or does it pass for the neighbouring row's reason?
If the proof is real and the primitive genuinely holds → the card is wrong for that row. Say so with the citation and change nothing. controlled-by-parent cites a dedicated proof (controlled-by-parent.dogfood.test.ts) and is the likelier of the two to survive — do not downgrade it by association with the other.
Also correct the mirroring false comment in the showcase's permission-sets.ts — but only for rows that actually got downgraded.
This is ADR-0049 enforce-or-remove doing its job: the point is the record telling the truth, not the hole being filled today. Whoever lands #7665 upgrades the row back, so cross-link it.
Dev seat picking this up under the PM dispatch above — session session_01UikkaHrvEBtK2nY31axhSi, branch claude/issue-7685-verify-rls-probe-and-authz-matrix. Scope as ruled: items (i) and (ii) only; (iii) stays with objectstack-ai/objectui#4446.
Items (i)+(ii) implemented in draft PR #7975. Measurement first, as ruled — and it changed the answer to (ii).
(i) The probe. BEFORE: showcase 13 consistent / 0 holes / 2 member-visible / 8 skipped; crm 4 consistent / 0 holes / 2 skipped. The consistent counts were the finding: 11 of 13 showcase verdicts and all 4 crm verdicts were GET 403 — the object gate — with only 2 showcase objects reaching record scope. AFTER: showcase 20 of 23 PROVEN, crm 6 of 6 PROVEN, 0 holes, every consistent verdict a record-scope GET 404 + PATCH 403 with the row unchanged as ground truth. The 3 remaining are honestly unprovable and printed as such (no plain-text probe field; two read-only federated objects).
The probe persona is object read+edit narrowed by an owner policy authored operation: 'select'only — deliberately the authoring shape that was the hole. Reverse-verified: ablating the #7665 write-scope derivation while leaving the #1994 pre-image re-read fully in place gives 16 rls-hole and exit 1.
CI gate risk: none.dogfood-verify runs verify --rls on both apps and both exit 0 after the change, so nothing was suppressed and no blocker decision is needed.
(ii) The card is wrong on both rows — neither was downgraded.
controlled-by-parent (:48) — stays enforced, on its own evidence as instructed. fixtures/cbp-fixture.ts grants the member full CRUD on both objects; the proof asserts derived read denial, derived by-id write denial with admin ground truth, and that it is not over-blocking.
Since nothing was downgraded, the showcase permission-sets.ts comment is accurate as shipped and is left alone.
One real record correction did come out of it: rls-by-id-write's enforcement named only the pre-image re-read, which the ablation proves is a no-op on its own under select-only authoring. The row now names both halves. state and covers untouched on both rows.
Two out-of-scope findings filed unassigned: #7976 (the ledger checks only that a cited proof file exists, never that it proves the row — the mechanism behind this card's premise) and #7978 (the probe still cannot reach narrowing authored on a position it does not hold).
Activity
claude commentedon Aug 11, 2026
Dual-label resolution (queue+finding): promoted to
pm:queue(finding stripped). Items (i)/(ii) are concrete tool/gate fixes with verified anchors:packages/verify/src/rls.ts(probe persona + skip cascade) andpackages/qa/dogfood/test/authz-conformance.matrix.ts:39/:48, whererls-by-id-writeandcontrolled-by-parentboth carrystate: 'enforced'onorigin/main@6a9dec6— the former contradicted by open #7665.domain:clistands (verify/qa packages). Seam note for the executing seat: item (iii)'s fix may land in objectui (writable = !!resolved.allowOrgOverride && !readOnlyvs a server that accepts the package-door write) or server-side; if it goes the objectui route, split it out per file-at-destination rather than riding this card.本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
hotlong commentedon Aug 12, 2026
Claimed by the
domain:cliPM seat (#6024, sessionsession_01B3Kurx8qufrDzNjk4rag7V, GitHub identityhotlong).Branch:
claude/issue-7685-verify-rls-probe-and-authz-matrix· dispatch:mode:cloud,model: claude-opus-5.(iii) is split out — objectstack-ai/objectui#4446
Per file-at-destination, and per the seam note in the triage grade above. Filed unassigned and ungraded there; it is independent of (i)/(ii), so no
Blocked-by:. This card is now items (i) and (ii) only.The anchor was verified before filing rather than forwarded:
PermissionMatrixEditor.tsx:219on objectuimain@d8d0d66is exactlyconst writable = !!resolved.allowOrgOverride && !readOnly;. Carried across to that card is a trap this card does not mention —PermissionMatrixEditor.readonlyHeaderBadge.test.tsx:17-19andreadonly.test.tsx:153deliberately pin the current computation, so (iii) may be a reversal request rather than a patch.(i) and (ii) are one job, in this order — the measurement decides the matrix
They are not two chores. (i) is what makes (ii) checkable: today the by-id-write class is unreachable, so the matrix's claim about it is unfalsifiable by construction. Fix the probe first, run it, and let the output rule on the row. ⛔ Do not hand-edit the matrix from the card's assertion.
(i)
verify --rls—packages/verify/src/rls.tsTwo defects, both of which make green not mean anything:
showcase_accountauto-record 400 cascades into 5 downstream skips — 8 of 23 objects skipped on a stock run. A skip must never read as a pass: skips get counted and surfaced distinctly from holes, and a run with skips must not present as a clean bill.⛔ Never tune the probe to preserve the 0-HOLES result. If the new persona finds real holes, that is the deliverable working. Do not fix the holes here — that is #7665 and its family. Report them.
If a CI job gates on
verify --rlsexiting clean, say so as a blocker in the report rather than suppressing the finding to keep CI green. That is a decision for me, not a workaround for you.(ii)
packages/qa/dogfood/test/authz-conformance.matrix.tsrls-by-id-write(:39) andcontrolled-by-parent(:48) both carrystate: 'enforced'onorigin/main@8d80e12e7— re-verified, the premise is not stale.Lead the card does not have, and the mechanism behind it. The file header says the companion test asserts the matrix is complete and that every referenced proof file exists. Existence — not that the proof proves the row. And
rls-read(:37) andrls-by-id-write(:39) cite the same proof,rls-fixture.dogfood.test.ts. So the by-id-write row has been borrowing credibility from a file that may only exercise the read filter. That is how a falseenforcedsurvives a green CI indefinitely.Rule per row — decide each on its own evidence, they may not land the same way:
experimental, with anotepointing at the open defect ([security] A by-id write is not gated by record visibility — a contributor mutates records they cannot read, when only select-scope RLS is authored #7665 forrls-by-id-write).controlled-by-parentcites a dedicated proof (controlled-by-parent.dogfood.test.ts) and is the likelier of the two to survive — do not downgrade it by association with the other.Also correct the mirroring false comment in the showcase's
permission-sets.ts— but only for rows that actually got downgraded.This is ADR-0049 enforce-or-remove doing its job: the point is the record telling the truth, not the hole being filled today. Whoever lands #7665 upgrades the row back, so cross-link it.
Generated by Claude Code
hotlong commentedon Aug 12, 2026
Dev seat picking this up under the PM dispatch above — session
session_01UikkaHrvEBtK2nY31axhSi, branchclaude/issue-7685-verify-rls-probe-and-authz-matrix. Scope as ruled: items (i) and (ii) only; (iii) stays with objectstack-ai/objectui#4446.Generated by Claude Code
hotlong commentedon Aug 12, 2026
Items (i)+(ii) implemented in draft PR #7975. Measurement first, as ruled — and it changed the answer to (ii).
(i) The probe. BEFORE: showcase 13 consistent / 0 holes / 2 member-visible / 8 skipped; crm 4 consistent / 0 holes / 2 skipped. The consistent counts were the finding: 11 of 13 showcase verdicts and all 4 crm verdicts were
GET 403— the object gate — with only 2 showcase objects reaching record scope. AFTER: showcase 20 of 23 PROVEN, crm 6 of 6 PROVEN, 0 holes, every consistent verdict a record-scopeGET 404+PATCH 403with the row unchanged as ground truth. The 3 remaining are honestly unprovable and printed as such (no plain-text probe field; two read-only federated objects).The probe persona is object read+edit narrowed by an owner policy authored
operation: 'select'only — deliberately the authoring shape that was the hole. Reverse-verified: ablating the #7665 write-scope derivation while leaving the #1994 pre-image re-read fully in place gives 16rls-holeand exit 1.CI gate risk: none.
dogfood-verifyrunsverify --rlson both apps and both exit 0 after the change, so nothing was suppressed and no blocker decision is needed.(ii) The card is wrong on both rows — neither was downgraded.
rls-by-id-write(:39) — staysenforced. The shared proof is not vacuous for it: since [security] A by-id write is not gated by record visibility — a contributor mutates records they cannot read, when only select-scope RLS is authored #7665 / merged PR fix(plugin-security): require by-id write targets to be within the caller's readable set under select-only RLS #7792,rls-fixture.dogfood.test.ts:107–172carries a dedicated select-only block whose member set grants full CRUD onrls_note, so its refusals are the record gate, and it asserts the by-id PATCH refused with the row unchanged plus that an in-scope write still lands.controlled-by-parent(:48) — staysenforced, on its own evidence as instructed.fixtures/cbp-fixture.tsgrants the member full CRUD on both objects; the proof asserts derived read denial, derived by-id write denial with admin ground truth, and that it is not over-blocking.Since nothing was downgraded, the showcase
permission-sets.tscomment is accurate as shipped and is left alone.One real record correction did come out of it:
rls-by-id-write'senforcementnamed only the pre-image re-read, which the ablation proves is a no-op on its own under select-only authoring. The row now names both halves.stateandcoversuntouched on both rows.Two out-of-scope findings filed unassigned: #7976 (the ledger checks only that a cited proof file exists, never that it proves the row — the mechanism behind this card's premise) and #7978 (the probe still cannot reach narrowing authored on a position it does not hold).
Generated by Claude Code