Skip to content

fix(state): parse ROADMAP checklist items with markdown emphasis (#651)#658

Draft
halindrome wants to merge 4 commits into
swt-labs:mainfrom
halindrome:fix/roadmap-checklist-bold-emphasis-parse
Draft

fix(state): parse ROADMAP checklist items with markdown emphasis (#651)#658
halindrome wants to merge 4 commits into
swt-labs:mainfrom
halindrome:fix/roadmap-checklist-bold-emphasis-parse

Conversation

@halindrome

Copy link
Copy Markdown
Contributor

What

Make VBW's state-consistency verifier parse ROADMAP checklist items and ## Phase N: section headings that use markdown bold/italic emphasis (e.g. - [ ] **Phase 1: Setup**), in addition to the existing plain and bootstrap-link forms.

Closes #651.

Why

ROADMAP checklists are frequently authored or hand-edited with emphasis (the in-repo bootstrap-roadmap.sh emits the link form, but LLM- and hand-authored ROADMAPs commonly use bold). roadmap_checklist_phase_num_from_line() only matched - [ ] Phase N: and - [ ] [Phase N:, so on any emphasized ROADMAP the verifier counted 0 checklist entries, failing roadmap_vs_summaries and state_vs_roadmap and hard-blocking verify-state-consistency.sh --mode archive (exit 2) — a persistent, unfixable "state drift" with no workaround.

How

  • Checklist parser (scripts/phase-state-utils.sh + the guarded duplicate in scripts/state-updater.sh): widened the regex \[?Phase[*_]*\[?[*_]*Phase, tolerating emphasis markers around the optional link bracket. Plain and link forms still parse; non-phase lines still don't match.
  • Section-heading counter (scripts/verify-state-consistency.sh): widened symmetrically (^#{2,3} [*_]*(\[)?[*_]*Phase [0-9]+:) so a ROADMAP that emphasizes both checklist items and ## Phase N: headings doesn't fail on a checklist-vs-section count mismatch (found in QA round 2).
  • Tests (tests/verify-state-consistency.bats): 5 new tests — bold roadmap_vs_summaries + state_vs_roadmap, a --mode archive bold test (the exact ROADMAP checklist parser rejects emphasized phase labels (**Phase N:**), permanently blocking archive #651 blocking path), a parser unit test across plain/link/bold/italic/bold-link + a negative, and a both-emphasized reconciliation test. All confirmed to fail against the pre-fix regex.

Single centralized parser: every ROADMAP-checklist consumer routes through roadmap_checklist_phase_num_from_line, so this is a complete fix, not a point patch.

Testing

  • bash testing/run-all.sh green: 3596 BATS / 0 failed, 51/51 contract, lint 1/1
  • shellcheck -S warning clean on all changed scripts; bash -n clean
  • New tests verified as genuine regression guards (fail pre-fix, pass post-fix)
  • Back-compat: plain and bootstrap-link forms still parse; non-phase lines still rejected
  • 3 QA review rounds (reports posted as comments)

shanemccarron-maker and others added 4 commits June 16, 2026 09:11
…-labs#651)

ROADMAP checklists are frequently authored or edited with markdown emphasis,
e.g. "- [ ] **Phase N: Name**". But roadmap_checklist_phase_num_from_line()
only matched the plain "- [ ] Phase N:" and bootstrap-link "- [ ] [Phase N:"
forms (the in-repo bootstrap-roadmap.sh emits the link form). On any ROADMAP
with emphasized checklist items the verifier counted 0 entries, failing
roadmap_vs_summaries and state_vs_roadmap and hard-blocking archive via
verify-state-consistency.sh --mode archive.

Widen the regex from \[?Phase to [*_]*\[?[*_]*Phase so bold/italic emphasis
markers around the optional link bracket are tolerated. Applied to both
copies (phase-state-utils.sh live + state-updater.sh guarded duplicate) and
document the accepted forms in verify-state-consistency.sh. Legacy plain and
link forms still parse; non-phase lines still do not match.

Adds regression coverage in tests/verify-state-consistency.bats: bold-format
roadmap_vs_summaries + state_vs_roadmap integration tests and a unit test of
roadmap_checklist_phase_num_from_line across plain/link/bold/italic/bold-link
forms plus a negative.

Closes swt-labs#651.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Round 1 (clean for merge) flagged two minor items:
- Added an explicit --mode archive test on a bold ROADMAP (swt-labs#651's named
  hard-block path), asserting exit 0 + verdict pass; prior tests covered
  only --mode advisory.
- Corrected the attribution: the in-repo bootstrap-roadmap.sh emits the
  link form; emphasized ROADMAP checklists are LLM-/hand-authored. Base
  commit message and test comment updated accordingly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Round 2 found a real residual with the same root cause as swt-labs#651: the
checklist counter parsed emphasis but the section-heading counter at
verify-state-consistency.sh:916 did not, so a ROADMAP that emphasizes BOTH
checklist items and '## Phase N:' headings would fail state_vs_roadmap on a
checklist-vs-section count mismatch.

Widen the heading grep to '^#{2,3} [*_]*(\[)?[*_]*Phase [0-9]+:' (same
emphasis tolerance as the checklist parser). Add regression test asserting
state_vs_roadmap passes (and --mode archive exits 0) when both checklist and
headings are bold. Heading grep counted bold headings as 0 pre-fix; full
suite 3596/0; shellcheck clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Round 3 (fresh, final) is CLEAN FOR MERGE: completeness sweep confirms every
ROADMAP-checklist consumer routes through the single centralized parser; the
round-2 heading widening is symmetric with no false positives; all 5 new tests
are genuine, deterministic guards (fail pre-fix); 104/104 file suite + full
suite green; shellcheck and bash -n clean; patterns bash 3.2 portable.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@halindrome

Copy link
Copy Markdown
Contributor Author

QA Review — Round 1 (fresh review against base 3ca99e60; addressed in address QA round 1)

- Model used: Claude Opus 4.8 (read-only pr-qa-reviewer agent)

- What was tested:
  • Diff scope: 3 scripts (regex widened in phase-state-utils.sh + state-updater.sh guarded
    duplicate; comment-only in verify-state-consistency.sh) + new bats tests. 4 files, +75/-3.
  • Regex correctness vs #651: sourced phase-state-utils.sh and probed 17 forms. Matches: plain,
    link [Phase N:, bold **, italic *, underscore __, bold-link **[, link-bold [**. Rejects:
    **Phaser 1:**, missing colon, "**Phase** 1:", lowercase phase, ## Phase heading, emphasis-
    without-Phase. Multi-digit (12) and leading-zero (03->3) normalize. ':' anchor preserved.
  • Real emitters: in-repo bootstrap (scripts/bootstrap/bootstrap-roadmap.sh) and
    create-remediation-phase.sh emit the LINK form; templates/ROADMAP.md emits PLAIN. No in-repo
    script emits a bold ROADMAP *checklist* item — emphasized checklists are LLM-/hand-authored,
    so the defensive widening is correct and regresses neither real emitter.
  • Duplicate-copy audit: function defined live once in phase-state-utils.sh and a guarded
    fallback in state-updater.sh; both bodies updated identically; no third stale copy
    (reconcile-state-md.sh, verify-state-consistency.sh source phase-state-utils.sh).
  • roadmap_section_count `## Phase N:` heading parsing still aligns with the bold checklist case.
  • Full suite 3594/0; new #651 tests non-tautological (pre-fix regex proven to NOMATCH bold);
    shellcheck -S warning clean on all 3 scripts.

- Expected vs actual:
  1. (#651 core) bold/italic emphasis forms parse without regressing plain/link or matching
     non-phase lines — fully satisfied; no defect.
  2. (#651 archive path) the issue's named breakage is `--mode archive` hard-blocking (exit 2),
     but the new integration tests asserted only `--mode advisory`. Test-coverage gap, not a
     code defect. Severity: minor.
  3. (attribution) the original commit message + test comment claimed bootstrap emits the bold
     checklist form; the in-repo bootstrap actually emits the link form. Severity: minor (accuracy).

- Severity: finding 1 none; findings 2 and 3 minor.
- Confirmed vs hypothetical: 1 CONFIRMED (17-form probe + full bats + pre-fix counter-proof);
  2 CONFIRMED (grep of new tests shows only --mode advisory); 3 CONFIRMED (grep of real emitters).

ROUND VERDICT: CLEAN FOR MERGE — parse fix correctly/completely satisfies #651 (all emphasis forms
parse, no regression, no false positives, both copies identical, no stale third copy, suite green,
shellcheck clean). Only a minor archive-path test-coverage gap and a comment-accuracy nit.

Addressed in fix(state): address QA round 1: (finding 2) added archive mode exits 0 on a markdown-bold ROADMAP (#651 blocking path) — drives --mode archive on a bold ROADMAP and asserts exit 0 + verdict pass, locking the exact user-visible regression #651 names. (Finding 3) corrected the base commit message and the test-block comment to state accurately that the in-repo bootstrap emits the link form and emphasized checklists are LLM-/hand-authored.

@halindrome

Copy link
Copy Markdown
Contributor Author

QA Review — Round 2 (fresh review of the round-1 state; one real residual found and fixed in address QA round 2)

- Model used: Claude Opus 4.8 (read-only Code Reviewer agent)

- What was tested:
  • Re-verified the widened checklist regex in both copies (phase-state-utils.sh live +
    state-updater.sh guarded fallback) — byte-identical; no third copy.
  • Probed 14 edge cases under bash: italic `_`, bold-italic `***`, `[X]`, link, bold-link,
    plain — all match; tab/leading-space indent, `[ Phase` (space after bracket), `- [] `
    (no space in checkbox), `Phasex`, `Phaze`, double-space `Phase` — all rejected; trailing
    `\r` (CRLF) harmless (regex end unanchored).
  • normalize_roadmap_phase_num leading-zero strip correct for every form.
  • Symmetry probe: checklist parser vs the `## Phase N:` section-heading counter.
  • Determinism/isolation of new tests; confirmed the --mode archive test is non-vacuous
    (the archive gate genuinely returns 2 on a real failure, per the existing exit-2 test).
  • Re-confirmed round-1 attribution correction in commit body + test comment.
  • Full suite + shellcheck -S warning on all touched scripts.

- Expected vs actual:
  1-4,6-9. Verification items — all CONFIRMED, no defects (regex correctness, both copies
     identical, no third copy, normalization, test determinism, attribution accuracy, suite green,
     shellcheck clean, bash 3.2 portability).
  5. ASYMMETRY (real residual, same root cause as #651): the checklist counter now parses
     emphasis, but the section-heading counter at verify-state-consistency.sh:916
     (`grep -cE '^#{2,3} (\[)?Phase [0-9]+:'`) did NOT. Probe: a ROADMAP with `## **Phase 1: X**`
     headings counts the bold heading as 0, so if an author emphasizes BOTH checklist items AND
     `## Phase N:` headings, roadmap_checklist_count != roadmap_section_count and state_vs_roadmap
     falsely fails — the same class of false failure #651 fixes, relocated to headings. The shipped
     tests dodged this by pairing bold checklists with plain headings only.

- Severity: findings 1-4,6-9 none (verification). Finding 5 minor (latent, narrow trigger:
  requires emphasized headings; outside #651's literal checklist text but identical root cause).
- Confirmed vs hypothetical: finding 5 CONFIRMED by probe (grep counts bold heading as 0).

ROUND VERDICT: CLEAN FOR MERGE — fix correct, symmetric across both copies, tested (103/103),
shellcheck-clean, bash 3.2-portable; one non-blocking latent asymmetry at heading counter:916.

Addressed in fix(state): address QA round 2: widened the section-heading counter at verify-state-consistency.sh:916 to the same emphasis tolerance (^#{2,3} [*_]*(\[)?[*_]*Phase [0-9]+:), so emphasized ## **Phase N:** headings count symmetrically with emphasized checklist items. Added regression test state_vs_roadmap reconciles when BOTH checklist and ## headings are emphasized (#651) (drives --mode archive, asserts pass). Verified the heading grep counted bold headings as 0 pre-fix vs correctly post-fix; full suite 3596/0; shellcheck clean.

@halindrome

Copy link
Copy Markdown
Contributor Author

QA Review — Round 3 (fresh final review of the complete change; clean for merge, recorded as an empty address QA round 3 commit)

- Model used: Claude Opus 4.8 (read-only pr-qa-reviewer agent)

- What was tested:
  • Cumulative diff 3ca99e60...HEAD (fix + QA r1 + QA r2): checklist parser widened in
    phase-state-utils.sh + state-updater.sh; heading grep widened in verify-state-consistency.sh;
    5 new bats tests.
  • Completeness sweep of every ROADMAP-checklist consumer in scripts/ (run_check_state_vs_roadmap,
    run_check_roadmap_vs_summaries, update-phase-total.sh, reconcile-state-md.sh incl. the
    rewrite_roadmap_checklist_projection path).
  • Parser probed on real bash: plain/link/bold/italic/triple/underscore/mixed forms + negatives.
  • Heading-grep false-positive probe (`## *Phaser 1:*`, 4-hash, 1-hash, no-space).
  • Genuine-guard check: reverted all 3 source widenings to pre-fix regex and reran the 5 new tests.
  • reconcile rewrite emphasis-preservation; full suite (104), shellcheck -S warning, bash -n.

- Expected vs actual:
  1. Completeness — every other ROADMAP-checklist/scheme consumer routes through the SINGLE
     centralized parser roadmap_checklist_phase_num_from_line (+ the roadmap_checklist_count/
     _phase_nums/_numbering_scheme helpers); no consumer re-implements the checklist regex. The only
     non-routed parser was the heading grep, widened symmetrically in round 2. The bold-bullet greps
     in update-phase-total.sh / reconcile-state-md.sh parse STATE.md system bullets, not ROADMAP
     checklists (out of #651 scope, correct as-is). No incompleteness.
  2. Heading widening rejects `## *Phaser 1:*`, 4-hash (`#{2,3}` caps at 3), 1-hash, no-space;
     over-accepts only the link-bracket form (harmless, consistent with the checklist parser).
  3. roadmap_vs_summaries maps phases numerically (roadmap_phase_dir_for_num), not via heading-anchor
     slugs — there is no `#phase-N-slug` derivation anywhere, so emphasis cannot break mapping.
  4. Parser correct on real bash across all forms; reconcile rewrite round-trips emphasis intact.
  5. All 5 new tests (95-99) flip to `not ok` against the pre-fix regex and `ok` against the fix —
     genuine, deterministic, isolated guards.
  6. 104/104 bats pass; shellcheck clean; bash -n clean; patterns bash 3.2 / BSD-grep portable.

- Severity: none (no findings).
- Confirmed vs hypothetical: all assessments CONFIRMED by execution (sourced parser, pre-fix guard
  revert, full suite, shellcheck).

ROUND VERDICT: CLEAN FOR MERGE — fix is centralized through a single parser every consumer already
routes through; heading widening is symmetric with no false positives; all 5 tests are confirmed
genuine guards; full suite + shellcheck + bash portability all pass.

Recorded as an empty fix(state): address QA round 3 commit (clean round — no code change required).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ROADMAP checklist parser rejects emphasized phase labels (**Phase N:**), permanently blocking archive

2 participants