A fractured identity keeps two bad records from merging. It does not make an
unknown game true. Until now a prop with an unresolved or verified-impossible
event still continued into grading under that synthetic key; it no longer does.
- event_binding_status contract: RESOLVED / UNRESOLVED / AMBIGUOUS /
CONTRADICTED / UNSUPPORTED. CONTRADICTED and UNRESOLVED stay distinct — one
means we know the association is wrong, the other that we do not know.
- ONE admission gate (gradeSlateService.admitForGrading), before dedupe and
before grading. Admission requires RESOLVED *and* a canonical_event_id; a
legacy derived game_id can never satisfy it. Rejected props are returned, not
discarded, so retention keeps them as evidence.
- Roster evidence is now DATE-SCOPED. statsapi honours ?date= and it changes the
answer (Joe Mack is on the 2026-08-26 Marlins roster, absent on 2026-04-15).
Evidence that does not describe the slate's date can only yield UNRESOLVED,
never CONTRADICTED — uncertainty must not become an accusation.
- A mis-nested market is REFUSED, never re-bound. Knowing Joe Mack is a Marlin
does not license moving a provider record into the Marlins game; that would
invent provenance.
Measured on the real 2026-08-26 slate: 2,878 props -> 2,874 admitted, 4 rejected
(EVENT_PLAYER_TEAM_CONTRADICTION), each player's correct game still resolving.
Doubleheader 824514/824478 both remain independently RESOLVED and admitted.
No change to probability, projection, side, grade, confidence, ranking,
normalization or calibration. Lineage remains disabled.
Suite 380/5,061/0 from the release worktree; web tsc exit 0.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CQJeAG8vcDoL5zkiaJyVb8
Release-isolated slice built from 41ba38e. Ships ONLY the event-integrity +
publication + lineage-canary closure; the 90-path development tree stays
undeployed.
- canonical MLB event identity from statsapi gamePk (mlb:gamepk:<pk>), with
event_identity_source/method/version recorded. The id is canonical; the
binding is derived and says so.
- IMPOSSIBLE-BINDING REFUSAL. Verified in prod 2026-08-26: Joe Mack (Marlins)
was bound to Dodgers@Braves and Yandy Diaz (Rays) to Rangers@WhiteSox, both
from one book in the 01:00/03:01 UTC cycles after their own games began. Root
cause is source market data, not the binder. A prop whose player's team is not
an event participant now refuses; unknown team preserves uncertainty.
- event-aware dedupe: books still collapse, events no longer do. An unresolved
MLB event fractures rather than falling back to the collision-prone
date+teams key.
- publication commit moved AFTER the authoritative Redis slate write, with
exact parity-gap identity when the product publishes and the record does not.
- lineage dual-write behind LINEAGE_CANARY_SPORTS, DISABLED for this deploy.
Excluded deliberately: WNBA feed/chain, market ontology, PerformanceDistribution,
calibration certification, truth diagnostics, applyRevision Phase-1, and the
analyzeViaEngine1 confidence-rounding change (a served field).
Suite 380/5,040/0 from this worktree; web tsc exit 0; champion output identical
to production.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CQJeAG8vcDoL5zkiaJyVb8