Bug description
When a fenced code block's opening fence directly follows a Markdown heading (with only blank lines in between), the importer misparses the fences and silently ignores every specification item after the block's closing fence. There is no error or warning — trace reports ok - 0 total and exits 0, and impl->req coverage tags pointing at the dropped items show up as orphaned.
Minimal reproduction
spec.md:
# Spec
## A diagram before any requirement
```mermaid
graph TD
A --> B
```
## Some requirement
`req~example~1`
A requirement that should be imported.
Needs: impl
$ java -jar openfasttrace-4.9.0.jar convert -o specobject spec.md
<?xml version="1.0" encoding="UTF-8"?>
<specdocument></specdocument>
$ java -jar openfasttrace-4.9.0.jar trace spec.md
ok - 0 total
Expected: req~example~1 is imported (1 item). Actual: no items, no diagnostic.
The info string is irrelevant — ```mermaid, ```json, ```foobar, and a bare ``` all trigger it. What matters is the position: move the same block so a paragraph of text precedes it and the requirement imports fine.
Root cause
In MarkdownImporter.configureTransitions(), the TITLE state (entered after a heading) has no transition for MdPattern.CODE_BEGIN. The opening fence therefore matches TITLE → START via EVERYTHING, and the closing ``` then matches CODE_BEGIN from START (the \w* info string is optional), opening a phantom CODE_BLOCK. Since LineParserStateMachine keeps its state on unmatched lines, everything up to EOF (or the next stray fence) is swallowed.
This looks like a gap in the fix for #280 (#433), which added the CODE_BLOCK state but only wired CODE_BEGIN from START.
Versions
Reproduced with openfasttrace 4.9.0 (latest release), OpenJDK 21, Linux. Originally surfaced in JabRef via the org.itsallcode.openfasttrace Gradle plugin 3.2.0.
Impact
Silent requirement loss: spec authors get zero signal that items vanished from tracing. JabRef currently works around it by moving diagrams after the last requirement.
I'll open a PR adding the missing TITLE → CODE_BLOCK transition plus a regression test.
Bug description
When a fenced code block's opening fence directly follows a Markdown heading (with only blank lines in between), the importer misparses the fences and silently ignores every specification item after the block's closing fence. There is no error or warning —
tracereportsok - 0 totaland exits 0, andimpl->reqcoverage tags pointing at the dropped items show up as orphaned.Minimal reproduction
spec.md:Expected:
req~example~1is imported (1 item). Actual: no items, no diagnostic.The info string is irrelevant —
```mermaid,```json,```foobar, and a bare```all trigger it. What matters is the position: move the same block so a paragraph of text precedes it and the requirement imports fine.Root cause
In
MarkdownImporter.configureTransitions(), theTITLEstate (entered after a heading) has no transition forMdPattern.CODE_BEGIN. The opening fence therefore matchesTITLE → STARTviaEVERYTHING, and the closing```then matchesCODE_BEGINfromSTART(the\w*info string is optional), opening a phantomCODE_BLOCK. SinceLineParserStateMachinekeeps its state on unmatched lines, everything up to EOF (or the next stray fence) is swallowed.This looks like a gap in the fix for #280 (#433), which added the
CODE_BLOCKstate but only wiredCODE_BEGINfromSTART.Versions
Reproduced with openfasttrace 4.9.0 (latest release), OpenJDK 21, Linux. Originally surfaced in JabRef via the
org.itsallcode.openfasttraceGradle plugin 3.2.0.Impact
Silent requirement loss: spec authors get zero signal that items vanished from tracing. JabRef currently works around it by moving diagrams after the last requirement.
I'll open a PR adding the missing
TITLE → CODE_BLOCKtransition plus a regression test.