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

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 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 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:


# 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:

\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 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:

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 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 and 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 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 and 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 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →