Skip to content

Commit 4c84f33

Browse files
committed
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
1 parent ee0e684 commit 4c84f33

2 files changed

Lines changed: 42 additions & 0 deletions

File tree

content/docs/ui/translations.mdx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,13 +141,29 @@ npx os i18n extract --locales zh-CN --fill todo --out src/translations
141141
142142
# Report coverage; fail the build when it slips
143143
npx os i18n check --strict --threshold 95
144+
145+
# Fail if the committed bundles have fallen behind the schema
146+
npx os i18n extract --locales zh-CN --fill todo --out src/translations --check
144147
```
145148

146149
`os i18n check` exits non-zero on violations, so it works as a CI gate.
147150
A missing string in the **default** locale is an error; missing strings in
148151
other locales are warnings until you set `--strict` / `--threshold`. The Todo
149152
example ships a completeness test alongside its bundlesworth copying.
150153

154+
The two gates answer different questions, and you want both. `os i18n check`
155+
asks *are the strings translated?*a coverage number about human work.
156+
`os i18n extract --check` asks *are the generated bundles still what the schema
157+
produces?*a freshness check about machine output. Renaming a field's label,
158+
adding an object, or removing a spec key leaves coverage at 100% while the
159+
bundles quietly go stale, which is exactly how this repo's own bundles ended up
160+
carrying translations for keys the schema had deleted (#3670).
161+
162+
`--check` writes nothing: it re-renders and diffs against `--out`, naming each
163+
stale file and printing the regenerate command. It runs in the same **merge
164+
mode** as a normal extract, so it never asks anyone to re-translatean
165+
up-to-date bundle re-extracts byte-identically.
166+
151167
## Current boundaries
152168

153169
Honest limits worth knowing before you plan around them:

skills/objectstack-i18n/SKILL.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,32 @@ locale are errors; `--strict` promotes non-default gaps to errors and
398398
`--show-keys` lists every missing key. `os lint --i18n-strict` folds the same
399399
gate into linting.
400400

401+
### `os i18n extract --check` — freshness, not coverage
402+
403+
If you commit **generated** bundles (`*.generated.ts` produced by
404+
`os i18n extract`), coverage is only half the gate:
405+
406+
```bash
407+
os i18n extract <config> --locales=zh-CN,ja-JP --fill=default \
408+
--out=src/translations --check
409+
```
410+
411+
`--check` writes nothing. It re-renders what a real extract would produce and
412+
fails if that differs from what is committed in `--out`, naming each stale or
413+
missing file and printing the regenerate command.
414+
415+
**Use both gates — they answer different questions.** `os i18n check` asks *are
416+
the strings translated?* (coverage: human work). `extract --check` asks *are the
417+
generated bundles still what the schema produces?* (freshness: machine output).
418+
Renaming a label, adding an object, or removing a spec key leaves coverage at
419+
100% while the bundles quietly go stale — which is exactly how the platform's
420+
own bundles ended up carrying translations for keys the schema had already
421+
deleted, plus fields with no entry in any locale.
422+
423+
It runs in the same **merge mode** as a normal extract, so it never asks for
424+
re-translation: an up-to-date bundle re-extracts byte-identically. Requires
425+
`--out` — there is nothing to compare against without it.
426+
401427
### Diff & Coverage Schemas
402428

403429
The spec models coverage results for tooling: `TranslationCoverageResult`

0 commit comments

Comments
 (0)