Uh oh!
There was an error while loading. Please reload this page.
fix(app-shell): stop authoring the retired rowLevelSecurity[].priority key in the Studio RLS editor (objectstack#7130) - #4057
Merged
Conversation
…y key (objectstack#7130) `rowLevelSecurity[].priority` is a retiredKey tombstone in @objectstack/spec 17.0.0 (objectstack#3896) — authored values are REJECTED at parse time with the upgrade prescription. PermissionAdvancedFacets still typed the key and seeded `priority: 0` on every policy its Add button created, and nothing on the save path stripped it, so a permission set saved after using the structured RLS editor carried a parse-rejected key. - drop `priority` from the local `RlsPolicy` shape and from the Add-policy seed - strip the retired key as policies are read out of the draft, so an edit-and-save round-trip of an already-poisoned policy comes out clean (editor hygiene, not a data migration) - re-anchor the docblock, which described the shapes as sampled from live data Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016R9de1FqP7NvwKvqXi92Gh
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
os-help
marked this pull request as ready for review
August 10, 2026 02:42
Uh oh!
There was an error while loading. Please reload this page.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixesobjectstack-ai/objectstack#7130
rowLevelSecurity[].prioritywas removed in@objectstack/spec17.0.0 (objectstack#3896) and left as aretiredKeytombstone, so an authored value is rejected at parse time with the upgrade prescription rather than ignored. The Studio structured RLS editor was still authoring it:PermissionAdvancedFacetstyped the key and seededpriority: 0on every policy its "Add policy" button created. Per the objectstack#7130 ruling, only the objectui producer changes here — the spec/ledger side is already executed and correct, and no objectstack file is touched.Premise re-verified at objectui
origin/main@11c1e71e8The card's three sites are all present, unchanged (the file's last touch is #3779, long merged):
:38docblock — "Shapes mirror the framework spec (sampled from live data): RLS policies{name,object,operation,using,check,enabled,priority}":49—priority?: number;on the localRlsPolicyinterface:368—{ name: '', object: '*', operation: 'all', using: '', enabled: true, priority: 0 }Zero-hit census re-run and falsified in both directions:
grep -n priorityon the file yields exactly those three lines; the known-present neighbourenabledyields 6 hits on the same file, andgrep -n prioradds nothing (no cross-line concatenation hiding a fourth site). Repo-wide, every otherpriorityin objectui belongs to a live key on a different surface (validation rules, hooks, kanban) — no other file types or produces an RLS policy shape.Spec side re-read at objectstack
origin/main:packages/spec/src/security/rls.zod.ts:432is theretiredKey(...)call, and:219records the deliberate exclusion ofpriorityfrom the alias suggestion pool.The unmeasured half the filer flagged: there is NO save-path scrub
Measured end to end; the answer is that nothing strips the key.
PermissionAdvancedFacets.tsx:161loads policies withasArray(draft.rowLevelSecurity)— verbatim, no normalization.next[i] = { ...pol, name: e.target.value }), so a storedpriorityis carried back out verbatim on any edit.PermissionMatrixEditor.tsx:546doSavesendspayload(the draft) straight toclient.save; the only transform is package scope'smergePermissionSlice.permission-slice.ts:94mergePermissionSlicereturns{ ...base, name, label, isDefault, objects, fields }— it takes onlyobjects/fieldsfrom the edit and copiesrowLevelSecurityfrom the freshly-read base.So at environment scope — the only scope where these facets are persisted (the docblock and
PermissionMatrixEditor.tsx:754both say "persisted by the whole-record Save at env scope") — the seededpriority: 0goes into the saved permission set unmodified. The severity in the card stands as filed: this is a live producer of a parse-rejected key, not a seeded-then-scrubbed field.Round-trip behaviour of an already-poisoned stored policy, before this PR: loaded verbatim, spread verbatim on every edit, re-persisted verbatim — the poison stays alive indefinitely.
The fix (editor-side only, no data migration)
prioritydropped from the localRlsPolicyinterface.priority: 0dropped from the Add-policy seed — it now authors exactly{name,object,operation,using,enabled}.RETIRED_RLS_KEYS+stripRetiredRlsKeys).policiesis the single value every write path spreads from, so an edit-and-save round-trip of a policy already carrying the key now comes out clean — which is what the dispatch ruling asked for. This is deliberately not a migration: a set nobody opens is untouched, nothing rewrites the draft on mount (that would fake an unsaved-changes state on open), and the strip is keyed to the named tombstone rather than being a blanket unknown-key purge, so live keys the editor does not itself render (e.g.positions,tags) survive a round-trip.Verification
Build closure first (fresh worktree), then the targeted gates:
eslinton the two touched files reports 0 errors and 3 warnings, all on pre-existing lines (:164propsany,:233set-state-in-effect).Reverse verification — direction predicted, then measured
Prediction: restoring the pre-fix component should turn all three new pins red — the seed pin because the key set gains a member, the two round-trip pins because the strip is gone. Took the fix out with
git checkout origin/main -- PermissionAdvancedFacets.tsx(nevergit stash), re-ran the new file, then reapplied from a patch:Red in the predicted direction, on all three. The third pin also carries a falsification assertion in the positive direction (
check/using/enabledsurvive the strip), so the pins cannot pass by emitting nothing.Scope
No objectstack edits. No data migration. Disjoint from objectstack#7129 (
packages/plugin-dashboard); at PR time the only other open objectui PR is the release PR #3598, and nothing in flight touches this file.Generated by Claude Code