Found while shipping #172. Filed unassigned.
Notation: this repo's issue-body sanitizer strips angle brackets and decodes HTML numeric character references, including inside code fences. So locale placeholders are written .LOCALE.mdx rather than with angle brackets, and -> stands for an arrow.
The reading
zh-Hant is a derived locale: content/docs/**/*.zh-Hant.mdx is generated from the zh-Hans sibling by apps/docs/scripts/gen-zh-hant.mjs and committed. It is never translated from English and never hand-written; AGENTS.md and docs/TRANSLATION.md now say so.
check-translations.mjs does not know that. It derives its locale list from apps/docs/lib/i18n.ts and treats every non-default locale identically, so --worklist emits Traditional items alongside the Simplified ones:
worklist entries: 505
{"de":75,"es":75,"fr":75,"ja":75,"ko":75,"zh-Hans":65,"zh-Hant":65}
{"en":"content/docs/build/agents.mdx","out":"content/docs/build/agents.zh-Hant.mdx","locale":"zh-Hant","mode":"auto"}
docs/TRANSLATION.md calls the worklist "the entire input to a pass". So the pass is being handed 65 items instructing it to translate English into Traditional Chinese.
Why it matters
Acting on one of those items produces a Traditional page that:
- was translated from English rather than converted from Simplified, i.e. a second, divergent Chinese voice on the same page;
- is overwritten by the next
pnpm --filter @objectos/docs gen:zh-hant;
- fails the CI step
gen-zh-hant.mjs --check in the meantime.
The bad outcome is contained — CI goes red and names the fix — so this is wasted pass effort and a confusing failure, not a shipping defect. That containment is why #172 filed it instead of fixing it.
The fix
The worklist (and the Missing/Stale columns, arguably) should skip locales that are generated from another locale. check-translation-output.mjs already carries the fact, as DERIVED_FROM, added in #172. The two scripts deliberately duplicate their small readers rather than share, so the choice is between a second DERIVED_FROM literal with a cross-reference comment and a shared leaf module under .github/scripts/lib/ — note tools/ci-scripts/run-self-tests.mjs scans only the top level of .github/scripts/, so a subdirectory is safe from its "declares --self-test but is not listed" rule.
Interim mitigation is prose only: docs/TRANSLATION.md now carries a warning to skip those items.
Related but not the same defect: #135 (worklist driven by provenance alone, so fidelity-flagged files are invisible to any pass).
Found while shipping #172. Filed unassigned.
Notation: this repo's issue-body sanitizer strips angle brackets and decodes HTML numeric character references, including inside code fences. So locale placeholders are written
.LOCALE.mdxrather than with angle brackets, and->stands for an arrow.The reading
zh-Hantis a derived locale:content/docs/**/*.zh-Hant.mdxis generated from thezh-Hanssibling byapps/docs/scripts/gen-zh-hant.mjsand committed. It is never translated from English and never hand-written;AGENTS.mdanddocs/TRANSLATION.mdnow say so.check-translations.mjsdoes not know that. It derives its locale list fromapps/docs/lib/i18n.tsand treats every non-default locale identically, so--worklistemits Traditional items alongside the Simplified ones:docs/TRANSLATION.mdcalls the worklist "the entire input to a pass". So the pass is being handed 65 items instructing it to translate English into Traditional Chinese.Why it matters
Acting on one of those items produces a Traditional page that:
pnpm --filter @objectos/docs gen:zh-hant;gen-zh-hant.mjs --checkin the meantime.The bad outcome is contained — CI goes red and names the fix — so this is wasted pass effort and a confusing failure, not a shipping defect. That containment is why #172 filed it instead of fixing it.
The fix
The worklist (and the
Missing/Stalecolumns, arguably) should skip locales that are generated from another locale.check-translation-output.mjsalready carries the fact, asDERIVED_FROM, added in #172. The two scripts deliberately duplicate their small readers rather than share, so the choice is between a secondDERIVED_FROMliteral with a cross-reference comment and a shared leaf module under.github/scripts/lib/— notetools/ci-scripts/run-self-tests.mjsscans only the top level of.github/scripts/, so a subdirectory is safe from its "declares --self-test but is not listed" rule.Interim mitigation is prose only:
docs/TRANSLATION.mdnow carries a warning to skip those items.Related but not the same defect: #135 (worklist driven by provenance alone, so fidelity-flagged files are invisible to any pass).