Target repos: hatlabs/halpi2, hatlabs/halmet, hatlabs/sh-rpi, hatlabs/sh-esp32 — one pull request each, halpi2 first.
Planning assumed halpi2 was the only translated repo. A survey on 2026-08-13 found four, all the same shape: docs_structure: folder, a committed uv.lock, the same six checkers copied into scripts/, the same advisory workflow, default site_dir, and no print-site plugin. Everything below was written for halpi2 and applies unchanged to the other three.
State measured 2026-08-13 with the packaged checkers against fresh clones: all four build mkdocs build --strict clean and pass check-anchors site. halpi2, halmet and sh-esp32 pass the gate. sh-rpi fails it — tutorials/openplotter-server/index.md exists in English only, so all nine locales report missing. Drain that backlog before flipping sh-rpi's gate, not after.
PR #47 merged on 2026-08-12, so the halpi2 block is lifted.
Correction to the approach below: the caller does not get a paths filter. A required check that never runs on a pull request touching none of the filtered paths leaves that pull request unmergeable forever, so examples/docs-repo/ deliberately omits it.
Goal: The scripts are gone, the shared workflow runs, and an English-only
edit can no longer merge.
Requirements: R14, R15, R17
Dependencies: Units 5, 6, 7 — all merged.
Files:
- Delete:
scripts/translation_status.py, scripts/stamp_translation.py,
scripts/map_anchors.py, scripts/check_glossary.py,
scripts/check_typography.py, scripts/check_anchors.py
- Modify:
pyproject.toml
- Modify:
.github/workflows/translation-status.yml
- Modify:
.claude/skills/translate-page/SKILL.md
- Modify:
CLAUDE.md
Approach:
- Pin the package; declare
pyyaml no longer implicitly — it arrives as a
dependency of the package rather than transitively through MkDocs.
- The workflow file shrinks to triggers, path filters and the
uses: stanza at
@main.
- Update every
scripts/… reference in the translate-page skill and in
CLAUDE.md to the entry point names. A skill that points at deleted files is
the failure mode that makes the gate unmeetable.
- Before flipping the gate, confirm the repository is clean.
main was clean at
planning time; PR #47 merging
English-only would change that, and the backlog must be drained first — see
Risks.
- Land the gate flip as its own change so the pull request that enables it is
itself the evidence that the repository passes.
Execution note: The verification below is the acceptance test for the whole
plan. Do not mark this unit complete on a green run alone — the deliberately
stale branch must go red.
Test scenarios:
- Integration: a branch editing one English page with no translation updates
fails CI, and the comment names that page in all nine locales.
- Integration: the same branch with all nine translations updated and stamped
passes.
- Integration: a branch adding a new English page with no translations fails on
missing.
- Integration: a branch deleting an English page without deleting its
translations fails on orphaned.
- Happy path: a branch touching only
mkdocs.yml navigation, with the tree
already current, passes.
- Integration: running the packaged commands locally in a fresh clone after
uv sync reproduces the CI verdict.
Verification:
- The pull request that enables the gate is green.
- A scratch branch with one English-only edit is red, and its comment explains
why without opening the job log.
Target repos:
hatlabs/halpi2,hatlabs/halmet,hatlabs/sh-rpi,hatlabs/sh-esp32— one pull request each,halpi2first.hatlabs/halpi2hatlabs/halmethatlabs/sh-esp32hatlabs/sh-rpi(drain the backlog first, see below)Planning assumed
halpi2was the only translated repo. A survey on 2026-08-13 found four, all the same shape:docs_structure: folder, a committeduv.lock, the same six checkers copied intoscripts/, the same advisory workflow, defaultsite_dir, and no print-site plugin. Everything below was written forhalpi2and applies unchanged to the other three.State measured 2026-08-13 with the packaged checkers against fresh clones: all four build
mkdocs build --strictclean and passcheck-anchors site.halpi2,halmetandsh-esp32pass the gate.sh-rpifails it —tutorials/openplotter-server/index.mdexists in English only, so all nine locales reportmissing. Drain that backlog before flippingsh-rpi's gate, not after.PR #47 merged on 2026-08-12, so the
halpi2block is lifted.Correction to the approach below: the caller does not get a
pathsfilter. A required check that never runs on a pull request touching none of the filtered paths leaves that pull request unmergeable forever, soexamples/docs-repo/deliberately omits it.Goal: The scripts are gone, the shared workflow runs, and an English-only
edit can no longer merge.
Requirements: R14, R15, R17
Dependencies: Units 5, 6, 7 — all merged.
Files:
scripts/translation_status.py,scripts/stamp_translation.py,scripts/map_anchors.py,scripts/check_glossary.py,scripts/check_typography.py,scripts/check_anchors.pypyproject.toml.github/workflows/translation-status.yml.claude/skills/translate-page/SKILL.mdCLAUDE.mdApproach:
pyyamlno longer implicitly — it arrives as adependency of the package rather than transitively through MkDocs.
uses:stanza at@main.scripts/…reference in thetranslate-pageskill and inCLAUDE.mdto the entry point names. A skill that points at deleted files isthe failure mode that makes the gate unmeetable.
mainwas clean atplanning time; PR #47 merging
English-only would change that, and the backlog must be drained first — see
Risks.
itself the evidence that the repository passes.
Execution note: The verification below is the acceptance test for the whole
plan. Do not mark this unit complete on a green run alone — the deliberately
stale branch must go red.
Test scenarios:
fails CI, and the comment names that page in all nine locales.
passes.
missing.translations fails on
orphaned.mkdocs.ymlnavigation, with the treealready current, passes.
uv syncreproduces the CI verdict.Verification:
why without opening the job log.