Files
deepseek-harness/docs/i18n
Tianyi Cui 3841c4ee58 docs(i18n): briefed update path in the workflow, contract, and Agent Note
The dsh-translate-docs skill now triages updates onto a briefing-driven
path — gen-translation-brief output as the translator's whole working
set, orchestrator-applied mechanical fence edits, scoped record/check —
while the whole-document path for new pairs is unchanged. The i18n
README documents the scoped gate forms and the briefing tool;
development.md lists the new command; the new bilingual Agent Note
records the decision and the ten-example benchmark behind it (briefed
path ~1/3 the tokens and wall clock of the corpus-loading path at equal
judged quality; whole-document re-translation rejected on preservation
collapse). Counterpart updates in this commit were produced with the
new briefed path; the new note's Chinese side is a whole-document
translation.
2026-07-27 00:44:22 +08:00
..

Bilingual documentation

English | 中文

This repo's documentation is read by people and agents both inside and outside the company, so every document in scope is maintained in English and Simplified Chinese. This page defines the pairing contract, enforcement gate, scope, and exclusions; translation-rules.md defines how to translate; terminology.md is the terminology source of truth. The committed agent workflow lives in .agents/skills/dsh-translate-docs.

The pairing contract

  • Both languages carry equal authority. A document may be authored and reviewed in either language first — a Chinese-first Agent Note is as legitimate as an English-first one — and the counterpart is translated from it. Neither file outranks the other; what binds them is that they must say the same thing.

  • A pair is three sibling files. The English foo.md, the Chinese foo.zh.md, and a consistency record foo.i18n.yaml, all in the same directory. No locale directories, no separate translation repo, no interleaved bilingual files. Pairs merge whole: a PR never lands one language without the other two files.

  • The consistency record. foo.i18n.yaml holds the full git blob hash of each side as of the last time the two were confirmed to say the same thing:

    foo.md: 3f786850e387550fdab836ed7e6dc881de23001b
    foo.zh.md: 89e6c98d92887913cadf06b2adb97f26cde4849b
    

    Blob hashes, not commit hashes, so the record is computable for files edited in the same PR (git hash-object foo.md) and consistency is a pure content comparison. The recorded hashes also recover the exact last-confirmed text of either side, so an out-of-sync pair is updated by patching the counterpart minimally against the edited side's diff — never by re-translating whole files. pnpm run gen-translation-brief <pair> assembles that update's working set mechanically: the edited side's diff since last confirmation, the counterpart sections it lands in, the terminology rows it touches, and the binding update rules (briefed-updates Agent Note). After bringing the pair back in line, pnpm run verify-translation-pairing --write <pair> re-records both hashes; that yaml diff is the reviewable act of confirming consistency, which is why --write requires naming the pairs you confirmed (--write --all is the explicit corpus-wide form).

  • Language switcher. Both files link to each other immediately after their H1 heading: the English file carries English | [中文](foo.zh.md) and the Chinese file carries [English](foo.md) | 中文.

  • Structure mirrors the counterpart. Heading depths and order, list kinds, ordered-list starts, list item counts, table row and column counts, link targets, and verbatim code blocks match one to one across the pair — see translation-rules.md for the full preservation rules. Existing Markdown gates apply to .zh.md files unchanged (verify-md-wrap, verify-md-links).

The gate: verify-translation-pairing

pnpm run verify-translation-pairing (part of doc-sync, which contributors run locally for documentation changes and CI runs exhaustively) enforces the contract mechanically:

  1. Every document in scope has a complete pair. README discovery is case-insensitive on the basename, so missions/readme.md is in scope alongside the other documentation roots.
  2. Every pair artifact that exists at all is complete and consistent: all three files present, each side's current blob hash equals the recorded one (editing either side without re-confirming the pair goes red), both sides carry the language switcher, and the structural signatures match in order — heading depths, verbatim code blocks (info string and content), table row and column counts, list kinds, ordered-list starts, item counts, and every link target apart from the switcher.
  3. Files listed as excluded have no .zh.md and no .i18n.yaml at all.

Source-oriented code gates consume an exact .zh.md fence sequence as a derivative of its unsuffixed sibling instead of compiling or manifesting the same code twice. The sequence must match in length, order, fence kind, and byte-exact body; otherwise both copies remain independently checked and the pairing gate reports the structural mismatch.

pnpm run verify-translation-pairing --list prints the current pairing state of every document in scope — missing, out-of-sync, or ok. It never fails; missing and out-of-sync rows identify violations that the normal check rejects.

pnpm run verify-translation-pairing <pair...> checks just the named pairs — any of a pair's three files (or its bare stem) names it — so an update loop verifies its own pair in seconds instead of re-scanning the corpus. The no-argument corpus-wide form is what doc-sync and CI run; a scoped green never substitutes for it at PR level.

The practical rule this gate creates: when a PR edits either side of a paired document, the same PR updates the counterpart and re-records the pair (run the dsh-translate-docs skill, then --write <pair>), exactly like the repo's existing doc-sync rule for code and READMEs. A PR that leaves a pair out of sync goes red in CI.

The gate's limit, stated plainly: a green gate means the pair was confirmed consistent at these exact contents, not that the confirmation was sound. It checks hashes and shape; it cannot judge whether the two sides actually say the same thing, or whether the wording is accurate, well-termed, and natural — that is the reviewer's half of the contract, per translation-rules.md. A re-recorded pair with a sloppy counterpart passes the gate; it must not pass review.

Scope and exclusions

Scope: every non-vendor README, plus every document under .agents/notes/**, docs/**, and python/**. README matching is case-insensitive on the basename and covers future directories without another manifest edit. Dependency and ignored build-output trees are discovery exclusions, not source documentation.

Excluded (never paired, and the gate rejects a .zh.md or .i18n.yaml for them):

  • docs/cordis-catalog/, docs/tool-catalog/, docs/config-catalog.md, docs/persistence-catalog.md, docs/module-graph.md, docs/agent-lifecycle.md, docs/capability-seams.md, docs/event-producer-consumer.md, docs/graph-atlas.md, and docs/tool-execution-pipeline.md — generated files; their generators emit English only today, so a hand-written translation would go stale on every regeneration. The planned follow-up is to teach the generators to emit Chinese alongside English, at which point these leave the exclusion list.
  • docs/AGENTS.md, .agents/notes/**/AGENTS.md, and their CLAUDE.md instruction symlinks — agent instructions, maintained in English only like the root AGENTS.md.
  • docs/i18n/terminology.md and style-samples.md — both are bilingual by construction.
  • translation-prompt.md — the automated pipeline's prompt template; its body is machine-consumed verbatim, so a paired translation would change pipeline behavior.

Universal requirement: every current or future document in scope must merge as a complete bilingual pair. scripts/translation-pairing.manifest.json contains only explicit exclusions; there is no per-file rollout list, date cutoff, or README-specific policy class.

Division of labor

Counterparts here are produced by an agent running dsh-translate-docs and reviewed by a human — inference is cheap here, review attention is the scarce resource. The gate checks pair completeness, recorded hashes, switchers, and its documented structural signature. Review still owns translation quality, terminology, and structural requirements that the signature does not encode. The prompt contract is executable: scripts/translation-prompt.ts renders the committed template (terminology injected; the template carries its own calibrated rules) into either direction and parses the three-section response, while verify-translation-prompt exercises both render directions and the checked-in example in doc-sync.