jd-match: one boilerplate bullet strips every later bullet's skills
Nobody has claimed this yet.
Assessment
- Difficulty
- 3/5
- Estimated time
- Half a day
- Newbie friendliness
- 66/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- typescript
- Domain
- data
Research direction
Start with stripBoilerplate in src/lib/jd-match/extract-jd-terms.ts, where a blank line currently ends the skipped block. The change is to end the block at any line that starts with a bullet or enumerator, so only the anchor bullet is dropped. Add fail-before cases to extract-jd-terms.test.ts for the bulleted JDs in the table, then check that the sponsorship paragraph and the multi-line EEO paragraph still produce no terms. Done means the docblock and module header describe the new rule and those tests pass.
Written by the indexing model from the issue text.
Description
Problem
stripBoilerplate in src/lib/jd-match/extract-jd-terms.ts drops a line containing a boilerplate anchor and every non-blank line after it, up to the next blank line. Its docblock calls the line-granular over-strip "rare in practice". It isn't, because most JDs list requirements and benefits as bullets with no blank lines between them. Once one bullet hits an anchor (must be authorized to work, visa sponsorship, health insurance, paid time off, …), every later bullet in the list is dropped. The skills in those bullets never reach terms, nouns or coverage.
Whether a skill counts depends only on bullet order. Probed on main (#1175 found this, and kept term extraction byte-identical to main on purpose):
| JD | skills |
|---|---|
Requirements:\n- Must be authorized to work in the US\n- 5+ years of Python\n- Kubernetes and Terraform in production |
[] |
| Same three bullets, authorization line last | python, kubernetes, terraform |
We are unable to sponsor visas.\nMust have Python and Kubernetes experience. |
[] |
Benefits:\n- Health insurance\n- Python training budget |
[] |
The user sees real requirements missing from the keyword coverage, and the score is computed over the wrong set.
Scope
- In a list, an anchor bullet drops only that bullet. A line that starts with a bullet or enumerator (
-,*,•,1.,a)) ends any active boilerplate block, the same way a blank line does today. - Keep the block skip for prose paragraphs (an EEO paragraph wrapped over several lines must still be dropped whole).
- Don't move to sentence-level stripping. #1175 tried it over four review rounds, and every boundary rule (terminators without a following space, soft-wrap joins, dangling conjunctions, abbreviations) leaked or over-stripped in a new way. A bullet boundary is a line-start check, with no punctuation heuristics.
- Prose that runs on from an anchor line with no blank line (row 3) and the same-line case (
Salary range: $100k. We use Rust and Go.) are out of scope. Fixing them needs a sentence boundary, which is the approach ruled out above. Row 3 stays in the table to show the limit.
Acceptance criteria
- The bulleted JDs above (rows 1, 2 and 4) give the skills in the non-anchor bullets (
python,kubernetes,terraformwhere present), regardless of where the anchor bullet sits. - The anchor bullet's own content still never reaches terms:
TN/OPT/CPTfrom a sponsorship bullet stay out, and so does Samhit's wrapped…employment\nvisa (e.g., H-1B, TN, OPT/CPT)…paragraph case (a test row in #1175). - A multi-line EEO paragraph (no bullets) is still dropped as a block.
-
stripBoilerplate's docblock and the module header (lines ~14–17) describe the new rule. - Fail-before unit tests in
extract-jd-terms.test.ts.
Notes
The eligibility findings from #1175 are detected on the raw JD and are display-only, so this change doesn't affect them.
- Dominant language
- TypeScript
- Stars
- 11
- Forks
- 4
- PR merge metrics
- No merged PRs in 30d
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
-
fix(heuristics): unit number before a Saint-named city drops "St." from the locationPossibly taken @gaal-agent claimed this 14 days ago. Openbug gaal ux:parsing
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
-
Migrate Gaal implement/review/revise to the local gaal watch; keep mechanical workflows on ActionsOpenarchitecture chore github_actions needs-human ready-for-agent
Difficulty 5/5 Over a week Newbie friendliness 8/100
-
Parser: achievement year lost on re-import when '· YYYY' wrapped to its own linePossibly taken @gaal-agent claimed this 9 days ago. Openbug gaal ready-for-agent ux:parsing
Difficulty 3/5 1-2 days Newbie friendliness 25/100
-
Export: auto-bolded metric bullets extract one word per line in stream-order parsers (pypdf/Drive)Possibly taken @gaal-agent claimed this 9 days ago. Openbatch:export-standards bug gaal ready-for-agent ux:edit-export
Difficulty 3/5 1-2 days Newbie friendliness 25/100
-
Return legs from /download/ to /: Fix now lands on the missing field, and a bfcache miss keeps the résuméPossibly taken @s-annam claimed this 15 days ago. Openimprovement ready-for-agent ux:flow
All issues in offlinecv/OfflineCV
Similar issues
-
bug skills
Difficulty 2/5 1-3 hours Newbie friendliness 77/100
equinor/fusion-framework#5846 ·
Maintainers usually reply within 1 day
-
Difficulty 1/5 Under an hour Newbie friendliness 74/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
Eyevinn/open-videocore#1256 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
[Bug]: Theme preset geist points at undefined --font-geistPossibly taken @claude claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 73/100
Maintainers usually reply within 1 day