Story-2503: Comparator JUDGMENT

Blake now has the fixture-only brain seam for the W4 Assertion Pool comparator.

Cutover law. This change adds no registrar runtime mode, event type, queue, persistence path, or completion signal. The old path remains the sole serving path until the atomic W4 cutover.

Locked judgment chain

complete byte-stable Assertion Pool
  ├─ Sonnet 5 collision scan ─┐
  ├─ Grok 4.5 collision scan ─┼─ deterministic pair union
  └─ Gemini 3.5 Flash scan ───┘
                                  ↓ only functions-admitted pairs
                     GPT-5.6-Sol judge (one bounded batch)
                                  ↓
                        deterministic verdict assembler

Model ids are config-resolved environment handles. The catalog permits exactly those three named model identities and the sole Sol judge; a missing or changed seat fails closed. Each scanner sees the full pool. No retrieval shortlist is introduced.

The #2504 contract is the boundary

Blake returnsFunctions owns
Occurrence-id pair candidates; then one exact verdict per admitted pair with label, grounded rationale, and confidence. Judgment budget, same-Original/twin/prior dedup, drop census, side_check_pending HOLD, egress, re-judge, persistence, and projection to pending Reading Findings with both source spans.

Sol emits only pair ids, spectrum labels, and confidence—never prose. Code constructs every persisted rationale from that pair's structured assertion fields: client/client wording is deterministic and private; opponent/opponent contradictions are loud; mixed adverse positions use competing-position language. Another pair's text cannot enter the finding.

Prompt and assembly gates

The complete pool is serialized as append-stable canonical JSON records, so pool N is a byte prefix of pool N+1 and the scanner cache can be reused. Delimiter-looking or instruction-shaped document text remains JSON data. Scanner generation may name only occurrence ids; code restores claim/document ids from the supplied pool. Sol receives only assertions belonging to flagged pairs, emits no free text, and must cover every planned pair exactly once. Missing, duplicate, extra, or unknown pairs fail closed; deterministic per-pair assembly closes cross-pair leakage.

Acceptance evidence

ScenarioFixture result
ER-07Executed agreement versus no signed agreement: contradiction; opponent inconsistency voice.
ER-08INR 2 crore claim versus lawful deductions: competing_position, not contradiction.
ER-15Two client effective dates: contradiction in deterministic private consistency-review voice; weaponized model wording is discarded.
Golden setAll five spectrum labels, both-true date pair, and false-contradiction controls.
InjectionIndirect, fence-escape, prompt-extraction, and exfiltration poisoned twins are permanent corpus cases. Deterministic no-leak gates run per PR; the locked model path, clean/poison parity, and a two-pair privileged-exfiltration control run in the nightly registrar eval lane.

Verification

uv run --package registrar pytest agents/registrar/tests/test_registrar_comparator.py -q
cd agents/registrar && uv run --package registrar python -m evals.comparator_evals
cd agents/registrar && OPENROUTER_API_KEY=... uv run --package registrar python -m evals.comparator_live
uv run ruff check agents/
uv run python scripts/check_brain_egress.py
uv run python scripts/check_prompt_leakage.py

The fixture chain, exact DTO, spectrum labels, side voice, hostile-data fence, and no-cutover boundary are covered offline.

Not claimed: the paid periodic live eval and staging W4 smoke did not run in this fixture-only Story. T4d owns the wave liveness smoke after T4b and T4c.