Part 3 of 7 · Applicant screener series ~5 min read

How an applicant gets scored

An application reaches the reader as stripped text and a role. The reader’s job is narrow on purpose: for each must-have in the rubric, decide whether the resume meets it, and quote the line that proves it. That checking is the one place a model earns its keep. But the model never picks the label. Plain Python counts how many must-haves were met and compares that to your pass marks. The cut-off is yours, and it’s the same for every applicant.

Key takeaways

  • The reader checks one must-have at a time and quotes the resume line that meets it, or marks it missing.
  • The yes/maybe/no label is plain Python — it counts met must-haves against the pass marks in your rubric.
  • Your pass marks set the cut-off. Change a must-have or a pass mark in the doc and the next score uses it.
  • Every score is saved with the per-must-have reasons, so a human can check the reasoning later.
  • The model reads the resume; it never decides who passes. The rules do that.

The scoring flow, per applicant

Scoring flow per applicant A vertical flow diagram. At the top, an input box "Stripped resume + role" holding the resume text with personal fields removed and the role applied for. Below that, a step "Load rubric for role" — pulls the must-haves, nice-to-haves, and pass marks from the role's doc. Below that, a step "Reader checks each must-have" — Bedrock Haiku 4.5 reads the text and, for each must-have, returns met or missing plus the quoted resume line that proves it. Below that, a step "Count met must-haves" — plain Python tallies how many must-haves were met. Below that, a check "Compare to pass marks" — the count is compared to the yes mark and the maybe mark from the rubric; at or above the yes mark routes to Yes; at or above the maybe mark routes to Maybe; below routes to No. Each terminal box — Yes, Maybe, No, and a fourth Needs-human box for anything the reader couldn't read cleanly — carries the per-must-have reasons. Every result is written to DynamoDB with the count, the label, and the quoted reasons. A note at the bottom: the model reads and quotes; your pass marks decide — change a mark in the doc and the next score uses it. Stripped resume + role skills · history · no personal fields Step 1 Load rubric for role must-haves + pass marks Step 2 Reader checks each must-have Haiku 4.5: met/missing + quote Step 3 Count met must-haves plain Python tally Step 4 Compare to pass marks below mark → no can’t read → needs human Step 5 Attach the reasons write result to DynamoDB No parked, reviewable Maybe met the maybe mark Yes met the yes mark Needs human couldn’t read cleanly if unreadable below yes mark maybe yes The model reads and quotes; your pass marks decide — change a mark and the next score uses it.
Fig 3. The scoring flow, per applicant. The reader checks each must-have and quotes the proof; plain Python counts and compares to your pass marks; the result lands on yes, maybe, no, or needs-human. The rubric holds the cut-off; the code only enforces it.

What the reader actually does (and doesn’t)

The reader is one Bedrock Haiku 4.5 call per application. The prompt is tight: here is a resume (stripped of personal fields), and here is a list of must-haves. For each must-have, say whether the resume meets it, and if it does, quote the exact line that shows it. If it doesn’t, say so. Return a small structured result and nothing else. Do not invent experience that isn’t written down. Do not consider anything outside this list.

That last instruction matters. The reader is told to judge against the must-haves and only the must-haves. It is not asked for an overall impression, a gut feel, or a ranking. Those are exactly the judgments where bias slips in. By keeping the model’s job to “does this line meet this requirement, yes or no, show me the proof,” the output is something a human can check in seconds rather than a score they have to trust.

Your pass marks, not the model’s

Once the reader returns which must-haves were met, the model’s job is done. Plain Python takes over. It counts the met must-haves and compares that count to two numbers from your rubric: the yes mark and the maybe mark. If you wrote “all four must-haves earns a yes; three earns a maybe,” then four met is a yes, three is a maybe, and two or fewer is a no. That’s the whole rule. No weighting magic, no hidden model judgment, no surprise.

Putting the cut-off in plain Python and plain numbers is deliberate. It means the same resume always gets the same label. It means you can change the bar — tighten it when you have too many yeses, loosen it when the role is hard to fill — by editing one line in a doc. And it means when somebody asks “why was this person a maybe and not a yes,” the answer is a number you can point at, not a model you have to defend.

Some must-haves are genuinely non-negotiable — a license the law requires, a shift the job can’t flex on. The rubric can mark those as required. A required must-have that’s missing caps the label at no regardless of the count. Even then, the candidate isn’t deleted — the no is parked in a reviewable list, with the missing required item shown, so a human can still look and override if the resume simply didn’t mention it.

When the reader isn’t sure

Resumes are messy. Sometimes the text came out garbled from a bad scan. Sometimes a must-have is borderline — the resume says “managed a small team” and the must-have is “managed a team of 10+,” with no number given. The reader is told that “not clearly met” is not the same as “met,” and that a missing number is a gap, not a pass. But it’s also told to flag the borderline ones rather than guess.

Anything the reader couldn’t read cleanly, or where a key must-have was truly ambiguous, lands in a small needs-human pile instead of being forced into yes, maybe, or no. A person looks at those directly. This is the safety valve: the system would rather ask a human than make up an answer, because a made-up “no” quietly closes a door that should have stayed open.

Every score is explained, and saved

For each application, the result written to DynamoDB has four things: the label, the count of met must-haves, the per-must-have reasons (met or missing, with the quoted line), and a stamp of which rubric version was used. That record is what the hiring manager sees on the candidate card in the next post, and it’s what an audit reads months later. There is no part of the score that isn’t written down and tied to a job-related requirement.

Next post: how a strong match reaches the hiring manager — the short summary, the four guardrails before routing, and the human review step that sits between a score and any decision.

All posts