Skip to content

Reject a dotted page slug in the locale-surface gate - #215

Merged
hotlong merged 1 commit into
mainfrom
claude/issue-208-dotted-slug-guard
Aug 26, 2026
Merged

Reject a dotted page slug in the locale-surface gate#215
hotlong merged 1 commit into
mainfrom
claude/issue-208-dotted-slug-guard

Conversation

@hotlong

@hotlong hotlong commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Fixes #208

What

middleware.ts's matcher exempts .*\..*, unanchored, so it skips the
locale rewrite for any path with a dot anywhere — not just an asset path.
Because hideLocale: 'default-locale' makes that rewrite the thing that maps
an English page's unprefixed public URL onto the internal /en/... route, a
docs page whose slug contains a dot would build, prerender, and be advertised
correctly everywhere, then 404 at its own public URL while every other
locale (which doesn't depend on the rewrite) still served it fine.

Per the grading comment on #208, and #209's measurement that the matcher's
dot exemption has no other live consequence, this does not touch
middleware.ts — the four generated artifacts and every .mdx route depend
on that exemption today, and a regression there would be caught by nothing.
middleware.ts is unmodified in this PR.

Instead, .github/scripts/check-locale-surface.mjs now asserts, as a pure
function of content/docs/, that no page's derived slug contains a dot —
turning the silent 404-at-your-own-URL into a build-time failure that names
the offending file.

How

New dottedSlugPages() reuses the same page path string readDocsPages()
already derives for the sitemap/llms oracle — which strips the locale suffix
(quickstart.zh-Hans.mdxdocs/quickstart) before building that path — so
a real translated file never trips the new rule; only a dot that survives
into the derived URL segment does. New rule dotted-slug is wired into
evaluate() next to the existing translation-orphan check (also a pure
content-tree assertion, no build output needed), and the success/verdict
lines are extended in place rather than a new format being printed alongside.

Self-test fixtures (--self-test)

  • Red: page slug contains a dot (the #208 shape) — a page with only
    probe.dotted.mdx fires exactly dotted-slug (sitemap/llms bodies in the
    fixture are extended to match so this case isolates to the new rule alone).
  • Green: a real locale-suffixed filename does not trip the dotted-slug rulequickstart.mdx + quickstart.zh-Hans.mdx, the exact shape named
    in the card, fires nothing.

Verdict counts move from 16 case(s) over 9 rule(s) and 3 artifact(s) to
18 case(s) over 10 rule(s) and 3 artifact(s).

Verification

  • pnpm turbo run type-check — pass.
  • pnpm turbo run build — pass (996 pages generated).
  • pnpm turbo run test (--force) — pass, 3 self-tests, locale-surface at
    18/10/3 above.
  • node .github/scripts/check-locale-surface.mjs on the unmodified tree —
    exit 0, 79 logical pages / 335 docs entries, zh-Hans at 62 (matches the
    card's "62 existing translated files").
  • Added a temporary content/docs/probe.dotted.mdx, rebuilt, ran the gate —
    exit 1, naming docs/probe.dotted has a dot in its slug (content/docs/probe.dotted.mdx). Removed the probe file — git status --short shows only the gate script modified. Rebuilt again — gate back to
    exit 0.
  • A real locale-suffixed file from the 62
    (content/docs/operate/upgrade.zh-Hans.mdx) is part of every clean gate
    run above and does not trip the new rule.

File surface: .github/scripts/check-locale-surface.mjs only, as scoped.
middleware.ts untouched.


Generated by Claude Code

middleware.ts's matcher exempts any path containing a dot, unanchored,
so it also skips the locale rewrite for a docs page whose SLUG (not
just an asset extension) has a dot in it. Because hideLocale is
'default-locale', that rewrite is what maps the unprefixed public URL
onto the internal /en/... route -- skip it and the page builds,
prerenders, and is advertised correctly everywhere, then 404s at its
own public URL while every other locale still serves it fine (#208).

Per the PM's adjudication on #208 (and #209's measurement that the
matcher exemption has no other live consequence), this does not touch
middleware.ts. Instead check-locale-surface.mjs now asserts, as a pure
function of content/docs/, that no page's derived slug contains a dot
-- converting the silent 404 into a build-time failure that names the
offending file.

The new dottedSlugPages() reuses the same page path readDocsPages()
already derives for the sitemap/llms oracle, which strips the locale
suffix (quickstart.zh-Hans.mdx -> docs/quickstart) before building
that path -- so a real translated file never trips it, only a dot
that survives into the derived URL segment does.

Self-test fixtures: one red case (a dotted slug) and one explicit
green case naming the #208 trap directly (a real locale-suffixed
filename). Verdict counts move from 16 case(s)/9 rule(s)/3
artifact(s) to 18 case(s)/10 rule(s)/3 artifact(s).

Fixes #208
@hotlong
hotlong marked this pull request as ready for review August 26, 2026 05:18
@hotlong
hotlong merged commit e8b2062 into main Aug 26, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[finding] A docs page whose slug contains a dot would 404 at its public URL and answer 200 at the internal /en/ route

2 participants