# Application Tracker

> Use when the user says "add this job to my tracker," "update the pipeline," "what's my status," or "what's overdue". Maintains pipeline/tracker.csv and the per-application records, runs an integrity check, and renders a pipeline-health dashboard. The source of pipeline truth.

- Skill: `guerrilla2799/application-tracker` (Agent Skill)
- Install (CLI): `npx skillmds@latest add guerrilla2799/application-tracker`
- Raw SKILL.md: https://api.skillmd.com/api/skills/guerrilla2799/application-tracker/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: guerrilla2799 (https://skillmd.com/u/guerrilla2799)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/guerrilla2799/application-tracker

---


# Application Tracker

The local pipeline CRM. Every job the user is chasing lives here, one CSV row plus one record file, and this skill keeps them clean, consistent, and honest about what's next.

## When to use
- User says "add <job> to the tracker," "mark <company> as applied/interviewing/rejected," "log the recruiter call."
- User asks "where's my pipeline," "what's overdue," "what should I do today," "pipeline health."
- Any other skill finishes a stage and needs the status/record updated (resume tailored, letter sent, interview scheduled, offer received).
- The `search-and-scale-os` weekly cadence reads this skill's dashboard as its pipeline snapshot.

## Inputs
- Reads:
  - `workspace/pipeline/tracker.csv` – the row-per-application ledger (schema below).
  - `workspace/pipeline/applications/<id>-company-role.md` – the per-application records.
  - `templates/application-record-template.md` and `templates/tracker-schema.csv` for the skeletons.
- Needs from user:
  - For an add: company, role, and enough to seed a row (url, source, comp, location if known).
  - For an update: which `id` (or company/role) and what changed (status, next action, contact, notes).

## Schema (tracker.csv)
`id,company,role,location,comp_range,source,url,date_found,fit_score,status,priority,next_action,next_action_date,contact,referral_path,notes`

- **id.** `J001`, `J002`, … zero-padded, never reused. Row links to `applications/<id>-company-role.md`.
- **fit_score.** 0–100 (from `job-fit-scoring`).
- **status.** Normalize to the vocab: `found → researching → tailoring → applied → screening → interviewing → final → offer → negotiating → accepted / rejected / withdrawn / ghosted`.
- **priority.** `A / B / C`.
- **next_action** / **next_action_date**. Every live row must have both. Terminal rows (accepted/rejected/withdrawn/ghosted) may leave them blank.
- Quote any field containing a comma. Keep the header row exactly as above.

## Workflow
1. **Add or update.**
   - *Add:* mint the next `id`, write the row, and create `applications/<id>-company-role.md` from the template. Set `status: found` (or further along if warranted) and a real `next_action`.
   - *Update:* find the row by `id`/company, change the fields, and mirror the change into the record file's Status line and Timeline/log (append a dated entry, never overwrite history).
2. **Normalize status.** Map whatever the user said onto the vocab exactly. "Heard back / phone screen" becomes `screening`, "onsite / panel" becomes `interviewing`, "final round" becomes `final`, and "no response in 3+ weeks" becomes `ghosted`.
3. **Dedupe.** Same company + same role = one row. If a dupe exists, merge into the lower `id`, keep the richer notes, and delete the extra. Flag near-dupes (same company, adjacent roles) rather than auto-merging.
4. **Integrity check.** Scan the whole tracker and report:
   - **Orphans.** `id` in CSV with no record file, or a record file with no CSV row.
   - **Missing next_action.** Any live (non-terminal) row without `next_action` or `next_action_date`.
   - **Overdue.** `next_action_date < today` on a live row.
   - **Status/priority mismatch.** E.g. `interviewing`/`offer` marked priority C, or priority A sitting in `found` with no movement in 7+ days, or a `fit_score ≥ 80` still at `found`.
   - **Stale.** No timeline entry in 14+ days on a live row.
   - **Schema drift.** Bad status value, malformed date, missing id, unquoted comma.
5. **Maintain the record files.** Ensure each live `id` has its record with Status/Fit/Priority header current, Materials paths filled once resume/letter exist, and the log appended for the latest event.
6. **Render the dashboard** (below) in chat.
7. Write the updated `tracker.csv` and any touched record files back to disk.

## Pipeline-health dashboard
Render this in chat every run:

```
PIPELINE HEALTH: <date>

Counts by status:
  found N · researching N · tailoring N · applied N · screening N
  interviewing N · final N · offer N · negotiating N
  terminal: accepted N · rejected N · withdrawn N · ghosted N
  Active (non-terminal): N

Conversion (cumulative, active + terminal-positive):
  applied → screening      X/Y  (Z%)
  screening → interviewing X/Y  (Z%)
  interviewing → offer     X/Y  (Z%)
  applied → offer          X/Y  (Z%)

Integrity flags:
  Orphans: [...]
  Missing next_action: [...]
  Overdue (date < today): [id | company | action | was due]
  Status/priority mismatches: [...]
  Stale 14+ days: [...]

WHAT'S OVERDUE (do first):
  1. <id> <company> | <next_action> (due <date>, N days late)

WHAT'S NEXT (priority-A, due soon):
  1. <id> <company> | <next_action> (due <date>)

Priority-A needing action: N
```

Conversion counts a stage as "reached" if the row is at that status or any later one (so an offer counts toward screening and interviewing too). State counts, not just percents, when Y is small.

## Output
- Writes to: `workspace/pipeline/tracker.csv` (updated) and `workspace/pipeline/applications/<id>-company-role.md` (created/updated).
- Renders: the pipeline-health dashboard in chat.
- Format: CSV per the schema, record files per `application-record-template.md`, and the dashboard as the block above.

## Rules & quality bar
- **Single source of truth.** The CSV is authoritative for status and next action. The record file holds the narrative. Keep them in sync every write.
- **Never lose history.** Timeline entries are append-only and dated.
- **Every live row has a next action.** A row with no next step is the #1 pipeline leak. Flag it loudly.
- **Honest status.** Don't mark `applied` until it's actually submitted (a human does that), and don't leave dead threads as `interviewing`. Move them to `ghosted`/`rejected`.
- **Terminal is terminal.** Once accepted/rejected/withdrawn/ghosted, stop nagging for next actions.
- Deterministic bookkeeping. No fabricated companies, comps, or dates. If a field is unknown, leave it blank rather than inventing one.

## Related skills
- `job-sourcing` – feeds new `found` rows in.
- `job-fit-scoring` – populates `fit_score` and often `priority`.
- `resume-tailor` / `cover-letter` set Materials paths and move rows to `tailoring`/`applied`.
- `interview-prep` / `interview-followup` drive `screening → interviewing → final` and log debriefs.
- `offer-negotiation` – drives `offer → negotiating → accepted`.
- `search-and-scale-os` – the orchestrator, which reads this dashboard for its weekly cadence and to decide what to surface.

