Repository navigation
fix(plugin-security): Everyone and Guest position descriptions read as admin copy - #23987
Merged
objectstack-fleet[bot] merged 2 commits intoOct 16, 2026
Merged
Conversation
…s admin copy The two audience anchors' descriptions drop their design-record ids; the references stay in the docblock above AUDIENCE_ANCHOR_METADATA. The admin-copy vocabulary pin now judges every built-in position, and the boot test's existing-database scenarios pin that the catalog read answers the declared text while the rows a retired seeder wrote keep theirs. Claude-Session: https://claude.ai/code/session_018VqJPGA1NDNSCZsnecsChP Co-authored-by: Claude <noreply@anthropic.com>
…iltin-position-copy
Contributor
📓 Docs Drift CheckNothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)), so this run has no opinion about the docs. What this run could not see
Coarse fallback — 15 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
Contributor
Author
席位核对 · ACCEPT ·
|
objectstack-fleet
Bot
deleted the
claude/issue-23919-builtin-position-copy
branch
October 16, 2026 17:21
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 free
to 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 #23919
Clause-②: no
What changed
Setup's Positions page (
/apps/setup/metadata/position) lists each built-in position with itsdescription. The two audience anchors' descriptions carried design-record ids; they now read as plain admin copy. The docblock aboveAUDIENCE_ANCHOR_METADATA(packages/plugins/plugin-security/src/builtin-positions.ts), which already cited ADR-0090 D5/D9, now ties each id to the sentence it governs. Wording only: names, labels, bindings and the boot path are unchanged.everyoneguestThe first read: what the boot path does with a stored built-in row whose description differs
Read at
origin/main68ffa5dc1a, before any edit.sys_positionrow: the built-in and declared position seeders are retired (builtin-positions.tsmodule doc, lines 16-19; ADR-0131 D2, C3 stage 6a).builtin-positions.boot.test.tsalready pins this in its three existing-database scenarios: the census equalsLEGACY_ROWSand the write ledger is empty (the case "writes no sys_position row, and leaves an existing database's rows as they were").os migrate).packages/cli/src/utils/organization-ownership-inventory.tsgivessys_positionfate 2, mirror deletion, with theSEEDEDselector (managed_byin package / platform / system). OnlyAUTHOREDrows are converted to definitions, so a platform-managed built-in row is deleted, and it is never converted or compared.sys_positionrow object any more (C3 stage 8; header ofsrc/__tests__/legacy-catalog-objects.testkit.ts). The Positions nav item is/apps/setup/metadata/position?scope=environment(security-plugin.ts:1587). That is the metadata door, and it lists the declarations. The only runtime read of asys_positionrow,idSpellingHintsinposition-catalog-refusal.ts, reads only the row'sname.So an upgraded tenant's administrator sees the declaration's text, the same as on a fresh install. The stored text is leftover data that nothing reads, and
os migratedeletes it. The claim's stop branch assumed that existing tenants would keep the ADR ids if the boot kept the stored text. Read 3 shows that assumption is false, so this PR changes the declaration only and leaves the boot path untouched. A boot-time refresh of these rows would add asys_positionwrite that ADR-0131 C3 stage 6a retired, and nobody would see the result. The only precedent that refreshed platform-managed rows from code,os meta resync, was deleted in9e9e6f97fc.Pins
src/objects/admin-copy-vocabulary.test.ts(from the family's precedent, PR fix(setup-copy): approval, security, automation and sharing descriptions read as admin copy; ADR numbers move to comments #23917) addssecurityBuiltinPositionsto its population. The label and description of all six built-in positions are judged, and the population is pinned to includeeveryone,guest,platform_adminandorg_admin.src/builtin-positions.boot.test.tsadds one case to each existing-database scenario (single,single + organization,walled). Foreveryoneandguestit asserts three things: the stored row's text (LEGACY_ROWS, unchanged) differs from the declaration; the census row still holds that stored text; and the security catalog read answers the declaration's text. TheLEGACY_ROWSdocblock now says that the anchors' stored text is older than their declarations.Verification
The implementation commit is
bebfe4cf6a. The final headd3a4d92391mergesorigin/main2054a0888cinto it. None of the four incoming commits touches plugin-security, its dependencies, orpackages/specsource.pnpm --filter '@objectstack/plugin-security^...' build(the upstream dependency closure) — exit 0. After the merge,turbo run build --filter=!@objectstack/docs— 75/75 tasks, exit 0.pnpm --filter @objectstack/plugin-security exec vitest run --maxWorkers=2 src/objects/admin-copy-vocabulary.test.ts src/builtin-positions.boot.test.ts: 2 files, 63 passed. That is 55 boot cases (12 scenarios, 3 of them new existing-database cases) plus 8 vocabulary cases (1 new). Re-run ond3a4d92391together withbuiltin-positions.test.tsandbuiltin-positions.declaration-phase.test.ts: 4 files, 73 passed.pnpm --filter @objectstack/plugin-security test(atbebfe4cf6a): 188 files passed; 3736 passed, 45 skipped.pnpm --filter @objectstack/plugin-security typecheck: exit 0 (tsc --noEmit, the scripts project, andcheck:test-typecheckovertsconfig.test.json: 0 errors).scripts/ablation-replace.mjs, on the committed tree): I put(ADR-0090 D9)back into theguestdeclaration. Anchornever a wildcard.',went x1 to x0, and the blob went9a36e5037bb6to1e2122e49ffb. Result: 4 failed, 59 passed. The vocabulary case failed onguest.description (an ADR number, a decision id), and all three new existing-database cases failed. Restore: blob9a36e5037bb6== HEAD, andgit diff HEADis empty. The test imports the module fromsrc, so nodist/leg was needed.pnpm check:i18nexit 0. plugin-security has 7 bundles, all in sync, and nothing to regenerate: the bundles hold object copy, and position descriptions never reach them.d3a4d92391, after the build:node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 65 commands for this diff, the same list as atbebfe4cf6a. All 65 exited 0, with each exit captured before any pipe.--ran: 65 derived, 65 run, 0 NOT-MEASURED, 0 UNRUN. On the first run atbebfe4cf6a,check:i18nandcheck:dual-build-cjs-loadsanswered exit 3 (PREREQUISITE NOT MET: nodist/) until the build had run.test:repo, the dogfood shards, and the workspace type-check lanes.Acceptance notes
everyone/guestrows keep the older text untilos migratedeletes them as seeded mirrors. This PR does not touch those rows.BUILTIN_IDENTITY_METADATAin@objectstack/spec. They carry no design-record vocabulary today, and the new population case now guards them too.Generated by Claude Code