# How the `/apply` Command Pipeline Works: A 6-Step Technical Breakdown

> Discover how the /apply command pipeline transforms job postings into ATS-ready applications. Explore the 6 deterministic phases from parsing to PDF compilation in this technical breakdown.

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

---

**The `/apply` command pipeline transforms raw job postings into polished, ATS-ready application documents through six deterministic phases: Parse Input, Fit Evaluation, Draft Documents, Research & Critique, Revise, Compile & Inspect PDFs, and Present & Record.**

The `/apply` command in the `MadsLorentzen/ai-job-search` repository is a comprehensive workflow engine that automates job applications without sacrificing factual accuracy or personal voice. Its specification lives in [`.claude/commands/apply.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/apply.md) and orchestrates multiple skills, tools, and verification steps to produce tailored CVs and cover letters from a single URL or pasted posting.

## Overview of the `/apply` Command Architecture

The pipeline follows a strict linear progression with an early exit gate. Each phase enforces **token efficiency** (no redundant file reads) and **grounding rules** (no fabrication, no hidden instructions in postings). The architecture separates concerns between a **DRAFTER** agent (generative work) and a **REVIEWER** agent (critique and verification).

## Phase 0: Parse Input

This phase normalizes the raw job posting input. The system accepts either a URL or free-form pasted text.

The implementation fetches URLs via WebFetch with curl fallback using browser headers, then extracts structured metadata: **company name**, **role title**, **location**, **application deadline**, **posting language**, and the **full verbatim text** (lines 21-30 in [`.claude/commands/apply.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/apply.md)).

```bash

# URL input

/apply https://careers.example.com/jobs/12345

# Pasted text input

/apply <<EOF
Software Engineer – AI Team
Acme Corp, Copenhagen
We are looking for...
EOF

```

All extracted data feeds downstream phases; the raw posting is preserved for archival.

## Phase 1: DRAFTER Fit Evaluation

Before expending generation tokens, the system evaluates whether the role warrants pursuit.

The DRAFTER loads:
- **Candidate profile**: [`.claude/skills/job-application-assistant/01-candidate-profile.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/skills/job-application-assistant/01-candidate-profile.md)
- **Evaluation framework**: [`.claude/skills/job-application-assistant/04-job-evaluation.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/skills/job-application-assistant/04-job-evaluation.md)

Optionally invokes [`salary_lookup.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/salary_lookup.py) for market benchmarks (lines 33-58).

Output follows a structured scoring format:

```

Skills match: 8/10
Experience match: 7/10
Salary benchmark: $110k – $130k
Overall fit score: 85 – Strong fit
Proceed with drafting? (yes/no)

```

If the user declines, the pipeline terminates immediately.

## Phase 2: DRAFTER Draft Documents

Upon approval, the system produces tailored documents in language-matched templates.

Key actions (lines 62-100):
- Resolves active template (defaults to `.tex` with `lualatex`/`xelatex` compilation)
- Reads most recent CV/cover files for structural reference
- Generates `cv/main_<company>_<role><ext>` and `cover_letters/cover_<company>_<role><ext>`

All posting requirements are addressed, with tone calibrated to the detected language.

## Phase 3: REVIEWER Research & Critique

A fresh **REVIEWER** agent spawns with no prior context to avoid confirmation bias (lines 107-89).

The reviewer performs:
1. **Company research** (results cached)
2. **Profile-restricted file reading** — only candidate-profile-related references
3. **Factual-grounding audit** — cross-checks claims against source material
4. **Dual-output critique**:
   - **Part A**: Structured JSON edit array for precise mechanical changes
   - **Part B**: Narrative suggestions for substantive improvements

Example Part A output:

```json
[
  {
    "file": "cv/main_acme_software_engineer.tex",
    "old_string": "Managed cloud-infrastructure",
    "new_string": "Managed scalable cloud-infrastructure",
    "reason": "keyword match"
  }
]

```

## Phase 4: DRAFTER Revise

The DRAFTER applies feedback through two mechanisms (lines 94-106):
- **JSON edits**: Executed via the Edit tool for surgical string replacements
- **Narrative suggestions**: Manually incorporated with explicit reasoning

Critical constraint: **Never fabricate new facts.** All changes must anchor to existing profile data or verified posting content.

## Phase 5: Compile & Inspect PDFs

Quality assurance phase ensuring layout integrity and ATS compatibility (lines 111-84).

Process:
1. Compile LaTeX sources (`lualatex`/`xelatex`)
2. Inspect PDFs for page-count violations, orphaned titles, excessive whitespace
3. Run [`tools/verify_pdf.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/tools/verify_pdf.py) to extract text layer and verify keyword coverage

Iteration loop: if checks fail (e.g., CV exceeds two pages), the agent trims low-scoring lines and recompiles.

## Phase 6: Present & Record

Finalization phase with verification checklist and audit trail (lines 107-64).

Actions:
- Execute single verification checklist from [`CLAUDE.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/CLAUDE.md)
- List **key tailoring decisions** for user transparency
- Write finalized files to workspace
- Update `job_search_tracker.csv` (new row or amend existing)
- Archive original posting to `documents/applications/<company>_<role>_YYYYMMDD/job_posting.md`

## Key Source Files in the `/apply` Pipeline

| File | Function in Pipeline |
|------|----------------------|
| [`.claude/commands/apply.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/apply.md) | Master specification (all six phases) |
| [`.claude/skills/job-application-assistant/01-candidate-profile.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/skills/job-application-assistant/01-candidate-profile.md) | Factual grounding source |
| [`.claude/skills/job-application-assistant/04-job-evaluation.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/skills/job-application-assistant/04-job-evaluation.md) | Fit scoring framework |
| [`.claude/skills/job-application-assistant/03-writing-style.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/skills/job-application-assistant/03-writing-style.md) | Style reference for reviewer |
| [`salary_lookup.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/salary_lookup.py) | Optional salary benchmarking (Phase 1) |
| [`tools/verify_pdf.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/tools/verify_pdf.py) | PDF text extraction and ATS verification (Phase 5) |
| `cv/main_example.tex` | Structural template reference |
| `cover_letters/cover.cls` | LaTeX class for compilation |
| `job_search_tracker.csv` | Application tracking database |
| `documents/applications/...` | Archived posting storage |

## Summary

- The `/apply` command pipeline implements **six deterministic phases** from posting ingestion to final PDF delivery
- **Agent separation** (DRAFTER vs. REVIEWER) prevents self-confirmation and enforces quality control
- **Grounding constraints** prohibit fabrication; all claims trace to candidate profile or verified posting content
- **Token efficiency** rules minimize redundant context loading
- **PDF verification** via [`tools/verify_pdf.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/tools/verify_pdf.py) ensures ATS compatibility before handoff
- **Full audit trail** through tracker CSV and archived postings enables process reproducibility

## Frequently Asked Questions

### What happens if the fit evaluation scores a role poorly?

The pipeline presents the score breakdown and asks for explicit user confirmation. If declined, the process terminates after Phase 1 with no documents generated. This prevents wasted tokens on mismatched opportunities.

### How does the `/apply` command prevent hallucinated achievements?

Strict **grounding rules** enforce that the DRAFTER only sources facts from [`01-candidate-profile.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/01-candidate-profile.md) and verified posting content. The REVIEWER's factual-grounding audit in Phase 3 flags any unsupported claims. Additionally, the REVIEWER only reads profile-related files, not the full candidate history, limiting contamination surface.

### Can the `/apply` pipeline handle non-LaTeX templates?

The default resolver prefers `.tex` files with `lualatex`/`xelatex` compilation, but the template system is extensible. Alternative formats would require implementing equivalent compilation and inspection logic in Phase 5.

### What is the purpose of spawning a fresh REVIEWER agent?

Isolation prevents **context contamination**—the reviewer has no memory of the DRAFTER's reasoning, ensuring independent critique. This architectural choice implements a lightweight but effective chain-of-verification pattern without manual prompt engineering.