Summary
Streaming markdown rendering is the rendering of model- or agent-produced markdown into a rich terminal view incrementally, chunk by chunk, as tokens arrive — rather than all at once after the stream completes. The central failure mode is marker leakage: source syntax such as ## heading hashes or ** emphasis delimiters appearing literally in the rendered output. A second, subtler failure is chunk-dependence: output that differs depending on where chunk boundaries fall. The robust acceptance criterion for such a renderer is a parity property — split/chunked output must equal whole-line output — enforced by property-style tests rather than per-case assertions.
Key Points
- Two distinct bugs show up in streaming renderers:
- Marker leakage — headings and emphasis render with their source markers (
##,**) still visible. - Chunk-dependence — a construct split across chunk boundaries renders differently (or leaks) than the same construct delivered whole.
- Marker leakage — headings and emphasis render with their source markers (
- Root cause pattern (yoyo #1029): the heading branch of
render_linewrapped the raw line in BOLD+CYAN instead of stripping#and running inline formatting on the heading text. - Emphasis after a list/ordered marker could leak when resolved mid-stream, because
try_resolve_block_prefixcalledrender_inlinerather than the carrying variant introduced by an earlier fix (#661). Whole-line versions rendered clean. - An existing test that asserted the heading with hashes effectively pinned the bug — tests can encode the defect as expected behavior.
- OpenAI Codex fixed the same class of bug by removing source
#markers from rich heading rendering, keeping them only in an explicit raw mode, and adding raw/rich snapshot tests. - Codex's broader test pattern: compare incremental (streamed) output against full rendering across paragraphs, headings, lists, block quotes, code fences, and tables.
- The right acceptance test is a parity property, not a hand-written case per construct.