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
Setup: position holders and permission-set assignment as people-and-organization pages #28241
Filing gate: ④ child of epic #28236, carried over from ADR-0146 D7 / #28130 phase 3b (ruled before the re-plan, unaffected by it). ⛔ Not a claim.
Part of #28236 (P0, child N-27) · lane: domain:ui · size: M.
Business reason. Assigning people is an administrator's daily work, but today it lives inside metadata item pages: a position's holders inside the position's page, a permission set's users at the bottom of the permission matrix. When the metadata catalog moves to Studio (N-26), administrators would lose these unless they have Setup pages of their own; an administrator should not need Studio to add a holder.
Measured at d6c0a75f1a: views/metadata-admin/PositionHoldersSection.tsx renders inside the position item page; AssignedUsersSection.tsx renders under the matrix in PermissionMatrixEditor.tsx (~line 2469, Setup only — the Studio-embedded designer hides it).
Wanted.
Setup → People & organization: a Position holders page (pick a position, list/add/remove holders) built from PositionHoldersSection.
Setup → People & organization: a Permission-set assignment page (pick a set, list/assign/unassign users) built from AssignedUsersSection.
Gated by setup.access and the delegated-administrator scope, as the sections are today; the sections inside the item pages keep working until N-28 retires those routes.
Tests: both pages reachable from Setup nav; add/remove round-trips; a delegated admin outside scope refused verbatim.
Not here. Queue membership (ADR-0142 D2); moving the catalog (N-26); retiring routes (N-28).
Dedupe.position holders Setup page open+closed: 50 hits (#25909, #24757, #25333 closed are column/visibility fixes); permission set assignment Setup page: 77 hits (#24775, #26191 closed, different surfaces). None adds the standalone pages.
Claim: PM loop round 4 · 2026-10-31T02:45Z
Session: session_01L9qibz8HEj53Wx2uphTo2o (seat; implementation by card thread session session_01L9qibvdtrVLjcNWmcBoHnP, mode:thread)
Account: os-tesla (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/project-thread-hr3zwc (the card thread's designated push branch, the recorded platform exception to claude/issue-<n>-<slug>)
Worktree: objectstack-issue-28241
Domain: domain:ui
Seat: domain:ui#3
File surface: new Setup page files under ui/packages/app-shell/src/views/setup/** (or Setup's page folder), their routes, imports of PositionHoldersSection / AssignedUsersSection (not moved), i18n keys, tests, .changeset/28241-*.md (stop on breach; explain in the report)
Container & model: M, mode:thread, model: default (dispatch-gates --tier re-run on the actual diff), effort: high
Clause-②: no (expected; re-judged on the diff)
Metadata-protocol: none
Responsibility: the pages are ours (ui); if Setup's nav is server metadata, the nav entries become a carried finding
Thread-read: none
Premise: per the card's measurement; the dev re-measures on current main before code
Serial constraints cleared: seat-3 siblings #28239#28240#28241#28179#28164 hold declared regions of shared files (FRAME.md); #28148 (paused) holds views/setup/PackagedAutomationPage.tsx + packagedFlowLedger.ts
Maintainer 2026-10-31 「ui 车道一堆任务啊,应该并发开满啊」. Order: /mnt/project-files/ui-seat-3/r2026-10-31/dispatch-28241.md under FRAME.md.
{
"issue": 28241,
"status": "done",
"branch": "claude/project-thread-hr3zwc",
"pr": "https://github.com/objectstack-ai/objectstack/pull/28310",
"session": "session_01L9qibvdtrVLjcNWmcBoHnP",
"premise_still_valid": true,
"summary": "Two Setup component pages, security:position-holders and security:permission-set-assignment, registered in builtinComponents.tsx: pick a registry position or permission set (URL ?position= / ?set=), then manage holders through the imported PositionHoldersSection / AssignedUsersSection, unmoved. A failed catalog read is drawn as a failure with retry, never as an empty list. Setup nav is server metadata (plugin-security navigationContributions), so the two nav entries are carried as a finding and the PR says Part of #28241.",
"tests": "head eab3e80a: pnpm --dir ui exec vitest run packages/i18n/ packages/app-shell/src/views/setup/ -> 105 files, 1577 passed, 13 skipped, exit 0; scripts/__tests__/check-i18n-call-site-keys + check-i18n-dead-keys + views/setup -> 14 files, 427 passed; controls ResourceEditPage.setupCatalog-7611, PermissionMatrixEditor.setupCatalog-7611, PositionHoldersSection*, AssignedUsersSection*, setupHoldersGrant-12082 green (119 files, 1691 passed before the de pin fix); type-check @object-ui/i18n + @object-ui/app-shell exit 0. Ablation via scripts/ablation-replace.mjs (src read directly by vitest, no dist): deleting the getTypeStatus error branch in CatalogAssignmentPage.tsx -> 1 failed (the read-failure test), 7 passed; restored blob == HEAD, git diff HEAD empty.",
"gates": "dispatch-gates --commands on eab3e80a: 34 lines, each run with stdin from /dev/null, all :: exit 0 (incl. pnpm --dir ui exec vitest run scripts/ -> 169 files passed, 2 skipped, and node scripts/check-sdui-manifest.mjs exit 0); --ran reconciliation: 34 derived, 34 run, 0 NOT-MEASURED, 0 UNRUN. Extra: pnpm --dir ui check:new-line-citations -> 0 new, exit 0. First sweep on e5d1abbc red pnpm --dir ui exec vitest run scripts/ (check-i18n-call-site-keys / dead-keys: templated key builder) -> fixed by literal keys, re-run green. PR check-runs: in_progress at report time.",
"line_budget": "21 files, +1140 / -3 (under the 3,000 line class)",
"files_changed": [
".changeset/28241-setup-people-assignment-pages.md",
"ui/packages/app-shell/src/services/builtinComponents.tsx",
"ui/packages/app-shell/src/views/setup/CatalogAssignmentPage.tsx",
"ui/packages/app-shell/src/views/setup/PositionHoldersPage.tsx",
"ui/packages/app-shell/src/views/setup/PermissionSetAssignmentPage.tsx",
"ui/packages/app-shell/src/views/setup/peopleAssignments.ts",
"ui/packages/app-shell/src/views/setup/PositionHoldersPage.test.tsx",
"ui/packages/app-shell/src/views/setup/PermissionSetAssignmentPage.test.tsx",
"ui/packages/app-shell/src/views/setup/peopleAssignments.navContribution.test.tsx",
"ui/packages/app-shell/src/views/setup/peopleAssignments.test.ts",
"ui/packages/i18n/src/__tests__/de-quote-pairing-3876.test.ts",
"ui/packages/i18n/src/locales/{ar,de,en,es,fr,ja,ko,pt,ru,zh}.ts"
],
"deviations": [
"builtinComponents.tsx (shared registration module, not named in the FRAME's owner list) gained two imports and two registerAppComponent blocks; no sibling region touched.",
"de-quote-pairing-3876.test.ts pinned count 101 -> 102 (one new correctly paired span from setupAssignments.notFound), with its ledger comment line; outside the declared file surface but forced by the de pack key.",
"The dependency closure was built once (turbo build --filter=@object-ui/app-shell^..., 64 tasks) before tests; no build of the diff's own packages was needed for vitest (src aliasing)."
],
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
"mcp_calls": "4 — mcp__github__issue_read x4 (get #28241, get_comments #28241 x2, get #28236); 0 write tools",
"api_writes": "2 — relay pr_create (POST dispatch, run 41167577691 -> #28310) and this os-dev-report comment via post-stamped",
"open_questions": [],
"out_of_scope_findings": [
"carrier: ui seat 3 (domain:server) · the two Setup nav entries: packages/plugins/plugin-security/src/security-plugin.ts navigationContributions gains a group_people_org contribution with { type: 'component', componentRef: 'security:position-holders' } and { type: 'component', componentRef: 'security:permission-set-assignment' }; without it the pages open only by URL and #28241 item 4 'both pages reachable from Setup nav' stays open · dedupe words: Setup people organization nav position holders, permission set assignment nav entry, group_people_org component entry"
]
}
Nothing in this card remains. Per the landing note 6539442400, the card closes once #28316 lands, and it has. State: pm:dispatched removed. ui seat 3 is signing off (maintainer 2026-10-31T09:43Z 「UI 车道下班」).
Activity
objectstack-fleet commentedon Oct 31, 2026
domain:ui#3 · os-tesla · session_01L9qibz8HEj53Wx2uphTo2o
Claim: PM loop round 4 · 2026-10-31T02:45Z
Session:
session_01L9qibz8HEj53Wx2uphTo2o(seat; implementation by card thread sessionsession_01L9qibvdtrVLjcNWmcBoHnP,mode:thread)Account:
os-tesla(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/project-thread-hr3zwc(the card thread's designated push branch, the recorded platform exception toclaude/issue-<n>-<slug>)Worktree:
objectstack-issue-28241Domain:
domain:uiSeat:
domain:ui#3File surface: new Setup page files under
ui/packages/app-shell/src/views/setup/**(or Setup's page folder), their routes, imports ofPositionHoldersSection/AssignedUsersSection(not moved), i18n keys, tests,.changeset/28241-*.md(stop on breach; explain in the report)Container & model:
M,mode:thread,model: default(dispatch-gates --tierre-run on the actual diff),effort: highClause-②: no (expected; re-judged on the diff)
Metadata-protocol: none
Responsibility: the pages are ours (ui); if Setup's nav is server metadata, the nav entries become a carried finding
Thread-read: none
Premise: per the card's measurement; the dev re-measures on current
mainbefore codeSerial constraints cleared: seat-3 siblings #28239 #28240 #28241 #28179 #28164 hold declared regions of shared files (FRAME.md); #28148 (paused) holds
views/setup/PackagedAutomationPage.tsx+packagedFlowLedger.tsMaintainer 2026-10-31 「ui 车道一堆任务啊,应该并发开满啊」. Order:
/mnt/project-files/ui-seat-3/r2026-10-31/dispatch-28241.mdunderFRAME.md.objectstack-fleet commentedon Oct 31, 2026
domain:ui#3 · os-tesla · session_01L9qibvdtrVLjcNWmcBoHnP
os-dev-report
{ "issue": 28241, "status": "done", "branch": "claude/project-thread-hr3zwc", "pr": "https://github.com/objectstack-ai/objectstack/pull/28310", "session": "session_01L9qibvdtrVLjcNWmcBoHnP", "premise_still_valid": true, "summary": "Two Setup component pages, security:position-holders and security:permission-set-assignment, registered in builtinComponents.tsx: pick a registry position or permission set (URL ?position= / ?set=), then manage holders through the imported PositionHoldersSection / AssignedUsersSection, unmoved. A failed catalog read is drawn as a failure with retry, never as an empty list. Setup nav is server metadata (plugin-security navigationContributions), so the two nav entries are carried as a finding and the PR says Part of #28241.", "tests": "head eab3e80a: pnpm --dir ui exec vitest run packages/i18n/ packages/app-shell/src/views/setup/ -> 105 files, 1577 passed, 13 skipped, exit 0; scripts/__tests__/check-i18n-call-site-keys + check-i18n-dead-keys + views/setup -> 14 files, 427 passed; controls ResourceEditPage.setupCatalog-7611, PermissionMatrixEditor.setupCatalog-7611, PositionHoldersSection*, AssignedUsersSection*, setupHoldersGrant-12082 green (119 files, 1691 passed before the de pin fix); type-check @object-ui/i18n + @object-ui/app-shell exit 0. Ablation via scripts/ablation-replace.mjs (src read directly by vitest, no dist): deleting the getTypeStatus error branch in CatalogAssignmentPage.tsx -> 1 failed (the read-failure test), 7 passed; restored blob == HEAD, git diff HEAD empty.", "gates": "dispatch-gates --commands on eab3e80a: 34 lines, each run with stdin from /dev/null, all :: exit 0 (incl. pnpm --dir ui exec vitest run scripts/ -> 169 files passed, 2 skipped, and node scripts/check-sdui-manifest.mjs exit 0); --ran reconciliation: 34 derived, 34 run, 0 NOT-MEASURED, 0 UNRUN. Extra: pnpm --dir ui check:new-line-citations -> 0 new, exit 0. First sweep on e5d1abbc red pnpm --dir ui exec vitest run scripts/ (check-i18n-call-site-keys / dead-keys: templated key builder) -> fixed by literal keys, re-run green. PR check-runs: in_progress at report time.", "line_budget": "21 files, +1140 / -3 (under the 3,000 line class)", "files_changed": [ ".changeset/28241-setup-people-assignment-pages.md", "ui/packages/app-shell/src/services/builtinComponents.tsx", "ui/packages/app-shell/src/views/setup/CatalogAssignmentPage.tsx", "ui/packages/app-shell/src/views/setup/PositionHoldersPage.tsx", "ui/packages/app-shell/src/views/setup/PermissionSetAssignmentPage.tsx", "ui/packages/app-shell/src/views/setup/peopleAssignments.ts", "ui/packages/app-shell/src/views/setup/PositionHoldersPage.test.tsx", "ui/packages/app-shell/src/views/setup/PermissionSetAssignmentPage.test.tsx", "ui/packages/app-shell/src/views/setup/peopleAssignments.navContribution.test.tsx", "ui/packages/app-shell/src/views/setup/peopleAssignments.test.ts", "ui/packages/i18n/src/__tests__/de-quote-pairing-3876.test.ts", "ui/packages/i18n/src/locales/{ar,de,en,es,fr,ja,ko,pt,ru,zh}.ts" ], "deviations": [ "builtinComponents.tsx (shared registration module, not named in the FRAME's owner list) gained two imports and two registerAppComponent blocks; no sibling region touched.", "de-quote-pairing-3876.test.ts pinned count 101 -> 102 (one new correctly paired span from setupAssignments.notFound), with its ledger comment line; outside the declared file surface but forced by the de pack key.", "The dependency closure was built once (turbo build --filter=@object-ui/app-shell^..., 64 tasks) before tests; no build of the diff's own packages was needed for vitest (src aliasing)." ], "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm", "mcp_calls": "4 — mcp__github__issue_read x4 (get #28241, get_comments #28241 x2, get #28236); 0 write tools", "api_writes": "2 — relay pr_create (POST dispatch, run 41167577691 -> #28310) and this os-dev-report comment via post-stamped", "open_questions": [], "out_of_scope_findings": [ "carrier: ui seat 3 (domain:server) · the two Setup nav entries: packages/plugins/plugin-security/src/security-plugin.ts navigationContributions gains a group_people_org contribution with { type: 'component', componentRef: 'security:position-holders' } and { type: 'component', componentRef: 'security:permission-set-assignment' }; without it the pages open only by URL and #28241 item 4 'both pages reachable from Setup nav' stays open · dedupe words: Setup people organization nav position holders, permission set assignment nav entry, group_people_org component entry" ] }objectstack-fleet commentedon Oct 31, 2026
domain:ui#3 · os-tesla · session_01L9qibz8HEj53Wx2uphTo2o
Landed · 2026-10-31T05:13Z
501c864dd5(ACCEPT 6539017329)domain:serveras #28316; this card closes when that landsobjectstack-fleet commentedon Oct 31, 2026
domain:ui#3 · os-tesla · session_01L9qibz8HEj53Wx2uphTo2o
Closed
completed· 2026-10-31T09:52Z501c864dd5(ACCEPT 6539017329)domain:server)completed2026-10-31T06:07Z via PR #28332Nothing in this card remains. Per the landing note 6539442400, the card closes once #28316 lands, and it has. State:
pm:dispatchedremoved. ui seat 3 is signing off (maintainer 2026-10-31T09:43Z 「UI 车道下班」).