# How the Reviewer Agent Works and What It Checks in the AI Job Search Repository

> Discover how the reviewer agent in ai-job-search works. This Claude-powered sub-agent critiques CVs, researches companies, and provides structured JSON edits and feedback.

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

---

**The reviewer agent is a Claude-powered sub-agent that critiques drafted CV/cover-letter content and researches target companies during the `/apply` and `/interview` workflows, returning structured JSON edits and narrative feedback.**

The reviewer agent plays a critical quality assurance role in the **ai-job-search** repository maintained by **MadsLorentzen**. Spawned after the initial drafting phase, this specialized agent enforces content standards, verifies company-specific claims, and ensures token-efficient processing—all without duplicating the drafter's file I/O.

## How the Reviewer Agent Is Invoked

The reviewer agent is instantiated using the **Agent tool** (a generic Claude agent interface) with a fresh context to prevent interference with the drafter's state.

### Inline Draft Passing for Token Efficiency

Rather than asking the reviewer to read files from disk, the main workflow **passes draft content inline** in the agent prompt. This design choice eliminates redundant file operations and keeps token usage minimal.

From [`.claude/commands/apply.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/apply.md) (lines 15-16):

> *"When dispatching the reviewer agent, pass draft content **inline in the agent prompt** rather than asking the agent to Read files you already have in memory."*

This approach ensures that the reviewer operates on the exact text already resident in the main workflow's memory, not a stale disk copy.

## What the Reviewer Agent Checks

The reviewer performs five distinct categories of checks, each governed by specific rules defined across the repository's command and skill files.

### Company Research Cache Lookup

Before initiating any web search, the reviewer **checks the local `company_research/` cache**. If cached research exists for the target company, it is reused; otherwise, the reviewer performs fresh **WebFetch/WebSearch** operations and persists results to the cache.

Test suite assertions in [`tests/test_company_research_cache.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/tests/test_company_research_cache.py) (lines 101-108) verify this behavior:

- The reviewer prompt must reference the cache path
- The reviewer must check the cache before researching

This caching layer guarantees reproducibility across runs and prevents unnecessary API calls.

### Verification of Company-Specific Claims

Any claim about the target company—partnerships, product launches, expansions, financial results—**must be independently verified** via WebFetch/WebSearch. The researcher's output is **not implicitly trusted**.

The writing style rule in [`.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) (line 13) is explicit:

> *"NO unverified company claims"*

Unverified statements must be re-phrased generically or omitted entirely.

### Content Critique (Structured Edits - Part A)

The reviewer returns a **JSON array of `old_string → new_string` edits** for immediate application. These structured edits are applied directly using the **Edit tool** without human intervention.

Per [`.claude/commands/apply.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/apply.md) (lines 196-199):

> *"Apply Part A (structured edits) directly with the Edit tool."*

### Narrative Suggestions (Part B)

Higher-level feedback—company-specific angles, action-oriented reframing, gap handling strategies—is delivered as **narrative suggestions**. Unlike Part A edits, these require manual judgment by the drafter.

From [`.claude/commands/apply.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/apply.md) (lines 199-202):

> *"Apply Part B (narrative suggestions) using judgment."*

### Honesty and Gap Handling

Gaps in the candidate's profile are **explicitly left empty** rather than filled with keyword stuffing. The reviewer enforces the same honesty standard applied to the drafter.

From [`.claude/commands/apply.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/apply.md) (line 293):

> *"missing (gap) … Never stuff keywords."*

## How the Reviewer Integrates Its Feedback

The feedback integration follows a strict four-step sequence defined in [`.claude/commands/apply.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/apply.md):

1. **Receive feedback** — JSON edits plus narrative notes from the reviewer agent
2. **Apply Part A automatically** — Execute structured edits via Edit tool without re-reading draft files
3. **Process Part B manually** — Embed verified company details, refine phrasing, respect verification rules
4. **Run verification checklist once** — Execute Step 6 final verification after all edits complete

The reviewer focuses exclusively on content critique and research; **verification is the drafter's responsibility**. As specified in [`.claude/commands/apply.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/apply.md) (Step 6):

> *"Run the full verification checklist exactly once, at the end (Step 6). The reviewer focuses on content critique, not verification."*

## Code Example: Reviewer Agent Workflow

```python

# Step 3 – spawn the reviewer agent (simplified)

review_prompt = f"""
You are a reviewer. Critique the following drafts and suggest improvements.

CV:
{cv_text}

Cover Letter:
{cover_letter_text}
"""
reviewer_feedback = agent.run(
    name="general-purpose",
    prompt=review_prompt,
    tools=["Edit"]  # allow structured edits

)

# Step 4 – apply structured edits (Part A)

for edit in reviewer_feedback["edits"]:
    edit_tool.apply(
        file=edit["file"],
        old_string=edit["old_string"],
        new_string=edit["new_string"]
    )

# Step 5 – manually address narrative suggestions (Part B)

# e.g. insert researched company details after verifying via WebFetch/WebSearch

```

This workflow reflects the implementation in [`.claude/commands/apply.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/apply.md) (lines 15-16, 196-202).

## Why This Design Matters

The reviewer agent architecture delivers three critical benefits:

- **Token efficiency** — Inline draft passing eliminates redundant file reads and context window consumption
- **Separation of concerns** — Drafter handles structure and language generation; reviewer handles research and critique
- **Reliability** — Cached research with mandatory verification prevents hallucinated company claims

## Key Source Files

| File | Role |
|------|------|
| [`.claude/commands/apply.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/apply.md) | Full specification of reviewer-agent dispatch, inline draft passing, edit handling, and verification checklist |
| [`tests/test_company_research_cache.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/tests/test_company_research_cache.py) | Unit tests confirming cache-first behavior and writeback |
| [`.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) | "No unverified company claims" rule enforcement |
| [`.claude/commands/interview.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/interview.md) | Mirrors reviewer usage for the `/interview` workflow (Step 2) |

## Summary

- The **reviewer agent** is a Claude-powered sub-agent spawned during `/apply` and `/interview` workflows
- Drafts are passed **inline** to optimize tokens and avoid disk I/O
- Checks include: **cache lookup**, **claim verification**, **structured edits (Part A)**, **narrative suggestions (Part B)**, and **honesty enforcement**
- Part A edits apply automatically; Part B feedback requires manual implementation
- Verification runs **once at the end**—the reviewer does not perform final claim checking

## Frequently Asked Questions

### How does the reviewer agent receive draft content?

The main workflow passes CV and cover letter text **inline in the prompt** rather than asking the reviewer to read files. This design, specified in [`.claude/commands/apply.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/apply.md) (line 15), prevents token waste and ensures the reviewer works with current in-memory content.

### What happens if company research is already cached?

The reviewer **checks `company_research/` first**. If cached data exists, it is used directly; otherwise, the reviewer executes WebFetch/WebSearch and writes fresh results back to the cache. Tests in [`tests/test_company_research_cache.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/tests/test_company_research_cache.py) (lines 101-108) enforce this behavior.

### Can the reviewer agent hallucinate company details?

The workflow **explicitly prevents this**. Per [`.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) (line 13), the reviewer must flag any unverified claims. The drafter then re-phrases or removes them. Final verification (Step 6) provides an additional safety layer.