Repository navigation
Description
Bug
In the id web editor's markdown ↔ ProseMirror codec (pkgs/id/src/web/markdown.rs), saving a document whose blockquote starts with a non-paragraph block (a fenced code block, a table, or a thematic break) inserts two stray blank lines — > lines — at the top of the quote, before that first block:
Input:
> ```rust
> let x = 1;
> ```After one load/save round trip:
>
>
> ```rust
> let x = 1;
> ```The ProseMirror document is correct throughout (the blockquote contains exactly one code_block, no empty paragraphs) and the output is a stable fixpoint — the two lines appear on the first save and stay. But every affected file gets polluted on save, the quote renders with a gap at the top in other renderers, and the diff noise obscures real edits.
Verified repro (this run, main 3b9d159)
Standalone verbatim-codec probe crate (evidence log: goal hidden_files/probe-2026-10-26-1415/out3.log, probe source is current markdown.rs verbatim):
markdown_to_prosemirror("> ```rust\n> let x = 1;\n> ```\n")→{"type":"blockquote","content":[{"type":"code_block","attrs":{"params":"rust"}, …}]}— correct, no empty paragraphs.prosemirror_to_markdownof that document →"> \n> \n> ```rust\n> let x = 1;\n> ```\n"— two leading blank quote lines.- Same pattern for a table as first block (
> | a |…→ two leading>lines) and a thematic break first (> ---\n> text→ two leading>lines, plus the normal separator beforetext). - Controls that save cleanly: blockquote starting with a paragraph, a heading, or a list; a blockquote where the same code block is not first (
> intro+ fence) saves with exactly the one normal separator line. - Control isolating the layer: comrak's own parse →
format_commonmarkrender of the original input produces the same two blank lines, so the quirk is in the comrak CommonMark renderer behaviour the codec's save direction relies on (prosemirror_to_markdown, markdown.rs:868-874, serializes a hand-built AST withformat_commonmark) — the codec inherits it on every save even though its own AST is correct.
Not #954: that issue is no-info code blocks being rewritten as indented blocks (document-level). This one is about leading blank lines inside a blockquote, affects info-string fences, tables and thematic breaks, and also appears when the block is not first in the file but first in the quote.
Why it matters
Silent file pollution on save, in the same codec family as #982/#954/#981 but a distinct mechanism: quoted code snippets, quoted tables and quoted rules are common in notes/docs, and the first save of any such file rewrites its top-of-quote for no reason.
Suggested fix
In the save direction, stop the two spurious separator lines from reaching the file — e.g. investigate whether the hand-built AST is missing something the renderer keys on for a blockquote's first child (in which case fix json_to_ast's blockquote/code_block construction), or post-process the serialized output to collapse a blockquote's leading blank > lines (only at quote start — blank separators between blocks in a quote are required and must be kept, cf. the > intro + fence control). If the behaviour turns out to be unfixable without forking the renderer, record that and close with the rationale rather than leaving it untracked.
Acceptance criteria
- Round-trip tests: blockquote starting with (a) a fenced code block with an info string, (b) a table, (c) a thematic break followed by text — each saves byte-identical to its input (no leading
>lines). - Regression controls unchanged: blockquote starting with paragraph/heading/list, and paragraph-then-fence inside a quote (exactly one separator blank line), still round-trip as today.
- Existing
web::markdowntests pass.
Activity
developing-today commentedon Oct 26, 2026
CODE-173
dezren39 commentedon Oct 26, 2026
🤖 Agent note · filed
hidden_files/probe-2026-10-26-1415/out3.log): a blockquote whose first block is a fenced code block, table or thematic break saves with two stray leading>blank lines; the ProseMirror doc is correct and comrak's own parse→render shows the same quirk, so it is the save direction's renderer behaviour. Enqueued as a triage packet to repo-health-code-pilot.65 remaining items
dezren39 commentedon Nov 5, 2026
🤖 Agent note · handed off
dezren39 commentedon Nov 5, 2026
agent-note:v1
task: 6565
state: handed_off
lane: code-b (queue) / opencode (execution)
Issue #1002 and canonical PR #4816 re-verified OPEN at claim (2026-11-05), no held/user-owned/do-not labels on either. Execution lane assigned
opencode; handing off to the laptop opencode claimant — PR #4816 remains the canonical PR, do not create a competing PR. Parking task 6565 for 20 minutes for the claimant. Note: attempts 32/32 (at max_attempts cap) — if the claimant misses this lease, the task will need a cap raise to be claimable again. Unresolved review items on PR #4816 per prior checkpoint: CodeRabbit major fence-state finding + nitpick on blank quoted line inside fenced block.dezren39 commentedon Nov 5, 2026
🤖 Agent note · handed off