The docs renderer prints backticks literally when `code` sits inside **bold** — `renderInline` is a flat split, so the bold arm emits its own contents as raw text
Repo: motir-core. One PR. Found while running MOTIR-2608, whose sub-step 2 opens with a bold run wrapping the code span `.devcontainer/devcontainer.json` — and renders, in the shipped production build, with the backticks visibly on screen. Not caused by that card's diff: the construct is on origin/main unchanged, and 2608's change neither introduced nor can fix it.
The cause
app/(public)/docs/_components/DocBlocks.tsx → renderInline:
text.split(/(\*\*[^*]+\*\*|`[^`]+`)/g).map((part, index) => {
if (part.startsWith('**') && part.endsWith('**')) {
return <strong …>{part.slice(2, -2)}</strong>; // ← raw text, never re-scanned
}
…
});
The split is FLAT and one level deep. A bold run is matched whole, and its contents are emitted as a raw string child of <strong> — so any backtick inside it is never seen by the code arm. The mirror case is different and correct: a code span containing ** SHOULD print the asterisks, because code is literal — which is why the fix belongs in the bold arm only.
[^*]+ also means the two marks cannot interleave at all, so the failure is not confined to bold-wrapping-code — a bold run that merely contains a backtick pair splits at the wrong boundary, and the rendered emphasis then covers the wrong words.
The sites, on origin/main (2026-08-10)
Five, in three modules, found with:
grep -rno '\*\*[^*]*`[^`]*`[^*]*\*\*' lib/apiDocs/*.ts
| site | what a reader sees |
|---|---|
lib/apiDocs/sandbox.ts:250 | the --rm warning — backticks printed |
lib/apiDocs/sandbox.ts:273 | sub-step 2's filename — backticks printed |
lib/apiDocs/sandbox.ts:293 | a bold run split mid-sentence around two code spans |
lib/apiDocs/cli.ts:226 | same shape, around .motir.json |
lib/apiDocs/guide.ts:189 | same shape, around totalCount |
That is a reading from 2026-08-10 and it will drift — re-run the grep rather than trusting the table, and fix every site it returns.
Do this
- Make
renderInlinerecursive on the bold arm: feedpart.slice(2, -2)back throughrenderInlineinstead of emitting it as a raw string, so a code span inside bold becomes a<code>inside the<strong>. Leave the code arm literal. - Widen the split so the two marks can interleave — the
[^*]+inside the bold alternative is what forces a whole run to be asterisk-free, and it is the cause of the mid-sentence split atsandbox.ts:293. - Do NOT reach for a Markdown library.
DocBlocks.tsx's own header records why this renderer exists (two marks, in a document set we author ourselves); this is a bug in that renderer, not a case for replacing it.
Acceptance criteria
- A
proseblock whose text is a bold run wrapping a code span renders a<strong>containing a<code>, with no backtick and no asterisk in the rendered text — asserted by a component test that reads the rendered DOM, not the source string. - The mirror holds: a code span containing
**still renders the asterisks literally. The test asserts BOTH directions, so the fix cannot degenerate into "strip every mark everywhere". - Every site the grep above returns renders correctly on the built page, and the fix is in the renderer — no authored string in
lib/apiDocs/*.tsis edited to route around it. renderInlineMarks— the exported siblingrenderInlinebacks, used by callers laying out their own paragraph — inherits the fix rather than getting a second copy.app/**/docs/**per-file coverage floors stay green, and every existing api-docs test still passes.
Out of scope
The authored copy. Nothing in lib/apiDocs/*.ts should be rewritten to dodge the renderer — a page whose bold cannot contain a filename is the defect being fixed.