Skip to content

fix(app-shell): pair-added permission sets read Custom in the Studio Access header - #29835

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-qs4mew
Nov 3, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-qs4mew

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Steedos · project thread
Fixes #29809

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:Studio「权限」中,定制包(.custom)里的权限集(「新建类似」复制的,或在定制包里新建的)头部标签不再显示「包内置」,而是与左侧列表的「新增」一致,显示自定义标签。
  • 为什么改:管理员打开自己复制的权限集,头部却说它是包内置的,无法判断这是谁的权限集、升级包时会不会被覆盖。
  • 风险与回滚:只改头部标签选哪个词,判据取自左侧列表已用的定制标记(customizationMarks.ts),不新增读取;基础包自带的权限集、被定制的基础包权限集仍显示「包内置」;Setup 与元数据管理页不传标记,行为不变。回滚即还原本 PR。
  • 先看:PermissionMatrixEditor.tsx 的 shippedByPackage 一行;StudioDesignSurface.tsx 中 Access 宿主传入 customizationMark 的一行;StudioDesignSurface.accessPairCopy-29674.test.tsx 新增的三个用例。
  • 两分钟验证:cd ui && pnpm exec vitest run packages/app-shell/src/views/studio-design/StudioDesignSurface.accessPairCopy-29674.test.tsx -t 29809,应见 3 个用例通过(复制件、定制包新建件为自定义,基础包权限集为包内置)。
  • 需要你做的:无,席位落地。

What changes

  • The provenance rule (PermissionMatrixEditor.tsx): shippedByPackage was !!packageId || codeIsArtifact. The pair's package door supplies a packageId, so every set a base's .custom pair holds read "Package" in the Studio header while the rail marked the same row "Added". It is now customizationMark !== 'added' && (!!packageId || codeIsArtifact). Both badge sites (the page badge and the Studio header chip) still read that one value; no badge string, legend or key is touched.
  • The mark comes from the host (StudioDesignSurface.tsx, AccessPillar): a new optional page prop customizationMark (type CustomizationMarkKind from customizationMarks.ts). The pillar passes railMarks?.markOf(...) for the open set, the same call the rail row's RailCustomizationMark makes, so the rule is the one customizationMarks.ts holds (ADR-0146 D3) and is not derived a second time.
  • Unchanged: a set the read-only base ships still reads Package; a customized base set (a served override) still reads Package, since the base ships it; Setup's permission page and the metadata admin pass no mark.

Tests

  • StudioDesignSurface.accessPairCopy-29674.test.tsx, one new top-level describe in the existing real-client harness (real StudioDesignSurface, AccessPillar and PermissionMatrixEditPage over the real metadata client and a fetch stub; base read-only, pair writable):
    • a New similar copy in the pair: the header chip reads Custom and the rail row carries the added mark;
    • a set created in the pair (its draft only, listed from the pair's drafts): the same;
    • CONTROL: the base's own set reads Package and its rail row carries no mark.
  • StudioDesignSurface.accessTabs-12456.test.tsx (the Package pin for a package's own set) stays green, unchanged.
  • Ablations, each through scripts/ablation-replace.mjs with the on-disk proof and a proven restore to HEAD:
    • the rule back to !!packageId || codeIsArtifact: the two pair cases red, the control green;
    • the host passing customizationMark={null}: the two pair cases red, the control green.
Test runs (fix at 26d194d; re-run at the merged head 27943c8)
  • New describe plus accessTabs-12456: Test Files 2 passed (2), Tests 16 passed (16).
  • Every ui test file naming PermissionMatrixEdit, AccessPillar or perm-provenance-badge (68 files): Test Files 68 passed (68), Tests 474 passed (474).
  • pnpm --filter @object-ui/app-shell run type-check: exit 0. eslint on the three touched files: 0 errors (the warnings are on lines this diff does not touch).
  • At 27943c8 (after merging main, closure rebuilt): the same 68 files, Test Files 68 passed (68), Tests 474 passed (474); app-shell type-check exit 0; node scripts/check-sdui-manifest.mjs exit 0.

Acceptance notes

  • While the base's customization read is in flight, or after it fails, the rail draws no mark, so the header keeps its previous answer (Package) for a pair set. The two agree; no fallback to the row's addedIn was added, since that would be a second copy of the rule (seat ruling on the plan).
  • The chip's words are untouched here. The card Studio zh-CN: one word left per state after #29705 — 已关闭 vs 已停用, 自定义 vs 定制, and Access's perm.badge.custom #29729 renames the Custom badge's text, and whichever PR lands second merges main.
  • Not measured live: no dev server run. The real-client harness drives the surface end to end; the card measured the rail's "Added" live on 601832b1a6, and an added mark now decides the header regardless of the layered code reading.

Verification

Gates

node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at 26d194d: 35 derived families, all run locally, all exit 0, node scripts/check-sdui-manifest.mjs among them. --ran reconciliation: "35 derived famil(ies) accounted for — 35 run, 0 NOT-MEASURED". The merge of main touched none of this diff's files. Changed lines 86 (4 files), under the 3000 threshold.


Generated by Claude Code

…Access header

The provenance chip read `!!packageId || codeIsArtifact`, and the pair's
package door supplies a `packageId`, so every set the `.custom` pair holds
read "Package" beside the rail's "Added". The Access host now passes the
mark its rail row draws (customizationMarks.ts), and an added set reads
Custom; base sets and customized base sets still read Package.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QsR2jQi6dVYD8adyv8MhKt
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface labels Nov 3, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:ui#4 · zhuangjianguo · session_01QsR2jR7ZFkpqmm4U8S1f9y

席位核对 · ACCEPT · 2026-11-03T07:07Z

Head-sha: 27943c853a3dd14905e74d40a19cb6b2c2a4a7e7

  • Shape: draft → main, Fixes #29809 in the body only. 4 files, +82 / −4 (86 lines ≤ 3000). No governed path (check-governed-merges --pr 29835 on the final file list: 0 of 4 hit the register). Clause-②: no and Metadata-protocol: none are line-initial in the body and the changeset, so no review face applies and no contract review is owed.
  • Premise, measured: it holds. The filer measured it on 601832b1a6 (showcase, zh-CN): a New similar copy of showcase_contributor reads 包内置 in the header and 新增 on the rail. On the claim head, PermissionMatrixEditor.tsx L727 read const shippedByPackage = !!packageId || codeIsArtifact;, and both badge sites read it.
  • Read in the diff:
  • Tests: three cases are added to the real-client accessPairCopy-29674 harness: the copy, a set created in the pair, and the base set as control. accessTabs-12456 stays green. Two ablations each turn 2 of 3 red with the control green (the rule reverted, and the host passing null); both were restored. The 68 neighbouring files pass 474 of 474 tests. 35 of 35 derived gates exit 0, and check-sdui-manifest exits 0.
  • Accepted deviations (Acceptance notes):
    • While the customization read is in flight or has failed, the header keeps Package for a pair set. The rail shows no mark either, so the two agree. This was ruled on the plan.
    • There was no live dev-server run. The harness drives the surface end to end, and the filer's live reading is the premise.
  • Out of scope: the report lists none (out_of_scope_findings: []). Skills-docs: is not owed (Metadata-protocol: none, no narrowing arm). Serial note: Studio zh-CN: one word left per state after #29705 — 已关闭 vs 已停用, 自定义 vs 定制, and Access's perm.badge.custom #29729 (seat 2) renames the custom badge's words in the same file. Whichever lands second merges main.
  • Gates (check-runs on this head): 44 success, 11 skipped (opt-in, path-filtered — Build Core for a ui-only diff — or matrix placeholders), 0 failed or pending, including Live E2E UI and all 16 Test UI shards. Every required context succeeded or was skipped by its path filter.
  • Landing: ordinary queue landing, pr_ready then automerge_enable. Fixes #29809 closes the card on 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/s tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Studio Access: a permission set the .custom pair added reads "Package" in its header, beside the rail's "Added"

1 participant