Skip to content

feat: column-gated sidebar-header recovery for two-column flattens - #118

Merged
s-annam merged 1 commit into
mainfrom
gh-117
Jun 18, 2026
Merged

feat: column-gated sidebar-header recovery for two-column flattens#118
s-annam merged 1 commit into
mainfrom
gh-117

Conversation

@s-annam

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

Copy link
Copy Markdown
Contributor

Summary

A two-column résumé flatten can glue a sidebar bar-value onto a real section header (e.g. 20% Projects), producing a body-size line that the text-only matchSectionHeader path correctly rejects as prose. After #115 tightened Guard 7 (uppercase-lead), the accidental match was lost and chromium-two-column-sidebar dropped projectsCount 2 → 0.

This recovers the section properly without reopening the prose FP class #115 closed. The gate is column membership, not font: the per-page columnBoundaries map is threaded into splitIntoSections, and a new branch in classifyLine recovers the section name only when the line is body-size, header-shaped, and sits in the secondary column (line.x >= columnSplitX) of a detected two-column layout. Main-column prose (5 Years Experience, 20% Experience) and single-column docs never trigger it; the text-only path is unchanged.

Closes #117

Test plan

  • npm run typecheck clean
  • npm run test green (446 passed / 35 files)
  • Snapshot rebaked: chromium-two-column-sidebar.expected.json projectsCount 0 → 2 + projects added to fieldsPopulated; score block unchanged; no other fixture moved
  • AC pins: matchSectionHeader("20% Experience" / "5 Years Experience" / "10+ Years Experience") still return null
  • Column-gated unit coverage: (a) recover in secondary column, (b) main-column negative, (c) single-column negative

A two-column flatten can glue a sidebar bar-value onto a real section
header — e.g. "20% Projects" — producing a body-size line that the
text-only matchSectionHeader path (and after #115, Guard 7) correctly
rejects as prose. The fix restores the lost projectsCount (2→0 on the
chromium-two-column-sidebar fixture) without reopening the FP class
that #115 closed.

Changes:
- Add `matchSectionAnchorToken` in regex.ts: the unguarded trailing-
  anchor cousin of `matchAnchorFallback`. Normalizes, splits, returns
  the section whose anchor set contains the LAST token (anchorFallback-
  enabled only). No prose guards — the caller's column signal replaces
  them.
- Extract `isHeaderShort` from `isVisualHeader` in sections.ts so the
  column-gated branch and the L3 visual path share one predicate.
- Thread `columnBoundaries` (the per-page split-x map already produced
  by detectColumnBoundaries) into `splitIntoSections` and `classifyLine`.
  A new branch in `classifyLine` fires only when: (a) columnSplitX is
  defined, (b) line.x >= columnSplitX (secondary column), and (c) the
  line is header-short. Within that gate, `matchSectionAnchorToken` can
  recover the section name without prose guards.
- Pass `boundaries` through the `parseHeuristic` → `splitIntoSections`
  call in openresume.ts.
- Add tests: matchSectionAnchorToken unit suite (regex.test.ts) + three
  sections.test.ts cases pinning the (a) recover / (b) main-column /
  (c) single-column gate.
- Rebake chromium-two-column-sidebar.expected.json: projectsCount 0→2,
  `projects` added to fieldsPopulated; score block unchanged.

Resolves #117
@s-annam
s-annam requested review from rohithgollapalli and removed request for rohithgollapalli June 18, 2026 03:02
@s-annam

s-annam commented Jun 18, 2026

Copy link
Copy Markdown
Contributor Author

Merging via admin bypass (no second reviewer available). This is a narrow follow-up fix to #115 / the section-recognition epic (#109): PR #115 correctly tightened Guard 7 to reject numeric-lead prose, which as a side effect dropped the accidental recovery of sidebar-glued headers like 20% Projects (projectsCount 2→0 on the chromium-two-column-sidebar fixture). This restores that capability properly — column-gated recovery in the secondary column only, text-only matchSectionHeader untouched so every prose false-positive pin (5/10+/20% Experience → null) stays green. CI verify + fallow are green (full suite 446 pass); no open review threads.

@s-annam
s-annam merged commit 0c84317 into main Jun 18, 2026
2 checks passed
@s-annam
s-annam deleted the gh-117 branch June 18, 2026 03:04
s-annam added a commit that referenced this pull request Jun 25, 2026
)

Recover section headers glued to a sidebar bar-value in two-column flattens (e.g. `20% Projects`), regressed by #115's Guard 7 tightening. Gated on secondary-column membership; text-only matchSectionHeader path untouched so prose FP pins stay null.

Resolves #117
s-annam added a commit that referenced this pull request Jun 28, 2026
)

Recover section headers glued to a sidebar bar-value in two-column flattens (e.g. `20% Projects`), regressed by #115's Guard 7 tightening. Gated on secondary-column membership; text-only matchSectionHeader path untouched so prose FP pins stay null.

Resolves #117
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.

Two-column flattened section headers with sidebar-noise prefixes go undetected (e.g. 20% Projects)

1 participant