mirror of
https://github.com/MadsLorentzen/ai-job-search.git
synced 2026-09-17 00:26:26 +00:00
fix(cv-template): use ASCII hyphens and explicit ranges in CV date fields (#276)
* fix(cv-template): use ASCII hyphens and explicit ranges in CV date fields LaTeX ligatures `--` into an en-dash (U+2013), so a `\cventry` date written `2016--2024` reaches the PDF text layer as `2016<U+2013>2024`. Many ATS parsers split date ranges only on an ASCII hyphen and therefore extract no range at all. Separately, a bare single year gives the parser a start date with no end. Confirmed against a real Workday resume import: a CV built from this template lost the end date of a short contract role and imported no education entries whatsoever, forcing manual re-entry. The failure is silent - extraction was otherwise clean, with literal contact details, no (cid:) markers and correct reading order, so every existing check in the ATS Parseability section passed. - main_example.tex: date placeholders now use a single hyphen - 05-cv-templates.md: document both causes, with examples, and add the check to step 5d Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFNdaj4fB6Xrd29PQ6hc9B * chore(cv-template): bump framework_version to 1.4.0 The ATS date-format guidance added in the previous commit modifies a framework template, which the CI framework version guard requires to be accompanied by a version bump. Minor bump: new documented subsection, no breaking change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(changelog): record the CV date-field hyphen fix and fork reconciliation Documents the U+FFFD extraction failure under lualatex, the fix, and the framework_version bump. Includes the fork reconciliation note requested in review: the five changed lines in cv/main_example.tex are the \cventry date fields every fork personalizes, so rebasing forks should expect conflicts there, resolve in favour of their own dates, and reapply the -- to - change by hand. Adds a grep to locate remaining instances and a pdftotext check to verify. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: kgb <kevingblackman@gmail.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
kgb
parent
6392ca1628
commit
befaaf5eef
@@ -1,5 +1,5 @@
|
||||
---
|
||||
framework_version: 1.3.0
|
||||
framework_version: 1.4.0
|
||||
---
|
||||
|
||||
# CV Templates and Tailoring Guide
|
||||
@@ -244,6 +244,31 @@ What to check in the extraction:
|
||||
- **Reading order.** The stock banking style is single-column, so extraction order matches visual order. Custom templates (via `/add-template`) with sidebars or multi-column layouts can interleave unrelated lines; if extraction order is scrambled, the user is trading ATS compatibility for looks and should be told.
|
||||
- **Keyword coverage.** Match the posting's required/preferred terms against the extracted text, in the posting's language. Prefer the posting's exact term over a synonym when it is truthfully applicable - ATS matching is often literal. Never add a keyword the profile does not support.
|
||||
|
||||
### Date fields must be ASCII ranges (confirmed ATS import failure)
|
||||
|
||||
This one is worth knowing about because it fails **silently**. A CV that passes every other check in this section - clean extraction, no `(cid:)` markers, contact details intact, correct reading order - can still have its dates dropped on import. In a real Workday resume import, a CV built from this template lost the end date of a short contract role and failed to import **any** education entry at all, forcing manual re-entry. Nothing about the PDF or its text layer looked wrong.
|
||||
|
||||
Two independent causes, both easy to avoid:
|
||||
|
||||
1. **`--` in a `\cventry` date renders as an en-dash (U+2013), not a hyphen.** LaTeX ligatures `--` (two ASCII hyphens, U+002D) into a single en-dash glyph, so `2016--2024` reaches the PDF text layer as `2016<U+2013>2024`. Many parsers split date ranges only on an ASCII hyphen and see no range at all. Write the date argument with a **single hyphen**:
|
||||
|
||||
```latex
|
||||
\item{\cventry{2016-2024}{Role Title}{Organization}{Location}{}{...}} % parses
|
||||
\item{\cventry{2016--2024}{Role Title}{Organization}{Location}{}{...}} % en-dash, may not
|
||||
```
|
||||
|
||||
This applies to the **date argument only**. Keep `--` everywhere it is typographically correct in prose, for example a numeric range like `EUR 600k--1M`.
|
||||
|
||||
2. **A bare single year gives the parser no end date.** A short contract, mandate or internship written as `\cventry{2016}` imports as a start date with nothing to close it. Use an explicit range, with months where the role ran under a year:
|
||||
|
||||
```latex
|
||||
\item{\cventry{Mar 2016 - Jul 2016}{Contract Role}{Client}{Location}{}{...}}
|
||||
```
|
||||
|
||||
Where a genuine range exists, use it even when a single year would be factually accurate - a degree written `1995` is true but imports worse than `1992-1995`. Do not invent a start date you do not have; a lone graduation year is fine, just expect it to be typed in by hand.
|
||||
|
||||
**Add this to the step 5d checks**: after extracting the text layer, confirm every experience entry shows a start *and* an end separated by an ASCII hyphen. Because the failure is silent and invisible in the PDF, the candidate otherwise discovers it only while filling in the application form.
|
||||
|
||||
## Page Budget - Hard 2-Page Limit
|
||||
|
||||
The CV **must** fit on exactly 2 pages when compiled. Use these content limits as a guide:
|
||||
|
||||
@@ -29,6 +29,30 @@ per-file diff commands.
|
||||
`location` veto so a re-read of the file (or a future debugging session) can recover why a
|
||||
job did or didn't make the shortlist.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **CV date fields now use ASCII hyphens, so the PDF text layer extracts cleanly** - the
|
||||
stock template wrote date ranges as `[YYYY--YYYY]`, and on the repo's mandated `lualatex`
|
||||
toolchain the `--` en-dash ligature extracts from the PDF as U+FFFD (`�`). The stock
|
||||
template therefore failed the ATS checklist's own "no `�` replacement characters" item on
|
||||
*every* date field, and did so silently: the rendered page looks correct, and no existing
|
||||
check inspected the extracted text. `cv/main_example.tex` now uses `[YYYY-YYYY]` and
|
||||
`[YYYY-Present]`, and `05-cv-templates.md` documents the failure mode and the check that
|
||||
catches it (`framework_version` 1.3.0 to 1.4.0). The two-page layout budget is unaffected.
|
||||
|
||||
**Fork reconciliation note.** The five changed lines in `cv/main_example.tex` are the
|
||||
`\cventry` date fields - three under Professional Experience, two under Education -
|
||||
precisely the lines every fork personalizes. Rebasing forks should expect conflicts there,
|
||||
resolve them in favour of *their own* dates, and then apply the same `--` to `-` change by
|
||||
hand. To find remaining instances across your own CV variants:
|
||||
|
||||
```
|
||||
grep -rn '\\cventry{[^}]*--' cv/
|
||||
```
|
||||
|
||||
Verify afterwards with `pdftotext -layout <file>.pdf - | grep -c '�'`, which should
|
||||
return `0`.
|
||||
|
||||
### Security & privacy
|
||||
|
||||
- **The gitignore guard now covers every personal-output rule** - `security_guards.py`
|
||||
|
||||
+5
-5
@@ -77,7 +77,7 @@
|
||||
\begin{itemize}
|
||||
|
||||
% --- Most Recent Role ---
|
||||
\item{\cventry{[YYYY--Present]}{[Job Title]}{[Company]}{[City, Country]}{}{\vspace{1pt}
|
||||
\item{\cventry{[YYYY-Present]}{[Job Title]}{[Company]}{[City, Country]}{}{\vspace{1pt}
|
||||
\begin{itemize}
|
||||
\item [Achievement or responsibility 1 - be specific, use numbers where possible]
|
||||
\item [Achievement or responsibility 2]
|
||||
@@ -88,7 +88,7 @@
|
||||
\vspace{3pt}
|
||||
|
||||
% --- Previous Role ---
|
||||
\item{\cventry{[YYYY--YYYY]}{[Job Title]}{[Company]}{[City, Country]}{}{\vspace{1pt}
|
||||
\item{\cventry{[YYYY-YYYY]}{[Job Title]}{[Company]}{[City, Country]}{}{\vspace{1pt}
|
||||
\begin{itemize}
|
||||
\item [Achievement or responsibility 1]
|
||||
\item [Achievement or responsibility 2]
|
||||
@@ -98,7 +98,7 @@
|
||||
\vspace{3pt}
|
||||
|
||||
% --- Earlier Role ---
|
||||
\item{\cventry{[YYYY--YYYY]}{[Job Title]}{[Company]}{[City, Country]}{}{\vspace{1pt}
|
||||
\item{\cventry{[YYYY-YYYY]}{[Job Title]}{[Company]}{[City, Country]}{}{\vspace{1pt}
|
||||
\begin{itemize}
|
||||
\item [Achievement or responsibility 1]
|
||||
\item [Achievement or responsibility 2]
|
||||
@@ -114,13 +114,13 @@
|
||||
\vspace{1pt}
|
||||
\begin{itemize}
|
||||
|
||||
\item{\cventry{[YYYY--YYYY]}{[Degree] in [Field]}{[Institution]}{[City, Country]}{}{\vspace{1pt}
|
||||
\item{\cventry{[YYYY-YYYY]}{[Degree] in [Field]}{[Institution]}{[City, Country]}{}{\vspace{1pt}
|
||||
Thesis: ``[Thesis Title].'' [Brief description of research focus.]
|
||||
}}
|
||||
|
||||
\vspace{3pt}
|
||||
|
||||
\item{\cventry{[YYYY--YYYY]}{[Degree] in [Field]}{[Institution]}{[City, Country]}{}{\vspace{1pt}
|
||||
\item{\cventry{[YYYY-YYYY]}{[Degree] in [Field]}{[Institution]}{[City, Country]}{}{\vspace{1pt}
|
||||
[Brief description or key topics.]
|
||||
}}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user