refactor: route all markdown parsing through mdq() (plan 022)#93
Open
DavertMik wants to merge 1 commit into
Open
refactor: route all markdown parsing through mdq() (plan 022)#93DavertMik wants to merge 1 commit into
DavertMik wants to merge 1 commit into
Conversation
Enforce the "no regex/includes/line-splitting on markdown" rule across 8
violation sites. Adds one additive accessor — MarkdownQuery.meta() returning
{type, depth, text} — which removes the need for hand-rolled marked.lexer
walks. The `marked` import is now gone from experience-tracker and
experience-compactor.
- researcher Summary regex + parser `.includes('Extended Research')` -> mdq queries
- planner cleanExperienceFlows + table swap -> positional replaces with
re-query-after-each-mutation (no more String.replace on section raw text /
/^---/gm regex)
- experience-tracker: whole-section truncation (never cuts mid-fence),
writeAction/writeFlow dedup via mdq, listTocHeadings/extractHeadingSection/
renderAsHowTo rebuilt on meta()
- experience-compactor: listSections on mdq; clickXY regex -> isNonReusableCode
- knowledge-tracker firstLine via mdq().meta()
Deviations (both improvements, verified): renderAsHowTo matches with startsWith
via meta() (the plan's contains-matcher would infinite-loop on titles
containing the marker); planner's "and N more discoveries" note-append was
previously dead code (no-op after the tail blockquotes were removed) and now
correctly appends. Step 5 verified byte-identical to the old lexer walk;
Step 7's clickXY->isNonReusableCode broadening pinned by no test.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Explorbot Self-RegressionCommit
Attempt details
Session analysis — basic (native): Session AnalysisThe Issues list page was tested for core functionality: creation, filtering, search, and navigation. Four of five flows work correctly. The label filter feature fails to display a visual indicator of the active filter state, which is a required UX expectation. Coverage
What works
Defects[Medium] Label filter lacks visual active state indicatorAffects:
UX issues
Execution Issues
|
DenysKuchma
approved these changes
Jul 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Plan 022 — Route all markdown manipulation through
mdq()The project rule (CLAUDE.md, twice) is absolute: all markdown manipulation goes through
mdq()— never regex,.includes(), or line-splitting. This fixes 8 violations, including 4 hand-rolledmarked.lexerwalks that re-implemented mdq's own section logic with subtly different semantics.New mdq API (additive only)
MarkdownQuery.meta()→Array<{type, depth, text}>— exposes token type, heading depth, and unwrapped text. This is the gap that forced the lexer walks. 6 new unit cases inmarkdown-query.test.ts.Migrated
researcher.ts## Summaryregex +researcher/parser.ts.includes('Extended Research')→ mdq queries.planner.tscleanExperienceFlows+ table swap → positional.replace()with re-query-after-each-mutation (offsets go stale after a replace). Removed allString.replace(section.text(), …)and/^---/gm.experience-tracker.ts: whole-section truncation (never cuts mid-code-fence),writeAction/writeFlowdedup via mdq, andlistTocHeadings/extractHeadingSection/renderAsHowTorebuilt onmeta().experience-compactor.ts:listSectionsonsection2+meta(); the re-hardcoded clickXY regex →isNonReusableCode().knowledge-tracker.tsfirstLine →mdq().meta().markedimport removed from experience-tracker and experience-compactor.Two deviations (both improvements, verified)
renderAsHowTousesstartsWithviameta(), not the plan's literalh2(~"marker"). That contains-matcher would infinite-loop on a title containing the marker (## FLOW: undo FLOW: steps) and diverges from the oldstartsWith. The implemented version provably terminates and matches the old output (whitespace-only diff — the old code accidentally doubled blank lines).cleanExperienceFlows'> ... and N more discoveriesnote was dead code — the old.replace()no-op'd because the tail blockquotes were already removed from the string. The new code correctly appends it, as the plan specifies.STOP-candidates cleared
isNonReusableCodebroadening — no test pins the narrow behavior; the#ember123case yields the same final result (dropped at strip stage). All 43 compactor tests pass.Verification
bun test tests/unit→ 772 pass / 0 fail (+8 new tests; no existing assertions modified).bun test tests/integration/→ 63 pass / 0 fail.bun run lint→ clean;tsctotal neutral (639 = 639).grep markedin both files → empty;## Summaryregex gone;meta()present.🤖 Generated with Claude Code