# AI Job Search Framework Workflow Specifications: The Complete 6-Stage Pipeline

> Explore the complete 6 stage AI Job Search Framework workflow: setup, scrape, rank, apply, outcome, and upskill. Learn how our thin-pointer architecture ensures deterministic automation.

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

---

**The AI Job Search Framework implements a thin-pointer architecture with six discrete workflow stages—`/setup`, `/scrape`, `/rank`, `/apply`, `/outcome`, and `/upskill`—where commands read only from canonical files in `.claude/` and write only user-confirmed results, ensuring deterministic, idempotent automation.**

The MadsLorentzen/ai-job-search repository orchestrates a modular pipeline for automating job searches through AI agents. This workflow specification centers on a strict **read-once, write-only-when-confirmed** contract that maintains the candidate profile, evaluation rubrics, and application history as a single source of truth under the hidden `.claude/` directory.

## The Thin-Pointer Architecture

At the core of the workflow specifications lies a **thin-pointer design** that treats the `.claude/` directory as the immutable source of truth for all agent operations.

### Single Source of Truth

According to [`AGENTS.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/AGENTS.md) in the repository root, all agent runtimes must load canonical specifications and candidate profiles from specific files under `.claude/skills/` and `.claude/commands/`. As stated in lines 9-18 of [`AGENTS.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/AGENTS.md): *"All agent runtimes should load the canonical specifications and candidate profiles from the files and directories below… Do not duplicate these rules or specifications. Treat `.claude/` files as the single source of truth."*

This means higher-level commands never hardcode business logic. Instead, they pointer-reference files such as [`.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) for personal data and [`.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) for scoring rubrics.

### The Read-Once Contract

Every workflow step follows a strict I/O contract:

1. **Parse input** from command-line arguments, URLs, or interactive user replies
2. **Read source files once** (candidate profile, evaluation rubric, portal skill manifests)
3. **Perform the focused operation** (scrape, rank, draft, review, compile)
4. **Persist only confirmed changes** to files like `job_search_tracker.csv` or [`seen_jobs.json`](https://github.com/MadsLorentzen/ai-job-search/blob/main/seen_jobs.json)

This guarantees that rerunning any command produces identical results unless the underlying canonical files have changed, making the entire pipeline idempotent and auditable.

## The 6-Stage Workflow Pipeline

The framework decomposes the job search process into six discrete, composable stages, each triggered by a specific command.

### Stage 0: Onboarding with `/setup`

The `/setup` command initializes the candidate environment by walking users through three possible onboarding paths: importing an existing documents folder, uploading a single CV, or completing an interview-style questionnaire. This populates the seven skill files under `.claude/skills/job-application-assistant/`, including [`01-candidate-profile.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/01-candidate-profile.md) which serves as the central repository for facts, dates, and metrics.

### Stage 1: Job Collection with `/scrape`

The `/scrape` command discovers job postings via portable portal CLIs located in `.agents/skills/*/SKILL.md` (such as LinkedIn or Jobindex adapters). It stores raw postings under `documents/applications/` and records metadata—including posting URLs and discovery timestamps—in [`job_scraper/seen_jobs.json`](https://github.com/MadsLorentzen/ai-job-search/blob/main/job_scraper/seen_jobs.json). This stage operates read-only against the portal APIs and write-only to the local document store.

### Stage 2: Triaging with `/rank`

The `/rank` command loads [`01-candidate-profile.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/01-candidate-profile.md) and the evaluation rubric from [`04-job-evaluation.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/04-job-evaluation.md) to score every new posting in [`seen_jobs.json`](https://github.com/MadsLorentzen/ai-job-search/blob/main/seen_jobs.json). It applies language and location vetoes based on the rubric's constraints, then writes a ranked shortlist back to [`seen_jobs.json`](https://github.com/MadsLorentzen/ai-job-search/blob/main/seen_jobs.json) with fit scores and filtering tags. By default, it surfaces the top 5 matches, though users can specify `/rank --top 10` for extended lists.

### Stage 3: Full Application with `/apply`

The `/apply` command implements a two-agent workflow defined in [`.claude/commands/apply.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/apply.md). The sequence executes six distinct steps:

1. **Fit evaluation** against the candidate profile and job requirements
2. **Drafting** a tailored CV and cover letter using `cv/main_example.tex` as the LaTeX baseline
3. **Reviewer agent** audit of the drafts for accuracy and tone
4. **Edit application** of reviewer feedback
5. **Compilation and validation** of PDFs
6. **Logging** the application to `job_search_tracker.csv`

The command pauses for user confirmation before persisting any generated documents or tracker entries.

### Stage 4: Outcome Tracking with `/outcome`

After submitting applications, the `/outcome` command (found in [`.claude/commands/outcome.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/outcome.md)) records final statuses—such as "interview scheduled" or "rejected"—and feeds this data back into the candidate profile. This calibration loop updates the weights and thresholds used by [`04-job-evaluation.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/04-job-evaluation.md) for future ranking operations.

### Stage 5: Continuous Upskilling with `/upskill`

The `/upskill` command reads the complete application history from `job_search_tracker.csv`, analyzes patterns in rejected or successful applications, and suggests new skill targets. It then updates the upskill skill file at [`.claude/skills/upskill/SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/skills/upskill/SKILL.md) to guide the candidate's professional development.

## Practical Command Reference

The following bash commands demonstrate the standard workflow execution path:

```bash

# Stage 0: Initialize your profile (run once or when adding new documents)

/setup

# Stage 1: Pull latest postings from configured portals

/scrape

# Stage 2: Generate ranked shortlist (default top 5, override with --top)

/rank
/rank --top 10

```

```bash

# Stage 3: Apply to a specific job URL

# The workflow prompts for confirmation before drafting documents

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

```

```bash

# Stage 4: Record the result after hearing back from the employer

outcome AcmeCorp

# Stage 5: Analyze patterns and suggest skill improvements

upskill

```

Each command outputs a concise status report and links to generated artifacts, such as `cv/main_acme_software_engineer.tex`, `cover_letters/cover_acme_software_engineer.pdf`, or updated tracker rows in `job_search_tracker.csv`.

## Core Specification Files and Their Roles

The workflow depends on these canonical files residing in the `.claude/` directory:

- **[`AGENTS.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/AGENTS.md)** — Defines the thin-pointer architecture and mandates that agents load specifications from `.claude/` files rather than duplicating logic
- **[`.claude/commands/setup.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/setup.md)** — Implements the onboarding wizard and skill file generation
- **[`.claude/commands/rank.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/rank.md)** — Contains the triaging logic and scoring implementation
- **[`.claude/commands/apply.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/apply.md)** — Defines the six-step application drafting and review workflow
- **[`.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)** — Stores the candidate's immutable facts, employment history, and metrics
- **[`.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)** — Houses the scoring rubric with skill weights and veto criteria
- **`cv/main_example.tex`** — Master LaTeX template used as the baseline for all generated CVs
- **[`job_scraper/seen_jobs.json`](https://github.com/MadsLorentzen/ai-job-search/blob/main/job_scraper/seen_jobs.json)** — Auto-generated database of fetched postings and ranking metadata
- **`job_search_tracker.csv`** — Append-only log of every application and final outcome

## Summary

- The AI Job Search Framework uses a **thin-pointer architecture** where `.claude/` files serve as the single source of truth for all agent operations.
- The workflow comprises **six discrete stages**: `/setup` (onboarding), `/scrape` (collection), `/rank` (triaging), `/apply` (generation), `/outcome` (tracking), and `/upskill` (calibration).
- Each command follows a **read-once, write-only-when-confirmed** contract, ensuring deterministic behavior and full auditability.
- Core specification files—including [`AGENTS.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/AGENTS.md), [`01-candidate-profile.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/01-candidate-profile.md), and `04-job-evaluation.md**—are never duplicated; agents reference them directly to maintain consistency.

## Frequently Asked Questions

### What is the thin-pointer design in the AI Job Search Framework?

The thin-pointer design is an architectural pattern where workflow commands do not embed business logic or candidate data directly. Instead, they reference (point to) canonical files in the `.claude/` directory—such as [`01-candidate-profile.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/01-candidate-profile.md) for personal data and [`04-job-evaluation.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/04-job-evaluation.md) for scoring rules. This ensures that all agents operate from a single, version-controlled source of truth rather than duplicating specifications.

### How does the `/rank` command evaluate job postings?

The `/rank` command loads the candidate profile from [`.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) and the evaluation rubric from [`04-job-evaluation.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/04-job-evaluation.md). It scores each new posting in [`job_scraper/seen_jobs.json`](https://github.com/MadsLorentzen/ai-job-search/blob/main/job_scraper/seen_jobs.json) against skill weights defined in the rubric, applies language and location vetoes, then writes ranked results back to the JSON store. By default, it surfaces the top 5 matches unless overridden with the `--top` flag.

### What files constitute the single source of truth?

According to [`AGENTS.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/AGENTS.md), the single source of truth includes all files under `.claude/skills/` and `.claude/commands/`. Specifically, the seven skill files under `.claude/skills/job-application-assistant/` (including the candidate profile and evaluation rubric) and the command definitions in `.claude/commands/` (such as [`setup.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/setup.md), [`rank.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/rank.md), and [`apply.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/apply.md)) are treated as canonical specifications that agents must load rather than replicate.

### Is the workflow idempotent if I rerun commands?

Yes. The workflow is designed to be idempotent because each command reads source files exactly once at execution start and writes only confirmed changes. For example, rerunning `/rank` will produce identical scores unless [`01-candidate-profile.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/01-candidate-profile.md) or [`04-job-evaluation.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/04-job-evaluation.md) have been modified. Similarly, `/setup` can be rerun with `--section` flags to update specific portions without reprocessing the entire onboarding pipeline.