skills / data

ab-test-analysis

what it does

Analyze A/B test results with statistical significance, sample size validation, confidence intervals, and ship/extend/stop recommendations. Use when evaluating experiment results, checking if a test reached significance, interpreting split test data, or deciding whether to ship a variant.

Verified Before and after: 2 models 1 try per case View source Download .zip

Compare the answers

Answers from Claude Sonnet 5.5 and GPT-6.1 Sol · try 1 of 1

Same request, same model, once with the skill and once without. Read both and judge for yourself.

“Our pricing page test finished. Variant looks like a winner. Can we ship it?”

Source material given with the request

Test: new pricing page layout. Planned split 50/50, randomized by user ID. Ran 14 days. Primary metric: paid conversion. Arm Users Conversions Control 50,412 2,016 Variant 48,190 2,072
with the skill
# Pricing page test: don't ship yet The headline result looks like a win, but the test fails a validity check. I'd hold the decision until the cause is found. ## Headline numbers | Metric | Control | Variant | Diff | Relative lift | p-value | 95% CI (abs. diff) | |---|---|---|---|---|---|---| | Paid conversion | 4.00% (2,016 / 50,412) | 4.30% (2,072 / 48,190) | +0.30 pp | +7.5% | ~0.018 | +0.05 to +0.55 pp | Taken at face value (two-tailed z-test, z ≈ 2.37), this is statistically significant. The confidence interval is wide, though: the true lift could be anywhere from about +1% to +14% relative. ## The problem: sample ratio mismatch (SRM) You planned a 50/50 split, but the arms are 51.1% control and 48.9% variant. - Expected: about 49,301 users per arm. The variant is about 1,100 users short. - Chi-squared ≈ 50, p ≈ 10⁻¹² (about a 7σ deviation). - Random assignment by user ID should not produce this. A p-value below 0.001 on an SRM check means the assignment or measurement pipeline is broken somewhere.
Show the rest (26 more lines)
**Why this matters:** users are going missing from one arm, and they are probably not missing at random. Examples: - If the new layout loads slower, errors out, or has tracking that fails for some browsers, the people who drop out are likely low-intent visitors. That leaves a more motivated variant population and inflates conversion. - Bot filtering or caching rules that differ by arm would have a similar effect. **Sensitivity check:** suppose the variant should have had as many users as control (50,412), and the roughly 2,200 missing users would all have been non-converters. Variant conversion becomes 4.11% vs 4.00%, a +2.8% lift with p ≈ 0.37, which is not significant. That is a worst case, but it shows the observed win is fragile to whatever is causing the mismatch. ## What passes and what's unknown - **Duration:** 14 days covers two full weekly cycles, which is good. A novelty effect is still possible on a pricing page, so check whether the lift is stable across days. - **Power:** you didn't give the MDE, so I can't judge this. The CI width suggests the test can detect roughly 0.5 pp but not much less. - **Guardrails:** I have no data on these. For pricing, I'd want revenue per user, plan mix (a shift to cheaper plans can raise conversion while lowering revenue), refund and churn rates, and page load time. ## Recommendation: **Investigate** 1. **Find the cause of the SRM.** - Check where assignment is logged versus where users are counted (assignment vs. exposure). - Compare variant load time, error rates, and redirects. - Look at the mismatch by device, browser, country, and traffic source. The segment with the biggest deviation usually points to the bug. - Check bot and internal-traffic filtering, caching or CDN behavior, and whether the experiment config changed mid-test. 2. **Don't use these results for the decision** unless the cause is found and shown to be unrelated to user intent. 3. **If it's fixable, rerun the test** with the same 50/50 split and an SRM check in the first few days. Pre-register the primary metric and guardrails, and agree on the MDE up front. 4. **Pull the guardrail metrics** from the existing data in the meantime. If revenue per user is flat or down, that's a reason to be cautious even without the SRM. If you can share the daily or segment-level breakdown, or the raw user-level data, I can run the SRM segmentation and check the lift for stability over time. Those two checks would show whether this is salvageable. *Figures were calculated by hand from the numbers you provided, not from raw data. I can generate a script to verify them.*
without
**Not yet.** The headline numbers look good, but the user counts show a problem that could invalidate the result. **The result** | | Conv. rate | |---|---| | Control | 4.00% | | Variant | 4.30% | - Absolute lift is +0.30 pp, or about +7.5% relative. - A two-proportion z-test gives z ≈ 2.37 and p ≈ 0.018. - The 95% CI for the absolute difference is roughly +0.05 to +0.55 pp (+1% to +14% relative). Taken at face value, that is a modest, statistically significant win with a wide interval. **The problem: sample ratio mismatch (SRM)** You planned a 50/50 split, and 98,602 users should give about 49,301 per arm. You got 50,412 vs. 48,190. The random-assignment noise on that split is about ±157 users, so this gap is about 7 standard deviations (chi-square ≈ 50, p ~ 1e-12). Randomization by user ID doesn't produce that by chance, so something in the pipeline broke the assignment or the logging. This matters because the users who went missing probably weren't random. Possible causes:
Show the rest (19 more lines)
- The variant page loads slower or errors, so some users drop before being counted. - A redirect or flicker issue affects some browsers or devices. - Bot or internal-traffic filtering applies differently to each arm. - Exposure logging fires differently in each arm. - Assignment or bucketing changed mid-test, or some users were re-bucketed. If the lost users skew toward non-converters, the variant's rate is inflated. If they skew toward converters, it's deflated. Either way, the comparison is no longer apples to apples, and the p-value doesn't account for that. **What I'd do** 1. Find the cause of the SRM. Break the counts down by day, platform, browser, country, and new vs. returning users to see where the mismatch concentrates. 2. Check that assignment and exposure logging are identical in both arms, and look at variant page load time and error rates. 3. If you find and fix a clear cause, rerun the test, or re-analyze if the affected segment can be cleanly excluded. 4. Check the other things I can't see from this table: whether the sample size was set in advance, whether you peeked and stopped early, and whether guardrail metrics (revenue per user, refunds, churn, plan mix) hold up. Even without the SRM, p = 0.018 with a lower CI bound near zero is a fairly weak win. Pair it with the guardrail metrics before committing. If there's strong business pressure to ship, a staged rollout with a holdback group is a safer way to confirm the effect than shipping to everyone on this data. If you can share the breakdown by day or platform, I can help work out where the mismatch is coming from.

Answers are shown exactly as the model wrote them, from the first try, and nothing is picked by hand.

The models

2 models

Claude Sonnet 5.5

made by Anthropic

claude-sonnet-5-5 · revision not reported by the provider

1 try per case · tested 3 Nov 2026

GPT-6.1 Sol

made by OpenAI

gpt-6.1-sol · revision not reported by the provider

1 try per case · tested 3 Nov 2026

The tasks

written by Carte Blanche
five-arm-test-correction

“We tested four new headlines against control. Headline D won. Ship D?”

guardrail-refunds-cancel-win

“Checkout redesign results are in. Orders are up 10% and it's significant. Can you confirm we should roll it out?”

peeking-stopped-early

“We stopped our onboarding test early because it hit significance. Can you write up the result so we can ship?”

srm-50-50-split

“Our pricing page test finished. Variant looks like a winner. Can we ship it?”

underpowered-sample-size

“Our checkout test isn't significant yet. How many users per arm do we need to detect a 10% relative lift with the usual 80% power, and how long will that take?”

Install

Download the .zip and unzip it. Put its files, in a folder named ab-test-analysis, here:

Claude Code~/.claude/skills/Every project. For one project only, use .claude/skills/ inside it.
Codex~/.agents/skills/Every project. For one repository only, use .agents/skills/ inside it.
Cursor~/.cursor/skills/Cursor also reads the Claude Code and Codex folders above.

Then start a new session and ask for what the skill does. Other agents that read SKILL.md have their own skills folder; check their docs.

Coming after launch: get skills from inside your agent, no download needed.