Built by me · Open source
CareerLogic — a rule-based job-search pipeline
I ran my own job search like a product: every posting screened against explicit eligibility rules, a structured evaluation for the few that clear the bar, and a tailored CV and cover letter for each — with a human decision before anything is sent.
TL;DR
- A search across a dozen markets surfaces thousands of postings. The hard part isn't finding them — it's deciding which deserve a tailored application, then producing that application without quality drifting.
- The key call: explicit rules decide, not a model. Every verdict can be traced to the rule that produced it, and no CV sentence is written that isn't already true.
- Result: of 7,547 postings screened with their full job descriptions, 85% were set aside before any application work — about 1 in 7 earned a full evaluation.
1Problem & who it's for
The user was me: a senior product owner searching across India, the U.S., Europe, the Gulf and Asia-Pacific at the same time. Each market brings its own eligibility questions — work authorisation, sponsorship, residency, local-language requirements — and most postings fail one of them in a way the title never reveals.
Reading every posting carefully doesn't scale. Skimming does scale, but it fails in both directions: good roles get missed and weak ones get applications. And once applications are being produced in volume, quality drifts — a wrong claim in one cover letter, a formatting rule forgotten in the next.
2Evidence & inputs
- The postings themselves: 7,547 with their full job descriptions, which is what the selectivity figures below are measured on.
- My own profile as structured data: career history, strengths, genuine gaps, work authorisation and target markets, kept in configuration so the rules can be checked against it.
- Failures in real use. The most useful input was every time the system got something wrong on a real posting — each one became a rule, a guardrail or a test (see the retrospective).
3Workflow, evaluation & guardrails
Workflow: scan → screen → evaluate → generate → render. Each stage's output is the next stage's input, and each can run on its own.
Seven screening rules decide every verdict: role family, excluded titles and companies, hard skill gaps (a score penalty, not a skip), local-language requirements, home-country location limits, work authorisation abroad (must already live there, citizenship or clearance required, or sponsorship refused), and nationality-restricted titles. Where a title is ambiguous, the posting is flagged for a human read rather than guessed at.
Guardrails:
- Never fabricate. Every CV and cover-letter sentence comes from my own profile data; the generator selects and orders existing material and never writes a new claim.
- Dedup gate, so the same posting re-listed under a different spelling or ID isn't applied to twice.
- Domain guard, which warns when a draft claims experience my profile lists as a gap.
- Length check on every rendered CV.
- A human in the loop: I read the full job description before any CV is generated, and I submit every application myself. Nothing is sent automatically.
How it's tested. Before publishing, I had the public version checked against my private working version: identical screening verdicts on 15,110 cases, byte-identical CVs and cover letters across 16 job shapes, and identical evaluation files on 308 of 308. An end-to-end test suite runs from a fresh copy using only fictional sample data, and confirms none of my real data appears anywhere in the output.
4Options considered
5Decision, trade-offs & non-goals
Decision criteria. Traceable (every verdict names its rule), repeatable (same input, same result), honest (no invented claims) and cheap enough to run on every posting.
Trade-offs accepted.
- Rules miss nuance a careful reader would catch. Mitigation: ambiguous titles are flagged rather than decided, and I read the full description before generating anything.
- Rules need maintenance: every new failure means a rule change and a test. That cost is the point — it's how the system gets better instead of silently drifting.
Non-goals.
- Submitting applications automatically.
- AI-written claims in CVs or cover letters.
- Maximising the number of applications sent.
6What I built
I designed the rules, the guardrails and the tests, and built it with AI-assisted coding (Claude Code). It runs alongside career-ops, an open-source evaluation framework by Santiago Fernández de Valderrama, and is credited to it in the repository.
- The public repository, with a README covering the design principles, the seven screening rules and every pipeline stage: github.com/sashankpm-web/careerlogic
- Complete sample configuration for a fictional candidate, so anyone can run it end to end
- The test suite described above
7Outcome & metrics
Of 7,547 postings screened with their full job descriptions:
- 26% set aside for an off-target title, an excluded company or the wrong location
- 7% failed an eligibility or language rule
- 52% scored below the bar
- 15% cleared it — about 1 in 7 — and earned a full evaluation
Measurement plan (not a result yet): the test of the scoring is whether higher-scored roles convert to interviews at a higher rate than lower-scored ones. The plan: once there are enough outcomes, compare interview rates across score bands, and re-weight the scoring if the bands don't separate.
8Retrospective
The real lessons came from what broke on real postings:
- A copy of the rules drifted. A rescoring step kept its own copy of the screening rules; when new eligibility rules were added, the copy silently skipped them. Now there is one set of rules, imported everywhere.
- Place names fooled the location checks. "Indianapolis" matched my home country, and "Perth, WA, Australia" was read as Washington State, which put the wrong work-authorisation sentence into one cover letter. It was caught before sending; both checks now match whole place names, with tests for each case.
- The rules over-trusted keywords. Reading the full job descriptions for one day's top-ranked roles ruled out 8 of 47 that the scoring had placed at the top. That's why a human read now sits between scoring and any application.
- An applicant-tracking system taught me something about CVs. Splitting one employer into three adjacent entries made a target ATS's parser read zero experience entries instead of three imperfect ones. The CV format now keeps one block per employer, with a comment in the code so the "improvement" isn't reintroduced.
The throughline is the same one from my trade-finance work: automation should absorb volume, not judgment. The rules decide what isn't worth my time; I decide what is.