Scoring resumes (3-gate funnel)
A resume is not done until it has passed an independent 3-gate funnel and the scorecard is recorded.
The gates mirror hiring: recruiter -> staff engineer -> hiring manager. Each is a different eye that
judges only what it can perceive. All personas, rubrics, weights and thresholds live in
config/scoring_panel.yaml — use it verbatim; do not hard-code them here.
Principles
- A blank slate, every time. One subagent per gate, each in a fresh context: it has never seen this candidate and
meets them for the first time through the resume alone. It is given ONLY the JD, the resume text and its own
read_mode/rubric. Never pass our fit analysis, decision notes or a previous score (anchoring). - Different eyes, different rubrics. Do not hand the three gates one shared rubric.
- Do not average. The verdict is the worst tier, tagged at the earliest failing gate; the tracking number is the minimum gate score. A recruiter's 65 and a hiring manager's 82 average to a comfortable 73.5 — but the resume died at the first gate and the HM never sees it.
- Judge what is readable, not what is true. A reviewer meeting a stranger's resume has no ground truth, so it scores how convincing the document is — an inflated claim just fails to convince. Truthfulness is the author's responsibility: that is why this repo never fabricates experience (see the build skill).
- Score the real document. Extract text from the built
.docxonce, check it is non-empty, and pass it inline to all three gates (a gate given an empty read will hallucinate and score garbage). - Findings are not edits. Acting on a finding must never fabricate. A JD keyword needs a backing bullet from real experience; otherwise it is an honest gap.
Process
- Load
config/scoring_panel.yaml. - Gather inputs: the JD (from the record), the extracted resume text, confirm it is one page.
- Dispatch the three gates in one message (parallel), each built from
reviewer-prompt-template.md. - Compose: tier each gate from its own
pass/borderline; verdict = worst tier at the earliest gate (NO@recruiter,BORDERLINE@hiring_manager, orPASS); tracking number =min(gate totals); consensus = what >= 2 gates flag independently; classify each deduction fixable vs inherent. - Write a
## Scorecardsection into the application record (format below) and a line in its log.
Scorecard format
## Scorecard — YYYY-MM-DD (resume: <output>.pdf)
**Funnel: Recruiter ✅ NN → Staff ⚠️ NN → HM ❌ NN → NO@hiring_manager**
**Weakest gate: NN/100**
| Gate | Score | Sub-scores | Verdict |
|---|---|---|---|
| Recruiter | NN/100 | stack NN/45, seniority NN/30, scan NN/25 | ✅ |
| Staff eng | NN/100 | tech NN/35, projects NN/30, jd NN/35 | ⚠️ |
| HM | NN/100 | job NN/65, level NN/35 | ❌ |
**Probe list (staff):** 1) … 2) … 3) … **Risk memo (HM):** …
**Consensus (>=2 gates):** …
**Deductions:** fixable: … · inherent (interview narrative): …
**Ranked next edits:** 1) … 2) … 3) …
Common mistakes
- Anchoring the gates with our own analysis or an earlier score.
- Averaging the three scores.
- Asking a reviewer to grade truthfulness (it can only grade persuasiveness).
- Letting a gate deduct for things the application form asks separately (see
out_of_scopein the config). - Treating an inherent gap as fixable by rewording.
- Raising the score by fabricating.