Skip to content

fix(app-shell): the delegated-admin scope facet shows the spec default for an unset key - #26990

Merged
objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/issue-26706-delegated-admin-scope-display
Oct 28, 2026
Merged

objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/issue-26706-delegated-admin-scope-display

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #26706

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:Studio › Access › 权限集 › 委派管理(Delegated admin)里的开关,对范围里没有设置的键显示协议(AdminScopeSchema)的默认值;管理员切换开关时才写入显式的布尔值。
  • 为什么改:委派管理是大客户安全下放管理权的方式,屏幕上显示的委派范围必须和服务端实际执行的一致,管理员才能正确判断自己授出了什么。
  • 风险与回滚:只改前端显示,不改存储数据、保存载荷和服务端校验;回滚即 revert 本 PR。
  • 先看:PermissionAdvancedFacets.tsx 的 ADMIN_SCOPE_SWITCH_DEFAULTS 与 scopeSwitchOn(风险 hunk:两个 Switch 的 checked);新测试 PermissionAdvancedFacets.adminScopeDefault-26706.test.tsx;PermissionAdvancedFacets.adminScopeAnchor.test.tsx 里两处期望值的更新。
  • 两分钟验证:pnpm --dir ui exec vitest run packages/app-shell/src/views/metadata-admin/PermissionAdvancedFacets.adminScopeDefault-26706.test.tsx(先 build @objectstack/spec),预期 Tests 6 passed (6)。
  • 需要你做的:无,席位落地。

What changes

The delegated-admin scope facet shows the spec default for an unset key.

  • Each switch in the Delegated admin facet now draws scopeSwitchOn(scope, key): the scope's own boolean when it sets one, and otherwise the spec default for that key from ADMIN_SCOPE_SWITCH_DEFAULTS. That is the value AdminScopeSchema parses the key to and the value the server enforces.
  • Drawing a default writes nothing. The draft keeps an untouched key unset, so a save keeps it unset. A flip writes an explicit boolean, as before. The write paths (setScope / setScopeDetail) and the business-unit gate are unchanged.
  • The two defaults are restated, not imported, for the reason useTenancyPosture gives (the @objectstack/spec/security value entry adds its schema modules to the console bundle). They are typed against the spec's AdminScope, and the new test reads every expected value from the installed spec, so a default the spec moves fails CI here.
  • Landing site: ui/packages/app-shell/src/views/metadata-admin/PermissionAdvancedFacets.tsx, the site the card expected. A grep of ui/ for the two keys finds no other surface that draws them.

Tests

  • New PermissionAdvancedFacets.adminScopeDefault-26706.test.tsx, 6 cases: a CONTROL that the installed spec parses each unset switch key to a boolean default; an unset key draws the spec default (with a business unit, and while the switches wait for one); naming the business unit writes that key alone; a flip writes an explicit boolean and draws it, and flipping back keeps the key written; an explicit boolean draws as itself.
  • PermissionAdvancedFacets.adminScopeAnchor.test.tsx: two expectations updated. Each asserted the boolean a single flip writes from the drawn state, and that value follows what the switch draws.
  • Ablation, one time, through scripts/ablation-replace.mjs: one switch's checked reading was put back to its pre-change expression (anchor 1 to 0, replacement 0 to 1, blob cabc1416e0fd to c5282ce2ba31). Result: Tests 6 failed | 12 passed (18) across the two facet files, in the direction declared in advance (red). Restored: the blob equals HEAD and git diff HEAD is empty. The test imports the component by relative path, so the run read src/ and no dist/ leg applies. Run on 3592965f; the merge of main since then does not touch the facet or its tests.

Acceptance notes

  • None. No out-of-scope finding.

Verification

All readings below were taken on head 394213f2 (a merge of origin/main at f1cd529d).

Facet suites: 8 files, 113 tests, exit 0
pnpm --dir ui exec vitest run --maxWorkers=2 (the 7 PermissionAdvancedFacets.*.test.tsx files + src/__tests__/spec-symbol-parity.test.ts)
 Test Files  8 passed (8)
      Tests  113 passed (113)
Type check: @object-ui/app-shell type-check, exit 0

tsc --noEmit && tsc -p tsconfig.test.json. tsc -p tsconfig.test.json --listFilesOnly lists both changed test files, so the test-layer program compiles them.

Derived gate families: 34 of 34 run; 33 exit 0, one test run timed out under load and passed on re-run

node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths; change set from the merge base) derived 34 commands. Each ran with its exit code captured before any pipe.

  • 33 commands: exit 0.
  • pnpm --dir ui exec vitest run scripts/: exit 1, Tests 9 failed | 5056 passed | 2 skipped (5067). All 9 failures are Test timed out in 15000ms in whole-tree scans, on a shared box with the other gates running. The 6 files that timed out, re-run alone under the verify lock: Test Files 6 passed (6), Tests 522 passed (522), exit 0. The same command on 3592965f, before the merge of main, exited 0. This diff does not touch ui/scripts/.
  • --ran reconciliation: 34 derived famil(ies) accounted for — 34 run, 0 NOT-MEASURED (a DERIVED zero — all 34 recorded an exit code and none of them is 3).

Declared narrowing: origin/main moved again after the merge. The derivation names 6 gate-input files that changed upstream since 394213f2. CI runs those families on the merge ref of this PR.

Not run locally, and owned by CI: pnpm lint, the test:repo project, and the workspace type-check lanes.


Generated by Claude Code

…t for an unset key

Each switch in the delegated-admin scope facet draws the draft's own
boolean, or the spec default for a key the draft leaves unset; a flip
writes an explicit boolean, and drawing a default writes nothing.

Claude-Session: https://claude.ai/code/session_01J8VVAkZns5rNnK2rtszzbQ
Co-authored-by: Claude <noreply@anthropic.com>
…ult for an unset key

Claude-Session: https://claude.ai/code/session_01J8VVAkZns5rNnK2rtszzbQ
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

ACCEPT — PM review on head 394213f2 (session session_01J8VVAkZns5rNnK2rtszzbQ)

  • File surface: 4 files inside the claimed surface (the delegated-admin facet, its tests, a changeset). The write paths and the server are unchanged.
  • Disclosure: the title, body, commits and changeset describe only "the facet shows the spec default for an unset key".
  • Governed check: NOT governed (check-governed-merges.mjs --pr 26990).
  • CI on 394213f2: 53 check-runs, 0 failure, 0 pending.
  • Open follow-up: stored scopes are decided separately on [Decision] Delegated-admin scopes saved before the #26706 fix: leave as is, ask admins to re-check, or migrate (detail withheld pending maintainer) #26996 (needs-user-decision). This display-only PR does not depend on it.
  • Landing authority: maintainer, this session, 2026-10-28, verbatim: 「26878 合入;26990 绿了也合;委派范围立决策卡」

Landing: ready + auto-merge.


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface

Projects

None yet

2 participants