Six layers, one doctrine: artifacts over assertions. Model output is never trusted where a mechanical check is possible, and every stage must produce evidence the next stage verifies.
1. Ingestion. Adapters for Greenhouse, Lever, Ashby, Workday, Eightfold, SmartRecruiters, Jibe, generic JSON feeds and the SimplifyJobs aggregate poll your universe's boards on a schedule, normalize postings, and detect closures — with guards: an empty response never mass-closes a board, and a poll that would close most of a board refuses. A URL resolver routes any posting link to its ATS detail API for the full job description; a 404 there closes the posting as a dead link. Captured text is quality-graded: page scripts, stylesheets and application-form pages are refused at the door (each of those once impersonated a JD).
2. Deterministic filters (free). Location policy (segment-wise, default-deny for unrecognized foreign sites), seniority-plus-specialist titles, back-office departments — with a carve-out: a title matching your declared target families always survives. A 30-day age window uses the ATS's own posted date. These are the only things allowed to skip a posting without a full read, plus title-family routing for companies you have not curated yet.
3. Judgment. Each surviving posting's full JD is scored 0–10 against your pack's profile by a headless Claude call, returning verdict, resume variant, rationale, and evidence fields: the posting's real experience floor, its target cohort, and the gap between you and its ideal candidate — each with a verbatim quote.
4. Gates (code, not model). Kill patterns (sponsorship, citizenship, ITAR, clearance, PhD, program restrictions) run over the FULL text at record time. Which patterns kill versus merely flag derives from your declared constraints. A model-asserted kill needs a fired gate or a verbatim quote; a cap-changing claim counts only when its quote is really in the text (title included); score caps from your calibration are clamped in code. A free sweep re-runs gates over the whole corpus every poll, so a new pattern retroactively kills old misses.
5. Verification. Every 7+ score is re-derived in batches by a stronger model before it can reach an alert channel. Near-duplicate postings of one role are reconciled — identical captures by deterministic copy, differing ones by fresh judgment — and the sweep verifies convergence actually happened rather than trusting that it wrote rows.
6. Surfaces. Local dashboard (review queue, companies, pipeline, CRM with decay timers, calendar, system health), morning digest, phone pushes for verified high scores only, WAL-safe daily backups, and an optional cloud safety net that alerts if your machine goes silent.
- Counters, not vibes. Every mechanism has a counter; the pipeline checks its own artifacts moved at the end of every poll and pages on violation. A week-long silent outage taught this.
- Blind verdicts are provisional. Anything decided without the full text is re-decided when the text arrives.
- Evidence or it didn't happen. A 9/10 once rested on a fabricated cohort claim; a kill once rested on a work-permit guess; a "verified 10" once rested on an application form's dropdown menu. All three failure classes are now mechanically impossible.
- Degrade loudly, never silently. Judge failures pause scoring with the error named; unresolvable JDs park visibly; deferred work is an event.
Everything personal lives in candidate/ (gitignored): profile, gate
switchboard, calibration caps, target families, resume variants, universe,
deadlines ledger. The engine reads a person only through the pack loader,
prompts are rendered from it per call, and two fictional personas — one
new-grad international student, one experienced citizen — keep both
constraint paths tested in CI forever.