mirror of
https://github.com/MadsLorentzen/ai-job-search.git
synced 2026-09-17 16:46:24 +00:00
Seven improvements sourced from blind regression probes comparing current outputs against real April-2026 baselines (each an area where the older outputs scored better): - every stated requirement addressed - matched or honestly gapped, never silently omitted (the benchmark run omitted a stated Kubernetes requirement entirely; omission reads as hiding under questioning) - nice-to-haves engaged by name with honest adjacency framing; posting's literal term preferred, including in CV section headings - stated logistics/prerequisites addressed in the letter (clearances, availability, job ID, multi-country language mapping) - domain-transfer argument leads the CV profile statement for domain-changers - evidence links (href) on every verifiable named artifact framework_version: 05 -> 1.2.0. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
274 lines
15 KiB
Markdown
274 lines
15 KiB
Markdown
---
|
|
framework_version: 1.2.0
|
|
---
|
|
|
|
# CV Templates and Tailoring Guide
|
|
|
|
<!-- SETUP: Profile statements and section ordering are personalized by running /setup -->
|
|
|
|
## Template: LaTeX moderncv (Banking Style)
|
|
|
|
All CVs use the moderncv LaTeX package with the "banking" style and "blue" color scheme.
|
|
|
|
**Output file:** `cv/main_<company>_<role>.tex`
|
|
**Compile with:** **lualatex** on MiKTeX/TeX Live. pdflatex often fails on modern MiKTeX installs with `fontawesome5` font-expansion errors; lualatex handles the same sources cleanly.
|
|
**Master reference:** `cv/main_example.tex` (comprehensive CV with all competencies, experience, and achievements - use as source when building targeted CVs)
|
|
|
|
### Compile command
|
|
|
|
```bash
|
|
cd cv && lualatex -interaction=nonstopmode main_<company>_<role>.tex
|
|
```
|
|
|
|
Expected output: `Output written on main_<company>_<role>.pdf (2 pages, ...)`. Any page count other than 2 is a failure that must be fixed before presenting to the user.
|
|
|
|
## Document Structure
|
|
|
|
```latex
|
|
\documentclass[11pt,a4paper,sans]{moderncv}
|
|
\moderncvstyle{banking}
|
|
\moderncvcolor{blue}
|
|
|
|
% Force both first and last name AND section headings to render in moderncv
|
|
% blue (color1). Default banking on lualatex+MiKTeX leaves these black, which
|
|
% looks inconsistent with the rest of the blue accent scheme.
|
|
\renewcommand*{\firstnamestyle}[1]{{\fontsize{34}{36}\bfseries\upshape\color{color1}#1}}
|
|
\renewcommand*{\lastnamestyle}[1]{{\fontsize{34}{36}\bfseries\upshape\color{color1}#1}}
|
|
\renewcommand*{\sectionstyle}[1]{{\sectionfont\color{color1}#1}}
|
|
|
|
\usepackage[utf8]{inputenc}
|
|
\usepackage{hyperref}
|
|
\hypersetup{
|
|
colorlinks=true,
|
|
linkcolor=blue,
|
|
filecolor=magenta,
|
|
urlcolor=blue,
|
|
pdftitle={[YOUR_NAME] - CV},
|
|
pdfpagemode=FullScreen,
|
|
}
|
|
\usepackage[scale=0.77]{geometry}
|
|
\usepackage{import}
|
|
|
|
% Personal data
|
|
\name{[FIRST_NAME]}{[LAST_NAME]}
|
|
\address{[YOUR_ADDRESS]}{}{}
|
|
\phone[mobile]{[YOUR_PHONE]}
|
|
\email{[YOUR_EMAIL]}
|
|
\extrainfo{\href{[YOUR_LINKEDIN_URL]}{LinkedIn}, \href{[YOUR_GITHUB_URL]}{GitHub}}
|
|
|
|
\begin{document}
|
|
\makecvtitle
|
|
|
|
% 1. Profile statement (1-3 sentences, tailored per role)
|
|
% 2. Skills section
|
|
% 3. Education section
|
|
% 4. Professional Experience section
|
|
% 5. Selected Publications (if applicable)
|
|
% 6. Honors and Awards (if applicable)
|
|
% 7. References
|
|
|
|
\end{document}
|
|
```
|
|
|
|
### Color overrides
|
|
|
|
The three `\renewcommand*` lines in the preamble are required on lualatex+MiKTeX. Without them the firstname, lastname, and section headings render in black even though `\moderncvcolor{blue}` is set, which looks inconsistent with the rest of the blue accent scheme (links, bullet markers, contact icons). The override forces all three to use `color1` (moderncv's accent colour, which becomes blue under `\moderncvcolor{blue}`). Both names render bold; if you prefer the firstname in regular weight, change the firstnamestyle override from `\bfseries` to `\mdseries`. Don't drop the override - on most modern installs the defaults render visibly wrong.
|
|
|
|
### Spacing inside itemize lists (important)
|
|
|
|
**Do not place `\vspace{...}` between `\item` entries in an `itemize` list.** Even though the source looks symmetric, this pattern occasionally produces a noticeably oversized gap before a single item: the inter-item `\vspace` creates a paragraph break that interacts unpredictably with the list's internal `\itemsep`, so LaTeX renders one of the gaps wider than the rest. Remove the inter-item `\vspace` and let `itemize` use its native uniform spacing.
|
|
|
|
```latex
|
|
% WRONG - intermittently produces an oversized gap before one bullet
|
|
\begin{itemize}
|
|
\item \textbf{Foo}: ...
|
|
\vspace{1pt}
|
|
\item \textbf{Bar}: ...
|
|
\vspace{1pt}
|
|
\item \textbf{Baz}: ...
|
|
\end{itemize}
|
|
|
|
% RIGHT - uniform spacing using the list's native itemsep
|
|
\begin{itemize}
|
|
\item \textbf{Foo}: ...
|
|
\item \textbf{Bar}: ...
|
|
\item \textbf{Baz}: ...
|
|
\end{itemize}
|
|
```
|
|
|
|
Two related patterns are fine and should be kept:
|
|
- `\vspace{1pt}` immediately after `\section{...}` (between section heading and first item) - this is between the heading and the list, not between list items.
|
|
- `\vspace{3pt}` between top-level `\cventry` blocks in Professional Experience or Education - this gives breathing room between roles and renders consistently.
|
|
|
|
## Section-by-Section Tailoring
|
|
|
|
### Profile Statement / Elevator Pitch (Best Practice)
|
|
This is the most important section to customize. It appears right after `\makecvtitle`.
|
|
|
|
Write 5-7 lines that function as an "elevator pitch": a concise, compelling introduction explaining why you're qualified for *this specific role*. Focus on what the employer gains from hiring you.
|
|
|
|
When the role sits outside your home domain, **lead with the domain-transfer argument** - the one or two sentences connecting your background to their problem (e.g. wave physics to radar signal processing) belong in the profile statement's opening, not buried in the cover letter. It is the strongest card a domain-changer holds; play it first.
|
|
|
|
**Create 2-3 profile statement templates for your main role types:**
|
|
|
|
<!-- SETUP: These are populated based on your background -->
|
|
**For [YOUR_PRIMARY_ROLE_TYPE] roles:**
|
|
> [YOUR_PROFILE_STATEMENT_TEMPLATE_1]
|
|
|
|
**For [YOUR_SECONDARY_ROLE_TYPE] roles:**
|
|
> [YOUR_PROFILE_STATEMENT_TEMPLATE_2]
|
|
|
|
Statements labeled *[Used for: <company>_<role>]* were extracted from archived application drafts by `/setup` Path A. They are **phrasing references, never fact sources**: when drafting from one, every factual claim still comes from `01-candidate-profile.md` - a past tailored draft does not vouch for its own accuracy.
|
|
|
|
### Core Competencies / Skills Section (Best Practice)
|
|
Reorder and emphasize based on the role. Use bold category labels.
|
|
|
|
List **5-7 key competencies** in bullet format, tailored to the specific job. For each competency, briefly explain how it adds value to the position.
|
|
|
|
Use the posting's own core term in the matching bullet's bold label when it truthfully applies - ATS and skim-reading hiring managers match literally, and "MLOps" in a heading outperforms a paraphrase like "ML Deployment".
|
|
|
|
### Education
|
|
- Always include your highest degrees
|
|
- For senior roles, keep education brief (dates and titles only)
|
|
- Include thesis topics when relevant to the target role
|
|
|
|
### Professional Experience
|
|
- Rewrite bullet points to emphasize aspects most relevant to the target role
|
|
- Use 4-6 bullets for most recent role, 3-4 for previous, 2-3 for older
|
|
- **Emphasize measurable results** where possible: "Reduced processing time by X%", "Model adopted by the team"
|
|
|
|
### Handling Employment Gaps (Best Practice)
|
|
If there is a gap in your employment history:
|
|
- The gap should be explained matter-of-factly if needed
|
|
- Describe how professional development continued during the gap
|
|
- Frame as deliberate skill-building and career repositioning
|
|
|
|
### Publications
|
|
- Include Google Scholar link if applicable
|
|
- Select 3-4 most relevant publications (not always all of them)
|
|
- For non-academic roles, keep brief
|
|
|
|
### Evidence Links
|
|
Wherever the CV names a verifiable artifact - a public project, a hackathon entry, a publication - carry its link (`\href`) so a reader can verify the claim in one click. A CV whose strongest claims are checkable reads as more credible everywhere else too.
|
|
|
|
### Honors and Awards
|
|
- Keep format brief, one line each
|
|
|
|
### References
|
|
- List 2-4 references with name, title, company, and contact
|
|
- End with: "More references are available upon request."
|
|
- **Do not attach reference letters** - employers typically contact references directly
|
|
|
|
## Compile-and-Inspect Loop (MANDATORY)
|
|
|
|
After writing the CV and before presenting to the user, always compile and visually inspect the PDF. Iterate until the layout is clean. Workflow:
|
|
|
|
1. Run `lualatex -interaction=nonstopmode main_<company>_<role>.tex`
|
|
2. Check the output page count: must be exactly 2
|
|
3. Read the PDF via the Read tool and visually inspect both pages
|
|
4. Check for **orphaned entries**: a `\cventry` title line must never sit alone at the bottom of page 1 with its bullets on page 2
|
|
|
|
### Fixing common page-break problems
|
|
|
|
**Problem: entry title on page 1, bullets orphaned to page 2**
|
|
Add `\needspace{5\baselineskip}` immediately before the problematic `\cventry`:
|
|
```latex
|
|
\needspace{5\baselineskip}
|
|
\item{\cventry{YEAR--YEAR}{Role Title}{Organization}{Location}{}{...}}
|
|
```
|
|
Include `\usepackage{needspace}` in the preamble.
|
|
|
|
**Caveat - use `\needspace` before entries, never before `\section` headings.** A section-level `\needspace` pushes the entire section (heading plus content) to the next page whenever the request does not fit, stranding empty space above and typically *adding* a page instead of saving one. Apply it only to the individual `\cventry` that actually orphans, and only after a compile shows the orphan.
|
|
|
|
**Problem: one trailing section spills to page 3 (e.g., References alone on page 3)**
|
|
Add `\enlargethispage{2-3\baselineskip}` before a late section (e.g., before `\section{Honors and Awards}`) to stretch page 2 by a few lines. This is the standard LaTeX rescue for near-miss overflows.
|
|
|
|
**Problem: 3 pages with significant content on page 3**
|
|
Cut content — do not compress geometry or `\vspace`. See "Relevance-weighted cutting" below for the rule.
|
|
|
|
**Problem: content finishes early on page 2 (feels thin)**
|
|
Restore the highest-relevance item that was previously cut — a CV that ends mid-page 2 looks incomplete.
|
|
|
|
## ATS Parseability
|
|
|
|
Most employers run CVs through an ATS before a human sees them, and the ATS reads the PDF's embedded **text layer**, not the rendered page. A CV can pass visual inspection and still extract as garbage. After the layout passes the compile-and-inspect loop, verify the text layer:
|
|
|
|
```bash
|
|
cd cv && pdftotext -layout main_<company>_<role>.pdf main_<company>_<role>.txt
|
|
```
|
|
|
|
`pdftotext` comes from [poppler](https://poppler.freedesktop.org/), not the TeX distribution - it is an **optional** dependency. If it is not installed, skip the mechanical check with a warning and rely on the visual PDF read for keyword coverage.
|
|
|
|
What to check in the extraction:
|
|
|
|
- **Contact details as literal text.** The stock template's fontawesome contact icons extract as glyph names (`MOBILE-ALT`, `Envelope`) - harmless noise, because the actual address and number are printed beside them. The failure mode is a contact detail carried *only* by an icon or a hyperlink (like the `LinkedIn` link text, whose URL is not in the text layer): invisible to an ATS. The email address must always appear as printed text.
|
|
- **No garbled output.** `(cid:NNN)` markers or `�` characters mean a font is embedded without a Unicode mapping - an ATS sees the same garbage. This shows up with unusual fonts in custom templates, not with the stock moderncv setup under lualatex.
|
|
- **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.
|
|
|
|
## Page Budget - Hard 2-Page Limit
|
|
|
|
The CV **must** fit on exactly 2 pages when compiled. Use these content limits as a guide:
|
|
|
|
| Section | Max budget |
|
|
|---------|-----------|
|
|
| Profile statement | 3-4 lines |
|
|
| Skills | 5 items, each 1-2 lines |
|
|
| Most recent role | 4-5 bullets |
|
|
| Previous role | 2-3 bullets |
|
|
| Older roles | 2 bullets (1 line each) |
|
|
| Education | 2-3 entries |
|
|
| Publications | 2-3 entries |
|
|
| Awards | 3 entries, single line each |
|
|
| References | "Available upon request." (single line) |
|
|
|
|
**If in doubt, cut rather than squeeze.** Reducing `\vspace` or geometry scale to force-fit content makes the CV look cramped.
|
|
|
|
## Relevance-weighted cutting (the right way to shrink a CV)
|
|
|
|
**Cut by signal, not by section.** Static priority lists ("remove oldest education first, then shorten the earliest role...") are wrong when a relevant "lower-priority" item is competing with an irrelevant "higher-priority" item. An older-role bullet that speaks directly to the posting is worth more than a recent-role bullet that does not.
|
|
|
|
For every candidate line, score three things:
|
|
|
|
1. **Relevance to THIS posting** — does the line hit a named tool, keyword, or stated responsibility in the job ad?
|
|
2. **Uniqueness** — is it the only place this claim appears, or is it duplicated elsewhere in the CV?
|
|
3. **Narrative load** — does the cover letter depend on it? If cutting the line would force you to rewrite a cover-letter paragraph, it is load-bearing.
|
|
|
|
Cut the lowest-total-score line first, regardless of which section it sits in.
|
|
|
|
### Practical order of cuts (easiest → last resort)
|
|
|
|
1. **Redundancy.** If an achievement appears in both Core Competencies AND a role bullet, the Core Competencies version is usually the cleaner cut (the experience bullet is more concrete evidence).
|
|
2. **Profile-statement fluff.** A sentence that just restates what Publications or Skills will show. ("Peer-reviewed publications on X..." is already a Publications entry — profile can claim it once and stop.)
|
|
3. **Low-relevance experience bullets.** A bullet about work that does not touch posting keywords, wherever it sits. This cuts across sections before touching the structural list.
|
|
4. **Low-relevance supporting content.** An older-role bullet that does not speak to the target role. A certification that does not touch the posting's stack. A language entry that can be condensed to one line.
|
|
5. **Low-relevance publications.** Keep 1-2 publications that best match the posting. Cut the rest before touching experience bullets.
|
|
6. **Last-resort structural cuts.** Oldest education entry, tightening an older role to 2 bullets, collapsing Certifications into a single line. These only happen if the relevance-weighted cuts above have already been exhausted.
|
|
|
|
### Pitfalls to avoid
|
|
|
|
- Do not mechanically cut from the bottom of a static section list without checking relevance. "Cut the oldest role first" is wrong if that role is literally about the skill the posting asks for.
|
|
- Do not cut the one concrete example the cover letter leans on. Relevance is measured against the cover letter you wrote, not just the job posting — interviewers will have read both.
|
|
- Do not cut to fit if the fit is borderline (2.02 pages). Prefer `\enlargethispage{2-3\baselineskip}` on a late section for near-misses; reserve content cuts for genuine overflow (content on page 3 that is more than a single trailing section).
|
|
|
|
## Recommended Section Order
|
|
|
|
The section order varies by role type:
|
|
|
|
**For technical / data science / ML roles:**
|
|
1. Profile statement / elevator pitch
|
|
2. Core competencies / Skills
|
|
3. Professional Experience (reverse chronological)
|
|
4. Education (reverse chronological)
|
|
5. Languages
|
|
6. Publications & Awards
|
|
7. References
|
|
|
|
**For domain-specific / specialist roles:**
|
|
1. Profile statement / elevator pitch
|
|
2. Core competencies / Skills
|
|
3. Education (reverse chronological) - credentials are a key qualifier
|
|
4. Professional Experience (reverse chronological)
|
|
5. Publications & Awards
|
|
6. References
|