Skip to content

fix: parse prose bodies, redacted dates, role-comma split (#158) - #159

Merged
s-annam merged 2 commits into
mainfrom
gh-158
Jun 24, 2026
Merged

fix: parse prose bodies, redacted dates, role-comma split (#158)#159
s-annam merged 2 commits into
mainfrom
gh-158

Conversation

@s-annam

@s-annam s-annam commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes the three defects the chanchal-sharma-sample.pdf referred-resume fixture (a Word/Office template with redacted 20XX placeholder years and glyph-less prose descriptions) surfaced, plus the score-readout render collapse:

  • RenderAtsScoreReadout score row no longer collapses when the completeness hint is long; the 3 dimension cards keep full width.
  • Parser — redacted yearsDATE_ANCHOR/MONTH_YEAR_ANCHOR admit 20XX (and XXXX/#### only when month-anchored), so March 20XX – December 20XX parses as a date range. All 3 roles now parse with correct title/company/dates.
  • Parser — prose bodies — bullet-less prose descriptions are captured as the role body (R1 hybrid y-gap split on the PDF path, isProseLine fallback for flat-y DOCX/markdown), and a wrapped paragraph folds into one body unit.
  • Parser — R2 — guarded "Role, Company" single-line headers split into title + company (guarded against Acme, Inc and location tails), making all three roles map consistently.
  • Scoring — pool per-role descriptions as a fallback bullet source when the accomplishment sections yield no marker bullets (glyph-less templates), mirroring the authed scorer. Specificity/Structure now grade the prose and the bullets render per role. chanchal-sample goes 1→3 roles, overall 24→79.
  • cascade.ts counts the experience team field in countExtractedChars so the better field mapping doesn't trip the low-extraction-ratio hard-fail.

5 corpus snapshots re-baked — all improvements or negligible drift (chanchal-sample/-bulleted-skills 0→0.9; single-word-name-mononym 0→0.86; weasyprint-two-column 0→0.64; awesome-cv 0.9→0.89).

Closes #158

Test plan

  • npm run typecheck clean
  • npm run test green (718 pass)
  • npm run lint clean
  • Manually verified in npm run dev on the target fixture (3 roles, descriptions render as bullets, score breakdown no longer collapses)

- AtsScoreReadout: add md:min-w-0/md:flex-1 + min-w-0 so score row
  no longer collapses when the completeness hint is long; all 3
  dimension cards keep full width
- regex.ts: DATE_ANCHOR/MONTH_YEAR_ANCHOR admit redacted placeholder
  years (20XX, and XXXX/#### only when month-anchored) so roles like
  "March 20XX – December 20XX" parse correctly as date ranges
- line-primitives.ts isProseLine + entry-blocks.ts: role descriptions
  written as bullet-less prose paragraphs are now captured as the role
  body, not absorbed into the header
- entry-blocks.ts R1 hybrid y-gap body signal: on the PDF path a
  paragraph-sized vertical gap (>1.4× section line-height) drives the
  header-vs-body split; DOCX/markdown (flat y) fall back to isProseLine.
  Same gap folds a wrapped prose paragraph into one body unit so a blurb
  stays one bullet instead of splitting mid-sentence
- score.ts: pool per-role descriptions as a fallback bullet source when
  the accomplishment sections yield no marker bullets (glyph-less Word/
  Office prose templates), mirroring the authed scorer's splitBullets so
  Specificity/Structure grade the prose and the bullets render per role
- extract/experience.ts R2 guarded "Role, Company" comma split: single-
  line headers like "Office manager, The Phone Company" split into title
  + company, guarded against legal suffixes ("Acme, Inc") and location
  tails
- cascade.ts: count the experience `team` field in countExtractedChars
  so better field mapping doesn't under-measure extraction and trip the
  low-extraction-ratio hard-fail
- Re-baked 5 corpus snapshots (all improvements or negligible drift):
  chanchal-sample conf 0→0.9 (exp 1→3, score 24→79 once prose grades as
  bullets); chanchal-bulleted-skills 0→0.9 (exp 2→3);
  single-word-name-mononym 0→0.86; weasyprint-two-column 0→0.64;
  awesome-cv 0.9→0.89

Resolves #158

@rohithgollapalli rohithgollapalli left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review

Solid parser PR — the entry-block rewrite, the top-origin y-gap math (sectionLineHeight/startsBodyByGap), and the redacted-year regex all check out. One real regression and one minor note.

1. src/lib/heuristics/extract/experience.ts:97-99splitRoleComma misattributes a city as the company for "Title, Location" headers (regression)

The guard only checks that the part before the comma looksLikeTitle and the part after isn't a bare legal suffix. It has no guard against a location tail when a title keyword is present before the comma — the documented location-tail defense ("no title keyword before the comma") only covers the "Company … City, ST" shape, not "Title, City".

Trace for Marketing Manager, San Francisco (a common header form):

  • before="Marketing Manager" (looksLikeTitle ✓), after="San Francisco" (not a legal suffix) → splits.
  • Downstream neither part looksLikeCompany, so the else-branch hits firstLooksTitle && !secondLooksTitlecompany = "San Francisco".

Before this PR the line stayed unsplit and company was left undefined — so the change actively introduces a wrong company field (a city). No corpus fixture exercises "Title, City", which is why tests stay green; it's a latent regression. Consider requiring looksLikeCompany(after) (or rejecting a known location shape) before splitting.

Minor — src/lib/score/score.ts:673-680

poolExperienceDescriptions only pools experience[].description, but the comment says it "mirrors the authed scorer," which also pools project (#95) and achievement (#96) descriptions. A glyph-less template whose prose lives only in a projects/achievements section (and whose accomplishment-section pool comes back empty) still grades 0. Low impact — worth a one-line note in the comment if intentional.

🤖 Generated with Claude Code

Address PR #159 review (rohithgollapalli):

- splitRoleComma no longer cleaves a location tail off as the company.
  "Marketing Manager, San Francisco" (bare city), "Product Designer,
  Austin, TX" (City, ST), and intl "City, Country" tails are now vetoed
  via looksLikeLocationTail, while real "Role, Company" headers with no
  legal suffix (Nod Publishing, Southridge Video) still split. Closes the
  latent regression where a city was recorded as the employer.
- poolExperienceDescriptions: document that it pools experience
  descriptions only, not project (#95) / achievement (#96) ones.
- Add experience.role-comma.test.ts regression coverage.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018GAj62FwHV2WHunBTGCR9P
@s-annam

s-annam commented Jun 24, 2026

Copy link
Copy Markdown
Contributor Author

Both findings addressed in 8107a8f:

  1. splitRoleComma "Title, Location" regression — added a looksLikeLocationTail veto (bare-city set + US_LOCATION_RE/INTL_LOCATION_RE) so "Marketing Manager, San Francisco" and "Product Designer, Austin, TX" no longer split a city into company, while real suffix-less "Role, Company" headers (Nod Publishing, Southridge Video) still split. New experience.role-comma.test.ts covers both directions.
  2. Pool-scope comment — documented that poolExperienceDescriptions pools experience descriptions only, not project (Projects dropped as a section — not extracted, bullets leak to "Other" #95) / achievement (Achievements section dropped — demoted to "other" sink, never extracted #96) ones.

Typecheck clean, 721/721 green.

@s-annam
s-annam merged commit efa1e61 into main Jun 24, 2026
2 checks passed
@s-annam
s-annam deleted the gh-158 branch June 24, 2026 17:18
s-annam added a commit that referenced this pull request Jun 25, 2026
Fixes redacted 20XX dates, prose-body capture, guarded Role,Company / Title,Location split, and prose-pool scoring for glyph-less Word templates; fixes score-readout render collapse. Resolves #158.
s-annam added a commit that referenced this pull request Jun 28, 2026
Fixes redacted 20XX dates, prose-body capture, guarded Role,Company / Title,Location split, and prose-pool scoring for glyph-less Word templates; fixes score-readout render collapse. Resolves #158.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

chanchal-sharma fixture: score-breakdown collapse + redacted-year roles dropped + glyph-less descriptions

2 participants