diff --git a/.github/scripts/check-locale-surface.mjs b/.github/scripts/check-locale-surface.mjs index 7bfacb5..00015b7 100644 --- a/.github/scripts/check-locale-surface.mjs +++ b/.github/scripts/check-locale-surface.mjs @@ -253,6 +253,9 @@ const RULES = [ 'unexpected-url', 'missing-url', 'duplicate-url', + 'legal-english-unmarked', + 'legal-translation-shows-english', + 'legal-page-unread', 'unexpected-locale-title', 'missing-locale-title', 'translation-orphan', @@ -299,7 +302,13 @@ const SITE_URL = 'https://docs.objectos.ai'; * code (see the header). This list changing is a deliberate act — translating * the privacy policy — so a drift going red and naming the page is the correct * outcome, not a maintenance tax: unlike the docs counts, it does not move on - * every content PR. + * every content PR. `zh-Hant` is listed because its copy is generated from the + * `zh-Hans` entry by `apps/docs/scripts/gen-zh-hant.mjs` (#312), the way every + * other Traditional page is. + * + * The same list is the oracle for what the built legal pages SHOW (#312, see + * `legalPages` below): a listed locale shows its own copy, and any other + * locale shows the English entry marked `lang="en"`. * * The site root is deliberately NOT here, and not expected anywhere below. It * is a language dispatch page that redirects to that locale's `/docs` — a URL @@ -309,8 +318,8 @@ const SITE_URL = 'https://docs.objectos.ai'; * which is what keeps the redirect from creeping back in at `priority: 1`. */ const STATIC_PAGES = [ - { path: 'privacy', locales: ['en', 'zh-Hans'] }, - { path: 'terms', locales: ['en', 'zh-Hans'] }, + { path: 'privacy', locales: ['en', 'zh-Hans', 'zh-Hant'] }, + { path: 'terms', locales: ['en', 'zh-Hans', 'zh-Hant'] }, ]; const rel = (p) => relative(ROOT, p); @@ -485,6 +494,171 @@ function expectedSitemapUrls(surface) { return urls; } +/* ------------------------------------------------- the legal pages (#312) -- + * `privacy` and `terms` in a locale `STATIC_PAGES` does not list render the + * English entry inside ``. Until #312 nothing marked it, so + * a German screen reader read the privacy policy with German rules, and + * `zh-Hant` got that English too. Three rules over the built HTML, with the + * English page's own `
` text as the oracle for "English": + * + * - `legal-english-unmarked`: on a locale that is not listed, every text + * node of `
` that is also English-page text must resolve to + * `lang="en"` (the nearest `lang`, as a screen reader applies it). The + * notice above it is in the route locale and is not English-page text. + * - `legal-translation-shows-english`: on a listed locale, no text node of + * `
` is English-page text and none resolves to `en`. It catches a + * locale that is advertised as written while it still shows English, the + * way `zh-Hant` did. + * - `legal-page-unread`: a built page missing in some locale, an English page + * with no `
` text, or an unlisted locale showing none of the English + * text. Each means a rule above compared nothing. + * + * "`
`" means the page's content: text inside a `
` and outside any + * `
` or `