Case study · built with Claude Code
JobOps
A job-search operating system, built with Claude Code. Sources jobs from ~19 integrations, gates them against policy I encoded in data, scores them against a rubric I wrote, and drafts applications within guardrails I defined. No database, no UI, no auto-submit: every application is reviewed by a human before it goes out. That human is me.
- Role
- Designer + sole engineer
- Stack
- Python · CSV · Claude Code
- Surface
- CLI, no UI
- Status
- Built; loop closed Aug 3 2026
01 · The brief
- The constraint: As a product designer who usually starts with a UI, I chose a CLI, agent-driven workflow with no UI to force engineering rigor.
- No hiding place: Every decision had to be named and every failure handled explicitly.
02 · Shape of the system
- Stack: 6 agent specs (
agents/*.md), 19 scraper integrations, Python runtime, and 5 CSV state files. - Scale: 93 target companies, 60 jurisdiction rules, ~5,500 scored job rows since April 2026.
[ATS APIs + job boards]
↓
[scrapers — 19 integrations]
↓
[data/inbox/*.json — raw, untouched]
↓
[ingest.py: dedupe → eligibility gate → audit gate → score]
↓
[data/jobs.csv — the scored funnel]
↓
[triage.py — the review queue]
↓
[drafter agent → cover.md + resume.md]
↓
[render.sh → PDF / DOCX / plain text]
↓
[human review → submission → applications.csv][VISUAL] System map — boxes connected by arrows, from ATS APIs → scrapers → inbox → ingest → jobs.csv → triage → drafter → render → human.
03 · The spec/runtime split — the part that matters
- Markdown specs vs Python runtime: Agents are prose instructions (non-deterministic); runtime code is strict Python (deterministic and testable).
- Decoupled ingestion:
scrapers/lever.mdis the spec;scripts/scrape.pyfetches, validates schemas, and writes to disk. If the LLM slips, the code holds.
“Data integrity must hold even when the LLM hallucinates.”— CLAUDE.md
04 · File-first state
- No in-memory state: Raw output lives in
data/inbox/, scored funnel injobs.csv, mutations logged tointeractions.csv. - Restartable architecture: Because state lives on disk, model failures cannot corrupt application state.
[VISUAL] State flow — small three-box strip: inbox/*.json (raw) → jobs.csv (scored) → inbox/processed/ (archive).
05 · The eligibility gate — domain knowledge became data
- The BGV audit trap: As an independent founder, my income evidence is client invoices and ITRs, not corporate payslips. SOP-driven mid/large enterprises fail this post-offer.
- Encoded as data, not code: I codified global jurisdiction rules into CSV/Python policy gates rather than leaving it to LLM prompts.
if country_hire == "IN" and headcount in ("200-1000", "1000+"):
return SKIP # SOP-driven HR can't defend the offer
if headcount == "10000+":
return PASS if country_hire == "global" else SKIP # federated big tech
if leadership_hires == "yes":
return PASS # founder in the loop can defend the offer[VISUAL] The gate as a tree — top-down binary decision tree ending in APPLY / SKIP.
06 · The scoring system
- Rubric weights (0–100): Title (20), skills (30), seniority (15), location (15), comp (20), minus staleness/aggregator penalties.
- Regression-tested strategy: Changes to strategy re-score all historical rows, locked with fixtures (52/52, 20/20, 13/13).
07 · The drafter — volume with taste
- Strict guardrails:<250-word letters, zero invented metrics, ≥80% keyword match, mandatory human pre-flight.
- Multi-faceted positioning: The same WellingZen project mapped to three different GitLab JDs with distinct framings.
| JD | Face of WellingZen |
|---|---|
| Senior PD, AI | AI-augmented engineering proof |
| Staff PD, Knowledge Graph | System-prototyping credibility |
| Staff PD, Security & Compliance | Security/policy chops |
The volume of a machine, the discrimination of a senior contractor.
[VISUAL] The fan-out — one project diverging into three distinct framing angles.
08 · The retro + pivot triggers
- Weekly funnel telemetry: Fridays,
/retrocomputes reply rates, track conversions, and comp-floor drift. - Surface, don't decide: The system surfaces signals for strategic pivots; the human pulls the trigger.
09 · The recursive plan
“It was not exactly a realisation, it was kind of the plan to leverage Claude to somehow improve my chances.”
- The loop: Built JobOps with Claude Code → used it to target AI-native teams → ran the portfolio site gating applications → drafted this case study.
- Milestone: On August 3, 2026, the first end-to-end application completed the loop (sourced → scored → gated → drafted → submitted).
[VISUAL] The loop — four nodes showing the recursive toolchain.
10 · What this v0 doesn't cover yet
- CLI screencaps and
/scrapedemos. - Public repo release (sanitized skeleton planned).
- Conversion telemetry at scale (early stage).
What the reader should take away
- Clear division of labor: LLMs handle labor (fetching, drafting); code handles integrity (schemas, gates); humans handle judgment (rubric, policy, final yes).
- The core thesis: Anyone can prompt an LLM. The value is the person who builds the system around it.