# Data validation - the cricket data behind db-mcp.tigzig.com

All 12 checks passed. Last run 21 Aug 2026, 17:00 IST (11:30 UTC).

The cricket data served by https://db-mcp.tigzig.com is checked on a schedule and
every result is published, pass or fail. The battery runs against BOTH database
engines behind the API and compares them row for row.

## Checks

| Check | What it proves | Result | Both engines | Remarks |
|---|---|---|---|---|
| `matches_without_balls` | Every ODI and T20 match has ball-by-ball data behind it. | PASS | postgres: 3 rows, duckdb: 3 rows | Test matches show no ball data because only ODI and T20 ball-by-ball is served. Expected, not a gap. |
| `negative_or_absurd_runs` | No delivery scores below 0 or above 7 runs. | PASS | postgres: 2 rows, duckdb: 2 rows |  |
| `null_density` | No missing venue, bowler, striker, runs or season. | PASS | postgres: 2 rows, duckdb: 2 rows |  |
| `orphan_balls` | No ball belongs to a match that does not exist. | PASS | postgres: 2 rows, duckdb: 2 rows |  |
| `over_index_bounds` | No T20 innings past over 19, no ODI innings past over 49. | PASS | postgres: 2 rows, duckdb: 2 rows |  |
| `balls_per_over_extremes` | Deliveries per over stay in a plausible range. | INFO | postgres: 8 rows, duckdb: 8 rows | Overs longer than six deliveries are wides and no-balls. The longest on record here is fifteen. |
| `innings_per_match` | Innings counts per match are 1, 2, or a super over. | INFO | postgres: 7 rows, duckdb: 7 rows | The one 8-innings T20 is Netherlands v Nepal, 2025, which went to three super overs. Genuine, not an error. |
| `matches_by_type` | Format mix and per-format date span agree across engines. | INFO | postgres: 3 rows, duckdb: 3 rows |  |
| `recent_matches` | Recent matches are present, so the twice-daily refresh is running. | INFO | postgres: 19 rows, duckdb: 19 rows |  |
| `recent_test` | Test matches are current in the match table. | INFO | postgres: 3 rows, duckdb: 3 rows |  |
| `row_counts` | Both engines hold the same number of rows, matches and date span. | INFO | postgres: 3 rows, duckdb: 3 rows |  |
| `schema_match_info` | The column list and its order have not changed. | INFO | postgres: 24 rows, duckdb: 24 rows |  |

PASS is an assertion that held. INFO is a distribution published for inspection
rather than asserted - deliveries per over and innings per match are legitimately
variable.

## Previous runs

| Run | Checks | Failed |
|---|---|---|
| 21 Aug 2026, 17:00 IST (11:30 UTC) | 12 | 0 |
| 21 Aug 2026, 16:50 IST (11:20 UTC) | 8 | 0 |
| 21 Aug 2026, 16:49 IST (11:19 UTC) | 8 | 1 |
| 21 Aug 2026, 16:40 IST (11:10 UTC) | 8 | 6 |

## What is being checked, and against what

Cricsheet publishes the source data. A pipeline parses it into a master file, and
a refresh job loads that master into the two engines the API serves from. These
checks run at the far end of that chain, against what the API actually returns.

Anything found is published as found. On the first run the two engines disagreed
by one row: a Test match present in one and missing from the other, because the
refresh job's skip test looked only at ball-by-ball data and a Test match adds
none. Fixed, and published rather than quietly corrected.

## Elsewhere

- The API itself: https://db-mcp.tigzig.com/v1/docs
- Everything else on this site: https://www.tigzig.com/llms.txt
