cmux NEXT: localization parity is a ratchet, and stacked pull requests skip ci.yml legacy lanes
Two fixes for the "Fast static checks" red that showed up on cmux NEXT pull requests (#23407, #23442). The package-groups half already landed in #23448.
Why the static preflight ran on #23442
#23442 was stacked: its base was another pull request's branch until that one merged and GitHub retargeted it (automatic_base_change_succeeded at 13:40; the CI run started 13:38). ci.yml skips its legacy lanes with base.ref != 'feat-cmux-next', so a stacked cmux NEXT pull request runs them, including the main-only static preflight.
scripts/ci/next_line.sh decides from the base commit instead. A base commit with plans/cmux-next/ is on the cmux NEXT line, whatever its branch is called; main has no such folder. If it can't read the base it prints false, which runs the legacy lanes as before. The changes job publishes it as next_line. Every ci.yml job that tested the base name now reads it: guards, browser, remote-daemon, linux-preflight, dogfood-build, ci-timing, the next-route routing step and the two ci-status verdicts. fast-guards and static-preflight don't wait for changes, so they keep their cheap name test and run the script as their first step. The ci-guards pr-red-checks caller (base.ref == 'feat-cmux-next') is left as it is.
Localization parity on cmux NEXT is a ratchet
On cmux NEXT, localization_catalog.py check finds 42,072 errors in 118 catalogs. On main it finds 0 errors in 10 catalogs. This PR adds scripts/localization-debt-baseline.json, a count per catalog of three kinds: needs_review, identical (copied English) and other. With that file present, check is a ratchet:
- Fails when any catalog gains copied English or malformed entries, including a catalog the baseline doesn't list.
- Reports, doesn't fail, new
needs_reviewstrings. cmux NEXT adds machine translations in that state on purpose (scripts/cmux-next/check-l10n.shcounts them as present). There were 269 more in one hour today, while copied English stayed flat at 2,267. Enforcing that kind would turn most string-adding pull requests red; it's one constant (DEBT_ENFORCED) to change. --write-baselineonly lowers counts. It refuses to raise an enforced count, and forneeds_reviewit keeps the lower of the current and recorded counts.- New
cmux-next localization debt ratchetjob in cmux-next-guards.yml runs the check with--base-baseline(the base's copy), so a hand edit that raises the baseline fails too.
main has no baseline, so there every parity error still fails. verify-local.py's localization check is green on cmux NEXT again.
Tests
tests/test_localization_catalog.py: 10 new ratchet tests.python3 tests/test_localization_catalog.py: base script 10 errors, head 39 OK.tests/test_next_line.py(new): stacked base withplans/cmux-nextis true; main, main stacks and other events are false; an unreadable base is false. Base 5 errors (no script), head 5 OK.- Both run in cmux-next-guards' tooling-tests and are registered in
tests/test-execution.toml. test_ci_change_areas.pyandtest_ci_linux_guard_routing.pyare updated for the new condition. The failures left in them (test_a_script_only_unrouted_workflows_or_linux_guards_run_reaches_no_macos_lane,test_repository_helpers_route_by_where_they_run) andtest_ci_test_execution_registry.py'stest_verify_local_jobs_option_keeps_recipe_tests_livefail the same way on base 68a3517.
Observed / Not run
- Ran: the tests above at head and at base;
python3 scripts/localization_catalog.py checkon the merged tree (42,072 errors, within the baseline, exit 0); actionlint on both workflows (clean); the cmux-next prepush gate. - Not run: a real stacked pull request through ci.yml. The routing is covered by test_next_line.py against throwaway repositories, and by the ci.yml structure tests.
Changelog
none
Agent session: huge-blue
🤖 Generated with Claude Code
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Fixes two cmux NEXT CI failures: stacked pull requests no longer run the main-only legacy lanes, and localization parity debt can only shrink, never grow.
scripts/ci/next_line.shdetects the cmux NEXT line from the base commit's contents (plans/cmux-next/) instead of the base branch name, so stacked PRs skip the legacy lanes too; every ci.yml lane and thechangesjob read itsnext_lineoutput.scripts/localization-debt-baseline.jsonrecords per-catalog parity debt;checkfails when a catalog gains copied English, malformed entries, or unlisted catalogs, reports (but allows) newneeds_reviewstrings, and--write-baselineonly lowers counts.- New
localization-ratchetjob in cmux-next-guards.yml enforces the base's baseline so hand edits that raise it fail. - Re-recorded the baseline after merging
feat-cmux-next: base added copied English in three catalogs before the ratchet existed, so it's written from scratch at the merged tree. pr_test_lanes.pyand its tests now account for the stacked-line route, andtest-execution.tomlruns the newtest_next_line.pyandtest_localization_catalog.pyon the linux-guard lane.