Found while correcting extend-existing-systems-with-ai (#149). Filed unassigned. Not fixed under that card: its file surface is one post directory, and this is a site-wide class that wants one guard rather than 24 hand edits.
What readers see
A **bold** span whose closing delimiter sits directly after CJK punctuation does not close, and the asterisks are rendered to the reader as literal text. The construction that triggers it is idiomatic in the translated posts:
一套更丰富的**开箱即用联邦(turn-key federation)**体验
^^ never closes
CommonMark's flanking rule is the cause and it is not a bug in the renderer: a closing run preceded by punctuation (), ”, 。) only closes when it is also followed by whitespace or punctuation. Followed by a CJK letter (体), it is not right-flanking, so the run is emitted verbatim. The English posts almost never hit it because English puts a space there.
Measured
Built from origin/main @ 3b6d563 (pnpm build), then counting literal ** in the emitted HTML of every blog page:
grep -rl '\*\*' dist/*/blog/*/index.html | wc -l # 24
24 pages, entirely in the CJK locales — ja (5), ko (5), zh-Hans (7), zh-Hant (7). zh-Hant inherits each one from its zh-Hans source through gen:zh-hant, so the ~7 zh-Hans fixes carry their zh-Hant twins for free. Samples:
ja/blog/business-app-in-16k-tokens/ — これが**コンテキストサイズのソフトウェア(context-s…
ko/blog/ai-wrote-your-app-dare-to-merge/ — 아니라 **“이 권한이 맞는가…
zh-Hans/blog/vibe-coding-technical-debt-2026/
(One of the 24, zh-Hans+zh-Hant extend-existing-systems-with-ai, is fixed in the PR for #149 because the correction rewrote that exact sentence; the other 22 are untouched.)
Why a guard, not just 22 edits
Nothing catches this today: the markdown is valid, content:lint passes, astro check passes, seo:smoke passes, and the page builds — the defect exists only in the rendered output. Every future translated post can reintroduce it, and it is invisible to anyone who does not read the CJK locales.
The cheap guard is a content-lint rule over the built (or rendered) HTML: no blog page may contain a literal ** outside <code>/<pre>. That is one grep, it closes the whole class, and it fails loudly on the next occurrence. The fix per site is to move the delimiter off the punctuation — **开箱即用联邦(turn-key federation)体验** renders correctly.
Re-check
pnpm build
grep -rl '\*\*' dist/*/blog/*/index.html
grep -o '.\{60\}\*\*.\{60\}' dist/ja/blog/business-app-in-16k-tokens/index.html
Generated by Claude Code
Found while correcting
extend-existing-systems-with-ai(#149). Filed unassigned. Not fixed under that card: its file surface is one post directory, and this is a site-wide class that wants one guard rather than 24 hand edits.What readers see
A
**bold**span whose closing delimiter sits directly after CJK punctuation does not close, and the asterisks are rendered to the reader as literal text. The construction that triggers it is idiomatic in the translated posts:CommonMark's flanking rule is the cause and it is not a bug in the renderer: a closing run preceded by punctuation (
),”,。) only closes when it is also followed by whitespace or punctuation. Followed by a CJK letter (体), it is not right-flanking, so the run is emitted verbatim. The English posts almost never hit it because English puts a space there.Measured
Built from
origin/main@3b6d563(pnpm build), then counting literal**in the emitted HTML of every blog page:24 pages, entirely in the CJK locales —
ja(5),ko(5),zh-Hans(7),zh-Hant(7). zh-Hant inherits each one from its zh-Hans source throughgen:zh-hant, so the ~7 zh-Hans fixes carry their zh-Hant twins for free. Samples:ja/blog/business-app-in-16k-tokens/—これが**コンテキストサイズのソフトウェア(context-s…ko/blog/ai-wrote-your-app-dare-to-merge/—아니라 **“이 권한이 맞는가…zh-Hans/blog/vibe-coding-technical-debt-2026/(One of the 24,
zh-Hans+zh-Hantextend-existing-systems-with-ai, is fixed in the PR for #149 because the correction rewrote that exact sentence; the other 22 are untouched.)Why a guard, not just 22 edits
Nothing catches this today: the markdown is valid,
content:lintpasses,astro checkpasses,seo:smokepasses, and the page builds — the defect exists only in the rendered output. Every future translated post can reintroduce it, and it is invisible to anyone who does not read the CJK locales.The cheap guard is a
content-lintrule over the built (or rendered) HTML: no blog page may contain a literal**outside<code>/<pre>. That is one grep, it closes the whole class, and it fails loudly on the next occurrence. The fix per site is to move the delimiter off the punctuation —**开箱即用联邦(turn-key federation)体验**renders correctly.Re-check
Generated by Claude Code