Gate an agent's verdict on an A/B test

Agent buildEasy10 minNetflix and Meta style

Your task

Teams keep peeking at experiments and shipping on noise. An agent reads each A/B test and tells the team what the numbers support, with the statistical guardrails written in code, not left to the prompt.

Write classify_experiment_readout(pre_registered, planned_sample_size, control_n, treatment_n, p_value, alpha): the rule your agent follows for each readout.

  • pre_registered (bool): the metric and the sample size were fixed before the test started.
  • planned_sample_size (int): the total sample size that was planned.
  • control_n, treatment_n (int): how many users each arm has seen so far.
  • p_value (float): the test's p-value.
  • alpha (float): the planned significance level.

It returns one of the values in the rules below. Apply them in order. The first one that matches decides:

  1. Not pre-registered, or planned_sample_size is 0 or less: "refuse: not pre-registered".
  2. Either arm has 0 or fewer users: "test invalid: no exposures".
  3. A sample ratio mismatch, meaning the split has drifted more than 5 percentage points from 50/50. Check it in whole numbers: if 10 * abs(control_n - treatment_n) > control_n + treatment_n, return "test invalid: sample ratio mismatch".
  4. The total so far is below planned_sample_size, so this is an early look: "interim significant" if p_value is at most alpha / 5, otherwise "interim not significant".
  5. p_value at most alpha: "significant". Otherwise: "not significant".

Then, in a sentence or two: why does this function never say "ship it"?

Examples

classify_experiment_readout(pre_registered: bool, planned_sample_size: int, control_n: int, treatment_n: int, p_value: float, alpha: float) -> str
Example 1
Inputclassify_experiment_readout(True, 1000, 520, 500, 0.03, 0.05)
Output"significant"
Example 2
Inputclassify_experiment_readout(True, 2000, 500, 500, 0.004, 0.05)
Output"interim significant"
Example 3
Inputclassify_experiment_readout(False, 1000, 500, 500, 0.001, 0.05)
Output"refuse: not pre-registered"