The LLM-as-judge half of the eval program — the piece Kinnari's main implementation plan explicitly defers.
"T3 Judge dimensions and new outcome-focused pillars (P10–P12) are explicitly out of scope for this phase and planned separately." — Kinnari's Evaluation Implementation Plan
This is that separate plan.
Per the current-tooling page, almost everything T3 needs is already in the repo.
| Capability needed for T3 | Already in repo |
|---|---|
| Multi-turn agent driver | ✅ conversation-runner-provider.ts orchestrates scripted candidate turns |
llm-rubric assertion | ✅ Workhorse · default judge openai:gpt-4o-mini · gpt-4o for nuanced |
| Scripted candidates | ✅ JSONL convention: vars.candidate_turns |
| Test corpus | ✅ ~200 cases across ~9 JSONL files in samples/ |
| Letta + Claude provider parity | ✅ Same eval matrix runs both |
| Threshold mechanism | ✅ gates.json (descriptive today — T3 thresholds added once calibrated) |
| Custom JS assertion pattern | ✅ voice-check-banned.js returns {pass, score, reason} |
T3 is purely a registry of llm-rubric assertion files pointing at the existing multi-turn outputs. No new providers, no new conversation infrastructure.
grader_type → promptfoo assertion net-new framingEvery indicator carries a grader_type. For T3 specifically:
grader_type | promptfoo assertion type |
|---|---|
llm_rubric_per_turn | llm-rubric graded on a single agent turn |
llm_rubric_per_transcript | llm-rubric (or trajectory:goal-success / conversation-relevance) on full transcript |
ground_truth | Human-labeled gold (calibration set only — not at runtime) |
Same recipe for all 37 judges. Only the rubric text and the context vars differ.
llm-rubricConcrete example for P4 Push-back craft:
# services/promptfoo-evals/taxonomy-evals/judges/p4-pushback-craft.yaml defaultTest: options: provider: id: openai:gpt-4o-mini # match existing default config: { temperature: 0 } assert: - type: llm-rubric value: | Pillar: P4 Interview Mechanics. Indicator: Push-back craft. Persona: {{alt.persona.summary}}. Candidate background: {{candidate.background}}. Prior turn (flagged textbook): {{candidate.lastMessage}}. Agent: {{agent.message}}. Score 0-2: 0 — accepted textbook answer / moved on 1 — generic challenge ("can you say more?") 2 — specific, in-persona challenge naming the gap JSON: { "score": 0|1|2, "rationale": "<one sentence>", "evidence_span": "<quote>" }
{{var}} interpolation inside llm-rubric.valueprovider override at suite or assertion level (swap to gpt-4o for nuanced judges)temperature: 0 + pinned model for reproducible scoresThe 37 judges in the metrics page don't cover these distinct failure modes. Each uses a specialised promptfoo assertion type, not generic llm-rubric.
| Complement | Why net-new | promptfoo assertion |
|---|---|---|
| Agent-claim groundedness | Distinct from "Rationale traceability" (P6) which grades rubric→verdict. This checks factual claims about candidate / company / persona's past. Catches the hallucination class. | context-faithfulness with contextTransform — pulls alt memory + JD + org corpus into context |
| Founder-verdict alignment | Beyond "agent applied rubric correctly" — would the actual founder agree with STRONG_YES/YES/MAYBE/NO? Ground-truth signal we'll need over time. | llm-rubric with a founder-persona judge prompt; agreement tracked across runs |
| Voice-match bulk triage | P1's 8 judges decompose voice well, but for fast pre-screen across many transcripts an embedding similarity score is cheaper and complements the granular ones. | similar against a gold transcript |
| # | Pillar | Indicator | Source | Why first |
|---|---|---|---|---|
| 1 | P4 | Push-back craft | 37 | Highest leverage on interview quality |
| 2 | P4 | Push-back authenticity | 37 | Pairs with #1 |
| 3 | P4 | Signal sufficiency | 37 | Catches pacing bugs |
| 4 | P5 | Per-candidate question fit | 37 | Catches "generic question" failures |
| 5 | P6 | Rationale traceability | 37 | Verdict-evidence gap |
| 6 | — | Agent-claim groundedness | Net-new | Hallucination — not in 37 |
| 7 | — | Founder-verdict alignment | Net-new | Calibration signal long-term — start collecting now |
services/promptfoo-evals/taxonomy-evals/judges/ with files 1–5 as llm-rubric yamlconversation-runner-provider.ts outputsamples/*.jsonl fixtures (no new test cases needed yet)context-faithfulness, founder-persona llm-rubric)gates.json once baselines existprovider.id + temperature: 0. Rubric text version-controlled with the yaml. Model bump = explicit re-calibration.gates.json integration — T3 thresholds added after week-2 baseline calibration. Until then, T3 results report only.| Decision | Options |
|---|---|
| Default judge model | openai:gpt-4o-mini (current default) · openai:gpt-4o for nuanced (push-back, rationale traceability, founder-verdict) — pin per assertion |
| Judge rubric authorship | One owner per pillar · round-robin · single owner for v0 |
| First wave (5 + 2) | Proposal in §5 — open to swaps |
| κ thresholds | 0.6 advisory · 0.75 blocking, per judge |
When T3 enters gates.json | After baseline calibration · sooner with advisory-only thresholds |
| Outcome pillars (P10–P12, also deferred) | Predictive validity, bias, calibration vs hire-outcome — discuss as a separate v0.1 plan once T3 v0 is shipping |