What changed, and why
The Judge of Craft grades a player's dispatch before the dice roll, on writing quality alone, into one of five grades — masterful / sharp / sound / vague / reckless. The grade tilts the D20 (±2) and scales the turn's gain (up to ×1.45). It is the player's skill lever.
The rubric capped that lever. It told the model the top grades were rare — "the top few percent" (masterful), "uncommon" (sharp), and "'sound' should be by far the most common grade." That language was calibrated for the old three-axis composite Judge; issue #162 narrowed the Judge to writing craft alone, so the rarity quota became pure downward miscalibration. The measured cost: masterful came back roughly 1-in-98 in playtesting — players trying to maximize craft essentially never reached it, so the +2 modifier and ×1.45 gain at the top of the craft economy were dead reward surface.
This PR loosens the rubric so genuinely excellent writing can reach the top at a meaningful rate, without losing the grader's ability to tell vague from sharp. The blast radius is small: five edits to one prompt string, plus eval and test instrumentation to prove the new distribution and a joint expected-value re-check with the sibling change #166. No game mechanic, swing band, or model route moved.
The rubric, loosened
The whole behavioral change lives in buildJudgePrompt. Two spots: the opening stance (line 297) and the grade definitions (308–314). Read them at HEAD — the old rarity phrasing is gone, replaced by quality language.
The reframe is quality-defined, not quota-defined. The opening now says "be exacting but not stingy … the top grades are earned, not rationed." Each grade describes what the writing looks like — masterful is "give it whenever the writing truly reaches that bar," sharp is "reach for it when the writing earns it" — instead of how often to hand it out. The closing line, which used to set the "sound" quota, is now a two-way discrimination rule: don't collapse excellent writing into "sound" to keep the top rare, and don't lift an ordinary ask into "sharp."
The opening stance and the five grade definitions, at HEAD.
server/utils/prompt-builder.ts · 592 lines
⋯ 296 lines hidden (lines 1–296)
⋯ 10 lines hidden (lines 298–307)
⋯ 278 lines hidden (lines 315–592)
Measuring the new distribution
"Validate by eval, not vibes" is the issue's instruction, so the calibration sweep in evals/judge-tune.eval.ts gained two measurements. The sweep grades six authored ladders (each four dispatches, best→worst) with both Haiku and Sonnet.
First, the result shape grew two fields: topMods (every modifier graded on a rung-0 authored-excellent dispatch — the reachability sample) and hardViolations (fairness-floor breaches).
The two new fields on the per-model result.
evals/judge-tune.eval.ts · 145 lines
⋯ 34 lines hidden (lines 1–34)
⋯ 100 lines hidden (lines 46–145)
They're filled inside the existing grading loop. The rung-0 dispatches feed the reachability sample; the floor counts a top rung read reckless or a bottom rung read masterful — the bake-off's fairness gate, re-measured here so one cheap run is the whole #167 read. A small helper turns the sample into a legible "masterful X% · sharp+ Y%" string.
Collecting the reachability sample + the floor, and the readout helper.
evals/judge-tune.eval.ts · 145 lines
⋯ 71 lines hidden (lines 1–71)
⋯ 53 lines hidden (lines 93–145)
The sweep then records three new rows: top-tier reach per model, and the discrimination floor — the one row that can fail (soft-miss) if either model ever breaches a fairness floor.
The recorded rows: reachability (read the rate) + the floor (the gate).
evals/judge-tune.eval.ts · 145 lines
⋯ 119 lines hidden (lines 1–119)
The joint EV re-check with #166
The issue is explicit that #167 must be balanced with #166 (the craft loss-shield), since both strengthen the craft channel — tune them independently and skilled play gets over-buffed. The key fact that makes this safe: **#167 changes how often a grade is earned, never what a grade pays.** No swing band moved. So the joint re-check reduces to one property — the realized-EV gradient between mastery and sloppiness must stay wide, so a more-reachable top can't become a cakewalk. That gradient is now pinned as a unit test.
Masterful realizes ~+21/turn, reckless ~−10 — a ~30-point gap, pinned ≥20.
tests/unit/utils/swing-bands.spec.ts · 194 lines
⋯ 131 lines hidden (lines 1–131)
⋯ 31 lines hidden (lines 164–194)
The evidence
Both sweeps ran live against the real models (Haiku is the production route; N=3 × 6 ladders). The before is the unchanged prompt; the after is this PR. Full write-up in evals/results/2026-06-27-judge-calibration-167.md.
| Metric (rung-0 = genuinely-excellent) | Baseline | After |
|---|---|---|
| Haiku masterful reach | 0/18 (0%) | 3/18 (17%) |
| Haiku sharp+ reach | 18/18 (100%) | 18/18 (100%) |
| Haiku anchor mean-dev | 0.25 | 0.15 |
| Haiku middle-rung exact | 21/36 | 28/36 |
| hard violations (both models) | 0 | 0 |
Masterful went from dead (0%) to the issue's target band (17% of genuinely excellent dispatches) on the live route. sharp+ held at 100%. The fairness floor stayed at zero breaches. And the harsh-middle the retune notes flagged — Haiku reading authored-"sound" as vague — got better (mean-dev 0.25 → 0.15, exact 21 → 28/36), a bonus from the "lands here unless it rises above it" wording. The standing gate sharp ≥ vague (in behavior.eval.ts) still holds with a clean two-point gap.