How matching works — ranked on your machine, explained in plain terms
When you run jpi jobs, nothing about you is sent anywhere to be matched.
Your machine downloads a public index of jobs, and the ranking runs locally,
against a profile that never leaves your computer. This page explains what
that ranking actually does — no formulas, no hand-waving. (Engineers who want
the formulas: the technical design of record lives in the repo at
docs/matcher.md.)
The two halves
On our side, we collect public job postings from the sources you'd check yourself (Greenhouse, Ashby, Lever, Workable, Hacker News, remote boards, open-source bounties) and label each one with the skills it's really asking for. That labeled index is public — it contains nothing about you.
On your side, the CLI builds a profile from your own git context: the languages and tools you demonstrably work with, plus anything you declare. The profile and the downloaded index meet on your machine, and the match score is computed there — no network needed to rank. Same profile, same index, same day — same ranking. (The one thing that moves on its own is freshness: a posting ages across the one-week and one-month marks, so rankings can shift slightly as time passes, not because anything was recomputed elsewhere.)
A closed dictionary of skills
Every skill — yours and the job's — must resolve to one of a few hundred
curated, canonical terms (ts counts as typescript; a word we don't
recognize is simply dropped). That sounds restrictive, and it's deliberate,
for two reasons:
- Privacy. Your profile can only ever contain terms from that dictionary. There is no free text in it — nothing that could carry your name, your employer, or anything else identifying.
- Honesty. There's nothing to keyword-stuff. A posting (or a profile) can't game the ranking with buzzwords the dictionary doesn't know.
The dictionary isn't a flat list — it knows how skills relate. It knows Next.js implies React, that Vue and React are neighbors, that FastAPI experience says something real (but not everything) about a Django role. So you get partial credit for adjacent skills: strong credit up a chain (Next.js → React), weaker credit sideways (React → Vue), and credit fades fast across bigger gaps so a near-miss never beats the real thing.
The score, in words
A job's score is mostly about fit in both directions:
- How much of what the job asks for do you cover?
- How much of your stack does the job actually use?
Both have to be true. A role that would use two of your fifteen skills isn't
a great match even if it needs nothing else; neither is a role that wants
twenty things and grazes one of yours. And rare skills count for more than
common words — matching on rust says more than matching on backend.
Two smaller factors round it out: seniority alignment (a staff role and a junior profile don't pretend to fit; adjacent levels are close, not equal) and freshness (this week's posting outranks last quarter's; a posting with no date is treated as middling, not punished).
What never happens
A few guarantees are built into the math itself, not bolted on as filters:
- No skill overlap, no result. A job can never appear just because it's senior and recent. If you share no real skill with it, its score is zero.
- Wrong center of gravity gets demoted. If a title names its defining skill — "Senior Rust Engineer" — and you have neither that skill nor a neighbor of it, matching on the incidental stack (Docker, Kubernetes) gets sharply penalized. Infrastructure overlap doesn't make you a Rust dev.
- Interests widen, they never inflate. If you declare an interest in a topic, that can surface more hybrid roles — but an interest is capped well below a proven skill, never shows up as evidence you matched, and never lowers anything else.
- Your hard filters are hard. Remote-only, role type, and salary floor are applied before scoring, not traded off against a good score. (A job with no salary data isn't rejected — missing data isn't evidence of low pay.)
Why the results can explain themselves
Because the dictionary tracks why two skills relate, every match can show its work: "Matched on fastapi→django, python + 2 more." That's not a summary written after the fact — it's the actual evidence the score was computed from.
Proof of work, and what it doesn't do
If you've built your Proof of Work credential, jobs where you have real merged contributions in the role's domain show a badge — and when two jobs score a near-dead-heat, the one where you have receipts wins the tie. That's all it does to the ranking: a tiebreaker among equals. It never lifts a weak match over a strong one.
What "strong match" means
Some surfaces (like the peer directory) only show matches above a fixed "strong" bar. That bar wasn't picked to feel right — it was measured: on a hand-labeled test set, every genuinely strong match scores above it and every plausible-but-wrong decoy scores below it, and an automated test fails if that ever stops being true. Because scores don't depend on how many jobs are in the pool, the bar means the same thing on everyone's machine.
Honest limits
The closed dictionary is a trade. If you work in something genuinely brand new, it may not be in the vocabulary yet — you can still declare it, and it's kept as a visible signal, but it won't influence ranking until it's added properly (that's a deliberate gate, so the ranking input stays curated). Postings with vague, buzzwordy descriptions also match less well than well-specified ones — which we'd argue is the system working.
Every change to the ranking is run against a frozen, hand-labeled test set before it ships, so "we tweaked the algorithm" can't quietly make your results worse.