fix(i18n): clear the accumulated drift in the generated translation bundles - #3670
Merged
Merged
Conversation
…undles Finishes what #3659 deliberately left alone. That PR regenerated only the `*.objects.generated.ts` bundles and explicitly EXCLUDED the metadata-forms ones, because the same run deleted keys and I had not yet checked whether it was discarding curated translations. It was not — I checked: capabilities.trash / capabilities.mru enable.trash/mru retired in 16.x (#2377); the schema now REJECTS them, with tombstone guidance in UNKNOWN_KEY_GUIDANCE. agent `visibility` removed 2026-07 (#1901). Those are the only deletions in the whole diff, and all three are translations for keys no author can write any more. Nothing live is lost. The same sweep also picks up what the bundles never learned: summaryOperations.{object,function,field,relationshipField,filter} sys_invitation.{business_unit_id,positions} (ADR-0105 D8) and fixes a third, separate problem: `sys_migration`'s labels and help text sat committed as EMPTY STRINGS in the ja-JP and es-ES bundles. An empty string is not an untranslated key — it renders blank, so that object had no readable labels at all in those locales. They now carry the schema text like every other untranslated key. Run in merge mode, so every existing translation is preserved; the only removals are the three dead keys above. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UYLC8TfjzHGwatNxZKdX7H
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 1 package(s): 2 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
Picks up #3666's CI caching fix ('stop PR-side cache churn'), which the workflow used by this PR's run predates — the run stalled for 50+ minutes on 'Run affected tests' across two attempts on separate runners.
os-zhuang
marked this pull request as ready for review
July 27, 2026 14:12
os-zhuang
added a commit
that referenced
this pull request
Jul 27, 2026
…-check` (#3683) * feat(cli): gate generated translation bundles with `os i18n extract --check` The generated translation bundles had no freshness gate. Nothing failed when they fell behind the schema, so they only ever got fixed when someone happened to re-run the extractor by hand — and by the time anyone did (#3670), three distinct drifts had accumulated at once: - translations left behind for keys the schema had REMOVED (`enable.trash` / `enable.mru`, #2377; agent `visibility`, #1901) — keys the schema now rejects outright; - keys the schema had GAINED with no entry in any locale (`summaryOperations.*`, the ADR-0105 D8 invitation-placement fields, and the better-auth 1.7 columns from #3647); - `sys_migration` committed with EMPTY STRINGS for its labels in ja-JP and es-ES, which renders blank rather than falling back to anything readable. This is the same shape as #3624: an artifact and its source with no gate between them, so the gap is only found by accident. #3647 closed that one for better-auth's columns by deriving the expected surface and failing the build; this does the same for translations. `--check` renders exactly what a real extract would write — both branches iterate one shared rendered set, so the check cannot drift from the writer — then compares against `--out` instead of writing, listing every stale or missing file and printing the regenerate command. It runs in merge mode like any other extract, so it never asks for re-translation: an up-to-date bundle re-extracts byte-identically. The flag lives on the CLI rather than in a repo script, so any consumer that ships generated bundles can gate them the same way. Here it is `pnpm check:i18n`, wired into lint.yml beside the other post-build consumer gates (it reads the built spec dist through the extract config). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UYLC8TfjzHGwatNxZKdX7H * docs(i18n): document the extract --check freshness gate The docs and the i18n skill both presented `os i18n check` as *the* CI gate. It is the coverage gate — it answers 'are the strings translated?'. For anyone committing generated bundles that leaves the other half unguarded: renaming a label, adding an object, or removing a spec key keeps coverage at 100% while the bundles quietly go stale. Documents the two as a pair, in both surfaces, since the skill is what ships to third parties via `npx skills add`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UYLC8TfjzHGwatNxZKdX7H --------- Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
收尾 #3659 刻意留下的那一块。
那个 PR 只重新生成了
*.objects.generated.ts,明确排除了 metadata-forms 的四个 bundle —— 因为同一次 extract 会删除一些 key,而当时我还没核实它是不是在丢弃已经翻好的内容。现在核实了:没有丢。 整个 diff 里的删除只有三条,全都是 spec 已经移除、作者再也写不出来的 key:
capabilities.trash/capabilities.mruenable.trash/enable.mru在 16.x 线被移除(#2377),schema 现在直接拒绝,并在UNKNOWN_KEY_GUIDANCE里留了 tombstone 指引visibility同一次扫描还补上了 bundle 从没学会的 key
summaryOperations.{object,function,field,relationshipField,filter}—— 字段汇总配置的子项,spec 里一直有(field.zod.ts:440)sys_invitation.{business_unit_id,positions}—— ADR-0105 D8 的 placement 字段以及第三个、独立的问题:空字符串
sys_migration的 label 和 help 在 ja-JP 和 es-ES 两个 bundle 里是以空字符串提交的。空字符串不等于"未翻译的 key" —— 它会渲染成空白,所以那个对象在这两个 locale 下根本没有可读的标签。现在它和其他未翻译 key 一样带上 schema 原文。
安全性
以 merge 模式运行(
--no-merge未传),所有既有翻译都保留;整个 diff 里的删除只有上面那三条死 key。测试
@objectstack/platform-objects223 passed (6 files) —— 含 bundle-ownership 守卫。Refs #3624, #3659, #2377, #1901。
Generated by Claude Code