What this epic is
An architecture pass over resumelint that turns "the core pipeline is healthy but the edges are unfinished" into a prioritized, intern-sized backlog. The cascade (Tier 0 extract+layout → Tier 1 openresume → Tier 1.5 regex) and the score math are in good shape. The findings cluster in two places: lib paths that were built but never wired to UI, and primitives the project's own CLAUDE.md assumes exist but don't (so the rules are quietly violated in-tree).
How we went about it
- Mapped the real shape, not the documented one — read
App.tsx, Result.tsx, cascade.ts, score.ts, types.ts, the JD-match and webllm surfaces, and the editable-parse hook.
- Grep-verified each suspected gap rather than trusting the prose: confirmed
onEvent is never passed, runCascadeFromMarkdown has zero UI consumers, fetch-jd.ts has zero .tsx importers, there is no Button primitive, and overrides from useEditableParse are never consumed by scoring/JD.
- Ranked by impact × pattern-value, not by size. Cheap wins that unlock data (telemetry) and pattern-setting primitives rank above feature breadth.
- Filed self-contained issues with
file:line anchors, an ordered plan, a Reuse analysis for each surface-adding issue, and testable acceptance criteria — so each is implementable after a /clear.
Smaller optional findings (parse cancel/abort, result persistence/share-link, folding JD into the overall score) were deliberately dropped for now — real but not pattern-setting. They live in the conversation if we want them later.
Sub-issues
A. Finish the paid-for lib paths (built, no UI) — highest ROI
B. Establish the primitives the architecture already assumes
C. Close the severed edit loop (product decision inside)
D. Pay down structure debt
E. Memorialize the rules so they hold for the future
Suggested order
#77 (tiny, unblocks funnel data now) → #80 (primitives, prereq for clean UI) → #83 (decompose, rides on #80) → #78 + #79 (finish lib paths, parallelizable) → #81 (ErrorBoundary, uses #80's ErrorState) → #82 (decide A vs B first; lands with #83's hook) → #84 (enforce, after #80 makes the tree green).
Do we need new hooks / CLAUDE.md rules to memorialize this?
Yes, but narrowly — and it's issue #84, not a CLAUDE.md rewrite. The takeaway from this pass is that resumelint's CLAUDE.md already had the right rules (one <Button>, no hardcoded palette, semantic tokens) — prose alone didn't keep them true. So the durable fix is automated enforcement (a style_guard.sh hook mirroring the existing reuse_surface_reminder.sh) plus a CONTRIBUTING.md mirror for PR-only contributors, both scoped in #84. The only CLAUDE.md edit needed is a one-line pointer to that hook under "What NOT to do" — also in #84. No broad rule expansion: the rules were fine; enforcement was missing.
Out of scope (parked)
Parse abort/cancel; result persistence + privacy-safe share link; JD as a 4th scored dimension. File later if we want them.
What this epic is
An architecture pass over resumelint that turns "the core pipeline is healthy but the edges are unfinished" into a prioritized, intern-sized backlog. The cascade (Tier 0 extract+layout → Tier 1 openresume → Tier 1.5 regex) and the score math are in good shape. The findings cluster in two places: lib paths that were built but never wired to UI, and primitives the project's own
CLAUDE.mdassumes exist but don't (so the rules are quietly violated in-tree).How we went about it
App.tsx,Result.tsx,cascade.ts,score.ts,types.ts, the JD-match and webllm surfaces, and the editable-parse hook.onEventis never passed,runCascadeFromMarkdownhas zero UI consumers,fetch-jd.tshas zero.tsximporters, there is noButtonprimitive, and overrides fromuseEditableParseare never consumed by scoring/JD.file:lineanchors, an ordered plan, a Reuse analysis for each surface-adding issue, and testable acceptance criteria — so each is implementable after a/clear.Smaller optional findings (parse cancel/abort, result persistence/share-link, folding JD into the overall score) were deliberately dropped for now — real but not pattern-setting. They live in the conversation if we want them later.
Sub-issues
A. Finish the paid-for lib paths (built, no UI) — highest ROI
onEvent) into the app (improvement)fetch-jd.tsin the JD input (feature)B. Establish the primitives the architecture already assumes
C. Close the severed edit loop (product decision inside)
D. Pay down structure debt
Result.tsx(refactor)E. Memorialize the rules so they hold for the future
Suggested order
#77(tiny, unblocks funnel data now) →#80(primitives, prereq for clean UI) →#83(decompose, rides on #80) →#78+#79(finish lib paths, parallelizable) →#81(ErrorBoundary, uses #80's ErrorState) →#82(decide A vs B first; lands with #83's hook) →#84(enforce, after #80 makes the tree green).Do we need new hooks / CLAUDE.md rules to memorialize this?
Yes, but narrowly — and it's issue #84, not a CLAUDE.md rewrite. The takeaway from this pass is that resumelint's
CLAUDE.mdalready had the right rules (one<Button>, no hardcoded palette, semantic tokens) — prose alone didn't keep them true. So the durable fix is automated enforcement (astyle_guard.shhook mirroring the existingreuse_surface_reminder.sh) plus a CONTRIBUTING.md mirror for PR-only contributors, both scoped in #84. The only CLAUDE.md edit needed is a one-line pointer to that hook under "What NOT to do" — also in #84. No broad rule expansion: the rules were fine; enforcement was missing.Out of scope (parked)
Parse abort/cancel; result persistence + privacy-safe share link; JD as a 4th scored dimension. File later if we want them.