# How to Extend the Job Search Tracker with Custom Status Values

> Learn to extend the AI job search tracker by adding custom status values. Update Markdown and validation files for seamless integration. Enhance your job search management today.

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

---

**You can extend the job search tracker with custom status values by updating the Markdown documentation and validation files that define the allowed enums, since the underlying CSV file has no schema constraints.**

The `ai-job-search` repository by MadsLorentzen manages job applications through a simple CSV-based tracker. Because the system relies on documentation-driven validation rather than hard-coded schemas, adding custom status values requires editing specific Markdown files that command handlers reference for allowed values.

## Where Status Values Are Defined

The job search tracker uses a `status` column in `job_search_tracker.csv` that is interpreted by several Claude commands (`/outcome`, `/rank`, `/scrape`, `/interview`). Valid status values are defined in two primary locations:

### Documentation Reference

The human-readable specification lives in [`documents/README.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/documents/README.md). This file contains a status table that serves as the source of truth for what values are considered valid across the ecosystem.

### Outcome Template

The `Status:` field in [`documents/applications/example/outcome.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/documents/applications/example/outcome.md) provides the template structure used when recording application outcomes. This template is referenced by the validation logic in [`.claude/commands/outcome.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/outcome.md) to ensure user inputs match expected values.

## Step-by-Step Implementation

To add a new custom status (such as `awaiting_feedback` or `on_hold`), modify the following files in sequence:

### 1. Update the Documentation

Edit the status table in [`documents/README.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/documents/README.md) to include your new status value in the list of allowed options.

```markdown
- **Status values**: `applied`, `interview`, `offer`, `hired`,
  `rejected`, `no_response`, `offer_declined`, `on_hold`

```

### 2. Extend the Outcome Template

Modify the `Status:` section in the outcome template to recognize the new value. This ensures that when you generate new outcome files for specific applications, the template includes your custom status as an option.

```markdown
**Status:** in_progress | hired | offer_declined | rejected | no_response | interview_only | on_hold

```

### 3. Adjust Validation Logic

The `/outcome` command validates user-provided status values against an allowed list. Update [`.claude/commands/outcome.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/outcome.md) to include your new status in the validation array:

```python
ALLOWED_STATUSES = [
    "in_progress", "hired", "offer_declined",
    "rejected", "no_response", "interview_only",
    "on_hold"      # ← new entry

]

```

### 4. Propagate to Skill Definitions

Several Claude skills reference status enums for specific workflows. Update these files to ensure consistency across scraping and upskilling operations:

In [`.claude/skills/job-scraper/SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/skills/job-scraper/SKILL.md), add the status to the scraped-job status enum:

```yaml
"status": "new/skipped/evaluated/ranked/expired/on_hold"

```

In [`.claude/skills/upskill/SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/skills/upskill/SKILL.md), verify the CSV header description includes the `status` column (no structural changes needed if the column already exists).

## How Commands Use Status Values

Understanding how various commands interpret the status column helps ensure your custom values integrate properly with existing workflows:

- **Deduplication** — The `/scrape` and `/rank` commands read the `status` column to determine whether a job has already been applied to or should be excluded from new searches.
- **Interactive Menus** — The `/outcome` and `/interview` commands filter tracker rows by status to present relevant workflow stages.
- **Calibration** — The `/setup` command only considers rows with final statuses (such as `hired` or `rejected`) when learning from past outcomes to improve ranking algorithms.

Because the tracker CSV has no enforced schema, updating the Markdown documentation and validation files automatically widens the set of values recognized by every dependent command.

## Summary

- The job search tracker stores status values in `job_search_tracker.csv` without schema enforcement.
- Valid status enums are defined in [`documents/README.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/documents/README.md) and [`.claude/commands/outcome.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/outcome.md).
- Adding custom status values requires updating four specific files: the README, the outcome template, the command validation logic, and the skill definitions.
- Once updated, commands like `/outcome`, `/rank`, `/scrape`, and `/interview` automatically recognize the new status values.
- The `/setup` calibration step uses status values to identify final outcomes for machine learning.

## Frequently Asked Questions

### Do I need to modify the Python source code to add a custom status?

No. The MadsLorentzen/ai-job-search repository uses documentation-driven validation. Since `job_search_tracker.csv` is a plain CSV without schema constraints, you only need to edit the Markdown files that declare allowed enums. The validation logic in [`.claude/commands/outcome.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/commands/outcome.md) references these definitions rather than hard-coding values.

### Will custom status values break the deduplication logic?

No, provided you update [`.claude/skills/job-scraper/SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/skills/job-scraper/SKILL.md) to include the new status in the relevant enum. The `/scrape` command checks the `status` column to skip existing applications, and it relies on the skill definition to determine which statuses indicate an active or completed application.

### Can I use the custom status immediately after editing the files?

Yes. Because the changes are effective immediately in the Markdown documentation that Claude commands reference, you can use `/outcome` or other commands with your new status value as soon as you save the updated files. No server restart or CSV migration is required.

### What happens if I forget to update one of the skill files?

If you omit updating [`.claude/skills/job-scraper/SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/skills/job-scraper/SKILL.md) or [`.claude/skills/upskill/SKILL.md`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.claude/skills/upskill/SKILL.md), certain commands may not recognize the custom status in specific contexts. For example, the scraper might overwrite or duplicate entries if it doesn't recognize your custom status as indicating an existing application. Always propagate changes to all four locations mentioned in the implementation steps.