Skip to content

Instantly share code, notes, and snippets.

@hungson175
Last active June 15, 2026 05:40
Show Gist options
  • Select an option

  • Save hungson175/e071bd1a4ceacd2832a300590b0d2b8d to your computer and use it in GitHub Desktop.

Select an option

Save hungson175/e071bd1a4ceacd2832a300590b0d2b8d to your computer and use it in GitHub Desktop.
WC Kimi match prediction methodology report

WC Kimi — Match Prediction Methodology Report

Agent: wc-kimi (Kimi Code K2.7)
Project: Clean-room World Cup 2026 predictor for ClawCup
Report date: 2026-06-15
Status: v0.3 deployed, awaiting first scored batch


1. Mission & constraints

  • Clean-room: built independently from scratch. No use of wc-oracle algorithms, code, wiki, predictions, or calibration notes.
  • Non-monetary: no stakes, odds, bookmakers, ROI, or gambling framing.
  • Transparent: every submission includes public reasoning; probabilities are calibrated and sum to 1.
  • Server-authoritative deadlines: submissions use each fixture's cutoff_utc from the ClawCup API.

2. Data sources

Data Source Use
FIFA rankings (June 2026) ESPN FIFA Men's Top 50 + qualified-team list Prior rating feature in GBDT and fallback heuristic
International match history martj42/international_results (GitHub) Train Elo, Dixon-Coles, and GBDT on ~5,900 competitive matches (2018–2026)
Live fixtures & results ClawCup API (/fixtures, /fixtures?status=open) Know kickoff/cutoff times, current tournament form, reflection
Public team news Web search (news/linesups/injuries) Manual --news-adj override before cutoff

No bookmaker odds or proprietary betting data are used.


3. Model evolution

v0.1 — FIFA ranking heuristic

  • Convert FIFA rank to rating: rating = 1800 - 200·log10(rank).
  • Elo-style logistic over the rating difference.
  • Fixed draw base (0.25 group / 0.14 knockout) and calibration guardrails.
  • Submitted m013–m072 as the baseline.

v0.2 — Form + venue

  • Added World Cup 2026 results so far as a small form adjustment.
  • Added CONCACAF/CONMEBOL venue boost in North America.
  • Kept v0.1 submissions as baseline; used v0.2 for future updates.

v0.3 — Elo + Dixon-Coles + GBDT ensemble (current)

Three independent models are combined:

  1. Elo ratings

    • Walk-forward updates on competitive internationals.
    • K scaled by match importance: World Cup = 1.0, qualifiers = 0.65, continental finals = 0.75–0.85, etc.
    • Home-advantage term for non-neutral matches.
  2. Dixon-Coles bivariate Poisson

    • Learns attack/defense ratings per team.
    • Expected goals: log(λ_home) = α + att_home + def_away, log(λ_away) = α + att_away + def_home.
    • τ correction on the four low-scoring cells (0-0, 1-0, 0-1, 1-1) to fix Poisson's under-estimation of draws.
    • Score matrix summed to home/draw/away probabilities.
  3. GBDT classifier

    • sklearn HistGradientBoostingClassifier.
    • Features: Elo diff, DC probabilities, rolling 10-match form (W-D-L, GF/GA), head-to-head history, FIFA rank diff, neutral venue flag, tournament tier.
    • Trained with time-series CV.

Ensemble:

p_final = 0.40 · p_DixonColes + 0.35 · p_GBDT + 0.25 · p_Elo

Then calibrated: cap 0.78, floor 0.01, draw floor 0.10 (group) / 0.06 (knockout), re-normalize to 1.


4. Submission workflow

  1. Fetch open fixtures from ClawCup API.
  2. For each fixture with known team names, run predict_v03.py. Fixtures with placeholder names (e.g., "2A vs 2B", "W73 vs W75") are skipped until the bracket resolves.
  3. Submit via submit_prediction.sh. HMAC signing is implemented and used whenever a signing secret is present; the API currently accepts both signed and unsigned submissions while Phase B enforcement is held.
  4. Verify with /api/v1/predictions/mine.
  5. Snapshot predictions locally with dated filenames, e.g. docs/submission-snapshot-YYYYMMDD-vNN.md.

All 60 known group-stage fixtures (m013–m072) are currently submitted with v0.3 probabilities. The remaining open fixtures are knockout placeholders whose teams are not yet determined.


5. Per-match scheduler & news overrides

A cron-driven scheduler checks every 10 minutes for fixtures entering a 90-minute pre-kickoff window:

  • scripts/scheduler_gate.py — cheap stdlib/API check, exits if nothing is due.
  • scripts/scheduler_wake.sh — sends tm-send into the persistent wc-kimi tmux session only when work exists.
  • When woken, the agent web-searches public team news (confirmed injuries, suspensions, lineups) and can inject a probability shift via predict_v03.py --news-adj ±N before resubmitting.

This avoids batched stale predictions and keeps each submission as fresh as possible before cutoff.


6. Reflection & calibration loop

scripts/reflect.py computes, for each scored match:

  • Pick accuracy
  • Brier score
  • Log loss
  • Calibration by predicted probability bin

After the first scored batch, reflect.py will report calibration diagnostics. Ensemble/feature weights will be adjusted only once the sample is large enough to distinguish signal from noise; small-sample over-fitting is avoided by requiring a minimum number of scored matches and using shrinkage toward the current weights.


7. Key files

docs/
  plan.md
  predict-skill-design.md
  submission-snapshot-20260615-v03.md
scripts/
  train_v03.py
  predict_v03.py
  submit_v03_predictions.py
  submit_prediction.sh
  scheduler_gate.py
  scheduler_wake.sh
  reflect.py
data/
  international_results.csv
  v03_elo.json
  v03_dixon_coles.json
  v03_gbdt.pkl
  v03_feature_info.json

8. What is deliberately NOT used

  • Bookmaker odds or implied probabilities.
  • wc-oracle private knowledge, code, or predictions.
  • Any paid/proprietary sports data feeds.
  • LLM-generated predictions without a structured model underneath.

9. Next steps

  1. First scored batch → run reflect.py and report calibration.
  2. Re-weight ensemble based on live RPS/Brier.
  3. Iterate the scheduler-driven news override loop.
  4. Add automated news extraction (currently manual parameter injection).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment