# How the AI Job Search Framework Ensures CV and Cover Letter Formatting Requirements

> Discover how the AI Job Search Framework guarantees perfect CV and cover letter formatting. Learn about template-centric Markdown, LaTeX compilation, PDF verification, and content budgets.

- Repository: [Mads Lorentzen/ai-job-search](https://github.com/MadsLorentzen/ai-job-search)
- Tags: how-to-guide
- Published: 2026-09-03

---

**The framework enforces strict document standards through template-centric Markdown specifications, deterministic LaTeX compile-and-inspect loops, automated PDF text-layer verification, and rule-driven content budgets that validate every CV and cover letter before delivery.**

The MadsLorentzen/ai-job-search repository implements a rigorous validation architecture for job application materials that guarantees compliance with precise typographic, structural, and ATS-readability standards. By encoding all formatting constraints in version-controlled template guides and automating verification through every stage of the `/apply` workflow, the AI Job Search Framework eliminates formatting errors, page-count violations, and character-encoding issues before documents reach hiring managers.

## Template-Centric Specification as the Single Source of Truth

All formatting requirements live in two canonical Markdown files that serve as the definitive reference for the entire system.

### CV Template Architecture

The CV template guide at [`.claude/skills/job-application-assistant/05-cv-templates.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/skills/job-application-assistant/05-cv-templates.md) defines the **modern-cv LaTeX template** specifications, including required packages, compile commands, and section ordering. It mandates **LuaLaTeX** as the compilation engine and enforces a strict **two-page budget** with specific rules for page-break handling. The guide specifies `\needspace{5\baselineskip}` placement before each `\cventry` block to prevent orphaned headings, and documents rescue strategies using `\enlargethispage` for trailing sections that risk spilling onto a third page.

### Cover Letter Template Standards

The cover letter specifications in [`.claude/skills/job-application-assistant/06-cover-letter-templates.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/skills/job-application-assistant/06-cover-letter-templates.md) describe the custom `cover.cls` class stored in `cover_letters/cover.cls`. This guide mandates **XeLaTeX** compilation, enforces a **one-page budget**, and specifies exact bullet-list placement rules outside the `\lettercontent{}` environment. It contains exhaustive tables mapping special characters to LaTeX escape sequences (`&` → `\&`, `%` → `\%`) and requires section heading translations when the document language differs from English.

## Compile-and-Inspect Loops for Deterministic Output

After generating target-specific `.tex` files, the framework executes deterministic compilation commands and inspects the resulting PDFs for structural violations.

### Engine-Specific Compilation

The `/apply` command runs engine-specific compilation based on document type:

```bash

# CV compilation (LuaLaTeX)

cd cv && lualatex -interaction=nonstopmode main_<company>_<role>.tex

# Cover letter compilation (XeLaTeX)

cd cover_letters && xelatex -interaction=nonstopmode cover_<company>_<role>.tex

```

Any compilation failure aborts the workflow immediately, preventing the generation of malformed PDFs.

### Page Budget Enforcement and Orphan Prevention

The framework validates **exact page counts**: CVs must be exactly two pages, and cover letters must be exactly one page. The validation logic counts pages in the compiled PDF and halts the `/apply` step if the count deviates from the specification. To prevent typographic orphans, the CV template enforces vertical spacing guards:

```latex
\needspace{5\baselineskip}
\item{\cventry{2022-2024}{Data Scientist}{Acme Corp}{Copenhagen}{}{%
    Developed a recommendation engine that increased sales by 12\%.\vspace{1pt}
}}

```

This ensures that job titles and their associated bullet points remain on the same page.

## Automated PDF Validation with verify_pdf.py

The [`tools/verify_pdf.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/tools/verify_pdf.py) script performs deep inspection of the generated PDF's text layer to ensure ATS compatibility and content integrity.

### Text Layer Extraction and ATS Readability Checks

The verification tool extracts the hidden text layer using **pypdf**, falling back to **poppler-utils** if necessary. It validates the presence of contact details as literal text (icons alone are insufficient), detects garbled characters (flagging `(cid:…)` or replacement glyphs), and verifies correct reading order to ensure single-column CVs preserve visual hierarchy. The framework invokes this tool automatically during the `/apply` phase:

```python
import subprocess
from pathlib import Path

def verify_cv(pdf_path: Path):
    """Run the built-in verifier; raises on any formatting problem."""
    cmd = [
        "python", "tools/verify_pdf.py",
        str(pdf_path),
        "--dump-text", str(pdf_path.with_suffix(".txt"))
    ]
    subprocess.run(cmd, check=True)

# Usage in the apply workflow

verify_cv(Path("cv/main_acme_engineer.pdf"))

```

### Keyword Coverage Verification

Beyond formatting, [`verify_pdf.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/verify_pdf.py) extracts the text content and validates keyword coverage against the target job posting, ensuring that the document content aligns with the role requirements before final delivery.

## Content Budget and Character Escaping Safeguards

The framework enforces strict quantitative limits on content length and automatic sanitization of special characters.

### Section-Level Line and Item Limits

Both template guides specify maximum budgets for each section. The CV template limits the **Profile statement to 3-4 lines**, **Skills to 5 items**, and individual bullet points to concise descriptions. The cover letter guide constrains the body to **250-300 words**. Helper functions count lines, bullets, and words during the `/setup` and `/apply` phases, trimming low-relevance items according to the relevance-weighted cutting strategy documented in the guides.

### Automatic LaTeX Character Escaping

Before compilation, the `/apply` engine performs a pre-compile scan to automatically escape prohibited characters. This prevents silent LaTeX comment loss (where `%` comments out subsequent text) or compilation failures from unescaped ampersands. The framework references the escape tables in the template guides to ensure consistency.

## Extending Validation to Custom Templates

When users register custom templates via the `/add-template` command, the framework extracts the compile engine, page limits, and required packages from the new template. It then wires these specifications into the same compile-and-inspect loop and PDF verification pipeline used for default templates. This ensures that **any** user-supplied template inherits the rigorous checks for page count, ATS readability, and character encoding.

## Summary

- **Template guides** at [`05-cv-templates.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/05-cv-templates.md) and [`06-cover-letter-templates.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/06-cover-letter-templates.md) serve as the single source of truth for all formatting requirements.
- **Deterministic compilation** uses LuaLaTeX for CVs and XeLaTeX for cover letters, with strict enforcement of two-page and one-page budgets respectively.
- **Orphan prevention** relies on `\needspace{5\baselineskip}` commands to keep section headings with their content.
- **[`verify_pdf.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/verify_pdf.py)** automates PDF text-layer extraction to validate ATS readability, contact detail presence, and keyword coverage.
- **Content budgets** enforce maximum line counts (3-4 lines for Profile), item limits (5 for Skills), and word counts (250-300 for cover letters).
- **Automatic escaping** sanitizes special LaTeX characters before compilation to prevent syntax errors.
- **Custom template registration** extends all validation rules to user-provided templates through the `/add-template` workflow.

## Frequently Asked Questions

### What LaTeX engines does the AI Job Search Framework use for document compilation?

The framework uses **LuaLaTeX** for CV compilation and **XeLaTeX** for cover letters, as specified in [`05-cv-templates.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/05-cv-templates.md) and [`06-cover-letter-templates.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/06-cover-letter-templates.md) respectively. These engines are chosen for their modern font handling and Unicode support, which are essential for the `modern-cv` template and custom `cover.cls` class. The `/apply` command runs these engines with `-interaction=nonstopmode` to ensure that compilation errors halt the workflow immediately.

### How does the framework prevent orphan lines in CV entries?

The framework enforces the use of `\needspace{5\baselineskip}` before each `\cventry` block, as documented in the CV template guide. This LaTeX command reserves five lines of vertical space before starting a new entry, ensuring that job titles and their associated descriptions remain on the same page. If trailing sections risk spilling onto an extra page, the guide recommends using `\enlargethispage` to compress content slightly and maintain the strict two-page budget.

### Can the framework validate custom user-provided templates?

Yes. Through the `/add-template` registration command, the framework extracts the compile engine, page limits, and required packages from custom templates. It then integrates these specifications into the standard compile-and-inspect loop and PDF verification pipeline. This guarantees that user-supplied templates undergo the same rigorous checks for page count, text-layer readability, and character encoding as the default templates.

### What happens if the generated PDF fails the verification checks?

If [`verify_pdf.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/verify_pdf.py) detects any formatting violations—such as garbled `(cid:…)` characters, missing contact details in the text layer, incorrect page counts, or keyword coverage gaps—it raises an exception that aborts the `/apply` workflow. The user receives immediate feedback about the specific validation failure, preventing non-compliant documents from being presented to applicants. This automated gate ensures that only properly formatted, ATS-readable PDFs exit the generation pipeline.