Merge on-device AI critique bulletFindings into Fix It's guidance
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 56/100
- Issue type
- Feature
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- typescript
- Domain
- ai, frontend, testing-qa
Research direction
Start with normalizeBulletText in src/lib/score/group-bullets.ts, then trace GuidanceItem construction in src/lib/score/guidance.ts and the finding flow from src/lib/webllm/critique-resume.ts into CritiquePanel.tsx and FixItToolbar.tsx. Define and test matching, duplicate and edited-text fallbacks, including the ok case and read-only rows. Run npm run verify; done means matched findings appear through the existing Fix It anchor without changing critique detection.
Written by the indexing model from the issue text.
Description
Problem
There are two separate per-bullet quality lanes today:
- Heuristic checks (
hasMetric,startsWithActionVerb,wellFormedLengthon
BulletObservation,src/lib/score/score.ts) run on every parse, no model required, and are
what Fix It steps through (bulletIssues/bulletGuidanceItems,
src/lib/score/guidance.ts:277-303,384-404) viaGuidanceItems keyed to a stable bulletid. - On-device AI critique (
ResumeCritique.bulletFindings,src/lib/webllm/critique-resume.ts)
runs only after a WebGPU model download and a user-run analysis, and classifies each bullet as
no_quantification/weak_verb/vague/ok, with an optionalsuggestionstring
(BulletFinding, ~line 38-48). It renders separately, inCritiqueResults
(CritiquePanel.tsx) inside the "Local AI feedback" disclosure, not through Fix It.
A BulletFinding carries only the bullet's text (bullet: string), never an id — the model
has no notion of the résumé's stable bullet identity. That's why it's never been merged into
GuidanceItem/Fix It: there's no direct key to join on.
This issue is a Phase 2 follow-up to #913 (deferred there per that issue's Decisions section):
once #913 lands, Fix It's dock + the tinted in-bullet marker become the one place notes show up
for the heuristic checks. Leaving the AI critique in its own disclosure, with its own
presentation, is the split #913 explicitly chose not to solve for this round.
Proposal
- Match each
BulletFindingto aBulletObservation/résumé bullet by normalized text —
normalizeBulletText(src/lib/score/group-bullets.ts) already exists for exactly this kind of
fuzzy join (it's used to attribute raw bullet text to parsed entries) and should be reused rather
than a new matcher written. - On a match, fold the finding into that bullet's
GuidanceItemas an additional issue (a fourth
category alongside the three heuristic ones —vaguehas no heuristic equivalent), using the
finding'ssuggestionas the issue's suggestion text, so it shows in the Fix It dock
(FixItToolbar.tsx) the same way a heuristic issue does. - On no match (see risks below), the finding needs a defined fallback — most likely: don't inject
it into Fix It, leave it visible inCritiqueResultsas today, so nothing is silently dropped.
Risks
- Duplicate bullet text. Two bullets with identical normalized text (common — "Led weekly
1:1s with the team" appears more than once across résumés) can't be disambiguated by text alone;
a match must pick a deterministic bullet (e.g. document order) or refuse to match when the text
is ambiguous. - Edited bullets. A user who edits a bullet's text after critique ran invalidates the match —
the finding'sbulletstring no longer equals any current bullet's normalized text. Decide
whether a stale finding is dropped, kept against the pre-edit text, or critique is asked to
re-run. - Depends on #913. The tinted-marker mechanism and the "read-only rows carry no marker" rule
land in #913; this issue's markers/dock entries must follow the same rules once #913 is merged.
Acceptance criteria
-
BulletFindings are matched to résumé bullets vianormalizeBulletText, with a defined,
tested tie-break for duplicate-text bullets. - A matched finding shows in the Fix It dock the same way a heuristic issue does (title +
suggestion,FixItToolbar.tsx), on the bullet's existingGuidanceItem/useFixItTarget
anchor — no second highlight mechanism. - An unmatched or stale (post-edit) finding does not silently disappear: it either stays
visible inCritiqueResultsor is otherwise accounted for, per the chosen fallback. - Tests cover: unique match, duplicate-text bullets, a bullet edited after critique ran, and
anokfinding (no issue injected). - No change to
critique-resume.ts's detection/classification logic — this is a
presentation/join change only. - Read-only bullet rows (project/achievement/certification) still surface no marker, matching
#913's rule, even if critique produced a finding for their text. -
npm run verifyis green.
- Dominant language
- TypeScript
- Stars
- 11
- Forks
- 4
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 45
Getting set up
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from offlinecv/OfflineCV
-
refactor testing
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Maintainers usually reply within 1 day
-
chore
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Maintainers usually reply within 1 day
-
documentation
Difficulty 1/5 Under an hour Newbie friendliness 92/100
Maintainers usually reply within 1 day
-
improvement ux:job-search
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
Maintainers usually reply within 1 day
-
documentation
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
Maintainers usually reply within 1 day
All issues in offlinecv/OfflineCV
Similar issues
-
docs
Difficulty 1/5 Under an hour Newbie friendliness 68/100
remix-run/react-router#15558 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
solana-foundation/pay-kit#341 ·
Maintainers usually reply within 1 day
-
Difficulty 1/5 1-3 hours Newbie friendliness 88/100
supabase/agent-skills#607 ·
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day