Repository navigation
Description
Finding
PR #407 (commit 8fa3ff6, fixes #401) added a trailing-fence recovery to issue_drafts() in scripts/research_workflow.py (lines 534–564 on current main, 00078c8): when a trigger-issue draft's block is unclosed at document level (closed=False), a trailing bare fence line is assumed to be the draft's own closing fence — mis-consumed as the embedded example's close — and is dropped before draft_prose() runs.
That assumption is wrong for one shape: an unclosed draft whose last line is the genuine closing fence of a properly closed inner code example. Dropping that fence leaves the example "unclosed" in draft_prose(), so the recovery path keeps the example's buffered lines as prose and link-checks them — losing the exemption a properly closed example is supposed to have (#393). Before #407, unfenced(block) exempted this shape, so this is a (narrow) false-positive regression introduced by #407: check can fail on a valid document because a link-shaped string inside a closed code example points nowhere.
Evidence (reproduced on current main)
Using issue_drafts() from scripts/research_workflow.py at main 00078c8:
- Draft fence properly closed, inner example properly closed → draft yields only prose; the example (including a
[not-a-real-link](missing-example-target.md)line) is stripped. - Same draft but the draft's own fence never closed (EOF) and the inner example's genuine closing fence is the document's last line → draft yields the example's contents as prose, including the
missing-example-target.mdlink, whichlinks()/check_link()would then fail as a missing link target.
The two shapes are indistinguishable from the block alone (both are closed=False with a trailing bare fence), so the fix needs a rule that does not sacrifice the closed-example exemption — e.g. only drop the trailing fence when the block, without it, still contains draft prose/a pointer after the example's opening fence that the #401 recovery exists to reach, or try both parses and prefer the one that keeps a properly closed example exempt when nothing follows it.
Why it matters
The research-workflow checker is a gate on concept documents. A false failure on a valid document trains authors to distrust or work around the check — the mirror image of the silent-escape failures #382/#391/#393/#401 fixed. The shape is plausible in practice: a draft at the end of a file whose author forgot the draft's closing fence, with a finished code example as its last element.
Acceptance criteria
- A regression test covers an unclosed draft ending with a properly closed inner example whose contents contain a broken link-shaped string:
checkpasses (example stays exempt). - The four fix(workflow): drafts whose inner code example is unclosed still escape the link check past the example (#400 residual) #401 regression tests from PR fix(workflow): check draft links past unclosed inner code examples (fixes #401) #407 still pass (both unclosed-example shapes, broken + valid pointers), and the full workflow suite stays green.
- No other
issue_drafts()behavior changes.
Activity
Merge pull request #411 from developing-today/sweep/410-closed-exampl…