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.
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 itas 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 regressionfrom 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
/thinkskill's export-hygiene section already tells operators to backtickangle-bracket tokens by hand (
`<claim-id>`, not the bare form), and thissession 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'smd_safe_text, the shared escaper everyrenderer 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_textwraps or escapes angle-bracket tokens the same way it wrapsunderscore identifiers, keeping the existing guarantees: idempotent, leaves
text already inside code spans alone, and composes correctly with URL
autolinking.
<colleague>and asserting
markdownlint-cli2passes under a default config./thinkskill's manual backtick-your-angle-brackets rulecan be relaxed to a note rather than a requirement.