Uh oh!
There was an error while loading. Please reload this page.
Retire the allowRestore / allowPurge columns from the metadata-admin permission matrix - #6607
Merged
os-sales merged 2 commits intoAug 27, 2026
Conversation
…sion columns Both keys gated `restore` / `purge` ObjectQL operations that have never existed — a dispatched restore/purge is denied unconditionally by the evaluator's fail-closed destructive-operation backstop — so the two matrix checkboxes were dead-end authoring surface: every tick wrote a grant no runtime has ever read. `@objectstack/spec` retired both keys as `retiredKey()` tombstones (objectstack#12497; maintainer ruling 2026-08-26 accepting objectstack#1883 recommendation B, ADR-0049 enforce-or-remove). Removed: the two authoring columns, the two typed fields, the two preview rows, the now-unreachable "Purge (hard delete) granted without Delete" lint, and the two column tooltips in both locale tables. `allowTransfer` is enforced upstream and is untouched. A value stored by an older editor is not modelled and not authorable; it rides through save untouched, as any key this editor does not model does. The installed spec (17.2.0) still ACCEPTS both keys at permission parse, so stripping stored values today would delete data the schema still honours — strip-on-load belongs with the bump that lands the retirement. The return path is named in every tombstone: both keys come back with the M2 lifecycle initiative, whose restart is recorded on objectstack#1883. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CRJge11jso9TpXRWFt1Z49
…ment Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CRJge11jso9TpXRWFt1Z49
Contributor
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
This was referenced Aug 27, 2026
os-sales
marked this pull request as ready for review
August 27, 2026 13:18
This was referenced Aug 27, 2026
Uh oh!
There was an error while loading. Please reload this page.
os-sales
deleted the
claude/issue-6595-retire-allowrestore-allowpurge-columns
branch
August 27, 2026 13:30
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.
Fixes#6595
Drops the two retired object-permission bits from the metadata-admin permission matrix: the authoring columns, the typed fields, the preview rows, and the now-unreachable "Purge (hard delete) granted without Delete" lint.
allowTransferis enforced upstream (objectstack#3004) and is untouched — it stays a column, and every pin below asserts that in the same render so the removals cannot pass for the wrong reason.Both removed keys gated
restore/purgeObjectQL operations that have never existed: a dispatched restore/purge is denied unconditionally by the evaluator's fail-closed destructive-operation backstop. Every tick of those checkboxes wrote a grant no runtime has ever read.@objectstack/specretired both asretiredKey()tombstones (objectstack#12497; maintainer ruling 2026-08-26 accepting objectstack#1883 recommendation B, ADR-0049 enforce-or-remove).The return path is named at every site the removal touched —
permission-slice.ts,PermissionMatrixEditor.tsx,previews/PermissionPreview.tsx, and both new pins: the keys come back with the M2 lifecycle initiative, whose restart is recorded upstream on objectstack#1883.The one thing measured on the day: the installed spec's posture
The card's premise splits into a part that is true either way and a part that depends on a bump that has not arrived. Measured 2026-08-27 against the installed
@objectstack/spec17.2.0, by running realObjectPermissionSchema.safeParsecalls with a control key:The control is what makes this falsifiable: the schema IS strict and DOES refuse unknown keys, and it still accepts both retired keys.
permission.zod-Bwl7_K0U.d.tsagrees at the type level (allowRestore: z.ZodDefault(z.ZodBoolean)).So the bump has not reached this repo, and this PR does what that implies:
indexed. The pin recording today's posture says so in its own header, so the bump PR replaces it deliberately rather than deleting a red.The card's line references were stale, and its site list was incomplete
Line numbers were re-derived by name rather than trusted. The three constructs the card named were all real (at 180-181, 27-28, 59-60/86 — unchanged). But a fourth site reads these keys and the card did not list it:
packages/app-shell/src/views/metadata-admin/i18n.tscarries the two column tooltips in both locale tables —perm.action.restore/perm.action.purgeinENGINE_STRINGS_ENandENGINE_STRINGS_ZH. Removing the columns without them would have left four dead keys in a pack whose EN/ZH halves must stay in step. Removed in both locales; the pack is theengine.*carve-out, so no pack gate reaches it either way.Three prose sites were also carrying the removed columns as fact and are corrected: the editor's header comment (
lifecycle (Transfer / Restore / Purge)), the column-legend note (Tr/Re/Pu/VA/MA), the fixed-column count (object + 9 CRUD + bulk, now 7 — themin-wfloor is deliberately unchanged, so the grid simply has more room), and the preview's capability list plus its two legend lines.Tests
Two new pin files,
PermissionMatrixEditor.retiredLifecycleKeys.test.tsxandpreviews/PermissionPreview.retiredLifecycleKeys.test.tsx, following the shapePermissionAdvancedFacets.retiredKeys.test.tsxset for the RLSprioritytombstone: pin the key SET, not the absence of two keys, because a set assertion is what stops a retired key drifting back in beside a live one. They cover the column set, the checkbox surface, what reaches the wire (the "Grant all" seed, whose key set is the real product of this change), the dropped lint measured on a draft that still trips the lints that stayed, and the carry-through of a stored legacy value.Reverse verification — direction predicted before running: RED. Restoring the two columns, the two preview rows and the lint on top of the committed fix turns all 7 new pins red (
Test Files 2 failed (2) · Tests 7 failed (7)); every one of them fails, so none was passing for an unrelated reason. Mutation confirmed on disk by anchored grep counts (short: 'Re'=1,long: 'Purge'=1, purge-lint=1) plus blob hashes differing from the HEAD blobs — not a bare diffstat. Restore leg proven the same way:git hash-objectreproduces both HEAD blobs byte-for-byte andgit diff HEADis empty. No rebuild leg applies — both pins import their subject by relative source path (./PermissionMatrixEditor,./PermissionPreview), so nodist/sits in the resolution path.Union re-run after the final commit, at
005a792:Test Files 19 passed (19) · Tests 90 passed (90)@object-ui/app-shelltype-checktsc --noEmitandtsc -p tsconfig.test.jsoncheck-changeset-presence✅ 6 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s)check:control-bytes✅ check-control-bytes: OK (scanned 5455 tracked text file(s); skipped 85 binary)check:i18n-keyscheck:i18n-driftNo en value changed in this rangecheck:i18n-dead-keysThe type-check claim is measured, not assumed:
tsc -p tsconfig.test.json --listFileslists both new test files, so the green covers them rather than excluding them.Lint was narrowed deliberately, and here is why the narrowing loses nothing.
eslint --no-inline-config --format jsonover the 6 changed files reportserrorCount 0(27 warnings, all pre-existing patterns;--max-warningsis deliberately unset repo-wide, perlint.yml's own note). The population is read from eslint's own resolution — it returned exactly 6 result objects, so all 6 are in scope and none was ignored. And the invariance holds by construction:eslint.config.jsenables no type-aware linting (noproject/projectService/parserOptions.project), so a file's verdict depends only on its own contents and the config — this diff cannot move the verdict on any file it does not touch. CI runs the repo-widepnpm lintregardless.Out-of-scope findings, filed rather than fixed here
allowExport,readScopeandwriteScope, which the localObjectPermdoes not model. The sharpest shape: clicking All can widen effective read access by deleting areadScope: ownnarrowing. Different defect class from this card (those keys are live and enforced), so it is not touched here.PAYLOAD_SHAPESincheck-designer-field-key-parity.mjs, so the very class this card instantiates is invisible to that gate on the permission surface. This card arrived as a hand-written upstream referral, not from CI.Neither is addressed in this PR; both remain open.
Fence
Every edit is inside
packages/app-shell/src/views/metadata-admin/plus one.changeset/file. Nothing understudio-design/was read for edit or touched — the sibling round's region is untouched.Generated by Claude Code