Skip to content

id(web): footnotes are backslash-escaped on save — [^1] syntax mangled, definition orphaned #945

Closed

Description

@dezren39

Problem

Markdown footnotes in a file opened in the id web editor are mangled on save: the footnote syntax is backslash-escaped into literal text.

Verified probe on main a2eef6f7 (standalone crate compiling the verbatim pkgs/id/src/web/markdown.rs codec from main; log in the goal's hidden_files probe-2026-10-25-2312/probe2.log):

  • Input:
    Text with a note.[^1]
    
    [^1]: The footnote body.
    
  • markdown_to_prosemirror treats both the reference and the definition as ordinary paragraph text (footnotes never parse as footnotes).
  • Save (prosemirror_to_markdown) emits:
    Text with a note.\[^1\]
    
    \[^1\]: The footnote body.
    
    The \[ escapes mean the saved file no longer contains a footnote at all — it renders as literal [^1] characters, and the definition paragraph is orphaned plain text.

Root cause

  • commonmark_options() (pkgs/id/src/web/markdown.rs:67) enables strikethrough, tasklist and table extensions but not options.extension.footnotes, so comrak parses [^1] as plain text, and its CommonMark renderer escapes the brackets of text nodes on save.
  • Simply enabling the extension is not a fix by itself: the convert_node arm at markdown.rs:467 explicitly maps FootnoteDefinition / FootnoteReference to json!(null) — footnotes would then be silently deleted on open instead of mangled on save. The ProseMirror schema has no footnote node, so a representation decision is required (e.g. carry reference + definition as preserved raw text that re-emits verbatim, as sized images are carried through HTML forms).

Why it matters

Footnotes are standard in longer notes/docs. Today, opening a footnoted file in the web editor and saving any edit destroys every footnote in it — silently, and in a way that is hard to notice in a diff. Same silent-save-corruption class as #872/#873/#880/#881/#882.

Acceptance criteria

  • A markdown file with at least one footnote reference + definition round-trips open → save with the footnote still functioning as a footnote in the saved markdown (reference and definition both intact, not escaped, not deleted).
  • No regression to the currently passing codec tests; the strikethrough/tasklist/table extensions behave as before.
  • New unit tests in pkgs/id/src/web/markdown.rs cover the footnote round-trip, including a definition with more than one paragraph if the chosen representation supports it (otherwise the limitation is named in the PR).
  • If the chosen fix is "preserve verbatim as raw text", a re-open of the saved file must show the same preserved form (stable fixpoint, no progressive escaping).

Activity

  1. added
    kind/bugSomething isn't working (prefixed form of the classic bug label)
    task/triageQueue packet kind: verify, reproduce, and route this item
    source/creatorFiled by the new-issue-creator job
    on Oct 26, 2026
  2. developing-today commented on Oct 26, 2026

    @developing-today
    Contributor
  3. added
    priority/normalOrdinary priority (the default)
    queue/queuedHas a queued task in the Supabase agent queue
    app/idPackage/app: id (pkgs/ or apps/ in this repo)
    on Oct 26, 2026
  4. dezren39 commented on Oct 26, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · filed

    • Agent: new-issue-creator job
    • Session / ID: new-issue-creator run, 2026-10-25 23:15 CDT (America/Chicago)
    • Found via: filed this run
    • Task: footnotes mangled on save: commonmark_options (markdown.rs:67) never enables the footnote extension, so [^1] parses as plain text and the renderer escapes it to [^1]; enabling it naively would hit the markdown.rs:467 arm that drops FootnoteDefinition/Reference to null. Verified this run with a standalone crate compiling the verbatim codec from main a2eef6f (log: goal hidden_files probe-2026-10-25-2312/probe2.log). Queued for the code pilot queue (triage packet — PM representation decision needed).
    • Expectation: effort/m — done looks like footnote reference+definition round-tripping intact (not escaped, not deleted), with markdown.rs unit tests.
    • Links: n/a yet (queue packet enqueued this run)
  5. added
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Oct 26, 2026
  6. 16 remaining items

  7. dezren39 commented on Oct 26, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · parked

  8. dezren39 commented on Oct 26, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up

  9. added
    queue/claimedQueue worker lifecycle state
    and removed
    status/parkedDeliberately paused with a recorded resume condition
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    on Oct 26, 2026
  10. dezren39 commented on Oct 26, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

app/idPackage/app: id (pkgs/ or apps/ in this repo)kind/bugSomething isn't working (prefixed form of the classic bug label)priority/normalOrdinary priority (the default)source/creatorFiled by the new-issue-creator jobstatus:donetask/triageQueue packet kind: verify, reproduce, and route this item

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions