You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Split out of #142 by seat ruling, and sequenced behind #139 because both want scripts/content-lint.mjs.
Why
#142 fixes the generated side: gen-zh-hant.mjs will rewrite /zh-Hans/ link targets to /zh-Hant/ when it converts a post, so Traditional readers stop being sent to Simplified pages. That fix cannot reach the hand-written locales — index.ja.mdx, .ko, .de, .es, .fr are authored by people and agents, and each can carry the same defect with no generator to blame.
A cross-locale link is invisible to every gate today. #137's validator resolves the target and finds it perfectly real — it just belongs to another locale. The page renders, the link works, and the reader is quietly moved out of the language they were reading in, at which point the language switcher offers to "switch" them to the locale they were already in.
Scope
In resolveInternalLink() (or beside it), compare the locale segment of a body link against the locale of the file the link lives in. Mismatch → a finding.
Severity is the design question and it belongs to whoever picks this up. A deliberate cross-locale link is a real thing — an English-only companion post linked from a translated article is exactly what PR #168 does, on purpose, and #137 already makes the alternative a hard 404. So a blanket error would be wrong. Candidate shapes, decide and record the reasoning on this issue:
Warn always. Simple; every intentional cross-locale link becomes a permanent warning, which trains people to ignore warnings.
Warn only when the same-locale target exists, as a softer version of 2 while the corpus is cleaned up.
Option 2 mirrors the generator, which is a point in its favour: one rule, two enforcement points.
Measure first
Count what exists before choosing: how many cross-locale body links are in the hand-written locales today, and how many of those have a same-locale target that is actually built. If the answer is "a handful, all with same-locale targets", option 2 is free.
Acceptance
Rule chosen with the reasoning recorded here; ablation showing a mistake caught and an intentional cross-locale link not falsely flagged; pnpm content:lint, pnpm content:lint --published, pnpm check, pnpm build, pnpm seo:smoke green on the current tree.
Split out of #142 by seat ruling, and sequenced behind #139 because both want
scripts/content-lint.mjs.Why
#142 fixes the generated side:
gen-zh-hant.mjswill rewrite/zh-Hans/link targets to/zh-Hant/when it converts a post, so Traditional readers stop being sent to Simplified pages. That fix cannot reach the hand-written locales —index.ja.mdx,.ko,.de,.es,.frare authored by people and agents, and each can carry the same defect with no generator to blame.A cross-locale link is invisible to every gate today. #137's validator resolves the target and finds it perfectly real — it just belongs to another locale. The page renders, the link works, and the reader is quietly moved out of the language they were reading in, at which point the language switcher offers to "switch" them to the locale they were already in.
Scope
In
resolveInternalLink()(or beside it), compare the locale segment of a body link against the locale of the file the link lives in. Mismatch → a finding.Severity is the design question and it belongs to whoever picks this up. A deliberate cross-locale link is a real thing — an English-only companion post linked from a translated article is exactly what PR #168 does, on purpose, and #137 already makes the alternative a hard 404. So a blanket error would be wrong. Candidate shapes, decide and record the reasoning on this issue:
/zh-Hant/blog/x/is built and the file says/zh-Hans/blog/x/, that is unambiguously a mistake. If the target exists only in English, the link is the author's only option and passes silently. This is the rule thegen-zh-hant.mjsleaves/zh-Hans/body links intact, so Traditional readers are sent to Simplified pages #142 generator fix already implements on its side.Option 2 mirrors the generator, which is a point in its favour: one rule, two enforcement points.
Measure first
Count what exists before choosing: how many cross-locale body links are in the hand-written locales today, and how many of those have a same-locale target that is actually built. If the answer is "a handful, all with same-locale targets", option 2 is free.
Acceptance
Rule chosen with the reasoning recorded here; ablation showing a mistake caught and an intentional cross-locale link not falsely flagged;
pnpm content:lint,pnpm content:lint --published,pnpm check,pnpm build,pnpm seo:smokegreen on the current tree.