Hourly pay read as yearly
An $85 an hour contract failed a $175K floor.
Fix: Hourly rates are converted to annual before any pay rule runs.
Featured build · AI systems case study
LiveA daily AI job search that screens LinkedIn roles against my rules and resume, and emails me only the ones worth a look.
Why I built it
I looked at what was already out there, and none of it fit the way I actually like to search. AI has made custom tools like this possible in the span of an evening, so I built one that works exactly how I want it to.
The problem
My LinkedIn alerts said “30+ new jobs” every day, but each email showed six, and they weren't even the top six for my search. The rest meant digging through postings by hand, most of them with pay below my floor, onsite, or a stack I don't work in.
How a run works
Every morning a GitHub Action collects new roles and runs them through filters in order of cost. Most are dropped before any AI is involved.
Step 1
New roles from my alert emails and saved searches, minus anything already seen.
Step 2
Title words and companies I'm not interested in, checked in code.
Step 3
A small model screens titles 50 at a time and drops clear misses.
Step 4
Closed roles and posted pay below my floor are dropped for free.
Step 5
One Claude call per role scores fit against my resume and reads the facts.
Step 6
One email with a card for each role worth a look.
It never contacts anyone.
The only email it sends is the digest, to me.
The first two days
Screenednew roles found
181
Surfacedcards in my digest
16
Appliedstrong fits
7
In the first full run, 35 roles were dropped for pay below my floor, 17 for not being fully remote, and 9 for companies on my exclude list. Most of those were caught before any model call.
What a card tells me
What the first runs taught me
The first digest had nothing useful in it. Each run exposed something new.
An $85 an hour contract failed a $175K floor.
Fix: Hourly rates are converted to annual before any pay rule runs.
A posting URL the model returned redirected to an error page.
Fix: Every link is checked, and a dead one sends the role back for review.
A strong .NET legal-tech role scored 38 over libraries and a database I hadn't used.
Fix: A rubric that treats same-ecosystem tools as minor gaps.
Only 1 of the 6 jobs in an alert email ranked in the top 50 for that search.
Fix: Saved searches are read directly, not just the email.
LinkedIn's public search ranks by keywords but doesn't filter by them.
Fix: Depth is a setting, and every real filter runs per role.
A posting said “Canada only,” but LinkedIn's copy of it didn't.
Fix: When the company posts on its own job board, that version is scored.
Technical decisions
Free checks run first, a small model screens titles, and the full scoring call only sees roles that could still be a fit.
Scoring and fact extraction happen in the same Claude call, so each role costs one read, not two.
Each run has a usage budget and a time budget. Anything it can't reach waits in a queue for the next run instead of being dropped.
My stack, pay floor, exclusions, and scoring notes live in one config file. The code and prompts are generic, which is what made the public template possible.
Two optional settings read LinkedIn's public, logged-out pages to drop closed jobs and read a full day of results. They're off by default in the public template, because LinkedIn's terms prohibit automated access. Turning them on is each user's call.
Cost
Under 1%
of my weekly Claude Max limit per daily run, measured before and after a full run of 123 roles.
$4 to $5
per daily run at pay-as-you-go API prices, about 3 cents per role screened.
Current state
What’s next
Explore the work
The template has everything except my config and resume. Add yours, set five secrets, and it runs every morning.