Rewritten 2026-08-03. The original version of this issue proposed that sync maintain a per-language page-coverage manifest for the theme to consume. Measuring the actual latencies afterwards showed that proposal was disproportionate to the problem, so the ask has been narrowed to detection. The original framing is summarised in the comment below.
Context
QuantEcon/lecture-python-programming#490 wires the theme's language switcher into the English source, offering en, fa, fr and zh-cn. The theme emits every switcher link and every hreflang alternate as {language_url}/{pagename}.html, unconditionally, for every configured language. It has no notion of whether a page exists in a given edition, and no way to acquire one.
When the editions diverge, the switcher offers links that 404 and the hreflang alternates point at URLs that do not resolve. The second is the more consequential of the two: a bad alternate is crawled on every page of the site and devalues the annotations generally, not just for the affected page.
What the divergence actually is
This is where the original framing was wrong. Translation review is not the bottleneck. Every sync PR in this series merges within a day, usually within the hour:
| Edition |
Recent sync PRs, opened → merged |
.fa |
8 min, 12 min, 19 min, 46 min, 4 h, 23 h |
.fr |
48 min, 23 h |
.zh-cn |
15 min, 24 min, 48 min, 48 min, 23 h, 2 d |
Publishing is the bottleneck. Every repository in this series — the English source included — publishes only when someone pushes a publish* tag:
| Repository |
Last publish |
Days stale as of 2026-08-03 |
| lecture-python-programming |
2026-07-16 |
18 |
.fa |
2026-06-19 |
45 |
.fr |
2026-07-17 |
17 |
.zh-cn |
2026-06-19 |
45 |
Publish cadence dominates review lag by roughly 30×. Any measure of "which pages does edition X have" that means published and reachable would therefore be tracking publish-tag timing far more than translation progress.
The case that prompted this
polars was added to the English source on 2026-07-30 (QuantEcon/lecture-python-programming#408). Sync worked exactly as intended: PRs opened, were reviewed, and merged into all three editions the same day — .fa#144, .fr#20, .zh-cn#79, each inside an hour. polars.md and its _toc.yml entry are present in all four repositories now.
All four sites still 404 on polars.html, including English, because no publish tag has been pushed anywhere since it merged. Nothing in the translation pipeline failed here. This is publish cadence, start to finish.
What is worth asking for
Not a coverage manifest. Building a cross-repo data pipeline so the theme can suppress links would, on these numbers, mostly be an elaborate way of tracking publish tags — and it would need to distinguish file present on the default branch from published and reachable, which is the hard part and the part that changes most often.
What is missing is far simpler: nobody finds out when a switcher or hreflang target 404s. The condition is silent. It was found by hand, only because the switcher PR prompted someone to check.
So the proportionate ask is a cross-edition reachability check — build the site, collect the switcher and hreflang URLs the theme actually emitted, request each one, report the failures. Run it on a schedule rather than per-sync, since the state it observes changes on publish, not on merge.
Two things worth knowing for whoever picks this up:
- Sphinx's
linkcheck builder does not cover this. It works from the doctree and checks links in page content; the switcher and hreflang URLs are injected by the theme template and never appear there. This needs its own check against built HTML.
- The check is only meaningful across editions, so it needs to know the full edition set and each one's published URL. That is the reason this issue is filed here rather than in a single lecture repo — this action already knows the edition topology. If the maintainers judge a scheduled site check out of scope for a translation engine, the alternative home is a shared workflow run from each source repo, and that is a reasonable outcome.
Adjacent: #222 describes sync committing a first-translated lecture left unreachable because nothing adds it to _toc.yml. That is the same class of silent-reachability failure, one layer earlier.
Downstream
If detection later shows the residual window is big enough to be worth suppressing, the consuming change is a small conditional in quantecon-book-theme around the switcher and hreflang emission. That is not worth opening yet — measure first.
Separately, and independent of any of this: quantecon-book-theme ships no 404 template. A language-aware 404 on each edition, offering the English original when a translated page does not exist, fixes the reader-facing half of this with no cross-repo coordination at all, stays correct automatically, and also catches arrivals from search results and shared links that the switcher never touches. That is the better navigation fix and belongs on the theme.
Not blocking
QuantEcon/lecture-python-programming#490 is fine to merge as it stands.
Context
QuantEcon/lecture-python-programming#490 wires the theme's language switcher into the English source, offering
en,fa,frandzh-cn. The theme emits every switcher link and everyhreflangalternate as{language_url}/{pagename}.html, unconditionally, for every configured language. It has no notion of whether a page exists in a given edition, and no way to acquire one.When the editions diverge, the switcher offers links that 404 and the
hreflangalternates point at URLs that do not resolve. The second is the more consequential of the two: a bad alternate is crawled on every page of the site and devalues the annotations generally, not just for the affected page.What the divergence actually is
This is where the original framing was wrong. Translation review is not the bottleneck. Every sync PR in this series merges within a day, usually within the hour:
.fa.fr.zh-cnPublishing is the bottleneck. Every repository in this series — the English source included — publishes only when someone pushes a
publish*tag:.fa.fr.zh-cnPublish cadence dominates review lag by roughly 30×. Any measure of "which pages does edition X have" that means published and reachable would therefore be tracking publish-tag timing far more than translation progress.
The case that prompted this
polarswas added to the English source on 2026-07-30 (QuantEcon/lecture-python-programming#408). Sync worked exactly as intended: PRs opened, were reviewed, and merged into all three editions the same day —.fa#144,.fr#20,.zh-cn#79, each inside an hour.polars.mdand its_toc.ymlentry are present in all four repositories now.All four sites still 404 on
polars.html, including English, because no publish tag has been pushed anywhere since it merged. Nothing in the translation pipeline failed here. This is publish cadence, start to finish.What is worth asking for
Not a coverage manifest. Building a cross-repo data pipeline so the theme can suppress links would, on these numbers, mostly be an elaborate way of tracking publish tags — and it would need to distinguish file present on the default branch from published and reachable, which is the hard part and the part that changes most often.
What is missing is far simpler: nobody finds out when a switcher or
hreflangtarget 404s. The condition is silent. It was found by hand, only because the switcher PR prompted someone to check.So the proportionate ask is a cross-edition reachability check — build the site, collect the switcher and
hreflangURLs the theme actually emitted, request each one, report the failures. Run it on a schedule rather than per-sync, since the state it observes changes on publish, not on merge.Two things worth knowing for whoever picks this up:
linkcheckbuilder does not cover this. It works from the doctree and checks links in page content; the switcher andhreflangURLs are injected by the theme template and never appear there. This needs its own check against built HTML.Adjacent: #222 describes sync committing a first-translated lecture left unreachable because nothing adds it to
_toc.yml. That is the same class of silent-reachability failure, one layer earlier.Downstream
If detection later shows the residual window is big enough to be worth suppressing, the consuming change is a small conditional in
quantecon-book-themearound the switcher andhreflangemission. That is not worth opening yet — measure first.Separately, and independent of any of this:
quantecon-book-themeships no 404 template. A language-aware 404 on each edition, offering the English original when a translated page does not exist, fixes the reader-facing half of this with no cross-repo coordination at all, stays correct automatically, and also catches arrivals from search results and shared links that the switcher never touches. That is the better navigation fix and belongs on the theme.Not blocking
QuantEcon/lecture-python-programming#490 is fine to merge as it stands.