Skip to content

FCC i18n — translation workflow (v1.5.0 Pillar C scaffolding)

Status: SKELETON. v1.5.0 ships the i18n infrastructure — the mkdocs-static-i18n plugin configuration, the i18next + react-i18next setup, locale skeleton files, and the glossary. No actual translations are performed in v1.5.0.

Translation execution is deferred to v1.5.x and is gated behind explicit owner approval, because:

  1. Professional translation of the R.I.S.C.E.A.R. framework + 164 persona YAML files + 24-chapter guidebook is a significant human cost that requires owner sign-off on scope + budget + vendor choice.
  2. Several terms are "do not translate" (see glossary.csv). Machine translation will silently rewrite those terms, so a dry-run + glossary review step is required before any translation pass lands in main.

What v1.5.0 ships

MkDocs i18n (documentation site)

  • mkdocs-static-i18n plugin config added to mkdocs.yml for en (default), fr, es, de.
  • Locale files are placeholder markers — the English docs tree stands in for every locale until the actual translations land.

Frontend i18n (React web app)

  • i18next + react-i18next dependencies added to frontend/package.json.
  • frontend/src/i18n/config.ts — centralised i18next setup with the DEFAULT_LOCALE, SUPPORTED_LOCALES, and DO_NOT_TRANSLATE glossary.
  • frontend/src/i18n/locales/<lang>/common.json — four locale namespaces. en is the English baseline. fr, es, de contain {{TRANSLATE_FR}} / {{TRANSLATE_ES}} / {{TRANSLATE_DE}} placeholder markers that signal "translation required" to reviewers.

Glossary (glossary.csv)

Canonical list of terms with a do_not_translate flag. R.I.S.C.E.A.R., Zachman row + column names, OpenTelemetry / OTEL, FCC, POLARIS, LYRA, and other brand/acronym terms are flagged do_not_translate=true and MUST be preserved verbatim in every locale.

What v1.5.0 does NOT ship

  • Actual French/Spanish/German translations of any documentation page.
  • Actual translations in locales/fr/common.json, locales/es/common.json, or locales/de/common.json — these remain placeholder-markered.
  • A language-switcher UI widget in the frontend.
  • Locale-aware model-card generation.
  • Translated persona YAML files.

Workflow for landing real translations (v1.5.x owner-approval gate)

Any PR that replaces {{TRANSLATE_*}} markers with real translations MUST:

  1. Secure owner approval — the repo owner posts an issue or comment explicitly approving the translation scope, target locales, and translation vendor / methodology. This is the same owner-approval pattern used for seed_canonical(dry_run=False, i_understand_external_license_implications=True).

  2. Respect the glossary — no term flagged do_not_translate=true may be rewritten. CI will fail any PR that modifies a do-not-translate term in any locale file.

  3. Run the dry-run diff — compare locales/en/common.json keys against every target-locale file and confirm key-parity. Missing keys in a locale must be flagged, not silently dropped.

  4. Human review — machine-translation output is acceptable as a starting point, but every string MUST have a human reviewer sign-off recorded in the PR description. No un-reviewed MT output merges.

  5. Preserve the placeholder marker strategy for new strings — when new English strings are added, the locale files MUST add the same key with a {{TRANSLATE_<LANG>}} placeholder rather than leaving the key absent. Missing keys cause runtime Translation missing warnings that degrade UX.

Tests

See frontend/__tests__/i18n.test.tsx for the locale-parity + glossary- preservation test suite (ships green with all-placeholder locales).

Out-of-scope for v1.5.0

  • Right-to-left (RTL) locale support — deferred to v1.6.0 when Arabic and Hebrew are added to SUPPORTED_LOCALES.
  • Locale negotiation based on Accept-Language headers — deferred.
  • Translation memory + CAT-tool integration (e.g. Pontoon, Weblate, Crowdin) — deferred to v1.5.x once vendor is selected.