Skip to content

Latest commit

 

History

History
53 lines (45 loc) · 3.34 KB

File metadata and controls

53 lines (45 loc) · 3.34 KB

Workflow — Referee layer ("research referees" / "add the referee")

Profile match officials and wire their tendencies so the bot prices the ~205 cards/fouls/penalty questions on who is officiating, not just the teams. Dry-run by default.

All 52 FIFA-2026 head referees are already profiled in ../referees/ (stats.json = source of truth, profile.md generated). This runbook covers assigning a referee to a fixture and refreshing/adding a profile.

A. Assign a referee to a fixture (the common task)

FIFA names each match crew ~24-48h before kickoff.

  1. Find the fixture slug: python -c "from bot.data.odds import fixture_slug; print(fixture_slug('KOR','CZE'))"south-korea-vs-czechia.
  2. Add it to ../referees/assignments.json:
    {"assignments": {"south-korea-vs-czechia": "<referee-slug>"}}
  3. Add the fixture to that referee's stats.json assignments array, regenerate the profile (step C), and link it from games/NNN-*/game.md §7.
  4. Score: python -m bot run --offline --today — the assigned ref now tilts the cards/fouls/ penalty markets (visible in predictions/<date>.jsonl as the referee field).

B. Research / refresh a profile

For each referee, gather per-match (both teams) tendencies with cited sources (statshub, valuestats, footymetrics, worldreferee, transfermarkt):

  • yellow cards/match, red cards/match, penalties/match, fouls/match, 2nd-half card share
  • crew (2 assistant referees + VAR + 4th official), style, strengths, weaknesses, market strategy Set confidence (high/medium/low) by sample size & source quality. Honest nulls where unverified — never guess. Thin samples → low confidence → the ensemble shrinks the tilt.

C. Write + validate + generate

  1. Edit referees/<slug>/stats.json (schema: schema/referee_stats.schema.json).
  2. python scripts/validate_referee_stats.py # must be clean
  3. python scripts/gen_referee_profile_md.py # regenerates profile.md (never hand-edit it)

How it scores

The bot scales each team's card/foul λ by referee_rate / competition_avg (clamped 0.65-1.5) and sources penalty/red rates from the referee. A strict ref lifts total card/foul and penalty markets; "more cards than opponent" comparisons barely move (both teams rise together).

comp_avg.yellow_per_match MUST be the referee's real domestic-league average — not the flat 3.8 default. The tilt is ref_yellow / comp_yellow; a global 3.8 denominator re-encodes domestic card inflation (CONMEBOL / La Liga / Liga I refs price 1.15-1.41× by league culture, not strictness) and hurts the backtest (proven: flat-3.8 on all 36 settled refs dropped RBP 868.5→811.5, cards +77→+20). Run python scripts/enrich_referee_comp_avg.py (documented per-league map, research/RESEARCH_referee_data.md §2) so the tilt measures genuine strict-for-their-league. WorldReferee international samples are the best WC-context prior (≈0.75× domestic for card-heavy leagues).

Guardrails

  • Dry-run — never --submit without explicit go-ahead.
  • Cite every number; low confidence for thin samples (Brier punishes confident-wrong).
  • stats.json is the source of truth; profile.md is generated.
  • The head referee is modeled; ARs/VAR are documented for completeness, not given fabricated rates.