AI Benchmarking Methodology — How We Test AI Models & Detect Drift
Complete Technical Methodology — Statistically Rigorous, Execution-Based, Continuous Monitoring
Methodology Whitepaper
Public methodology edition, 2026 - measurement framework, benchmark surfaces, statistical interpretation and evidence-to-routing logic, written up for external technical review.
DOWNLOAD PDF13 pages · 136 KB[1] THE 4 BENCHMARK SUITES
CODING SUITE
Frequency: Every 4 hours
Tasks: 6 repo debugging + 1 hard function, all 7 every sweep
Trials: 7 per task, median scored
Scoring: 9-axis evaluation
Purpose: Debugging and coding capability
DEEP REASONING
Frequency: Daily at 3 AM
Tasks: 4 multi-turn scenarios, all four every day (one rotating task a day until 13 September 2026; the daily score is the mean over the four)
Scoring: 13-axis evaluation
Purpose: Complex reasoning tests
TOOL CALLING
Frequency: Daily at 4 AM
Tasks: 9, in real Docker sandboxes
Scoring: 7-axis evaluation
Purpose: Agent capability tests
CANARY SUITE
Frequency: Every hour
Tasks: 2 fixed probes (prime_check, merge_intervals), 2 trials each, 4,000-token answer budget; a trial that errors is not measured, not zero
Detection: Welch’s t-test on two windows — the last 6 h (a severe drop shows within the hour it lands) and the last 24 h (a moderate one six probes cannot separate from noise) — each against the prior 7 days on the same configuration; an incident needs a fall of at least 12 points at p < 0.01, and closes itself when the gap does
Response Time: within the hour
Until 13 September 2026 this suite raised an incident on any 10% fall in a 24-hour mean, with no test of significance, on answers cut off at 500 tokens. The 446 incidents it produced are retracted and excluded from every count on this site. The per-model drift signature had a related fault: its series interleaved the coding, reasoning and tool-use suites (three different scales) across configuration changes, so a reasoning run landing at 01:00 UTC read as a fall of thirty points. Since 13 September 2026 it reads the coding suite on its current configuration only; the 46 provider-wide incidents and 1,145 change points recorded before then came from the old series.
OUTPUT TO DATE
Counted from the database when this page was last generated, not written by hand — the previous figures had drifted thousands of rows behind and stated two different tool-session counts in the same paragraph. Since the first benchmark on 8 August 2025:
→ 182,695 scored benchmark runs
→ 63,719 tool-calling sessions
→ 5,033 deep-reasoning sessions
→ 1,482 drift incidents and change points recorded
[2] 9-AXIS SCORING METHODOLOGY
Each task is evaluated across 9 dimensions. The weight on each is set by how much it can actually distinguish one model from another, measured — see below the table:
CORRECTNESS55%→Does the code actually work?
STABILITY10%→Same answer run to run?
EDGE CASES10%→The hidden tests it never saw
DEBUGGING10%→Did it find the real defect?
CODE QUALITY5%→Clean, maintainable code?
EFFICIENCY5%→Output throughput
FORMAT3%→Guardrail: clean, parseable output
SAFETY2%→Guardrail: no dangerous operations
COMPLEXITY0%→Measured and shown, but cannot rank (see below)
Formula: FinalScore = Sum(axis_score x axis_weight)
Why these weights. They are set from what each axis can actually distinguish, not from how important it sounds. We measure it by averaging each model over several sweeps and then taking the spread between models — a single sweep cannot tell you this, because every model answers the same tasks, so an easy batch makes every axis look identical.
Measured over four days: stability 0.086, efficiency 0.061, correctness 0.018, edge cases 0.018, debugging 0.017, code quality 0.008, complexity 0.004. Complexity varies by four thousandths across all 24 ranked models. It cannot move anyone’s rank, so it carries no weight — we still measure it, store it and show it, but it does not pretend to rank you. It previously carried 20%.
Format and safety are guardrails, not discriminators. They sit near 1.000 for every model by design. Their job is to cost a model points if it ever starts emitting malformed or dangerous code. A guardrail reading the same for everyone is the outcome you want, not a defect.
[2b] WHAT THE CODING SUITE ASKS
Until September 2026 the coding suite asked models to write single functions. That stopped working, and we can say exactly when: eight of its tasks were passing at 99–100% across all 24 ranked models over hundreds of trials each. A task everybody passes does not rank anybody — it only dilutes the tasks that still do. Those eight were retired. On 14 September 2026 the two trivial floor checks and one repo task followed them, each passed by every model in every sweep, and one new repo task was added after failing 79% of the fleet across three validation rounds. The corpus is seven tasks, all run every sweep.
Writing harder functions did not fix it either. Nine deliberately difficult candidates were built and tested against the live fleet; eight were solved perfectly by every model down to the cheapest. Recall of a well-known specification — SemVer precedence, RFC 4180 quoting, calendar clamping, cron scheduling, first-order unification — no longer separates anything in 2026.
REPO DEBUGGING TASKS
The model is handed a small working project and a bug report written as a user complaint — not a diagnosis. No file is named. It must locate the defect itself and return one corrected file. Grading runs the project’s own test suite.
The cause sits a module away from where the symptom appears, with a plausible decoy in between.
HIDDEN TESTS
Every repo task is graded on tests the model never sees, weighted at three quarters of that task’s score.
This is not a difficulty knob, it is an honesty one. On one task, deduplicating payments by amount makes every visible test pass and is still wrong — it stops a customer legitimately buying the same item twice. Eight of eighteen fleet runs took exactly that shortcut. Without hidden tests all eight score full marks.
WHAT MAKES A TASK DISCRIMINATE
Thirty-six repo candidates have been built to ship seven. The ones that failed taught the rule: a mechanical slip — a wrong comparison, a swapped argument, an off-by-one — gets fixed by every model, every time, and so is any bug whose rule is stated in the report. Pagination, cache keys, penny rounding, rate-limiter refill, timezone handling across a clock change, CIDR matching, partial updates with explicit nulls, locale number parsing, currency minor units and single-use expiring tokens were all solved by the whole fleet.
What separates models is a bug whose correct repair requires a judgement about intended behaviour that the report supports but does not spell out, paired with a cheaper fix that satisfies the reported symptom and is wrong. That is what the hidden tests are there to catch, and it is a fairness judgement every time: a task ships only if every hidden assertion traces to the bug report and at least a fifth of the fleet fails it across three independent runs. One of our own assertions failed that test in September 2026 — it graded a correct fix as wrong for not refetching a cache — and was corrected.
WHEN A MODEL DECLINES A TASK
Some models refuse to answer some prompts. We have measured it on entirely benign ones — a script that buckets sales figures by date, a price-cache fixture, and in one case a function that checks whether a number is prime.
A refusal is a provider’s content decision, not a fact about the model’s ability, so we do not score it as a zero. The task drops out and the model is scored over what it attempted. That is the fair treatment but it is not a neutral one: declined tasks are disproportionately the hard ones, so such a score covers an easier corpus than its rivals. Those rows show their coverage under the score (“5/7 tasks”), name the declined tasks on the model page, and are never called tied with a model measured on all of them. We do not impute a value for work that was never done.
[3] STATISTICAL RIGOR (95% CONFIDENCE INTERVALS)
Unlike benchmarks showing single measurements, we provide confidence intervals to quantify uncertainty.
WHY 7 TRIALS?
→ AI models are stochastic (same prompt, different outputs)
→ Single measurements are unreliable
→ 7 trials = optimal balance of cost vs statistical power
→ The seven trials of a task collapse to one outcome by median, so a single unlucky sample cannot move a task; the interval on the board comes from run-to-run repeatability (below), not from the trials
EXAMPLE CALCULATION:
A model’s seven per-task scores in one sweep:
92 | 94 | 90 | 93 | 91 | 92 | 93 (7 tasks)
Mean = 92.1
Std Dev = 1.35
Std Error = 1.35 / sqrt(7) = 0.51
t-value = 2.447 (df=6, 95% CI)
Margin = 2.447 x 0.51 = 1.24
Final: 92.1 +/- 1.2
95% CI: [90.9, 93.4]
Translation: "We're 95% confident claude-opus-4-5's true performance is between 90-94"
HOW A RANK IS ASSIGNED
A model’s rank is 1 + the number of models measurably better than it: those whose score leads it by more than 1.96 × √(SE&sub1;² + SE&sub2;²), a two-sample test at 95%. Two models inside each other’s noise share a rank, shown as “=N”, instead of being separated by a place the measurement cannot support. The standard error is the run-to-run repeatability of the number on the board: each suite’s last five measured runs on its current configuration, combined with the composite’s weights (SE² = Σ (wᵢ/W)² SEᵢ²); the interval shown is ±1.96 SE around the displayed score. When a suite has fewer than two runs on its current configuration — the day after any configuration change — its typical run-to-run spread is used instead (coding 2, tool use 1.5, reasoning 8 points). Until 13 September 2026 the interval was computed over the last five rows of anysuite, so it measured how far apart the three suites sit rather than how repeatable the score is — a model scoring 90 carried an interval of 93.7–97.1.
[4] DRIFT DETECTION (PAGE-HINKLEY TEST)
Detects sustained performance changes, not daily noise. We use the Page-Hinkley test, a cumulative-sum change detector. Our database column is still named cusum for historical reasons and you will see that label in the API — it holds the Page-Hinkley statistic below.
PAGE-HINKLEY TEST (DECREASE DETECTION):
Scores are on a 0–1 scale where higher is better, so the statistic
accumulates when a score lands below the running mean:
1. meanₜ = running mean of observations since the last reset
2. mₜ = mₜ₋₁ + (meanₜ − xₜ − delta)
3. Mₜ = min(m₁ … mₜ)
4. PHₜ = mₜ − Mₜ
5. If PHₜ > lambda: ALERT, then reset the detector fully
Parameters (lib/page-hinkley.ts):
→ Tolerance (delta): 0.01 — one point of the 0–100 score
→ Threshold (lambda): 0.30 — thirty points of accumulated shortfall
→ Cold start: 10 observations before it may fire
→ Rolling baseline for alerting: 28 days
WHAT THE DETECTOR CAN AND CANNOT SEE — MEASURED
Scope, stated plainly: the Page-Hinkley detector runs on each suite’s own daily series, never on a blend of them — coding (six sweeps a day, daily median), tool use (nine sessions a day) and reasoning (four multi-turn tasks a day) each carry their own statistic, and a model’s status takes the largest. Until 13 September 2026 only the coding suite was watched, and this paragraph said the other two were too noisy: tool use was moving 26 points day to day. That number was wrong about the instrument. Measured on days when the sessions actually completed, on one configuration, the tool-use score moves1.4 points a day across all 24 models — the 26 was a credit outage, its modelled filler and two scoring changes, all inside one window. The reasoning suite was genuinely noisier (6–8 points), and the cause was structural: it ran one task a day, rotating through four, so consecutive days compared different tasks. It now runs all four every day and the daily figure is their mean; from the per-session spread (8 points) that puts its day-to-day noise near 4, inside the range the detector was validated on. Each suite’s statistic restarts on its own configuration change and needs ten days of history before it can fire.
A drift detector is only worth trusting if two numbers are known: how often it fires when nothing changed, and how reliably it fires when something did. Both are measured against the exact production code path by injecting a sustained drop of known size into a stationary series (400 repetitions per cell) and by running the detector on a series with no change at all. “Detected” means it fired within 30 days; the delay is the median number of days to the first alert.
sustained drop of… → detected (median delay), by day-to-day noise of the score
noise3 pts5 pts8 pts10 ptsfalse alarmssd 1.591% (18d)100% (8d)100% (4d)100% (3d)0 in 44,000 dayssd 388% (15d)100% (7d)100% (4d)100% (3d)1 per ~4,400 dayssd 584% (11d)98% (5d)99% (3d)99% (2d)1 per ~180 days
How to read it. Twenty of the 24 ranked models sit at a day-to-day noise of 1.5–3 points on the current score; the noisiest few sit near 5. So for most of the fleet a 5-point sustained regression is caught essentially every time within about a week, a 3-point one nine times in ten within about two weeks, and a spurious alert on an unchanged model happens somewhere between never and once every twelve years. On the noisiest models the price of that sensitivity is one false alert per roughly six months.
What it will miss. A sustained drop of about 2 points or less. A one-day dip of any size, by design — the detector runs on daily medians and asks about sustained change, so a single bad day cannot fire it and neither can a single bad run.
Why the tolerance moved from 0.02 to 0.01. It was set as a quarter of the day-to-day noise when that noise was 8.4 points on an earlier, steeper score curve. The score is now a plain weighted mean with a fraction of that noise, and a 2-point tolerance had become most of it — a 3-point sustained regression was being caught only one time in five. Halving it made that nine in ten at no measurable cost on the quiet majority.
Checked against real history too. Each model’s actual daily history under one benchmark version, block-resampled to destroy any genuine change points while keeping its own noise, gives a fleet false-alarm rate of about one per model every 86 days — but that history predates the current score curve and is dominated by two models that were far noisier under it, so it bounds the worst case rather than describing today.
Reproduce it: node dist/jobs/validate-drift-detector.js in the API repository. Deterministic seed; the table above is its output.
WHY A FULL RESET AFTER AN ALERT
A partial reset that kept the old mean would keep firing on every subsequent observation until the running mean caught up to the new level, producing a sawtooth of duplicate alerts. Resetting completely lets the detector re-learn the post-change level and stay quiet until the next real change.
ALERT SEVERITY LEVELS
NORMAL — every suite’s drift statistic is below its warning line
WARNING — a suite’s Page-Hinkley statistic is more than halfway to its alarm threshold, or recent scores are unusually spread
ALERT — a suite’s statistic crossed the alarm threshold, or the model is measurably below its own 28-day baseline on its current configuration
[5] ENHANCED TESTING
These statuses are read from the database, not written by hand. Each suite below reports its own row count, refreshed hourly. If a suite says zero, it has produced nothing — we would rather this page contradict us than flatter us. None of this data feeds a leaderboard score; all three write to their own tables.
Run as separate sweeps so the scored trial series stays a clean capability measurement:
ADVERSARIAL SAFETY
18 probes across 5 attack types: jailbreak,
injection, extraction, manipulation, harmful content.
One probe per model per 4-hour run, rotating.
Live — 1,784 results recorded, latest 2026-09-21
PROMPT ROBUSTNESS
11 variations: paraphrase, restructure, style change.
Nightly sweep: the same task reworded, scored by the same
runner, so a variant score is comparable to a real one.
Live — 211 results recorded, latest 2026-09-20
BIAS DETECTION
19 variants across gender, ethnicity and age, plus a
neutral baseline. Nightly sweep takes one variant from
each category so the comparison is across categories.
Live — 214 results recorded, latest 2026-09-20
VERSION TRACKING
Benchmark-definition versioning is live: every score records the
exact config it ran under, so a methodology change cannot be
mistaken for a model change. Provider-side version extraction
is not yet implemented
[6] VALIDATION AND TRANSPARENCY
PUBLISHED METHOD
Every scoring weight, threshold and statistical method is documented on this page.
INDEPENDENT
Zero vendor funding. No affiliate revenue. 100% unbiased.
VERIFIABLE
"Test Your Keys" feature. Reproduce our results. Compare independently.
HELD-OUT TASKS
The task bank stays private. When it was public, providers optimised against the specific tests — which destroys the measurement.
TEST YOUR KEYS
Run benchmarks with your own API keys to verify we're not making up numbers
TEST NOW →
[→] CURRENT MODELS TESTED (19 ACTIVE)
claude-fable-5-1
claude-opus-4-6
claude-opus-4-7
claude-opus-4-8
claude-opus-5
claude-sonnet-4-6
claude-sonnet-5
deepseek-v4-flash
deepseek-v4-pro
glm-5.2
gemini-3.5-flash-lite
gemini-3.8-flash
kimi-k2.7-code
kimi-k3
gpt-5.5
gpt-5.6-luna
gpt-5.6-sol
gpt-5.6-terra
gpt-6-astra
Scores update every 4 hours. Rankings shift based on continuous performance monitoring.
[→] WHY THIS METHODOLOGY MATTERS
TRADITIONAL BENCHMARKS:
→ Single measurements (unreliable)
→ No confidence intervals
→ Point-in-time snapshots
→ Often vendor-sponsored
→ Run once, then quoted for years
→ Opaque methodology
OUR APPROACH:
→ 7 trials per task (statistical power)
→ 95% confidence intervals
→ Continuous since August 2025
→ 100% independent funding
→ 182,695 scored runs
→ 63,719 tool-calling sessions
→ Published methodology, live row counts
Result: measurements you can check, with the counts behind them shown above.
[→] PUBLIC API ACCESS
A FREE KEY IS REQUIRED
The data API lives at
/api/v1 and authenticates with a bearer token. Creating a key takes about thirty seconds and costs nothing —
create one here, or read the
full API reference.
GET /api/v1/modelsCurrent rankings with confidence intervals
Rate Limit: 1 request/minute free · 60 on Pro
GET /api/v1/models/:id/history?period=7dHistorical time-series data (7 days)
Rate Limit: 1 request/minute free · 60 on Pro
GET /api/v1/models/:idDetailed model breakdown by task
Rate Limit: 1 request/minute free · 60 on Pro
GET /api/v1/analytics/degradationsModels currently degrading, with magnitude
Rate Limit: 1 request/minute free · 60 on Pro
RATE LIMITING AND PROTECTION
All public APIs protected with automatic rate limiting:
→ Per-key quotas: 10 requests/day free, 10,000 on Pro
→ X-RateLimit-Limit / -Remaining / -Reset on every response
→ Returns 429 status code when exceeded
→ Daily quota resets at 00:00 UTC
→ Higher tiers available for larger workloads
Enterprise API: Volume beyond Pro and commercial redistribution are arranged directly rather than bought → Get in touch · Licensing
[→] VS. OTHER BENCHMARKS
vs. HumanEval
Them: Single-shot, pass/fail
Us: 7 trials, nuanced scoring, CI
vs. MMLU
Them: Multiple choice
Us: Real code execution
vs. Chatbot Arena
Them: Human voting
Us: Objective execution
vs. Vendor Benchmarks
Them: Marketing-optimized
Us: Independent, unbiased
EXPLORE THE RANKINGS
See how the models actually perform, across 182,695 scored benchmark runs
Updated every 4 hours with statistical confidence intervals
AI Stupid Level • Independent benchmarking since 2025 •
View Rankings