T-GOY0-rebase-scan-corpus-assumptions-on-markdown-contract
Status: closed/done · Impact: low · Complexity: medium
plugin/skills/task-ensure-ready/scan_corpus_assumptions.ts is the advisory
scanner that flags uniform-corpus assumptions in a task’s ## Approach /
## Proposed sections. It still re-derives document structure by hand: a local
stripFrontmatter that recomputes the frontmatter line offset, plus a scanBody
that split("\n")-walks the body hand-tracking H2 sections and code fences. mc
0.2.0 (already vendored) parses the whole document and exposes section
navigation with absolute line numbers, so the bespoke walk can be replaced while
the scanner keeps emitting identical candidates and offsets.
| Location | Role today |
|---|---|
plugin/skills/task-ensure-ready/scan_corpus_assumptions.ts#stripFrontmatter | Wraps the shared util/frontmatter split but recomputes [body, lineOffset] via its own newline count |
plugin/skills/task-ensure-ready/scan_corpus_assumptions.ts#scanBody | splitLines(body) (a split("\n") wrapper), then hand-tracks the scoped H2 sections (SCOPED_SECTIONS: Approach / Proposed) and a code-fence state machine; absoluteLine = idx + lineOffset |
plugin/skills/task-ensure-ready/scan_corpus_assumptions.ts | Exports stripFrontmatter / scanBody / maskInlineCode / hasToleranceSignal; import.meta.main entrypoint emits one JSON candidate per line |
plugin/skills/task-ensure-ready/tests/ensure_ready.test.ts | The suite exercising the exported scanner functions and their candidate output |
plugin/lib/model/entities/task/ops/parse-touchpoints.ts | Shipped precedent: reads document structure through mc parse / sectionsAt with line-aware positions |
Proposed
Section titled “Proposed”scanBody derives its scoped sections and their line extents from a single mc
parse — sectionsAt(root, 2) (or findSection) filtered to the
SCOPED_SECTIONS names — and skips fenced code via mc’s codeBlockLines
instead of the hand-rolled fence state machine. Frontmatter splitting routes
through the shared util/frontmatter helper (already imported); because mc
reports absolute source line numbers, the stripFrontmatter line-offset
recompute collapses. The masking (maskInlineCode) and tolerance-signal logic
are untouched. Candidate output — section, signal, 1-indexed absolute line, and
snippet — is byte-identical to today; the exported function signatures are
preserved (or their callers in the test suite updated in lock-step).
Approach
Section titled “Approach”- In
scanBody, replace thesplitLines+ H2 + fence hand-tracking with a single mcparse; select the scoped sections viasectionsAt(root, 2)filtered toSCOPED_SECTIONS, and take each section’s body line extent from mc (sectionSpans/ the section node’spos). - Skip fenced code inside a scoped section with mc’s
codeBlockLinesrather than theinFence/fenceMarkerstate machine. Keep the per-section masked-line accumulation and the section-scopedhasToleranceSignalgate as they are — the change is how sections and fences are located, not how the tolerance/uniform phrase scan runs. - Route frontmatter through the shared
splitFrontmatterfromutil/frontmatterand use mc’s absolute line numbers directly, sostripFrontmatter’s offset recompute is no longer needed. Either keepstripFrontmatteras a thin shim (preserving the export) or drop it and update its callers inensure_ready.test.tsand theimport.meta.mainblock — pick one and apply it consistently. - Confirm the emitted candidates (section, signal, line, snippet) are
unchanged for every fixture; the absolute line numbers must match today’s
idx + lineOffsetvalues exactly. - Run the ensure-ready suite.
Files to touch
Section titled “Files to touch”| Location | Kind | Change |
|---|---|---|
plugin/skills/task-ensure-ready/scan_corpus_assumptions.ts#scanBody | modify | Locate scoped sections via mc parse / sectionsAt, skip fences via codeBlockLines, use mc’s absolute line numbers |
plugin/skills/task-ensure-ready/scan_corpus_assumptions.ts#stripFrontmatter | modify | Route through the shared util/frontmatter split; drop the bespoke offset recompute (keep as a shim or update callers) |
plugin/skills/task-ensure-ready/tests/ensure_ready.test.ts | modify | Confirm candidate output and offsets unchanged; update any call site if an export signature changes |
Acceptance criteria
Section titled “Acceptance criteria”- AC-1:
scanBodycontains nosplit("\n")body walk and no hand-rolled H2 / code-fence state machine; scoped sections and fence spans come from a single mcparse(sectionsAt/findSection+codeBlockLines). - AC-2: Frontmatter splitting goes through the shared
util/frontmatterhelper and the bespokestripFrontmatterline-offset recompute is removed (shimmed or its callers updated). - AC-3: The scanner’s JSON candidate output —
section,signal,line(1-indexed absolute), andsnippet— is byte-identical to today for the suite’s fixtures. - AC-4:
plugin/skills/task-ensure-ready/tests/ensure_ready.test.tspasses; exportedstripFrontmatter/scanBodybehavior is preserved or every caller is updated in the same change.
Out of scope
Section titled “Out of scope”- The uniform-corpus and tolerance-signal heuristics (
UNIFORM_PATTERNS,TOLERANCE_PATTERNS,maskInlineCode) — what the scanner flags is unchanged. - The
/sdlc:task-ensure-readyStep 3 LLM confirm-before-gap flow that consumes these candidates — this is a scanner-internal rebase only. scan_placeholders.ts(the sibling this scanner mirrors) — not in this task.
Dependencies
Section titled “Dependencies”- none — enabled by the already-vendored
markdown-contract0.2.0 (vendor/markdown-contract-0.2.0.tgz); no re-vendor needed. The precedentT-FN18migratedscan_placeholdersoff its bespoke walk onto mc and is already shipped (closed/done); this task applies the same idiom to the corpus-assumption scanner.
Discovery context
Section titled “Discovery context”- Surfaced by a read-side audit of remaining bespoke
split("\n")body walks after the markdown-contract adoption (milestone M-0009). This scanner mirrorsscan_placeholders.ts, whichT-FN18already moved onto mc.