# How the /apply Command Workflow Automates Job Applications in AI-Job-Search

> Explore the `/apply` command workflow in MadsLorentzen/ai-job-search. Discover its seven steps for automating job applications, from parsing to tracking.

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

---

**The `/apply` command in MadsLorentzen/ai-job-search executes a strict seven-step drafter-reviewer pipeline that parses job postings, evaluates candidate fit, drafts tailored CV and cover letter documents, verifies PDF ATS compatibility, and records the application in `job_search_tracker.csv`.**

The `/apply` command workflow transforms job URLs or pasted text into submission-ready application packages through a deterministic, audit-friendly process. This open-source automation, defined in [`.claude/commands/apply.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/apply.md), orchestrates two specialized AI agents to handle document drafting, peer review, and compliance verification without fabricating credentials.

## Step 0: Parse Input and Extract Metadata

The workflow begins by analyzing the `$ARGUMENTS` input to determine whether the user provided a URL or raw posting text.

If a URL is detected, the system invokes `WebFetch` to retrieve the page content. When standard fetching fails due to 403 errors or login walls, the pipeline automatically retries with browser headers and falls back to searching the employer's career site directly. From the parsed content, the system extracts **company name**, **role title**, **department**, **location**, **deadline**, and **posting language**, while preserving the full posting text for archival purposes.

## Steps 1–2: Drafter Agent – Evaluation and Document Creation

### Step 1: Evaluate Fit Against Candidate Profile

The **DRAFTER** agent loads the evaluation framework from [`.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) and the candidate profile ([`01-candidate-profile.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/01-candidate-profile.md)). It optionally executes [`salary_lookup.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/salary_lookup.py) to benchmark compensation against market data.

The agent produces a five-point evaluation covering **skills**, **experience**, **culture**, **salary**, and **overall fit**, presenting this assessment to the user with a continuation prompt before proceeding.

### Step 2: Draft CV and Cover Letter

Using the active template definitions from [`.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) and [`06-cover-letter-templates.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/06-cover-letter-templates.md), the drafter generates LaTeX or Typst source files. The default toolchain uses `lualatex` or `xelatex` unless a custom template was previously registered via `/add-template`.

The agent ensures every posting requirement is addressed—either matched to candidate experience or honestly noted as a gap—then writes the drafts to `cv/main_<company>_<role>.<ext>` and `cover_letters/cover_<company>_<role>.<ext>` while keeping the raw source in memory for the reviewer phase.

## Steps 3–4: Reviewer Agent – Critique and Revision

### Step 3: Research and Structured Critique

The **REVIEWER** agent receives the drafts inline (without file reads) and conducts independent research. It reads or creates cached company intelligence under `company_research/*.json`, consulting only the **candidate profile**, **behavioral profile**, **writing-style guide**, **evaluation rubric**, **master CV**, and [`CLAUDE.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/CLAUDE.md) as references.

The reviewer returns two artifacts: **Part A** containing JSON-structured edits for precise modifications, and **Part B** providing narrative suggestions for tone adjustments and strategic positioning.

### Step 4: Apply Structured Edits and Narrative Revisions

The drafter applies the JSON edits directly using the `Edit` tool, then manually implements narrative suggestions to add missing keywords, adjust tone, and weave in company-specific angles identified during research. The revised drafts become the final source files ready for compilation.

## Step 5: Compile PDFs and Run ATS Verification

This mandatory phase transforms source files into verified application artifacts through five sub-steps:

1. **Compile** the LaTeX/Typst sources using the resolved compile commands
2. **Visual inspection**: Verify page count, orphaned headings, whitespace anomalies, and cover letter layout integrity
3. **Iterative refinement**: Recompile until PDFs meet visual standards
4. **ATS parseability**: Extract the text layer using [`tools/verify_pdf.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/tools/verify_pdf.py), preferring `pypdf` with fallback to `pdftotext`, checking contact-detail visibility, reading order, and date extraction accuracy
5. **Keyword coverage analysis**: Compare extracted text against the requirement list from Step 1, marking each keyword as **covered**, **synonym-only**, **missing (have it)**, or **missing (gap)**

## Steps 6–6b: Present Final Output and Record Application

### Step 6: Final Verification and User Presentation

The system runs the [`CLAUDE.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/CLAUDE.md) verification checklist one final time, then presents a summary of key tailoring decisions—including emphasized qualifications, company angles incorporated, reviewer impact, and acknowledged gaps—alongside the generated file paths.

### Step 6b: Persist Application Data

The workflow ensures `job_search_tracker.csv` exists with the canonical header (adding a `deadline` column if missing), then inserts or updates a row with:

- Status: `drafted`
- Fit rating and file paths
- Source URL, channel, sector, role type
- Contact person and deadline

The full posting text is archived under `documents/applications/<company>_<role>/job_posting.md`. If the posting requires additional free-text fields (self-introductions, project entries), the system optionally drafts these supplements.

## Practical Usage Examples

Invoke the workflow using either a URL or raw text:

```text

# Apply using a job posting URL

> /apply https://jobindex.dk/job/1234567

```

```text

# Apply by pasting the job description directly

> /apply
Paste the full job posting text here

```

Typical interaction flow:

1. User submits `/apply <url>`
2. Step 0 parses the posting and extracts metadata
3. Step 1 displays fit evaluation with prompt: "Should I proceed with drafting?"
4. Upon confirmation, Steps 2–4 generate and refine documents
5. Step 5 compiles PDFs and reports: "Both files are ready for your review"

After manual review, users update the tracker status to `applied` using `/outcome <company>` or proceed to interview preparation with `/interview`.

## Summary

- The `/apply` command implements a **two-agent drafter-reviewer architecture** with seven strictly ordered steps (0–6b)
- **Input parsing** handles both URLs and raw text, with automatic retry logic for protected career sites
- **Document generation** uses LaTeX/Typst templates with honest gap acknowledgment rather than credential fabrication
- **ATS verification** via [`tools/verify_pdf.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/tools/verify_pdf.py) ensures machine-readable PDFs with proper keyword coverage mapping
- **Audit trail** maintenance includes CSV tracking in `job_search_tracker.csv` and archival storage of original postings

## Frequently Asked Questions

### How does the /apply command handle job postings behind login walls?

When `WebFetch` encounters 403 errors or authentication barriers, the workflow automatically retries with browser headers and falls back to searching the employer's public career site. If all fetching methods fail, users can paste the posting text directly as raw input to bypass URL fetching entirely.

### What files does the drafter create during the application process?

The system generates source files following the naming convention `cv/main_<company>_<role>.<ext>` and `cover_letters/cover_<company>_<role>.<ext>`, typically using `.tex` extensions for LaTeX processing. Compiled PDFs appear in the same directories, while archived postings store at `documents/applications/<company>_<role>/job_posting.md`.

### Does the /apply workflow verify that CVs will parse correctly in ATS systems?

Yes. Step 5 includes mandatory ATS verification using [`tools/verify_pdf.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/tools/verify_pdf.py) to extract text layers via `pypdf` or `pdftotext`, verifying contact-detail visibility, reading order, and keyword coverage against the original posting requirements. The system categorizes each keyword as covered, synonym-only, or missing.

### How does the application tracker maintain records of drafted applications?

The workflow updates `job_search_tracker.csv` with canonical headers including status (`drafted`), fit ratings, file paths, source URLs, and deadlines. It archives the full posting text and supports status transitions to `applied` via the `/outcome` command or interview preparation via `/interview`.