Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Merge on-device AI critique bulletFindings into Fix It's guidance

Closed
#1,008 0 comments 0 reactions 0 assignees View on GitHub

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

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

enhancement ux:score-clarity

Problem

There are two separate per-bullet quality lanes today:

  • Heuristic checks (hasMetric, startsWithActionVerb, wellFormedLength on
    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) via GuidanceItems keyed to a stable bullet id.
  • 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 optional suggestion string
    (BulletFinding, ~line 38-48). It renders separately, in CritiqueResults
    (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 BulletFinding to a BulletObservation/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 GuidanceItem as an additional issue (a fourth
    category alongside the three heuristic ones — vague has no heuristic equivalent), using the
    finding's suggestion as 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 in CritiqueResults as 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's bullet string 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 via normalizeBulletText, 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 existing GuidanceItem/useFixItTarget
    anchor — no second highlight mechanism.
  • An unmatched or stale (post-edit) finding does not silently disappear: it either stays
    visible in CritiqueResults or is otherwise accounted for, per the chosen fallback.
  • Tests cover: unique match, duplicate-text bullets, a bullet edited after critique ran, and
    an ok finding (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 verify is green.
Dominant language
TypeScript
Stars
11
Forks
4
Avg merge
1d 15h
Merged PRs (30d)
45

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from offlinecv/OfflineCV

All issues in offlinecv/OfflineCV

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.