Skip to content

i18n(platform-objects): ship the platform objects, Setup, Studio and Account in zh-Hant - #30951

Queued
objectstack-fleet[bot] wants to merge 3 commits into
mainfrom
claude/project-thread-1jep1s
Queued

objectstack-fleet[bot] wants to merge 3 commits into
mainfrom
claude/project-thread-1jep1s

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Elon · project thread

domain:server#1 · os-elon-musk · session_016WV4cya5ej5GQV86RPbRPK

Part of #30512 — package 11 of 11 (@objectstack/platform-objects), first of its seven locales: zh-Hant. Per the seat's ruling B, ar, fr, pt-BR, ru, de and ko follow one PR each, and the last PR of the series makes the bundle check read the platform locale table.

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么: 平台内置对象(用户、组织、会话、API 密钥、OAuth、SSO、SCIM、通知、邮件、任务、导入、元数据、设置、汇率等全部 sys_*)、Studio 里各元数据类型的配置表单、「设置」「Studio」「账户」三个应用的导航、系统概览仪表盘与数据集、平台页面标题,以及用户 / 组织记录页上的内联文案,补上繁体中文(zh-Hant)。
  • 为什么改: 平台语言表要求每个界面带齐 11 种语言;这是第 3 期按包补齐的最后一个包(platform-objects)的第 1 种语言。用繁中的管理员和开发者打开平台不再大面积看到英文。
  • 风险与回滚: 只加翻译数据和注册行,不动逻辑、schema、接口;原有 4 种语言一字未改。新语言同样走「源文本哈希回退」,手写部分每条都记了源哈希。测试改动都是把 zh-Hant 加进各测试的语言列表(覆盖变宽,没有放宽断言),外加 cli 一个形状测试的语言码正则放宽到接受 zh-Hant 这种书写体子标签(否则它一个内联文案都认不出)。回滚即撤 PR。
  • 先看: src/apps/translations/setup.translation.ts 与 src/metadata-translations/index.ts(注册),scripts/i18n-extract.config.ts(--locales 加 zh-Hant),然后抽看 zh-Hant.ts(导航,约 140 条)和任一生成文件。
  • 两分钟验证: node scripts/check-i18n-bundles.mjs --filter=platform-objects 输出 in sync;pnpm --filter @objectstack/platform-objects test 全绿。
  • 需要你做的: 本 PR 改动超过 3000 行(含生成物),按规程需人工合并;契约复核尚未做(contract review owed),复核通过后由席位请 os-zhuang / hotlong 审批。

What changes

  • Generated bundles zh-Hant.objects.generated.ts (1,674 leaves) and zh-Hant.metadata-forms.generated.ts (1,263 leaves), written by the repo's own os i18n extract --fill=default --source-hashes from the merge baseline, plus its provenance companion zh-Hant.source-hashes.generated.ts.
  • Hand bundle zh-Hant.ts (138 leaves: the Setup, Studio and Account navigation, the System Overview dashboard, the datasets and the platform pages), with zh-Hant.source-hashes.ts recording the digest of the en source each leaf was translated from: all 138, so the first source edit under any of them falls back instead of serving a superseded translation.
  • Registration: SetupAppTranslations and MetadataFormsTranslations serve zh-Hant through withSourceFallback, exactly as the existing three; the apps barrel exports zhHant.
  • Extract config: its docstring's --locales (what check:i18n executes) and its merge baseline carry zh-Hant, so the gate covers the new bundles from this PR on. The root pnpm i18n:extract script still lists three locales; the final PR of the series moves both it and scripts/check-i18n-bundles.mjs to the platform locale table.
  • Inline page copy: the 42 inline locale maps on the user and organization record pages and the System Overview dataset's null label gain a zh-Hant entry.

Tests

  • Locale lists widened to zh-Hant, no assertion changed: in this package plugin.translations.test.ts, setup-nav-per-user-stores.test.ts, sys-user-details-tab.test.ts, system-overview-null-label.test.ts (these four pin the shipped set and go red without it), and the vocabulary, parity, tombstone, source-hash, BU-rename, metadata-forms, repeater, dashboard-header, confirm-question and identity copy tests (these iterate a fixed list, so zh-Hant is now held to the same bars).
  • Cross-package pins held for zh-Hant: plugin-security's People & Organization nav test (its control pins the Setup locale set and goes red without the new tag); service-settings' setup-nav-hub-parity.test.ts (each Setup sidebar entry reads as its hub card's title); plugin-approvals' approval-status-vocabulary.test.ts (the my_pending view label equals the account nav's nav_account_approvals: 待我核准).
  • packages/cli/test/platform-page-i18n-parity.test.ts: its inline-map shape test recognised a locale key as xx or xx-YY only, so with a zh-Hant key present it recognised no map at all (expected 0 to be greater than or equal to 38). The pattern now also accepts a script subtag; the 42 maps are found again and every one is complete in all five shipped locales.

Acceptance notes

  • Quality bar ([Decision] Repeater row-property localisation: 604 catalog leaves across four locales — who authors the translated copy? #17508 / PR feat(spec): a repeater property panel names its columns in every locale, not only English #19345): written for a Taiwan reader. Each leaf starts from the reviewed zh-CN text, converted with OpenCC's Traditional (Taiwan, phrases) table and then a house glossary of about 170 term rules that matches the zh-Hant bundles nine packages already ship (權限, 類型, 中繼資料, 工作階段, 權杖, 金鑰, 檢視, 欄 / 列 for column / row, 套件, 範本, 稽核, 共用, 指派, 核准, 電子郵件, 唯讀, 逾時, 背景工作, …). 446 leaves whose English and zh-CN pair already has a zh-Hant rendering elsewhere in the repo reuse it verbatim. Every one of the 1,541 distinct short leaves was read, and the long help texts were reviewed by sample and by a targeted audit of each rule that rewrites words in context (row / column, 應用 / 應用程式, 按 / 依, 通過 / 透過).
  • Mechanical checks, per leaf against zh-CN: backtick spans, {{holes}}, {holes}, angle tokens and snake_case identifiers byte-identical (three intended differences, all Chinese prose inside a hole default or a JSON example: default:'該成員', "已封存"); no Simplified-only character remains (the only s2t remarks are the Taiwan forms 台, 准, 群, 游, 里).
  • Cross-package wording pins carried: nav_account_approvals = plugin-approvals' my_pending (待我核准); nav_assignment_rules = i18n(plugin-sharing): ship the assignment rule object in all eleven platform languages #30856's object name (指派規則); the queue, sharing, approval-delegation and HTTP-delivery entries read as their objects' zh-Hant labels; each nav_settings_* entry reads as its settings hub title from i18n(service-settings): ship the built-in settings pages in zh-Hant, ar, fr and pt-BR #30870 (so 郵件投遞 / 簡訊投遞 there, while the HTTP delivery log says 傳送).
  • Leaves equal to English, on purpose: the 40 objects leaves zh-CN already decided as echoes (ID, JWKS, Client ID, the SSO placeholders, …), each recorded by the extractor in zh-Hant.source-hashes.generated.ts, and three hand leaves (Webhooks, Studio, AI).
  • One cross-locale coincidence fixed: zh-CN's action.fields.method.helpText is the Latin GET / POST / PUT / DELETE, not the source; a converted copy made two locales agree on it and check:i18n-stale-fill reported it. zh-Hant now translates it (HTTP 方法(GET、POST、PUT、DELETE)); the stale-fill check passes with the baseline untouched. The zh-CN leaf itself is left as it is (existing fills are out of this card's scope).
  • No string opens with os followed by a lowercase word (check-cli-command-ids passes), and the whole "Lint · docs & code guards" lane was run locally before opening.

Verification

Package suites, typecheck, build (verify lock)
pnpm install --frozen-lockfile && turbo run build --filter=!@objectstack/docs   (at head e8d9055e, on main 33043bd8)
 Tasks:    118 successful, 118 total
pnpm --filter @objectstack/platform-objects test
 Test Files  117 passed (117)
      Tests  1636 passed (1636)          (1593 before this PR; the 43 new are the zh-Hant cases)
pnpm --filter @objectstack/platform-objects typecheck   (tsc, scripts tsconfig, check:test-typecheck OK)
pnpm --filter @objectstack/plugin-security test   246 files, 5686 passed | 45 skipped
pnpm --filter @objectstack/plugin-approvals test  115 files, 1502 passed
pnpm --filter @objectstack/service-settings test   71 files, 1351 passed
packages/cli: vitest run test/platform-page-i18n-parity.test.ts   27 passed
os-verify-lock: VERDICT command-exit 0   (one '&&' chain)
typecheck of plugin-security, plugin-approvals, service-settings and cli: 4 x exit 0
i18n gates, the derived families and the docs & code guards lane
node scripts/check-i18n-bundles.mjs (all packages)              (at e8d9055e)
check-i18n-bundles: OK (10 package(s) — all bundles in sync, no undeclared authoring keys).   EXIT 0
node scripts/check-i18n-stale-fill.mjs
check-i18n-stale-fill: OK (11 bundle set(s) — no new stale fills, 1 baselined).   EXIT 0
pnpm check:app-nav-i18n
check-app-nav-i18n: OK (13 contributor(s), 5 locale(s), 2 app(s) — setup: 56 merged nav id(s),
  account: 12 merged nav id(s) — every id labelled in every locale).   EXIT 0
pnpm check:i18n-coverage   OK (14 config(s), 426 baselined untranslated string(s), none new).   EXIT 0
pnpm check:i18n-walk-parity   EXIT 0
node scripts/check-cli-command-ids.mjs                         EXIT 0
dispatch-gates --commands (at e8d9055e): 64 families, each run and recorded with its exit code: 64 x exit 0
dispatch-gates --ran: 64 derived, 64 run, 0 NOT-MEASURED (a derived zero)
pnpm lint (repo-wide, at e8d9055e): exit 0
CI lane "Lint · docs & code guards", every command run locally   (at e8d9055e)
  56 commands (lane-verdict excepted), 56 x exit 0, check-cli-command-ids included
changed lines 7271 (+7216 / -55), 36 files: over the 3000-line human-merge threshold

The branch is one commit on main 33043bd8 (after #30931 landed); every number above was measured at that head. Main's commits since the earlier draft (#30846, #30919, #30929, #30931) touch no file this PR changes.

Dogfood: not run — content-only package PR, no ! in the title and no (narrowing) arm.


Generated by Claude Code

…Account in zh-Hant

Adds the Traditional Chinese bundles for every sys_* object, the metadata
configuration forms, the Setup / Studio / Account navigation, the System
Overview dashboard and datasets, and the platform pages, registers them in
the served bundles behind the source-hash fallback, and adds zh-Hant to the
user and organization pages' inline copy. The extract config documents
zh-Hant in --locales, so check:i18n gates the new bundles.

Tests that list the shipped locales now include zh-Hant; the page parity
shape test accepts a script subtag; the nav pins in plugin-approvals,
plugin-security and service-settings hold zh-Hant to the same agreement.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WV4cya5ej5GQV86RPbRPK
@github-actions github-actions Bot added size/xl documentation Improvements or additions to documentation tests tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface labels Nov 6, 2026
@github-actions

github-actions Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/platform-objects, touching 292 documentable anchor(s). ⚠️ 1 changed file(s) yielded no anchor (packages/platform-objects/src/apps/translations/index.ts), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files.

63 hand-written doc(s) name something this change touched — list omitted above 15 rows. Re-derive on the tree named below: node scripts/docs-audit/affected-docs.mjs --json 1aeeafd9d371be1fd5afa637c4f0ae6b6f4c1404.

⛔ 19 release-owned page(s) also affected — read-only, see AGENTS.md Documentation Guardrails.

What this run could not see
  • 1 changed file(s) yielded no anchor (packages/platform-objects/src/apps/translations/index.ts) — pages documenting those are invisible to this run
  • 1 anchor(s) matched too much of the corpus to be a work list: sys_user (symbol, 49 pages)
  • 33 name(s) were too generic to anchor anything (single lowercase words)
  • the SDK route bridge reached 63 of 222 client-bound route-ledger rows — the other 159 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 159: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 55 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 104 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

Coarse fallback — 2 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 1aeeafd9d371be1fd5afa637c4f0ae6b6f4c1404 → packageMentionDocs.

Which tree this was computed on

This run read content/docs from 207fb4b941de851f9d772488aacfb4b531f4b128 — the merge of head d104e2b4247de8c39d84c79ab7bcccd7abd220a4 into base 1aeeafd9d371be1fd5afa637c4f0ae6b6f4c1404, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 207fb4b941de851f9d772488aacfb4b531f4b128 && git checkout 207fb4b941de851f9d772488aacfb4b531f4b128
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 1aeeafd9d371be1fd5afa637c4f0ae6b6f4c1404 d104e2b4247de8c39d84c79ab7bcccd7abd220a4 && git checkout -B drift-repro 1aeeafd9d371be1fd5afa637c4f0ae6b6f4c1404 && git merge --no-ff d104e2b4247de8c39d84c79ab7bcccd7abd220a4

node scripts/docs-audit/affected-docs.mjs --json 1aeeafd9d371be1fd5afa637c4f0ae6b6f4c1404

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs 1aeeafd9d371be1fd5afa637c4f0ae6b6f4c1404 → pass the list as
args.docs, on the commit named under Which tree this was computed on.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:server#1 · os-elon-musk · session_016WV4cytLmJxfAmgPVjUbbW

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: e8d9055ec7ca343cb5b308a8019843f5c138f7e7
Local-runs: none
Scope: packages/platform-objects/scripts/i18n-extract.config.ts, packages/platform-objects/src/apps/translations/{zh-Hant.ts, zh-Hant.source-hashes.ts, zh-Hant.objects.generated.ts, zh-Hant.metadata-forms.generated.ts, zh-Hant.source-hashes.generated.ts, setup.translation.ts, index.ts}, packages/platform-objects/src/metadata-translations/index.ts, packages/platform-objects/src/pages/{sys-user,sys-organization}.page.ts, packages/platform-objects/src/apps/dashboards/system.datasets.ts, packages/cli/test/platform-page-i18n-parity.test.ts, the 19 platform-objects test files, packages/plugins/plugin-security/src/people-org-assignment-nav-contribution.test.ts, packages/plugins/plugin-approvals/src/translations/approval-status-vocabulary.test.ts, packages/services/service-settings/src/setup-nav-hub-parity.test.ts, .changeset/30512-platform-objects-locales-zh-hant.md + packages/platform-objects/src/apps/translations/{en,zh-CN,es-ES}.ts, {en,zh-CN}.objects.generated.ts, {en,zh-CN}.metadata-forms.generated.ts, {zh-CN,es-ES}.source-hashes*.ts, source-hash.ts, packages/services/service-settings/src/translations/zh-Hant.ts (main), packages/plugins/{plugin-approvals,plugin-sharing}/src/translations/zh-Hant.objects.generated.ts (main), packages/services/service-messaging/src/translations/zh-Hant.objects.generated.ts (main), scripts/check-i18n-bundles.mjs, root package.json, card #30512 and its comments, dev report 6686432570, PR #30951 body, precedent PRs #30870 and #30931

Diff read against merge base 33043bd8a2b34ed2efdc188f38173c1c44ca3f36: one commit, 36 files, +7216/-55. The head did not move during the review.

① Derived judgments

Must-fix: none.

Should-fix: none that blocks. Two wording notes, both inherited from zh-CN and so not a defect of this PR:

  • 帳戶 (4 uses: the Account app label, nav_account_linked, the Linked Accounts tab, two action dialogs) beside 帳號 (13 uses) for "account". zh-CN makes the same split (账户 / 账号). A later pass could pick one.
  • The user page's two-factor card says 兩步驟驗證 (sys-user.page.ts:482) while the sys_user object copy says 雙因素驗證 (13 leaves). Again a mirror of zh-CN (两步验证 vs 双因素).

Confirmed, by file.

Generated bundles (the shape question):

  • zh-Hant.objects.generated.ts is 3810 lines, zh-Hant.metadata-forms.generated.ts 2815, zh-Hant.source-hashes.generated.ts 61: line-for-line the same length as the zh-CN and en files, same header text, same export shape (zhHantObjects: NonNullable<TranslationData['objects']> at line 17, zhHantMetadataForms likewise, zhHantGeneratedSourceHashes: Readonly<Record<string, string>> at line 20).
  • Key sets counted programmatically: 2937 string leaves in en, zh-CN and zh-Hant each (1674 objects + 1263 metadataForms), key order identical to en, 0 missing, 0 extra. The PR body's counts (1,674 / 1,263) are right.
  • Source hashes: zh-Hant.source-hashes.generated.ts has 40 entries, the same 40 paths as zh-CN's table. Every one of the 40 digests equals hashSource(en leaf) recomputed with the function at source-hash.ts:270, and every one of those 40 zh-Hant leaves is a byte copy of en (ID, JWKS, Client ID, the SSO placeholders). Exactly 40 zh-Hant leaves equal en, all 40 carry an entry, and 0 leaves are English where zh-CN translates. So "40 echoes, the same 40 zh-CN decided" holds.
  • Hand bundle zh-Hant.ts: 138 leaves, same key set as en.ts, zh-CN.ts and es-ES.ts (138 each), key order equal to zh-CN.ts (the hand files already differ from en.ts in order; not new). zh-Hant.source-hashes.ts: 138 entries, one per leaf, 0 mismatches against the current en.ts source, 0 entries for unknown paths. That is more complete than zh-CN's 131; fine. Three hand leaves equal en on purpose: nav_webhooks = Webhooks (comment at zh-Hant.ts:105-109 records why), apps.studio.label = Studio, group_ai = AI.
  • Input change: scripts/i18n-extract.config.ts adds zh-Hant to the docstring --locales (line 11, what check-i18n-bundles.mjs executes, see its line 37), imports the two generated bundles and the hand bundle (lines 224, 229, 252) and adds the zh-Hant merge-baseline row (line 353). Nothing else in the config moved. The root package.json i18n:extract script (line 29) still lists three locales; the dev records this as left for the series' last PR. It does not affect the gate.

Translation quality (about 30 leaves read by hand across sys_user, sys_organization, sys_invitation, sys_api_key, sys_oauth_*, sys_scim_*, sys_email_template, sys_import_job, sys_setting_audit, the object, field, view, page, dashboard, action, dataset, permission and skill forms, the Setup/Studio/Account nav, the dashboard widgets and the two record pages):

  • Terms are the Taiwan register the nine earlier zh-Hant bundles use: 使用者, 電子郵件, 金鑰, 權杖, 工作階段, 稽核, 物件, 欄位, 檢視, 中繼資料, 套件, 範本, 唯讀, 字元, 圖示, 對話方塊, 「」quotes. Not a Simplified-to-Traditional character swap: e.g. "User" 用户 -> 使用者, "Session" 会话 -> 工作階段, "Icon" 图标 -> 圖示, "Readonly" 只读 -> 唯讀, "OAuth Apps" OAuth 应用 -> OAuth 應用程式.
  • Simplified-only forms: a scan over all 2937 generated leaves, the 138 hand leaves and the 45 zh-Hant entries added to the pages and dataset finds 0 hits for 们 设 应 户 选 删 编 辑 规 则 类 价 审 务 组 织 关 联 数 据 报 网 页 视 图 导 认 证 码 线 级 别 录 时 间 为 这 会 说 将 与 当 办 对 开 发 现 实 际 议 记 转 达 该 项 东 车 门 问 题 让 产 义 无 经.
  • 232 generated leaves are byte-equal to zh-CN; sampled, they are strings with no Simplified-only character (全部, 完成, 角色, 排序, 品牌, 已取消, 提供方 ID), so an unconverted leaf is not what they are.
  • Placeholders and tokens ({{ }}, { }, backtick spans, angle tokens) compared against zh-CN: 2 differences, both intended Chinese prose inside a token (default:'該成員' in sys_member.update_member_role.description; the JSON example "已封存" in action.fields.outcomeMessages.helpText). Against en there are 13 differences, and every one of them is already present in zh-CN (reordered backtick spans, a dropped or added code span in a help text); they are inherited, not introduced.
  • The stale-fill fix: metadataForms.action.fields.method.helpText is GET / POST / PUT / DELETE in zh-CN and HTTP 方法(GET、POST、PUT、DELETE) in zh-Hant (zh-Hant.metadata-forms.generated.ts). zh-CN is untouched in the diff; scripts/i18n-stale-fill-baseline.json is not in the file list, so the baseline is untouched as claimed.

Non-bundle source edits, each only adds a 'zh-Hant' key:

  • src/pages/sys-user.page.ts (+35/-23): 23 one-line inline maps gain 'zh-Hant' in place; 12 multi-line maps gain one 'zh-Hant': line. No page, tab, section, field list, visibleWhen or action changed. The -23 are the rewritten single-line maps.
  • src/pages/sys-organization.page.ts (+6/-6): the Members, Invitations and Teams tab labels and related-list titles gain 'zh-Hant'.
  • src/apps/dashboards/system.datasets.ts:60: SysAuditLogDataset's user_id nullLabel gains 'zh-Hant': '系統'.
  • src/apps/translations/setup.translation.ts: three imports and the 'zh-Hant': withSourceFallback(zhHant, en, zhHantSourceHashes, zhHantGeneratedSourceHashes) row (line 75), the same four-argument shape as the three rows above it; docstring updated.
  • src/apps/translations/index.ts:12: export { zhHant }.
  • src/metadata-translations/index.ts: two imports and the 'zh-Hant' row (line 48) with the third argument undefined, as the other three; two docstring lines reworded from "three" to "the translated locales".

Deviations:

  • packages/cli/test/platform-page-i18n-parity.test.ts:746: LOCALE_KEY widens from /^[a-z]{2}(-[A-Z]{2})?$/ to /^[a-z]{2}(-[A-Z][a-z]{3})?(-[A-Z]{2})?$/. The new pattern accepts a superset: every key the old one accepted is still accepted, and the only additions are xx-Abcd and xx-Abcd-YY. isInlineLocaleMap (line 749) requires every key to match, so under the old pattern a map holding zh-Hant was invisible and the floor at line 851 (maps.length >= 38) went red at 0, exactly as the dev reports. The test still catches what it caught: a non-locale key still makes a value not-a-map, the floor and the per-locale completeness check at lines 851-855 are unchanged, and with the widening all 45 inline maps on the two pages are judged in all five shipped locales.
  • Tests that pin the shipped set: plugin.translations.test.ts:195 (the ten-load list gains 'zh-Hant', 'zh-Hant'), setup-nav-per-user-stores.test.ts:116 (the sorted key list gains 'zh-Hant'), sys-user-details-tab.test.ts:37-47 (the three section fixtures gain the key), system-overview-null-label.test.ts:33, people-org-assignment-nav-contribution.test.ts:183. Each is the same assertion with one more element. The 15 list-iterating tests add zh-Hant to a LOCALES / TRANSLATED / FORM_BUNDLES constant and nothing else; bu-rename-consistency.test.ts:24 holds zh-Hant to /部門/ like ja-JP. No expectation was loosened anywhere in the 24 test files.

Cross-package pins, read in the merged zh-Hant bundles on main:

  • nav_account_approvals = 待我核准 (zh-Hant.ts:21) = plugin-approvals sys_approval_request._views.my_pending.label (plugin-approvals/.../zh-Hant.objects.generated.ts:123). approval-status-vocabulary.test.ts:143 now asserts it.
  • nav_assignment_rules = 指派規則 (zh-Hant.ts:66) = plugin-sharing sys_assignment_rule.label (i18n(plugin-sharing): ship the assignment rule object in all eleven platform languages #30856, plugin-sharing/.../zh-Hant.objects.generated.ts:348).
  • nav_queues = 佇列, nav_sharing_rules = 共用規則, nav_approval_delegations = 核准委派(外出), nav_http_deliveries = HTTP 傳送: each equals its object's zh-Hant label (sys_queue:295, sys_sharing_rule:107, sys_approval_delegation:344 in plugin-approvals, sys_http_delivery:319 in service-messaging). nav_sso_providers = SSO 提供方 = sys_sso_provider.pluralLabel (zh-Hant.objects.generated.ts:2016).
  • nav_settings_* (zh-Hant.ts:89-100) versus the i18n(service-settings): ship the built-in settings pages in zh-Hant, ar, fr and pt-BR #30870 hub titles in service-settings/src/translations/zh-Hant.ts: localization 在地化 (:123), company 公司 (:95), mail 郵件投遞 (:15), sms 簡訊投遞 (:48), branding 品牌 (:79), auth 驗證 (:195), storage 檔案儲存 (:284), ai AI 與 Embedder (:316), knowledge 知識庫 (:430), lifecycle 資料生命週期 (:466). All ten equal. setup-nav-hub-parity.test.ts:49 now runs that comparison for zh-Hant.

Precedent: the shape matches #30870 and #30931 (one changeset, hand bundle per locale, registration row, coverage test widened) and the earlier generated-bundle packages (generated bundle + provenance companion + docstring --locales + merge-baseline row).

② Semver level

.changeset/30512-platform-objects-locales-zh-hant.md: '@objectstack/platform-objects': patch, Clause-②: no, Metadata-protocol: none. The PR body carries the same two lines. Correct: the diff adds translation data and one registration row per bundle; no published type, export shape, spec key or accepted value moves. SetupAppTranslations and MetadataFormsTranslations keep their TranslationBundle type and gain a key the platform locale table already declares (PLATFORM_LOCALES, #30001). The changeset body matches the precedent changesets in form and names the package number and the six locales that follow.

③ Boundary flags

  • Face: record-recognisers.mjs --paths over the 36 paths says the paths decide no face (no packages/spec/src/**, no governed path). The Clause-②: line is a plain no, so no face of the contract four is touched by the declaration either. The review is owed by the 3,000-line rule (AGENTS.md line 499: 7,271 changed lines, generated files included), which lands the PR the Tier H way. The tier on this record is the one the dispatch brief asked for; the seat reads the recogniser's answer above when it requests the human approval.
  • Author: PR user.login is objectstack-fleet[bot] (relay); the body's attribution names os-elon-musk. The dev's open_questions is empty; security_findings withheld; two out_of_scope_findings are zh-CN quality notes, not changed here, and I agree they are out of this card's scope.
  • The dev's seven deviations are each confirmed above (regex widening, pinned-set tests, cross-package pins, root script left for the last PR, stale-fill fix in zh-Hant only). Turbo concurrency and the assignee are process notes.
  • Not changed, and should not be: scripts/i18n-stale-fill-baseline.json, scripts/check-i18n-bundles.mjs, root package.json, packages/spec/**.
  • CI on the head at the time of writing: every gate-carrying job that has finished is success (Lint & Repo Gates, TypeScript Type Check, Build Core, Governed Surface Queue Guard, Live E2E UI, Test UI, Check Changeset, Check PR Size, the Lint and Type Check sub-lanes, PR-body guards, Dogfood Regression Gate). Test Core (1/8) and (4/8) were still in_progress at the last read; (2/8), (3/8) and (5/8) to (8/8) are success. Nothing is red. The commit status is pending only because of those two shards. Skipped jobs are the UI, docs and opt-in lanes that do not run for this path set. The seat confirms the two shards green before asking for approval.

④ Design judgment

No hits file, so no schema, rule or narrowing to judge. The content was judged against the code it feeds: withSourceFallback (source-hash.ts:581) reads a hand table and a generated table per locale, and both zh-Hant tables are complete and digest-exact against the current en, so the first en edit under any leaf falls back rather than serving a stale string, which is the mechanism's purpose. The cli regex widening is the right fix for a test whose purpose is to judge every inline map on the shipped pages: the platform locale table ships a script-subtag tag, and a shape test that cannot see it judges nothing.

Implemented-by: claude/project-thread-1jep1s
Reviewed-by: session_016WV4cytLmJxfAmgPVjUbbW

VERDICT: PASS

@objectstack-fleet

objectstack-fleet Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor Author

domain:server#1 · os-elon-musk · session_016WV4cytLmJxfAmgPVjUbbW

维护者速读

  • 改了什么: 平台内置对象(用户、组织、会话、API 密钥、OAuth、SSO、SCIM、通知、邮件、任务、导入、元数据、设置、汇率等全部 sys_*)、Studio 里各元数据类型的配置表单、「设置」「Studio」「账户」三个应用的导航、系统概览仪表盘与数据集、平台页面标题,以及用户 / 组织记录页上的内联文案,补上繁体中文(zh-Hant)。
  • 为什么改: 平台语言表要求每个界面带齐 11 种语言;这是第 3 期按包补齐的最后一个包(platform-objects)的第 1 种语言。用繁中的管理员和开发者打开平台不再大面积看到英文。
  • 风险与回滚: 只加翻译数据和注册行,不动逻辑、schema、接口;原有 4 种语言一字未改。新语言同样走「源文本哈希回退」,手写部分每条都记了源哈希。测试改动都是把 zh-Hant 加进各测试的语言列表(覆盖变宽,没有放宽断言),外加 cli 一个形状测试的语言码正则放宽到接受 zh-Hant 这种书写体子标签(否则它一个内联文案都认不出)。回滚即撤 PR。
  • 先看: src/apps/translations/setup.translation.ts 与 src/metadata-translations/index.ts(注册),scripts/i18n-extract.config.ts(--locales 加 zh-Hant),然后抽看 zh-Hant.ts(导航,约 140 条)和任一生成文件。
  • 两分钟验证: node scripts/check-i18n-bundles.mjs --filter=platform-objects 输出 in sync;pnpm --filter @objectstack/platform-objects test 全绿。
  • 需要你做的: 本 PR 改动 7271 行(含生成物),超过 3000 行,按规程需 GOVERNED_APPROVERS(os-zhuang / hotlong)任一位 APPROVE。契约复核已过:PASS 记录 6686780589,Head-sha e8d9055ec7ca343cb5b308a8019843f5c138f7e7。批准后由席位经合并队列落地,不需要你合并。
  • 席位意见: 同意落地。纯翻译数据加注册行,结构与已合入的 i18n(service-settings): ship the built-in settings pages in zh-Hant, ar, fr and pt-BR #30870 / i18n(service-settings): ship the built-in settings pages in ru, de and ko #30931 同形;复核逐项核过键集、源哈希、繁体用字与两条跨包钉,无必须修复项。

席位核对 · ACCEPT · 2026-11-06T14:16Z · #30512 (platform-objects PR 1 of 7, zh-Hant)

Head-sha: e8d9055

  • Shape: 36 files, +7216 / -55. Generated bundles (zh-Hant.objects.generated.ts, zh-Hant.metadata-forms.generated.ts, source hashes), the hand bundle zh-Hant.ts, registration rows mirroring the existing three locales, one 'zh-Hant' key added to each inline page label map and the dashboard nullLabel, and 24 test files whose pinned locale lists gained zh-Hant. The same shape as i18n(service-settings): ship the built-in settings pages in zh-Hant, ar, fr and pt-BR #30870 and i18n(service-settings): ship the built-in settings pages in ru, de and ko #30931. Part of #30512, no Fixes: right, the final PR closes the card.
  • Premise measured: the contract review (record 6686780589, PASS, this head) counted 2937 leaves in en, zh-CN and zh-Hant each, key order identical, 0 missing or extra; every generated source hash equals hashSource(en); 0 Simplified-only characters; placeholders byte-equal to zh-CN.
  • Gates: every check-run on this head has concluded: 48 distinct checks, the latest run of each 35 success, 13 skipped, 0 failure; mergeable_state clean. Locally (dev report 6686432570 on i18n phase 3 (platform metadata and built-in emails): extraction and bundle checks read PLATFORM_LOCALES; backfill the seven missing locales #30512): build 118/118, platform-objects 1636 tests, 64 derived families exit 0 with --ran 0 not measured, pnpm lint 0, the docs & code guards lane 56 × exit 0.
  • Accepted deviations: the cli page-parity regex widened to accept a script subtag (a strict superset: the review confirmed it still catches everything it caught, and now sees the 45 zh-Hant maps); pinned-locale tests gained one element each with no assertion loosened; one stale-fill coincidence fixed in zh-Hant only. The root i18n:extract script stays at its current locales until the final PR, as planned.
  • Out of scope: existing zh-CN / ja-JP / es-ES English fills are reported, not changed (card scope). Skills-docs: not owed (Metadata-protocol: none).
  • Landing: over the 3000-line human-merge line (check-governed-merges.mjs --pr 30951: 0 governed paths, size decides). pm:awaiting-merge on this PR and review requested from os-zhuang and hotlong in the same stroke. After an APPROVE the seat flips it ready and arms auto-merge through the relay.

@objectstack-fleet objectstack-fleet Bot added the pm:awaiting-merge PR only: landing waits on the maintainer's own review and merge (SKILL.md 复核 ②); never on an issue label Nov 6, 2026
@os-zhuang
os-zhuang marked this pull request as ready for review November 6, 2026 14:22
@os-zhuang
os-zhuang enabled auto-merge November 6, 2026 14:22
@objectstack-fleet objectstack-fleet Bot removed the pm:awaiting-merge PR only: landing waits on the maintainer's own review and merge (SKILL.md 复核 ②); never on an issue label Nov 6, 2026
@os-zhuang
os-zhuang added this pull request to the merge queue Nov 6, 2026
Any commits made after this event will not be merged.
@github-actions

github-actions Bot commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

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

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

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

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

  • Test Core (3/8) — 失败步骤: Run this shard's tests

    @objectstack/platform-objects:test:  FAIL  src/apps/translations/app-nav-translation-parity.test.ts > every nav id an app presents is translated in every locale > account — zh-Hant
      ↳ 失败原因: @objectstack/platform-objects:test: AssertionError: untranslated nav ids in apps.account.navigation: expected [ 'grp_account_ai_assistant' ] to deeply equal []
    

↳ 失败原因 是判读的关键:超时(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,按失败测试文件聚合):

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

历史信号:

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

分诊清单:

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

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

…added

Main's #30935 gave the Account app a `grp_account_ai_assistant` group,
renamed the Connect page and both of its nav entries to "Connect an AI
Assistant", and moved the Setup entry behind System Overview. The zh-Hant
bundle was cut before it, so the app-nav parity test found the new group
unlabelled in zh-Hant.

zh-Hant now labels the group 「AI 助理」 (the wording plugin-security's
zh-Hant bundle already uses for the MCP assistant), reads the page and
both entries as 「連接 AI 助理」, and records the new source digests, so none
of the four leaves falls back to English.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WV4cya5ej5GQV86RPbRPK
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Nov 6, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:server#1 · os-elon-musk · session_016WV4cytLmJxfAmgPVjUbbW

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: d104e2b4247de8c39d84c79ab7bcccd7abd220a4
Local-runs: probe — one tsx script that imported the head's en.ts, zh-Hant.ts, zh-CN.ts, zh-Hant.source-hashes.ts and source-hash.ts to count leaves and recompute every digest with the repo's own hashSource; nothing else was built, run or re-run
Scope: packages/platform-objects/src/apps/translations/{zh-Hant.ts, zh-Hant.source-hashes.ts} + packages/platform-objects/src/apps/translations/{en.ts, zh-CN.ts, zh-CN.source-hashes.ts, source-hash.ts, app-nav-translation-parity.test.ts}, packages/plugins/plugin-security/src/translations/zh-Hant.objects.generated.ts, merge commit 8bb5eed, main commit 78eb352 (#30935), the head's check-runs

This is a delta record over record 6686780589, which reviewed head e8d9055ec7ca343cb5b308a8019843f5c138f7e7 and PASSed. The delta is two commits: a merge of main at 1b3e22f02c (merge commit 8bb5eeda86, parents e8d9055e and 1b3e22f02c) and one fix commit, d104e2b424, touching only the two hand-authored zh-Hant files (+9/-7). The 36 files judged in 6686780589 were not re-read; nothing in the delta changes them other than the two named below. The head did not move during this review.

① Derived judgments

Must-fix: none.

The merge commit is clean. git diff 1b3e22f02c 8bb5eeda86 equals git diff 33043bd8a2 e8d9055e (the PR's own 36 files, +7216/-55) hunk for hunk, and git diff e8d9055e 8bb5eeda86 equals git diff 33043bd8a2 1b3e22f02c (what main brought in: 216 files) hunk for hunk. The only textual differences are blob index lines and one hunk-header line offset in app-nav-translation-parity.test.ts, the one file both sides touched: the PR adds zh-Hant to its LOCALES table and #30935 rewords one comment line (grp_account_developer to grp_account_ai_assistant), in different regions, so git merged them without conflict and no hunk of either side was altered. No file of this PR was changed by conflict resolution.

The fix commit is exactly the missing parity. zh-Hant.ts gains grp_account_ai_assistant: { label: 'AI 助理' } in the Account app, retitles the three nav_connect_agent / pages.connect_agent.label leaves from 連接 AI 代理 to 連接 AI 助理, and moves the Setup app's nav_connect_agent from after nav_api_keys to after nav_system_overview, the position en.ts:72 and zh-CN.ts:53 give it since #30935. The comment above the Account leaf is reworded the same way en and zh-CN were. zh-Hant.source-hashes.ts gains the one new entry and replaces the three eeb174613510e87d digests with a4542422fb5e8a68, which are the same four lines #30935 wrote into zh-CN.source-hashes.ts, es-ES.source-hashes.ts and ja-JP.source-hashes.ts.

Counted on the head: en.ts 139 string leaves, zh-Hant.ts 139, zh-CN.ts 139; 0 missing, 0 extra; zh-Hant key order equals zh-CN (the hand bundles already differ from en in order, as 6686780589 noted). zh-Hant.source-hashes.ts has 139 entries, one per leaf, none for an unknown path, and every digest equals hashSource of the current en leaf. In particular hashSource('AI Assistant') is cff764b13822a259 and hashSource('Connect an AI Assistant') is a4542422fb5e8a68, the values recorded.

Wording: AI 助理 and 連接 AI 助理 are Traditional (助理 is the Taiwan word for "assistant"; zh-CN renders the same leaves as AI 助手 / 连接 AI 助手). No Simplified-only character is in the changed strings. plugin-security's zh-Hant uses AI 代理 for the English "AI agent" (an assignment principal, zh-Hant.objects.generated.ts:53,57), which is a different term; before #30935 these nav leaves read "Connect an Agent" and the PR rendered them 連接 AI 代理 to match, and now that en says "AI Assistant" the switch to 助理 keeps the two concepts apart in zh-Hant exactly as en keeps them apart. No other zh-Hant bundle in the repo carries an "assistant" leaf to conflict with.

#30935 brought nothing else zh-Hant lacks. Between the merge base and 1b3e22f02c the only commit touching packages/platform-objects/src/apps/translations or src/metadata-translations is 78eb352. In platform-objects it changed en.ts (the four leaves above and two comment lines), the three sibling hand bundles and their hash tables, and the parity test's comment line; it touched no *.generated.ts bundle, no metadata-translations file, and nothing under src/pages or src/apps/dashboards. Its other translation edits are the ui/packages/i18n locales, outside this package. So grp_account_ai_assistant and the three retitled leaves were the whole gap, and the fix closes it.

② Semver level

Unchanged from 6686780589: '@objectstack/platform-objects': patch, Clause-②: no, Metadata-protocol: none. The delta adds one translation leaf and reword three; no published type, export, spec key or accepted value moves.

③ Boundary flags

  • No path of the delta is a packages/spec/src/** or governed path; the face is still decided by the 3,000-line rule as in 6686780589.
  • Only the zh-Hant files moved; zh-CN.ts, en.ts, the generated bundles, scripts/i18n-stale-fill-baseline.json and the root package.json are untouched by the fix.
  • Check-runs on d104e2b424 at the time of writing: finished and success are Auto Label, Check PR Size, Dogfood Regression Gate, Flag docs affected by code changes, Governed Surface Queue Guard, PR-body guards, Test UI and the filter job. Still in_progress: Build Core, Check Changeset, Live E2E UI, Plan Test Core shards, the eight Lint sub-lanes and the four Type Check sub-lanes; the Test Core shards had not been planned yet. Skipped: the UI build, docs, opt-in and conformance lanes that do not run for this path set. Nothing is red; the commit status is pending only because the run is young. The seat confirms Test Core green, and in particular app-nav-translation-parity.test.ts "account — zh-Hant", before re-queueing.

④ Design judgment

No hits file. The content was judged against the code it feeds: withSourceFallback reads the hand table and the generated table per locale, and the zh-Hant hand table is again complete and digest-exact against the current en, so the first en edit under any leaf falls back rather than serving a stale string. The parity test reads en's Account and Setup navigation key sets against each locale's, and zh-Hant now carries both sets in full, which is the failure the queue reported and the only thing the fix needed to change.

Implemented-by: claude/project-thread-1jep1s
Reviewed-by: session_016WV4cytLmJxfAmgPVjUbbW

VERDICT: PASS

@objectstack-fleet
objectstack-fleet Bot enabled auto-merge November 6, 2026 15:18
@github-actions

github-actions Bot commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

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

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

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

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

  • Test Core (3/8) — 失败步骤: Run this shard's tests

    @objectstack/platform-objects:test:  FAIL  src/apps/translations/app-nav-translation-parity.test.ts > every nav id an app presents is translated in every locale > account — zh-Hant
      ↳ 失败原因: @objectstack/platform-objects:test: AssertionError: untranslated nav ids in apps.account.navigation: expected [ 'grp_account_ai_assistant' ] to deeply equal []
    

↳ 失败原因 是判读的关键:超时(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,按失败测试文件聚合):

历史信号:

  • ⚠️ 本 PR 过去 24h 已在队列失败 1 次(不含本次)。 内容未变而反复失败 ⇒ 高度怀疑 flaky 测试或与同组 PR 的语义冲突,重排不解决。
  • 过去 24h 队列共有 19 个失败构建(不含本次)。

分诊清单:

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

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

This branch has not been deployed

No deployments
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/xl tests 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.

3 participants