Skip to content

export renders angle-bracket tokens as inline HTML (MD033) — a claim naming <colleague> or <task-id> fails markdownlint #95

Description

@OriNachum

Summary

Found during end-to-end verification of the fifteen-issue sweep (task t19).
A claim whose text contains an angle-bracket token — <colleague>, <task-id>,
<slug> — renders verbatim into the exported spec, where markdownlint reads it
as inline HTML and fails MD033/no-inline-html.

This is a sibling of #87 but was NOT in its acceptance criteria, which name
*, backtick, [, ], and a leading #. It is therefore not a regression
from the 0.21.0 escaping work — it is a pre-existing gap that the 0.21.0 work
made newly visible by fixing everything around it.

Evidence

After 0.21.0, shell-cli's real exported spec goes from 8 markdownlint errors
to 1
. All seven MD037 failures clear. The single survivor is this MD033 case.

Current workaround

The /think skill's export-hygiene section already tells operators to backtick
angle-bracket tokens by hand (`<claim-id>`, not the bare form), and this
session hit it twice while authoring the sweep's own frame and plan. That works,
but it is a rule a human has to remember, enforced only by a failing lint run
after the fact — exactly the shape of problem #87 argued should be solved at
the renderer.

Why it was not fixed in 0.21.0

Out of scope by the release's own rule: it touches
devague/render/_md_safety.py's md_safe_text, the shared escaper every
renderer now composes, and expanding that during final verification risked the
seam bugs t19 was there to catch. (It did catch one: an underscore-bearing URL
was being truncated by the two escaping passes composing in opposite orders in
different renderers — see #94.)

What would close this

  • md_safe_text wraps or escapes angle-bracket tokens the same way it wraps
    underscore identifiers, keeping the existing guarantees: idempotent, leaves
    text already inside code spans alone, and composes correctly with URL
    autolinking.
  • A regression test exporting a frame whose claim text contains <colleague>
    and asserting markdownlint-cli2 passes under a default config.
  • Once it lands, the /think skill's manual backtick-your-angle-brackets rule
    can be relaxed to a note rather than a requirement.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions