Skip to content

fix(app-shell): permission-set editor header shows the served (translated) label - #27019

Merged
objectstack-fleet[bot] merged 5 commits into
mainfrom
claude/project-thread-2x7amc
Oct 28, 2026
Merged

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

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Warren · project thread
Fixes #26884

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:权限集详情页(Setup 与 Studio 访问支柱)的标题改用服务端按语言下发的标签,zh-CN 下显示「销售代表」而不是「Sales Representative」。
  • 为什么改:列表页已经显示翻译后的名称,点进去标题却是英文原文;编辑器的草稿来自未翻译的 layered 读取,而它已经读到的已发布列表是翻译过的。
  • 风险与回滚:只改显示,草稿与保存内容不变(保存仍发作者原文);标签被编辑或有不同标签的待发布草稿时显示草稿标签。回滚即还原这一个提交。
  • 先看:PermissionMatrixEditor.tsx 的 headerLabel 与加载末尾读取 served 行那段;新测试 PermissionMatrixEditor.servedLabel-26884.test.tsx。
  • 两分钟验证:pnpm --dir ui exec vitest run packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.servedLabel-26884.test.tsx,预期 4 个用例全绿。
  • 需要你做的:无,席位落地。

What changes

  • PermissionMatrixEditPage keeps the label of the row GET /meta/permission serves for this set (that read is localized at the REST boundary by the server's permission-set translator, and the editor already makes it for the published-set check). The header shows it while the draft's label equals the published authored label; otherwise it shows the draft's label, as before.
  • Both header sites read it: the Setup page's identity strip and the Studio Access pillar's StudioItemHeader title.
  • Display only: the served label is never written into draft, so a save sends the authored label unchanged. A set the published list does not hold (never published) keeps its draft label.
  • Scope cut, per the dispatch order: the card's second symptom (the metadata list chrome staying English under ja-JP / es-ES) is the ruled en fallback, not a defect (Ruling-ref 6431032267, verbatim: "the other eight locales fall back to en (no invented translations)"), so it is not touched here.
  • Changeset: @object-ui/app-shell patch.

Tests

New PermissionMatrixEditor.servedLabel-26884.test.tsx (4 cases): zh-CN served 销售代表 over layered "Sales Representative", and the autosave sends "Sales Representative" unchanged; ja-JP served label; a set the list does not hold keeps its draft label; an edit to the label shows the edit.

Ablation (one-off, scripts/ablation-replace.mjs, restored blob equals HEAD): putting draft.label back in the Setup header turns 3 of the 4 cases red (the never-published case stays green, as expected); restored, 4/4 green.

Acceptance notes

  • The served label comes from the same list request the editor already sends; no new request.

Verification

Local gates on 53382fa
  • node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack: 34 families derived, 34 run, every one exit 0; --ran reconciliation: 34 run, 0 NOT-MEASURED, 0 UNRUN. node scripts/check-sdui-manifest.mjs is among them (exit 0).
  • pnpm --dir ui exec vitest run packages/app-shell/src/views/metadata-admin/: Test Files 624 passed, Tests 6809 passed, 1 skipped (exit 0).
  • pnpm --filter @object-ui/app-shell type-check: exit 0.
  • Closure build pnpm --workspace-concurrency=2 --filter '@object-ui/app-shell^...' build: exit 0.

Human Minimum

  • 1. Schemas start as Zod; packages/spec holds no runtime logic. (not touched)
  • 2. Every name I added uses the casing for its kind.
  • 3. No formatter ran; pnpm lint passes. (CI)
  • 4. One issue, one branch off an up-to-date main, one pull request.
  • 5. A change that publishes carries a changeset, and both declaration lines are filled in here and in the changeset.
  • 6. packages/spec touched: n/a.
  • 7. No hand edits to content/docs/references/, packages/*/CHANGELOG.md or content/docs/releases/.
  • 8. Title, body and comments are in English (the 维护者速读 block is the dispatch-ordered Chinese summary).

🤖 Generated with Claude Code

https://claude.ai/code/session_01JQwxbZMgz2QbrsLJv3RD41


Generated by Claude Code

@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tooling labels Oct 28, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

维护者速读

  • 改了什么:权限集详情页(Setup 与 Studio 访问支柱)的标题改用服务端按语言下发的名称,中文下显示「销售代表」而不是英文原文。
  • 为什么改:列表页已显示翻译后的名称,点进去标题却是英文;编辑器早已读到翻译过的已发布列表,只是标题没用它。
  • 风险与回滚:只改显示,草稿与保存内容不变(保存仍发作者原文);标签被编辑或从未发布时显示草稿标签。回滚即 revert。
  • 先看:PermissionMatrixEditor.tsx 的 headerLabel 与加载末尾读取 served 行那段。
  • 两分钟验证:pnpm --dir ui exec vitest run packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.servedLabel-26884.test.tsx。
  • 需要你做的:无;CI 全绿后由席位落地。
  • 席位意见:只做显示、不写回草稿,判定条件(草稿标签等于已发布原文才换)对编辑中的情况安全;日文、西文列表外框按既裁回退英文已从本卡切除。

席位核对

ACCEPT · domain:ui#2 · session_01JQwxbXpF772qWJjojJvRXw · head 53382fab30 · 2026-10-28T01:45Z

  1. Shape: draft, base main, line 3 Fixes #26884 (the card's remaining item after the seat's scope cut is fully delivered; the cut list-chrome half is the ruled en fallback, Ruling-ref 6431032267, recorded in the claim); 3 files, +176/−4; not governed (ui/** + .changeset/).
  2. Premise measured: seat read of the diff (commits 139b6579, ab1d010b): servedLabel is set from the client.list('permission') row the editor already fetched, only when it differs from the layered authored label; headerLabel swaps it in only while draft.label === servedLabel.authored; setDraft is never fed the served label, so a save keeps the authored text; reset to null on each load.
  3. Gate check-runs (pinned to head 53382fab30): at this record 7 success, 10 skipped, 14 in progress. Landing waits for every check green; the dev's local reading is 34/34 derived families exit 0, --ran 0 NOT MEASURED, ablation 3 red / 1 green then restored to the HEAD blob, the metadata-admin directory (624 files) green, app-shell type-check 0.
  4. Accepted deviations: both header sites changed (the Setup identity strip and the Studio Access StudioItemHeader title) — the claim's "header label only" covers both, and the Studio site renders the same set; PR template headings folded into the body; @object-ui/app-shell patch changeset per the order.
  5. Out of scope: none filed. Skills-docs: n/a (Metadata-protocol: none).
  6. Landing clause: not governed ⇒ when every check on the current head is green or expected-skip, the seat lands it (pr_ready + automerge_enable); if the session's classifier refuses that stroke, as it did on fix(plugin-list): show list view sharing type and lock owner as read-only text, drop the dead Share button #27013, the maintainer is asked to click.

@github-actions

Copy link
Copy Markdown
Contributor

⛔ merge queue 构建失败 — 先分诊,再决定要不要重排

队列构建 40654188630 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集),
所以失败的测试可能在本 PR 没碰过的包里 —— 那不是重排能修的。每次盲目重排都会让排在后面的所有 PR 重建一轮。

分类:failure —— 按下面的日志分诊。

失败的 job(日志抽取,best effort):

  • Test UI (4/16) — 失败步骤: Run the ui tests (shard 4/16)

    × zh-CN: the header reads the served 销售代表, and a save keeps the authored label 1092ms
    × ja-JP: the header reads the label the served row carries 1052ms
    × a set the published list does not hold keeps its draft label 1046ms
    × an edit to the label shows the edit, not the served label 1045ms
    FAIL   dom  packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.servedLabel-26884.test.tsx > PermissionMatrixEditPage — header shows the served label (objectstack#26884) > zh-CN: the he
      ↳ 失败原因: (这条 FAIL 之后 12 行内没有可识别的原因行 —— 点进 job 看)
    FAIL   dom  packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.servedLabel-26884.test.tsx > PermissionMatrixEditPage — header shows the served label (objectstack#26884) > ja-JP: the he
      ↳ 失败原因: (这条 FAIL 之后 12 行内没有可识别的原因行 —— 点进 job 看)
    FAIL   dom  packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.servedLabel-26884.test.tsx > PermissionMatrixEditPage — header shows the served label (objectstack#26884) > a set the pub
      ↳ 失败原因: (这条 FAIL 之后 12 行内没有可识别的原因行 —— 点进 job 看)
    FAIL   dom  packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.servedLabel-26884.test.tsx > PermissionMatrixEditPage — header shows the served label (objectstack#26884) > an edit to th
      ↳ 失败原因: (这条 FAIL 之后 12 行内没有可识别的原因行 —— 点进 job 看)
    

↳ 失败原因 是判读的关键:超时(Test timed out in … / Hook timed out in …)多半是负载/时序,不是本 PR 的回归;
断言(AssertionError: …)才指向真实的行为改变。两者的 FAIL 行长得一模一样,只有这一行能区分。

⚠️ 断言这一侧有一类例外,判据是断言在测什么,不是它是不是 AssertionError。 断言的对象是产品行为(一个值、一个形状、一次拒收)⇒ 照上面读:真实的行为改变,去查,⛔ 不要重排掉;
断言的对象是这次实验自身的有效性前提(跑完的耗时、负载下的先后、任何只在时间预算内才成立的条件)⇒ 它跟超时是同一类,同样对负载敏感,重排一次是合法的判别手段。
识别是机械的:断言的消息或它比较的值本身点名了一段时长、一个时间戳、一个耗时计数。实测过的一对 —— AssertionError: SecurityPlugin.init() ran: expected false to be true 测的是产品行为(真回归);
AssertionError: this run took over a second, so second-precision stamps could have differed too: expected 1006 to be less than 1000 测的是实验前提:它守护的那条不变式当时是绿的,同一个 head 原样重排一次即成功。
穿着 AssertionError 外衣的时间测量,仍然是时间测量。(⛔ 这只改「怎么读一次红」,不改「哪些测试可以重排」——后者由别处管。)

跨 PR 相同签名(24h,按失败测试文件聚合):

  • packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.servedLabel-26884.test.tsx — 24h 窗口内只有本 PR 撞到过,暂不汇总(再有一个不同 PR 撞到就会自动开汇总 issue)。
  • ⚠️ 24h 评论账本没读完(超过 5 页仍未读到窗口尽头),所以上面的「不同 PR 数」是下界,不是全量。

历史信号:

  • 本 PR 过去 24h 无队列失败记录(首次)。
  • 过去 24h 队列共有 28 个失败构建(不含本次)。

分诊清单:

  1. 失败测试在本 PR 改动的包里 → 真回归,修 PR。
  2. 失败测试与本 PR 无关 → 看上面的「跨 PR 相同签名」;已有汇总 issue ⇒ flaky/环境问题实锤,去那张 issue 上谈,修好前重排只会再烧一轮全队列。
  3. 两者都不是 → 可能与同组 PR 语义冲突;等前面的 PR 落地或失败出队后再重排一次即可,不要连续重排。

Generated by Claude Code · merge-queue-triage workflow (#4859)

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对

ACCEPT · domain:ui#2 · session_01JQwxbXpF772qWJjojJvRXw · head b92946010f · 2026-10-28T08:36Z · re-pins the ACCEPT on 53382fab30

席位意见:队列里红是因为本 PR 新加的测试用的假客户端缺了 main 新增的 withPreviewDrafts;合入 main 后补上这一个方法,产品代码没变。

  1. Delta reviewed: 53382fab..b9294601 is a merge of origin/main (bacb157d, no rebase, no force) plus b9294601. That commit adds two lines to PermissionMatrixEditor.servedLabel-26884.test.tsx: withPreviewDrafts() { return this; } on the makeClient fake, the shape PR test(app-shell): give the new package-door matrix doubles the draft-overlaid read #27103 gave the other fakes. Apart from that test line, the PR's own hunks are byte-identical to the reviewed ones.
  2. Root cause of the queue kicks: since this branch was cut, main's PermissionMatrixEditor.tsx calls client.withPreviewDrafts(true) (Studio Access: the permission matrix lists no objects while the package's objects are still drafts ("0 objects"), so a new package cannot be secured before its first publish #26840), so the old fake made the load throw and the header never rendered. All 4 cases failed at about 1 s, in queue builds 40654188630 and onward. Recorded on Queue-flake anchor: packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.servedLabel-26884.test.tsx #27150 (6464145491).
  3. Shape: unchanged, Fixes #26884. Not governed. ≤ 3000 lines.
  4. Gate check-runs (pinned to head b92946010f): 44 succeeded and 11 were skipped; none failed or is pending. mergeable_state is clean.
  5. Accepted deviation: none. The added test line is inside the PR's own test file.
  6. Landing clause: maintainer instruction 2026-10-28 08:00Z. The seat readies it and enables auto-merge now (it was drafted at 08:17Z only to leave the queue).

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 28, 2026 08:37
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 28, 2026 08:37
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 28, 2026
Merged via the queue into main with commit 0f1045b Oct 28, 2026
56 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-2x7amc branch October 28, 2026 09:01
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

Projects

None yet

2 participants