Per-bullet feedback — redesign from a flat dump to an actionable model
Part of M5 · UI Improvements.
Problem
PerBulletFeedback in src/components/Result.tsx renders one BulletRow per detected bullet, each with three check pills (action verb / 8–30-word length / metric). On a real resume this means ~35 rows dumped in a single scroll. It's accurate but unusable: no hierarchy, no prioritization, and it buries the signal ("most of your bullets lack a metric") under 35 individually-rendered lines.
Goal
Replace the flat list with a UI that:
- Leads with the high-level shape — e.g. "12 of 35 bullets need attention" plus a per-check rollup ("28 missing a metric · 9 too long · 4 weak verb"). The summary line already exists in
PerBulletFeedback; promote it to the primary content.
- Categorizes bullets by failure mode (missing metric / length / weak verb), so the user works one category at a time instead of scanning 35 mixed rows.
- Encourages drill-down without forcing it — collapse the per-bullet detail behind an expand affordance per category (or a "show flagged bullets" toggle); passing bullets shouldn't render at full weight at all.
- Gives the user a model to act on — order by impact, show the worst offenders first, make it obvious what to fix next.
Stretch (flag as a separate phase — the high-value play)
Auto-rewrite flagged bullets to address their issues (add a metric placeholder, tighten length, lead with a strong action verb). This is where the real value is — turning a diagnostic into a fix. Likely depends on the in-browser AI rewrite work (M4 · #3-area) for the generative side; the deterministic side can pre-fill structure (verb list, length trim) without a model. Do not bundle the rewrite into the first pass — ship the categorized/summarized read-only redesign first, then layer rewrite on top.
Acceptance (first pass — read-only redesign)
Out of scope (this issue)
- The auto-rewrite stretch — tracked as a follow-up once the read-only redesign lands.
Files
src/components/Result.tsx — PerBulletFeedback / BulletRow (likely extract into a features/ component; Result.tsx is already over the 200-LOC guideline)
src/lib/score/score.ts — BulletObservation shape (read-only; check whether categorization needs any new derived field)
Per-bullet feedback — redesign from a flat dump to an actionable model
Part of M5 · UI Improvements.
Problem
PerBulletFeedbackinsrc/components/Result.tsxrenders oneBulletRowper detected bullet, each with three check pills (action verb / 8–30-word length / metric). On a real resume this means ~35 rows dumped in a single scroll. It's accurate but unusable: no hierarchy, no prioritization, and it buries the signal ("most of your bullets lack a metric") under 35 individually-rendered lines.Goal
Replace the flat list with a UI that:
PerBulletFeedback; promote it to the primary content.Stretch (flag as a separate phase — the high-value play)
Auto-rewrite flagged bullets to address their issues (add a metric placeholder, tighten length, lead with a strong action verb). This is where the real value is — turning a diagnostic into a fix. Likely depends on the in-browser AI rewrite work (M4 · #3-area) for the generative side; the deterministic side can pre-fill structure (verb list, length trim) without a model. Do not bundle the rewrite into the first pass — ship the categorized/summarized read-only redesign first, then layer rewrite on top.
Acceptance (first pass — read-only redesign)
npm run typecheck+npm run build+npm run testgreenOut of scope (this issue)
Files
src/components/Result.tsx—PerBulletFeedback/BulletRow(likely extract into afeatures/component;Result.tsxis already over the 200-LOC guideline)src/lib/score/score.ts—BulletObservationshape (read-only; check whether categorization needs any new derived field)