# Drafter-Reviewer Architecture in the `/apply` Command: Multi-Agent Pipeline for Job Applications

> Explore the Drafter-Reviewer architecture, a two-agent pipeline in the ai-job-search repo. Discover how it drafts and reviews CVs and cover letters for accurate job applications.

- Repository: [Mads Lorentzen/ai-job-search](https://github.com/MadsLorentzen/ai-job-search)
- Tags: architecture
- Published: 2026-09-01

---

**The Drafter-Reviewer architecture is a two-agent pipeline where a Drafter generates CV and cover letter drafts and a Reviewer critiques them for factual accuracy before final compilation.**

The `MadsLorentzen/ai-job-search` repository implements this Drafter-Reviewer architecture through the `/apply` slash command to automate job applications with human-level quality control. This design pattern separates content generation from critical review, ensuring every application remains factually grounded in the candidate's actual experience while tailoring content to specific job requirements.

## Architectural Overview of the Two-Agent System

The Drafter-Reviewer architecture defined in [`.claude/commands/apply.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/apply.md) distributes work between two specialized agents across six discrete steps. The **Drafter** handles all generation tasks—from fit evaluation to document drafting to PDF compilation—while the **Reviewer** operates as a fresh-context critic focused solely on content accuracy and strategic alignment.

This separation enforces a clean boundary between creation and validation. The Drafter works with full context of the candidate's history and the job posting, while the Reviewer receives drafts inline without file-system reads, eliminating latency and ensuring an objective critique of the presented text.

## Step-by-Step Execution Flow

### Step 0: Parse Input and Step 1: Evaluate Fit

The pipeline begins with metadata extraction from the job posting (URL or pasted text), capturing company, role, location, deadline, and language. The Drafter then evaluates fit using the framework defined in [`.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 invoking the salary-lookup tool for market context.

If the user confirms the fit assessment, the pipeline proceeds to drafting. If not, the process aborts immediately, saving tokens and time.

### Step 2: Draft CV and Cover Letter

The Drafter generates both documents simultaneously, respecting active templates defined in [`.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). This phase enforces strict requirement coverage—ensuring every mandatory qualification from the job posting appears in at least one document—while maintaining language consistency with the posting's locale.

### Step 3: Reviewer Research and Critique

The critical Reviewer phase receives the drafts inline via placeholders `<INSERT_CV_DRAFT_HERE>` and `<INSERT_COVER_LETTER_DRAFT_HERE>`, embedded directly in the prompt without file reads. This inline hand-off eliminates context window fragmentation and enforces a fresh perspective uninfluenced by previous drafting decisions.

The Reviewer performs three distinct audits:

- **Content critique:** Strategic alignment, tone, and requirement coverage
- **Factual grounding verification:** Cross-referencing against three immutable sources—[`01-candidate-profile.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/01-candidate-profile.md), the master CV template (`cv/main_example.tex`), and the candidate profile section of [`CLAUDE.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/CLAUDE.md)
- **Company research:** Contextual intelligence about the target employer

The Reviewer returns **Part A** (structured JSON edits for deterministic application) and **Part B** (narrative suggestions for stylistic improvements).

### Step 4: Revise Based on Feedback

The Drafter applies Part A automatically using the `Edit` tool, targeting specific `old_string` to `new_string` replacements. Part B suggestions require manual integration, forcing the Drafter to preserve factual grounding and avoid fabrication during stylistic refinement.

### Step 5: Compile and Inspect PDFs

The Drafter compiles LaTeX documents to PDFs using the active template's compile command, inspects layout integrity, and runs ATS-keyword checks via [`tools/verify_pdf.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/tools/verify_pdf.py). This step ensures machine-readability before human review.

### Step 6: Present Final Output

The system presents the finalized application package, runs the universal verification checklist, and records the submission in `job_search_tracker.csv` for audit trails.

## Key Design Patterns

### Inline Context Hand-Off

Instead of passing file paths, the architecture injects full document text directly into the Reviewer prompt:

```text
<CV_DRAFT file="cv/main_<COMPANY>_<ROLE><CV_EXT>">
<INSERT_CV_DRAFT_HERE>
</CV_DRAFT>

<COVER_LETTER_DRAFT file="cover_letters/cover_<COMPANY>_<ROLE><COVER_EXT>">
<INSERT_COVER_LETTER_DRAFT_HERE>
</COVER_LETTER_DRAFT>

```

This pattern minimizes token waste by avoiding redundant file reads and ensures the Reviewer evaluates exactly what the hiring manager will see.

### Structured Feedback Loop

The bifurcated response format creates a deterministic revision process:

- **Part A:** JSON array of edits with `file`, `old_string`, and `new_string` fields for programmatic application
- **Part B:** Free-form narrative guidance for nuanced improvements that resist structured encoding

This separation allows the Drafter to automate mechanical fixes while thoughtfully integrating strategic advice.

### Factual Grounding Audit

Both agents verify every claim against the three immutable data sources. The rule requires that any skill, achievement, or qualification mentioned in the application must exist in at least one of:

1. [`.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)
2. `cv/main_example.tex` (master CV template)
3. The candidate profile section of [`CLAUDE.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/CLAUDE.md)

This constraint prevents hallucination and maintains honesty in automated applications.

## Implementation Example

The following pseudocode illustrates the orchestration logic defined in the command specification:

```python
def apply(job_posting):
    # Step 0: Parse posting

    posting = parse_input(job_posting)
    
    # Step 1: Evaluate fit

    fit = evaluate_fit(posting)  # Uses 04-job-evaluation.md

    if not user_confirms(fit):
        return "Aborted"
    
    # Step 2: Draft documents

    cv_text, cover_text = draft_documents(posting, fit)
    
    # Step 3: Reviewer critique with inline drafts

    reviewer_prompt = build_reviewer_prompt(
        posting=posting,
        cv=cv_text,
        cover=cover_text
    )
    review = run_agent("general-purpose", reviewer_prompt)
    
    # Step 4: Apply structured edits (Part A) and narrative (Part B)

    for edit in review["Part A"]:
        apply_edit(edit["file"], edit["old_string"], edit["new_string"])
    incorporate_narrative(review["Part B"])
    
    # Step 5: Compile and verify

    compile_pdfs()
    run_ats_check()  # tools/verify_pdf.py

    
    # Step 6: Finalize

    record_application(posting)
    return generate_report()

```

## Source Files and Configuration

The Drafter-Reviewer architecture relies on the following canonical files:

| File | Role in Architecture |
|------|---------------------|
| [`.claude/commands/apply.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/apply.md) | Master pipeline specification defining all six steps and agent hand-offs |
| [`.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) | Immutable source of truth for candidate facts and grounding verification |
| [`.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 evaluation framework used in Step 1 |
| [`.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) | Active CV template selection and compilation commands |
| [`.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) | Cover letter template definitions |
| [`tools/verify_pdf.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/tools/verify_pdf.py) | ATS extraction and text verification for Step 5 |
| [`salary_lookup.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/salary_lookup.py) | Optional salary benchmarking for Step 1 |

## Summary

- The **Drafter-Reviewer architecture** separates content generation from quality assurance through a six-step pipeline defined in [`.claude/commands/apply.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/apply.md).
- **Inline hand-offs** pass draft documents directly into the Reviewer's context via XML tags, eliminating file-system latency and ensuring fresh critique.
- **Structured feedback** divides revisions into deterministic JSON edits (Part A) and narrative suggestions (Part B) for efficient integration.
- **Triple-source grounding** requires verification against [`01-candidate-profile.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/01-candidate-profile.md), `cv/main_example.tex`, and [`CLAUDE.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/CLAUDE.md) to prevent factual hallucination.
- The architecture optimizes for **token efficiency** through strict rules against re-reading files already in context.

## Frequently Asked Questions

### How does the Reviewer agent access the draft documents?

The Drafter injects the full text of the CV and cover letter directly into the Reviewer prompt using placeholders (`<INSERT_CV_DRAFT_HERE>` and `<INSERT_COVER_LETTER_DRAFT_HERE>`). This inline method avoids file reads and ensures the Reviewer evaluates the exact text that will be submitted, not cached versions.

### What prevents the AI from fabricating qualifications in the application?

The architecture enforces a **factual grounding audit** requiring both agents to cross-reference every claim against three immutable sources: the candidate profile document, the master CV template, and the Claude profile section. Any skill or achievement not found in these sources cannot be included in the final application.

### What is the difference between Part A and Part B feedback?

**Part A** consists of structured JSON edits specifying exact file paths, old strings, and new strings for deterministic application via the `Edit` tool. **Part B** contains narrative suggestions for tone, strategy, and content emphasis that the Drafter must manually interpret and integrate while maintaining factual constraints.

### Can the Drafter-Reviewer architecture handle different file formats?

Yes. While the default implementation uses LaTeX templates compiled to PDF, the architecture is format-agnostic. The Drafter respects whatever template is active 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), whether `.tex`, `.md`, or `.docx`, provided the appropriate compilation tools are configured in the template definition.