A job fit checker on a model that never writes

TypeSafe's Jev answers typed questions with probabilities and cannot generate a sentence. I built a job fit checker on it in a weekend. The interesting part was every place I expected to need text generation and did not.

TypeSafe shipped a model called Jev that cannot write. You hand it some state and a set of typed questions, and it hands back a probability for each answer. No prose, no JSON to parse, no output tokens to pay for. I wanted to know what you could build on a model like that, so I built JobFit: paste a job posting and your CV, and every requirement in the posting gets scored against your experience. The code is on GitHub.

Fill the example, run the check, and the review card fills in with the near misses listed first.

What the model actually returns

Jev takes three kinds of question. A boolean returns the probability the answer is true. A choice picks one option from a set you define and returns the probability of every option. A score rates the state on a ladder of rungs you write, and returns an interpolated float like 2.97 plus the spread across rungs. Through the AI SDK it is one call:

ts
const { answers } = await evaluate({
  model: 'typesafe-ai/jev',
  state: { requirement: line, candidateCV: cv },
  questions: {
    met: {
      type: 'boolean',
      instructions: 'Does the CV provide evidence the candidate meets this requirement?',
    },
    strength: {
      type: 'score',
      instructions: 'How strongly does the CV evidence this requirement?',
      criteria: [
        'the CV shows nothing relevant to this',
        'the CV shows adjacent or transferable experience',
        'the CV clearly meets this',
        'the CV goes well beyond this',
      ],
    },
  },
});

answers.met.probability; // 0.53
answers.strength.score;  // 1.05

The first thing that tripped me up was that a boolean never returns true or false. It returns 0.99, or 0.53, and collapsing that to a decision is your job. That felt like a missing feature for about ten minutes and then it became the whole product. A requirement with met at 0.96 and one at 0.53 are not the same kind of yes, and a normal language model would have given me the word yes for both.

The bucket that only exists because of probabilities

Every CV matcher I have seen gives you a list of what you have and what you lack. That is not what you need when you are writing a cover letter. What you need is the list of requirements where you have something adjacent but the posting does not obviously match your wording, because those are the sentences worth writing. JobFit sorts requirements into three groups: clearly met above 0.7, not evidenced below 0.3, and worth addressing in between. The middle group comes first on the page. It is the only reason the tool is worth opening, and it cannot exist without a model that reports how sure it is.

Extracting requirements without generating anything

The obvious design is to ask a language model to read the posting and list its requirements. Jev cannot do that, and I wanted to see how far the pure version would go. So the posting is split on newlines and sentence boundaries, and each fragment is sent with the same call as its own question: is this a concrete skill, qualification or requirement for the role? Headings, company blurb and the benefits paragraph should score low, real requirements should score high.

I did not guess the threshold. I ran the sample posting with the filter turned off and looked at the distribution. Real requirements landed between 0.68 and 0.90. The job title scored 0.46, the company sentence 0.39, the perks line 0.09. The cut belongs at 0.6, with clear air on both sides. On a very short posting the title can still creep over the line, which I saw once in a production smoke test, so this is a real limit rather than a solved problem.

A scoring bug I would not have caught without looking

The overall fit number was understating everyone. Someone who cleanly met every single requirement scored 67 percent. The cause was the rubric: the top rung is the CV goes well beyond this, so clearly meets this sits at rung two of three, and I was dividing by three. Meeting a requirement now earns full marks and exceeding it earns nothing extra, which is also the honest reading of what a hiring manager wants to know. Essential requirements count double in the aggregate, so missing a must-have hurts more than missing a nice-to-have.

What it cost

Jev is priced at $0.042 per million input tokens and output is free, which is roughly five to two hundred times cheaper than the language models people would normally point at this. A full check on an eight-requirement posting, with the requirement filter and the scoring in the same round trip, is about 7,000 tokens. That is $0.0003. The demo runs on my own gateway credits with a rate limit of two checks per IP per hour, and at that price the limit is there to stop someone being annoying, not to protect a budget.

What I would use it for next

A model that returns a distribution instead of a verdict changes what you can afford to build. You can put judgment in a hot loop: score every output of an agent, gate every tool call, check every file in a repo on a schedule. And because the answer carries its own uncertainty, you can build systems that escalate when they do not know instead of guessing, which is the thing missing from almost every AI product shipping right now. JobFit is a small example of that. Try it at jobfit-omega.vercel.app, and the source is at github.com/Sahilll15/jobfit.