Inspiration
Job search is difficult, but not for lack of listings. It's the flood: hundreds of postings, a large fraction of them ghost jobs that were never real, and a mass-apply culture that pushes candidates toward AI tools that quietly invent resume claims to get past ATS keyword filters. We wanted the opposite of an auto-apply bot: something that filters ruthlessly, tells you why a match is good or bad, and never puts a word on your resume that isn't true.
What it does
Hunt Desk is a filter-first job search desk. You upload a CV, it's matched against a harvested job corpus, and you get back scored matches (≥4.0) — each with a ghost-job flag and the evidence behind both the score and the flag, never a bare number. From a matched posting, Hunt Desk drafts a tailored resume and cover letter sourced only from your actual CV, exports a packet, and stops. You submit. We refused to build auto-submit at launch (ADR-0003) — ATS terms-of-service exposure and putting a model in the submit path weren't a weekend risk worth taking.
How we built it
- Harvest layer: a crawl engine with per-country adapter packs (Greenhouse, Ashby, Lever, Workday, etc.) feeding a shared Postgres corpus, respecting robots.txt and closing postings only after a complete, adapter-confirmed snapshot — so a partial fetch can't mass-close live jobs.
- Scoring: a pipeline that fetches the live JD (not a cached report) and returns evidence-backed scores; a failed fetch returns "unknown", never a 0.
- Fact-gate: the non-negotiable write path for CLI-generated materials — it's the thing standing between "tailored" and "fabricated."
- Marvin (the in-app materials writer): rewrites the source resume into a formatted resume/cover on the job page itself — reverse-chronological, one page, cleaned phrasing — while treating the uploaded CV as ground truth (ADR-0008).
- Privacy architecture: customer CVs never touch git, logs, or an unrelated model call; each customer gets an isolated worktree rather than a shared tenant column (ADR-0004), and the product surface (apply-dashboard/) is separated from the harvest/lib internals.
Challenges we ran into
Real resumes are messy, and that collided hard with our "never invent a fact" rule. Fact-gate was refusing true content — a school spelled University Kentucky in an OCR'd PDF vs University of Kentucky in the model's paraphrase, or jobs listed out of chronological order — because the extractor and the writer disagreed on formatting, not facts. We had to draw a sharp line (ADR-0008): the source resume is intake, not a thing to be graded against; only the output gets format rules. Getting there also meant fixing PDF text extraction itself — embedded/subset fonts, Identity-H encoding, ASCII85+Flate streams, CMaps — because Marvin was reading garbage or nothing from real-world resume PDFs, and Playwright's bundled Chromium didn't even install on macOS 13, silently blocking PDF export.
Accomplishments that we're proud of
Shipping resume + cover generation that writes directly onto the job page from a messy, real PDF, without ever touching a model with the raw CV outside the one sanctioned materials call. Evidence-backed scoring that would rather say "unknown" than lie with a fake 0%. And holding the line on ADR-0003 — refusing submit at launch even though autofill already exists in the codebase — because the two failures that actually matter (inventing a fact, leaking a CV) are both irreversible, and a submit button is not.
What we learned
The hardest part of "don't hallucinate" isn't the model — it's the pipeline around it. Most of our fabrication risk turned out to live in extraction and formatting mismatches, not the LLM making things up outright. We also learned that a safety gate applied at the wrong layer (blocking on cosmetic disagreement with the source) erodes trust in the gate itself, which was worth fixing before it got worse.
What's next for Hunt Desk
Move from one-checkout-per-customer worktrees to a real hosted multi-tenant layer (IN-01: shared harvest corpus, isolated candidate data, with a "user A cannot read user B" test on every new endpoint) with Stripe billing at $10/week. Expand harvest coverage into more country packs and boards. And only after a legal review and an official ATS submission API spike, revisit whether any part of submit can ever be safely automated — not before.
Log in or sign up for Devpost to join the conversation.