Personal project · 2026
Claim-to-Evidence Scouting
A scouting report makes claims — "creates a lot of chances", "doesn't track runners". This project tests each one against league data and my own video coding, using rules written down before the data is collected.
Status: the engine and a demo on synthetic data are built and tested. The real case study has no data yet.
Problem
In a scouting report, a line like "protests a lot to the referee" may come from one memorable match or from a real pattern, and the reader can't tell which. It is also easy, once the numbers are in, to adjust the criterion until the claim looks confirmed.
Context and motivation
I write player reports from video and wanted to know which of my own claims would survive a test. The idea comes from research practice: fix the method and the claims before looking at the data (pre-registration), and publish every result, including the ones that don't back the report.
What I built
Individual project: the method, the video-coding protocol, the Python engine, the tests, the CI pipeline and the case study.
From claim to verdict
01 Before the data
- player.yaml, claims.yaml, metrics.yaml
- Validated with pydantic
- Rules and minimums fixed (pre-registration)
02 Evidence
- League snapshot (private CSV)
- Official match facts
- My own video coding
- pandera contracts on every table
03 Calculation
- Per 90 minutes and per 100 touches
- Peer group: same positions, minimum minutes
04 Rules
- L — position among peers
- V — video share (Wilson 95%)
- M — majority of matches
- Sensitivity: the weakest result stands
05 Output
- claims.csv and evidence-report.md
- Four figures
- The conclusion is written by the scout
Technical decisions
5Three kinds of rule, chosen by the evidence
L places the player's season value among peers in the same positions (top quarter, above the median, or not). V uses the share of opportunities in my own video coding, with a one-sided 95% Wilson bound and leave-one-match-out checks. M counts the matches in which a behaviour was seen. Each claim uses the rule its evidence allows.
Seven verdicts, including "don't know"
Supported, partly supported, not supported, contradicted, inconclusive, insufficient data and unavailable. "Contradicted" only exists where the evidence can genuinely point the other way. No league verdict is presented as a significance test.
The final verdict is the weakest
Each claim also runs the pre-registered sensitivity checks (stricter peer minutes, possession adjustment, ambiguous video events). If they disagree, the weakest result stands.
Validated configuration, contracted data
Player, claims and metrics are YAML validated with pydantic; data tables have pandera contracts. Adding a player means copying a folder and editing two files — no code changes.
Third-party data stays out of Git
Only synthetic data is committed, and a test checks that. Real snapshots live in a private folder, with source, URL and retrieval date on every row.
What it does
c2e validateandc2e runCLI over a player folder- Per-90 and per-100-touches rates from season totals
- Peer group by position and minimum minutes
- L, V and M rules with sensitivity checks
- Markdown report, verdict table and four figures
- Video-coding protocol and a one-page coding reference
Evidence
what was checked, and how| What | Result | Source | Checked |
|---|---|---|---|
| Automated tests | 97 passed | pytest run locally (hand-worked cases, Hypothesis invariants, golden end-to-end test) | |
| Continuous integration | ruff, mypy, pytest and the demo on every push | .github/workflows/ci.yml | |
| Method status | 1.0-rc1, draft | docs/METHOD.md — frozen at the prereg-v1.0 tag |
Screenshots
2Limitations and next steps
Known limitations
- No real data yet: the engine and demo run on an invented player, teams and matches.
- The method and the claims for the case study (an attacking midfielder/winger in the Greek Super League) are drafts awaiting review before pre-registration.
- League positions are point estimates on small samples; they don't say whether a difference comes from the player, the role or the team.
Next steps
- Review and freeze the method and claims at the prereg-v1.0 tag
- Collect the league snapshot and code the case-study matches
- Publish the evidence report with every verdict

