Context
PR #41 added a deterministic noun-phrase pass to the JD extractor. The output is capped via allNouns.slice(0, NOUN_PASS_CAP) at src/lib/jd-match/extract-jd-terms.ts:210 — first-N in document order,
no ranking. The cap and the silenced overflow round-trip honestly to the UI ("the noun-phrase pass keeps the first ones it finds and drops the rest" in src/components/features/JdMatch.tsx:72-77), but
on a JD that opens with a marketing paragraph the first 25 capitalized phrases tend to be company-name fluff and the actually-informative phrases get dropped.
Goal
Rank noun-pass hits before slicing so the surfaced 25 are the most informative ones — and update the UI copy back to match.
Suggested approach
Deterministic ranking only — no LLM. A few cheap signals to combine into a score per hit:
- Hit count in the JD body (more occurrences → more central).
- Hit count in the requirements portion of the JD (heuristically: lines in a section whose heading matches
/requirements|qualifications|you'll have|what you bring/i).
- Presence in the existing weak-filler stoplist (
NOUN_STOP_PHRASES) at src/lib/jd-match/extract-jd-terms.ts:116-120 — extend it with company names, city names, and common product names as needed rather than introducing a parallel list. Keep additions small and inline-documented.
Sort by score, then slice. nounsDropped continues to record the overflow.
Acceptance criteria
Out of scope
- LLM-assisted ranking (separate milestone)
- Industry- or role-specific weights
Context
PR #41 added a deterministic noun-phrase pass to the JD extractor. The output is capped via
allNouns.slice(0, NOUN_PASS_CAP)atsrc/lib/jd-match/extract-jd-terms.ts:210— first-N in document order,no ranking. The cap and the silenced overflow round-trip honestly to the UI ("the noun-phrase pass keeps the first ones it finds and drops the rest" in
src/components/features/JdMatch.tsx:72-77), buton a JD that opens with a marketing paragraph the first 25 capitalized phrases tend to be company-name fluff and the actually-informative phrases get dropped.
Goal
Rank noun-pass hits before slicing so the surfaced 25 are the most informative ones — and update the UI copy back to match.
Suggested approach
Deterministic ranking only — no LLM. A few cheap signals to combine into a score per hit:
/requirements|qualifications|you'll have|what you bring/i).NOUN_STOP_PHRASES) atsrc/lib/jd-match/extract-jd-terms.ts:116-120— extend it with company names, city names, and common product names as needed rather than introducing a parallel list. Keep additions small and inline-documented.Sort by score, then slice.
nounsDroppedcontinues to record the overflow.Acceptance criteria
NOUN_PASS_CAPsliceJdMatch.tsxcopy updated to honestly describe the ranking step (per the team's copy-claims-round-trip-to-code rule)NOUN_PASS_CAPdocstring atsrc/lib/jd-match/extract-jd-terms.ts:106-115updated to matchOut of scope