Featured build · AI systems case study

Live

Job Hunt Pipeline

A daily AI job search that screens LinkedIn roles against my rules and resume, and emails me only the ones worth a look.

Sample digestFictional roles

Job Hunt Pipeline digest

A sample daily digest with two role cards showing fit scores, must-haves checklists, and a player-coach tag, on a dark mauve background.

Sample digest · Fictional roles

Role
Sole developer
Status
Live · runs daily on GitHub Actions
Outcome
181 roles screened, 16 surfaced, 7 applications in two days
Stack
C#, .NET 10, Claude, GitHub Actions, Gmail API

Why I built it

Yes, another AI job searcher

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

Six jobs out of thirty

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

Cheap checks first, one careful read last

Built

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.

  1. Step 1

    Collect

    New roles from my alert emails and saved searches, minus anything already seen.

  2. Step 2

    Free filters

    Title words and companies I'm not interested in, checked in code.

  3. Step 3

    Title check

    A small model screens titles 50 at a time and drops clear misses.

  4. Step 4

    Job page

    Closed roles and posted pay below my floor are dropped for free.

  5. Step 5

    Score

    One Claude call per role scores fit against my resume and reads the facts.

  6. Step 6

    Digest

    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

181 roles in, 7 applications out

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

Enough to decide in under a minute

Two cards from the sample digestFictional roles

Job Hunt Pipeline digest card

The first two role cards of the sample digest, each with a fit score, day-to-day summary and must-haves checklist.

Two cards from the sample digest · Fictional roles

Fit score and why
Scored against my resume with a rubric that separates learnable gaps from real ones.
Must-haves checklist
Each stated requirement, marked met, partial, or not met.
Day to day
What the job actually involves, in a sentence or two.
Manager or hands-on
A “Manager” title can be a player-coach role. The card says which, judged from the description.
The facts
Pay, remote, applicant count, and links to the LinkedIn listing and the company's own posting.

What the first runs taught me

Real data fixed more than planning did

The first digest had nothing useful in it. Each run exposed something new.

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.

Links that looked right but weren't

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.

Scoring was too harsh

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.

Six of thirty, and not the best six

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.

AND and OR aren't enforced

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 copy can leave things out

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

Built to be cheap, predictable, and reusable

Order checks by cost

Free checks run first, a small model screens titles, and the full scoring call only sees roles that could still be a fit.

One call per role

Scoring and fact extraction happen in the same Claude call, so each role costs one read, not two.

Budgets and a queue

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.

Everything personal in one file

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.

LinkedIn's public pages, as an opt-in

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

Runs on the subscription I already have

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

Live and in daily use

Live
  • Runs every morning on GitHub Actions
  • Public template with a demo digest and setup guide
  • Offline self-test with 51 checks

What’s next

A few weeks of tuning

Planned next
  • Adjust search depth and scoring notes from real digests
  • Read more company job boards directly

Explore the work

Run your own

The template has everything except my config and resume. Add yours, set five secrets, and it runs every morning.

Next in the set

Featured build

In Development
PokeJudge console output for a late-arrival scenario with a clarifying question and grounded recommendation.

PokéJudge AI

An AI rules assistant that asks the right questions before it recommends a cited ruling.

  • C#
  • .NET
  • RAG / Retrieval

Case study 1 of 5. Up next: PokéJudge AI.

Featured build

In Development
Loot Singles order detail screen showing sample-order cards and their set, condition, variant, and quantity details.

Loot Singles Fulfillment

A set-aware picking app built to prevent wrong-card mistakes and order collisions.

  • React
  • TypeScript
  • C#

Let's connect

If you're hiring, have a project in mind, or want to talk shop, I'd love to hear from you.

Email Me