Skip to content

Internationalization

The documentation treats English and Simplified Chinese as reviewed canonical sources. Every other enabled locale is a generated derivative. The language registry, source routing, model configuration, and API limits live in i18n/config.toml.

1. Language coverage and source routing

The registry intentionally enables a focused set of 12 site locales. It covers all six United Nations official languages: Arabic, Chinese, English, French, Russian, and Spanish. It additionally covers Japanese, Korean, and Traditional Chinese for East Asia, plus German, Italian, and Portuguese for Europe. English and Simplified Chinese are canonical, so 10 locales are machine translated.

Japanese, Korean, and Traditional Chinese use Simplified Chinese as their source. All other generated locales use English. Source selection is explicit per locale; the translator never guesses from a locale name or from document characters.

Adding a locale requires matching entries in i18n/config.toml and the MkDocs i18n language list. The documentation audit rejects inconsistent registries.

2. Canonical-document contract

Every MkDocs page has an English file and a .zh-CN.md file. A pull request, push to main, or manually dispatched quality run that changes one canonical version must include its counterpart in the checked commit range. The quality workflow checks:

  • canonical pairs and changed-pair coupling;
  • heading-level and code-fence parity;
  • local links and source references;
  • fixture and test inventories;
  • a strict build of every configured locale.

Canonical prose may be written manually or with AI assistance, but it must be committed and reviewed as ordinary source. The translation API is never called from a pull-request workflow.

3. Heading numbering and fragment stability

Markdown source stores descriptive heading text without outline numbers. During every MkDocs build, scripts/mkdocs_heading_numbers.py adds page-local numbers to H2–H6 headings. User Guide pages use lowercase letters at H2 (a., b.) and letter-plus-decimal descendants (a.1, a.1.1); other pages retain decimal page outlines. Separately, the left User Guide navigation uses hierarchical decimal numbers such as 1.1. H1 page titles and top-level navigation sections remain unnumbered. Generated numbers are presentation metadata: moving a section changes its visible number without changing its fragment identifier.

The build hook makes every heading identifier explicit before adding the visible number. i18n/legacy-heading-anchors.json retains aliases for fragments that were published before stored outline numbers were removed. Do not edit that generated compatibility map casually, and do not add manual outline numbers back to canonical or generated Markdown; the documentation audit rejects them.

4. Generated-document contract

Generated pages use MkDocs suffix mode, such as index.fr.md or guide/configuration.ja.md. Each page contains deterministic front matter recording:

  • the canonical source locale and path;
  • the source SHA-256 digest;
  • the resolved model and prompt version;
  • that the page is a machine translation.

i18n/manifest.json additionally records output digests and translation-input fingerprints. A page becomes stale when its source, glossary, prompt, model, or generated output changes. The translator only requests stale units unless a full rebuild is explicitly requested.

Translated headings keep their natural localized slugs and receive hidden aliases for the canonical source slugs. Because Markdown link destinations are otherwise protected from model changes, these aliases keep same-page and cross-page fragment links valid in every locale. The aliases can be refreshed offline without another translation API call.

Generated files must not be edited manually. The main-branch translation workflow regenerates them and checkpoints each completed locale as one commit on a generated-only branch derived from the exact quality-validated SHA. A later run can verify and reuse that branch, so an interruption only discards the locale still in progress. main remains unchanged until the workflow has run the required generated-language audit, complete test suite, and strict all-locale build. It then verifies that main has not advanced, promotes the validated checkpoint by one fast-forward push, and deploys that same validated site artifact.

5. Protected Markdown and prompt contract

Before an API request, the translator replaces front matter, fenced code, inline code, link destinations, HTML tags, and bare URLs with immutable placeholders. A response is rejected if any placeholder is missing, duplicated, invented, or moved outside the recoverable output contract.

The prompt also requires identical heading levels and code-fence languages. The implementation independently verifies those properties after restoring the protected content. Translation output must be a JSON object; prose around the JSON, empty content, abnormal completion reasons, or incompatible schemas are failures.

The Markdown and navigation-catalog prompts are versioned under i18n/prompts/. i18n/glossary.json carries stable product and command terminology.

6. Model configuration and credentials

The default model is configured as deepseek-v4-flash. The implementation does not branch on that name. A future model change only requires updating i18n/config.toml, passing --model, or setting the DEEPSEEK_TRANSLATION_MODEL workflow variable. The resolved model is recorded in every generated page and manifest entry.

GitHub Actions reads the API credential only from the repository secret named DEEKSEEK_API_KEY. It is injected only into the generation step when the offline plan reports pending API-backed units. It is never available to untrusted pull-request code or no-API planning, cleanup, and validation steps. Authentication values are never written to logs, generated files, artifacts, or the manifest.

7. Page notice and language preference

Machine-generated pages receive a localized warning at render time. The warning identifies the page as an AI translation, links to the authoritative English or Simplified Chinese source, and links to a pre-filled translation issue. It is not part of the translated Markdown and does not create a table of contents entry.

On a visitor's first root-page visit, the site compares navigator.languages with the configured language alternatives. A compatible locale is selected when available. A manual language selection is saved locally and takes precedence on later visits.

8. Maintainer commands

Show the number of pending translation units without making network calls:

uv run python scripts/translate_docs.py --plan

Verify that every generated page and catalog is current:

uv run python scripts/translate_docs.py --check
uv run python scripts/audit_docs.py --machine-mode required

Refresh stable source-heading aliases without API calls:

uv run python scripts/translate_docs.py --refresh-heading-anchors

Force a complete regeneration with an explicit model:

DEEKSEEK_API_KEY=... uv run python scripts/translate_docs.py \
  --force --model deepseek-v4-flash

The automated workflow uses the repository secret instead of placing a key on the command line.