Follow-up to #492, split out so the residue that PR #842 does not cover is recorded before #492 closes on merge.
What still breaks
recoverHeaderlessExperience (src/lib/heuristics/sections.ts) returns early on !singleColumn. So a two-column résumé whose work history carries no recognized experience heading is still dropped whole — exactly the #492 symptom, on the layout the recovery deliberately excludes.
The single-column case is fixed by #842 and is not in scope here.
Why it is invisible
#492's AC 5 asked that /probe-experience report a defect (not ok) on a headerless-experience résumé. #842 satisfies that AC by dissolving it for single-column — the fixture now routes an experience section, so ok is the correct verdict. It does not satisfy it for two-column:
localizeExperience scopes its date-range oracle to the already-routed experience region (src/lib/heuristics/localize/experience.ts:92). With no experience section routed, there is no region, so the oracle never sees the dated role cluster sitting in other.
EXPERIENCE_DEFECT_CLASSES has only experience-parser-miss and experience-under-segmented. Neither describes "no experience region exists at all".
Net: the probe reports Verify: ok with zero roles parsed, silently. That is worse than the parse miss itself — the lane whose job is to flag the miss reports clean.
Acceptance criteria
- A new
experience-no-section defect class in EXPERIENCE_DEFECT_CLASSES.
- The oracle runs document-wide (not region-scoped) when no
experience section was routed, so a dated title-cased cluster anywhere in the document raises the defect.
/probe-experience reports experience-no-section — not ok — on a two-column headerless-experience fixture.
- A fixture pinning the two-column headerless shape, with a synthetic persona per the
tests/fixtures/pdfs/README.md policy.
- Recovery itself stays out of scope: this issue makes the drop visible, it does not make it parse. Widening
recoverHeaderlessExperience past singleColumn is a separate decision — the two-column reader has to distinguish a headerless work-history rail from a sidebar, which the single-column recovery never has to.
Notes
Follow-up to #492, split out so the residue that PR #842 does not cover is recorded before #492 closes on merge.
What still breaks
recoverHeaderlessExperience(src/lib/heuristics/sections.ts) returns early on!singleColumn. So a two-column résumé whose work history carries no recognized experience heading is still dropped whole — exactly the #492 symptom, on the layout the recovery deliberately excludes.The single-column case is fixed by #842 and is not in scope here.
Why it is invisible
#492's AC 5 asked that
/probe-experiencereport a defect (notok) on a headerless-experience résumé. #842 satisfies that AC by dissolving it for single-column — the fixture now routes an experience section, sookis the correct verdict. It does not satisfy it for two-column:localizeExperiencescopes its date-range oracle to the already-routed experience region (src/lib/heuristics/localize/experience.ts:92). With no experience section routed, there is no region, so the oracle never sees the dated role cluster sitting inother.EXPERIENCE_DEFECT_CLASSEShas onlyexperience-parser-missandexperience-under-segmented. Neither describes "no experience region exists at all".Net: the probe reports
Verify: okwith zero roles parsed, silently. That is worse than the parse miss itself — the lane whose job is to flag the miss reports clean.Acceptance criteria
experience-no-sectiondefect class inEXPERIENCE_DEFECT_CLASSES.experiencesection was routed, so a dated title-cased cluster anywhere in the document raises the defect./probe-experiencereportsexperience-no-section— notok— on a two-column headerless-experience fixture.tests/fixtures/pdfs/README.mdpolicy.recoverHeaderlessExperiencepastsingleColumnis a separate decision — the two-column reader has to distinguish a headerless work-history rail from a sidebar, which the single-column recovery never has to.Notes