Skip to content

docs(i18n): 把 engine.* 的 en/zh 立场写进 i18n 惯例文档 (#4662) - #4867

Merged
yinlianghui merged 1 commit into
mainfrom
claude/issue-4662-engine-i18n-carveout
Aug 16, 2026
Merged

docs(i18n): 把 engine.* 的 en/zh 立场写进 i18n 惯例文档 (#4662)#4867
yinlianghui merged 1 commit into
mainfrom
claude/issue-4662-engine-i18n-carveout

Conversation

@yinlianghui

Copy link
Copy Markdown
Collaborator

Fixes #4662

按 2026-08-16 维护者裁定(评论 5306093125,方案 A)执行:记录立场,不迁移 key。docs-only。

前提复核(origin/main @ 65e88e6)

issue 的事实基础全部复现,无一失效:

  • packages/app-shell/src/views/metadata-admin/i18n.ts 4299 行;ENGINE_STRINGS_EN 1305 个 engine.* key、ENGINE_STRINGS_ZH 1349 个。
  • 十个语言包里 engine.* key 数为 0(grep -c engine packages/i18n/src/locales/*.ts 全 0)。
  • 文件头确实把这套两语言表记为 Phase 3f 的设计:服务端 /meta/typeslabel 为主路径,本地表是无翻译包环境的兜底 + zh-CN 的过渡真源。

命名空间分布(en 侧):studio 414、inspector 377、packages 95、edit 82,其余为 flow 设计器 / 诊断 / 目录等 —— 即整个 Studio 管理台面。

落点选择

packages/i18n/README.md,新增一节 Scope — the engine.* carve-out (metadata-admin / Studio)

选它的理由:仓内没有独立的 i18n 惯例文档 —— content/docs/** 无任何 i18n 页;skills/objectui/guides/i18n.md 是面向应用作者的对外技能指南,内部管理台的 carve-out 放进去不合适;三道 i18n 门的惯例各自记在自己的脚本头里。十语言包体系对外的权威落点就是这个包 README,因此按「⛔ 自创新文档除非确无既有落点」的要求,补进既有文档而非新建。

补的是什么(避免复述)

已有三处记录彼此一致,均未被改动:

已有记录 说了什么
i18n.ts 文件头 为什么存在(Phase 3f、服务端 label 为主)
scripts/check-i18n-call-site-keys.mjs 门为什么跳过它(1074 个调用点、移除排除项实测 89 个永久假红)
EXCLUDED_TRANSLATORS 按声明跳过,且未注册模块的 t 导入是硬错误

新增的三点是这三处都没有的:

  1. 语言后果 —— 只覆盖 en/zh,ar/de/es/fr/ja/ko/pt/ru 八个语言在这些页面渲染英文;这是 carve-out 的代价,不是漏做的 backfill。
  2. 门为什么看不见 —— key parity 是包与包相比,engine.* 不在任何包里,所以它不是该测试的例外,而是在其主题之外(刻意与该测试头部「唯一允许的例外是 outbound 消息集」区分,没去动那个测试)。
  3. 重启条件 —— 收窄到具体信号:出现非 en/zh 管理台的明确需求时重看;泛泛的「多语言覆盖」诉求不算,那部分包体系在其他所有面上已经服务到位。

另在 i18n.ts 文件头补一段指回该节,两处互指,并写明「任一处变动时保持同步」。

验证

docs-only 改动,没有任何门会因为这段文字的措辞变红,如实说明判据:

  • 有门看得见的部分:packages/i18n/README.mdcheck-doc-links.mjsSCAN_ROOTS 里(packages/*/README.md,disk 规则),新增的三个相对链接受该门覆盖。反向验证(方向预判为红,结果一致):把 ../app-shell/src/views/metadata-admin/i18n.ts 改成不存在的 i18n-NOPE.ts,门立刻报 Found 1 broken link (1 distinct target) ... [example-relative] 并 exit 1;改回后 Links are valid across 13 scan roots.
  • 无门看得见的部分:正文与既有记录是否一致,靠人读对齐 —— 已逐条比对 i18n.ts 文件头、call-site 门头部、EXCLUDED_TRANSLATORS 的 reason,无矛盾表述。

跑过的门(全绿):

node scripts/check-doc-links.mjs        -> Links are valid across 13 scan roots.
node scripts/check-control-bytes.mjs    -> OK (scanned 4354 tracked text file(s); skipped 85 binary)
node scripts/check-i18n-call-site-keys.mjs -> Every in-scope call-site key resolves against the en pack (2890 keys)...
node scripts/check-i18n-en-drift.mjs    -> No en value changed in this range.
node scripts/check-skills-paths.mjs     -> OK (93/94 stated path(s) resolve; 1 baselined)
node scripts/check-changeset-fixed.mjs / check-changeset-no-major.mjs -> OK

type-check(改到了 .ts 文件头注释,仓根 turbo,scoped):

pnpm exec turbo run type-check --filter=@object-ui/app-shell --filter=@object-ui/i18n --concurrency=2
Tasks:    31 successful, 31 total

测试:

pnpm exec vitest run packages/i18n/src/__tests__/all-locales-key-parity.test.ts \
                     packages/app-shell/src/views/metadata-admin/studio-locale.i18n.test.tsx --maxWorkers=2
Test Files  2 passed (2)
     Tests  37 passed (37)

changeset

.changeset/engine-i18n-carveout-recorded.md,空 frontmatter。这是门自己的读数,不是我的判断:因为动了 packages/app-shell/src/**(纯注释),check-changeset-presence.mjs 先判红要求声明;空 frontmatter 是它文档化的一等通过方式("declared as releasing nothing, which is the explicit exemption and a complete answer to this gate"),补上后:

✅  1 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s)

边界

⛔ 未迁移任何 key;⛔ 未动十语言包;⛔ 未碰 content/docs/releases/**;⛔ 未改 all-locales-key-parity.test.ts(engine.* 不是它的例外,加进去反而会误导)。


Generated by Claude Code

metadata-admin(Studio)的 engine.* 通过模块本地的两语言表解析,不进十语言包 ——
这是 Phase 3f 的设计(服务端 /meta/types 的 label 为主路径,本地表是无翻译包环境
的兜底),但此前只记在源码文件头里,读 i18n 惯例的人看不到。

packages/i18n/README.md 补一节 "Scope — the engine.* carve-out",从语言包体系
这一端陈述同一立场,并补上文件头没说的两个后果:只覆盖 en/zh(其余八个语言渲染
英文)、i18n 门按构造看不见该命名空间;写明重启条件 —— 出现具体的非 en/zh 管理台
需求信号时重看。i18n.ts 文件头加一段指回该节,两处互指。

未迁移任何 key,未动十语言包。

Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Aug 16, 2026
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Main entry (gzip) 24.7 KB 350 KB
Entry file index-mDFWTOEz.js
Status PASS

📦 Bundle Size Report

Package Size Gzipped
app-shell (index.js) 9.56KB 3.59KB
app-shell (runtime-config.js) 7.42KB 2.32KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 8.92KB 3.41KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 1.17KB 0.53KB
auth (AuthProvider.js) 25.13KB 5.40KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.13KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.64KB 2.21KB
auth (SocialSignInButtons.js) 9.60KB 3.89KB
auth (UserMenu.js) 3.40KB 1.22KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 38.46KB 10.17KB
auth (createAuthenticatedFetch.js) 6.34KB 2.43KB
auth (index.js) 2.35KB 1.07KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.02KB 0.88KB
auth (useIsWorkspaceAdmin.js) 1.61KB 0.85KB
collaboration (CommentThread.js) 26.07KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.65KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 496.22KB 110.42KB
core (index.js) 3.79KB 1.52KB
create-plugin (index.js) 10.08KB 3.26KB
data-objectstack (index.js) 157.05KB 43.28KB
fields (index.js) 231.73KB 57.60KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (currency.js) 1.22KB 0.64KB
i18n (i18n.js) 4.28KB 1.75KB
i18n (index.js) 3.35KB 1.38KB
i18n (pickLocalized.js) 3.69KB 1.73KB
i18n (provider.js) 23.12KB 7.62KB
i18n (useDisplayLocale.js) 2.84KB 1.45KB
i18n (useObjectLabel.js) 27.59KB 6.63KB
i18n (useSafeTranslation.js) 7.77KB 3.13KB
layout (index.js) 38.86KB 10.83KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.74KB
mobile (index.js) 1.50KB 0.62KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 2.53KB 0.85KB
mobile (useResponsive.js) 0.71KB 0.42KB
mobile (useResponsiveConfig.js) 1.36KB 0.63KB
mobile (useSpecGesture.js) 4.32KB 1.64KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 9.35KB 3.31KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 4.42KB 1.42KB
permissions (evaluator.js) 5.12KB 1.74KB
permissions (index.js) 0.91KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.52KB
permissions (usePermissions.js) 1.81KB 0.83KB
plugin-ai (index.js) 15.75KB 3.80KB
plugin-calendar (index.js) 46.86KB 12.91KB
plugin-charts (index.js) 64.44KB 18.28KB
plugin-chatbot (index.js) 181.21KB 43.14KB
plugin-dashboard (index.js) 128.14KB 32.58KB
plugin-designer (index.js) 212.39KB 42.83KB
plugin-detail (index.js) 239.81KB 59.97KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 115.34KB 27.74KB
plugin-gantt (index.js) 164.30KB 40.02KB
plugin-grid (index.js) 192.23KB 51.30KB
plugin-kanban (index.js) 52.72KB 14.54KB
plugin-list (index.js) 111.23KB 26.97KB
plugin-map (index.js) 18.16KB 5.81KB
plugin-markdown (index.js) 13.72KB 4.69KB
plugin-report (index.js) 41.38KB 11.09KB
plugin-timeline (index.js) 26.68KB 7.66KB
plugin-tree (index.js) 8.50KB 2.88KB
plugin-view (index.js) 83.81KB 20.49KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.66KB 3.50KB
providers (index.js) 0.44KB 0.22KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 3.77KB 1.33KB
react (SchemaRenderer.js) 27.53KB 9.41KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 1.28KB 0.68KB
react (schema-input.js) 1.45KB 0.83KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 4.09KB 1.74KB
sdui-parser (index.js) 4.47KB 2.03KB
sdui-parser (parse.js) 10.04KB 2.82KB
sdui-parser (types.js) 0.29KB 0.24KB
sdui-parser (validate.js) 4.69KB 1.48KB
types (ai.js) 0.20KB 0.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 0.99KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 0.20KB 0.18KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 0.20KB 0.18KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.87KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-retry.js) 4.32KB 2.02KB
types (index.js) 3.05KB 1.52KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 2.59KB 1.31KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (spec-report.js) 5.05KB 1.93KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 0.20KB 0.18KB
types (ui-action.js) 3.40KB 1.71KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

Copy link
Copy Markdown
Collaborator Author

【PM 验收 · ACCEPT】objectui 分片 PM(session_01GTRjn8xBqp75dk7kFupVRt)对 #4662 裁定(方案 A 记录立场,评论 5306093125)的实施验收:

实物核验:3 文件全为新增 —— i18n 包 README 新增 Scope 一节、i18n.ts 恰 14 行且全部为注释行(PM 逐行核:非注释改动 0)、空 frontmatter changeset(门自身读数判免发布);packages/i18n/src 零触碰(⛔ 迁移 key 兑现)。模型标识 0、releases 0。落点核准(留否决窗):裁定原文「where the i18n conventions live」—— dev 实测仓内无独立 i18n 惯例文档(content/docs 零 i18n 页、skills 指南是对外应用作者面、三道门的惯例各在脚本头),十语言包体系权威落点即该包 README,判断成立;README 对外可见的取舍(外部读者同样会问语言覆盖)已在 PR 声明,维护者若想只对内可见可移 docs/ 或 ADR。

内容质量:补的三点(语言后果、门为何看不见 —— engine.* 在 key-parity 主题之外而非例外、重启条件)恰是既有三处记录都缺的;刻意不动 all-locales-key-parity.test.ts 的理由(加进例外表会与其自述冲突)正确。反向验证:断链红(doc-links 门指名)+ 如实记录「措辞本身无门,判据是链接门绿 + 三处记录对齐」。CI 亲读:19 项全 completed(17 success + 2 skipped),零失败。零 finding。

处置:undraft + auto-merge(SQUASH)。


Generated by Claude Code

@yinlianghui
yinlianghui marked this pull request as ready for review August 16, 2026 19:23
@yinlianghui
yinlianghui added this pull request to the merge queue Aug 16, 2026
Merged via the queue into main with commit b6275db Aug 16, 2026
20 checks passed
@yinlianghui
yinlianghui deleted the claude/issue-4662-engine-i18n-carveout branch August 16, 2026 19:24
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

Projects

None yet

2 participants