# The Six Steps in the AI Job Search /apply Pipeline: A Complete Technical Guide

> Master the AI Job Search /apply pipeline. Discover the six technical steps transforming raw job postings into ATS-compliant applications and tracker records.

- Repository: [Mads Lorentzen/ai-job-search](https://github.com/MadsLorentzen/ai-job-search)
- Tags: deep-dive
- Published: 2026-08-29

---

**The `/apply` command executes a deterministic six-step drafter-reviewer workflow that transforms raw job postings into polished, ATS-compliant application documents and persistent tracker records.**

The AI Job Search framework (`MadsLorentzen/ai-job-search`) automates application generation through a rigorous pipeline defined in [`.claude/commands/apply.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/apply.md). This specification orchestrates a "drafter-reviewer" pattern that ensures every CV and cover letter is factually grounded, tailored to the company, and optimized for both human recruiters and applicant tracking systems.

## Overview of the Pipeline Architecture

The `/apply` pipeline treats job applications as structured data pipelines rather than one-off documents. When you invoke `/apply` followed by a URL or pasted text, the system initializes **Step 0** (input parsing) and then proceeds through six deterministic stages. Each stage is either executed by a **Drafter** agent (responsible for generation and compilation) or a **Reviewer** agent (responsible for critique and verification), creating a self-correcting loop that ensures high output quality.

## The Six Steps in Detail

### Step 1: Drafter Evaluates Fit

The pipeline begins by loading the candidate profile and evaluation rubric. The Drafter reads [`01-candidate-profile.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/01-candidate-profile.md) and [`04-job-evaluation.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/04-job-evaluation.md) to establish baseline criteria. If configured, the system invokes [`salary_lookup.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/salary_lookup.py) to benchmark compensation:

```bash
python salary_lookup.py "Acme Corp" --json --city "Copenhagen"

```

The Drafter then produces a quantitative fit score and presents a recommendation. The user must confirm to proceed, creating a hard gate that prevents wasted effort on poor-fit roles.

### Step 2: Drafter Drafts CV and Cover Letter

Upon approval, the Drafter resolves the active templates from [`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). It generates customized LaTeX source files, writing them to disk with predictable naming conventions:

- `cv/main_<company>_<role>.tex`
- `cover_letters/cover_<company>_<role>.tex`

These drafts address every explicit requirement from the job posting while respecting the stylistic constraints of the selected template.

### Step 3: Reviewer Researches and Critiques

The pipeline spawns a fresh **Reviewer** agent with no context of the drafting phase. The Reviewer receives the drafts inline and performs three concurrent tasks: researching the company via cached JSON or fresh web search, auditing factual grounding against public sources, and generating structured feedback. The output splits into:

- **Part A**: A machine-readable JSON edit list for automated application
- **Part B**: Narrative suggestions for tone, keyword density, and missing achievements

This separation allows deterministic edits to proceed automatically while reserving judgment-based changes for human or advanced model supervision.

### Step 4: Drafter Revises Based on Feedback

Returning to the Drafter, Step 4 applies all Part A edits automatically using the internal `Edit` tool. For Part B suggestions—such as inserting missing keywords or adjusting tone—the Drafter performs manual, judgment-based revisions. This hybrid approach ensures precision for factual corrections while preserving creative flexibility for stylistic improvements.

### Step 5: Compile and Inspect PDFs (Mandatory)

This critical compliance stage compiles the LaTeX sources and validates the output. The Drafter executes compilation commands:

```bash
cd cv && lualatex -interaction=nonstopmode main_acme_software_engineer.tex
cd ../cover_letters && xelatex -interaction=nonstopmode cover_acme_software_engineer.tex

```

Immediately after compilation, the pipeline runs [`tools/verify_pdf.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/tools/verify_pdf.py) to extract the text layer and simulate ATS parsing:

```bash
python tools/verify_pdf.py cv/main_acme_software_engineer.pdf --dump-text cv/main_acme_software_engineer.txt

```

If the PDFs fail layout checks, keyword coverage validation, or ATS extraction, the Drafter loops back to editing and re-compiles until the documents are clean.

### Step 6: Present Final Output

The final stage executes a verification checklist, summarizes key tailoring decisions (such as company-specific angles and reviewer impact), and persists the record. The system archives the original posting text to `documents/applications/<company>/job_posting.md` and appends a structured row to `job_search_tracker.csv`:

```python

# Pseudocode representing the CSV write operation

write_csv_row({
    "date": today(),
    "company": "Acme Corp",
    "role": "Software Engineer",
    "status": "drafted",
    "fit_rating": 84,
    "cv_file": "cv/main_acme_software_engineer.tex",
    "cover_letter_file": "cover_letters/cover_acme_software_engineer.tex",
    "source": "https://jobindex.dk/job/1234567",
    "deadline": "2026-09-15"
})

```

## Summary

The `/apply` pipeline in the AI Job Search framework converts unstructured job postings into rigorous application packages through six ordered stages:

- **Step 1**: Evaluate fit against candidate profile and rubric, optionally checking salary benchmarks
- **Step 2**: Generate LaTeX drafts for CV and cover letter using active templates
- **Step 3**: Spawn a Reviewer agent to research the company and produce structured critique
- **Step 4**: Apply automated JSON edits and manual revisions based on reviewer feedback
- **Step 5**: Compile PDFs and verify ATS compatibility through text-layer extraction
- **Step 6**: Archive source documents and record the application in the tracker CSV

## Frequently Asked Questions

### What triggers the salary lookup in Step 1?

The salary lookup executes only when [`salary_lookup.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/salary_lookup.py) is configured in your environment. According to the specification in [`.claude/commands/apply.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/apply.md), this tool runs conditionally; if unavailable, Step 1 proceeds using only the candidate profile and job evaluation rubric to calculate the fit score.

### How does the Reviewer agent research the company in Step 3?

The Reviewer first checks for cached company research in JSON format. If no cache exists or if the data is stale, the agent performs a fresh web search. This research, combined with the inline draft documents, enables the Reviewer to audit factual claims about company values, tech stacks, and recent news against public sources.

### What happens if the PDF compilation fails in Step 5?

Step 5 operates as a mandatory validation gate with iterative correction. If `lualatex` or `xelatex` returns errors, or if [`tools/verify_pdf.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/tools/verify_pdf.py) detects ATS parsing failures or layout issues, the Drafter automatically returns to editing mode. It applies necessary fixes to the LaTeX source and re-compiles, looping until the PDFs pass all extraction and visual checks.

### Where is the application data stored after Step 6?

Step 6 writes to two locations: the original job posting text is archived as `documents/applications/<company>/job_posting.md`, while structured metadata (company name, role, fit rating, file paths, and deadline) is appended to `job_search_tracker.csv` in the repository root. This dual-storage approach preserves both the source evidence and searchable application history.