ADR 0011 — Release notes are translated with each fragment¶
Status: accepted · 2026-11-08 (maintainer decision on #162)
Context¶
Fairmark is written for Italian analysts and SMEs. The documentation has an English source and
an Italian edition tracked by scripts/i18n.py. The release notes, the document written for
analysts, exist only in English: towncrier builds RELEASE_NOTES.md from changes/,
scripts/docs.py renders it on the site with the unreleased draft on top, and i18n/it.yaml
lists project/*.md as English only, so the Italian site links the English page. The GitHub
Release body is extracted from RELEASE_NOTES.md by scripts/release_notes.py. Agents write
most pull requests; the maintainer reviews in Italian. No version has been released yet, so
there is nothing to translate retroactively.
Options considered¶
- A. A translated fragment in each pull request. Each English fragment has a counterpart
per maintained language; one towncrier configuration per language builds
RELEASE_NOTES.<lang>.md. Cost: one to three sentences more per user-facing pull request. The Italian site is current after every merge. - B. Translation at release time. No cost per pull request. The Italian site has no current notes between releases, and the Prepare release workflow, which runs no agent, can no longer produce the release pull request on its own.
- C. Status quo. No cost. The readers the project targets read its one analyst document in English.
Decision¶
- Option A. A pull request that adds or edits
changes/<issue>.<type>.mdadds or editschanges/<lang>/<issue>.<type>.mdfor each maintained language. The author writes it withi18n/glossary.yaml; an author who cannot labels the pull requesttranslation-pending, the label the documentation already uses. - Pairing is by file name, without hash tracking. Fragments are one to three sentences and live only until the next release. An English fragment edited without its translation is a review finding; the maintainer reads both texts in the release pull request.
scripts/i18n.py checkrequires a translation for every English fragment and no orphan translation. It already runs in the Docs workflow, skipped withtranslation-pending, and inrelease.py ready, never skipped: a pending translation can be merged, not released.- Languages are not hard-coded. Each language with release notes declares its towncrier
configuration in
i18n/(translated section names, outputRELEASE_NOTES.<lang>.md, the same title format as English). Adding a language remains a maintainer decision. - The GitHub Release keeps one body: the English notes, then a link per language to
RELEASE_NOTES.<lang>.mdat the tag. - The Italian site renders
RELEASE_NOTES.it.mdwith its draft on top. The changelog stays English only.
Consequences¶
- Italian readers get the analyst document in their language, as current as the English one.
- The text is translated while its context is fresh, in a pull request the maintainer already reviews; the release pull request stays generated by the workflow.
- Same label, check and release gate as the documentation: no new process.
− Every user-facing pull request carries one more short file. External contributors can use
translation-pending, which moves the work to the maintainer before the release. − Name pairing does not detect an English fragment edited after its translation; accepted, bounded by review and by the life of a fragment.
The implementation task changes:
1. i18n/it.towncrier.toml (directory changes/it) and RELEASE_NOTES.it.md with the start
marker; verify that the English configuration in pyproject.toml ignores changes/<lang>/
in build and check.
2. scripts/i18n.py: fragment pairing in check, status and todo.
3. .github/workflows/prepare-release.yml and .agents/skills/release/SKILL.md: one
towncrier build --config per language; the release pull request body shows every text.
4. scripts/release_notes.py: the link per language.
5. scripts/docs.py: current_notes per language, with the draft title and the empty-draft
sentence from i18n/<lang>.yaml. i18n/it.yaml and translate_nav: an exception so that
project/release-notes.md is no longer English only and is not tracked as a translation;
docs/it/project/release-notes.md includes .generated/RELEASE_NOTES.it.md.
6. _typos.toml: exclude changes/it/ and RELEASE_NOTES.it.md.
7. changes/README.md, docs/en/project/releases.md, AGENTS.md, .agents/agents/translator.md
(fragments in the work list) and the code-reviewer checklist (paired edits), with the
Italian translations of the changed pages.