FAILURE MAP
← Case archive

FA-85676 / Ride-hailing fare and surge pricing / Open access

Partial pickup minutes not compensated · case 01

Drivers get nothing for the first 59 seconds beyond the time threshold.

Verified by executionVariant 1 · 7 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

Excess seconds are floor-divided into minutes.

VERIFIED REPAIR

Compensate each started minute.

Unsuccessful approach: Suppressing the first minute still denies compensation for short overruns.

Case contract

A long-pickup fee compensates drivers for pickups beyond thr_m meters and thr_s seconds. The distance part is per_km on meters beyond thr_m (prorated, half up); the time part is per_min on each started minute beyond thr_s; each part uses only its own positive excess. The total is capped at cap cents.

Why this case matters

Ride-hailing prices are computed per trip at scale; ordering, unit and boundary slips become systematic over- or under-charging.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(pickup_m, pickup_s, policy):
    ex_m = max(0, pickup_m - policy['thr_m'])
    ex_s = max(0, pickup_s - policy['thr_s'])
    fee = (ex_m * policy['per_km'] * 2 + 1000) // 2000 + ex_s // 60 * policy['per_min']
    return min(fee, policy['cap'])
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: time part started minutes',
   [12000, 601, {'cap': 600, 'per_km': 60, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}], 462),
  ('partial repair probe: time part started minutes',
   [3000, 660, {'cap': 600, 'per_km': 90, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}], 45),
  ('second regression', [12000, 660, {'cap': 600, 'per_km': 90, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   600),
  ('normal control 1', [4800, 300, {'cap': 600, 'per_km': 90, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   0),
  ('normal control 2', [4801, 600, {'cap': 900, 'per_km': 90, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   0),
  ('normal control 3', [4801, 600, {'cap': 900, 'per_km': 90, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   0),
  ('normal control 4', [3000, 900, {'cap': 900, 'per_km': 90, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   225)],
 [('regression: time part started minutes',
   [3000, 601, {'cap': 900, 'per_km': 90, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}], 30),
  ('partial repair probe: time part started minutes',
   [12000, 600, {'cap': 600, 'per_km': 60, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}], 432),
  ('second regression', [4800, 660, {'cap': 900, 'per_km': 60, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   30),
  ('normal control 1', [4801, 900, {'cap': 900, 'per_km': 90, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   225),
  ('normal control 2', [4800, 400, {'cap': 600, 'per_km': 90, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   0),
  ('normal control 3', [6000, 900, {'cap': 900, 'per_km': 60, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   297),
  ('normal control 4', [4800, 300, {'cap': 600, 'per_km': 60, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   0)],
 [('regression: time part started minutes',
   [4800, 601, {'cap': 600, 'per_km': 90, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}], 45),
  ('partial repair probe: time part started minutes',
   [4801, 660, {'cap': 900, 'per_km': 60, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}], 30),
  ('second regression', [2000, 601, {'cap': 600, 'per_km': 60, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   30),
  ('normal control 1', [4801, 600, {'cap': 900, 'per_km': 60, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   0),
  ('normal control 2', [4801, 600, {'cap': 600, 'per_km': 60, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   0),
  ('normal control 3', [4800, 900, {'cap': 600, 'per_km': 60, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   225),
  ('normal control 4', [12000, 900, {'cap': 600, 'per_km': 90, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   600)],
 [('regression: time part started minutes',
   [4801, 601, {'cap': 600, 'per_km': 60, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}], 45),
  ('partial repair probe: time part started minutes',
   [6000, 660, {'cap': 600, 'per_km': 90, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}], 138),
  ('second regression', [6000, 600, {'cap': 900, 'per_km': 60, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   72),
  ('normal control 1', [2000, 600, {'cap': 600, 'per_km': 90, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   0),
  ('normal control 2', [4800, 600, {'cap': 600, 'per_km': 90, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   0),
  ('normal control 3', [4801, 900, {'cap': 600, 'per_km': 60, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   225),
  ('normal control 4', [2000, 600, {'cap': 600, 'per_km': 60, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   0)],
 [('regression: time part started minutes',
   [4800, 601, {'cap': 600, 'per_km': 90, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}], 45),
  ('partial repair probe: time part started minutes',
   [4800, 660, {'cap': 900, 'per_km': 90, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}], 30),
  ('second regression', [6000, 600, {'cap': 600, 'per_km': 60, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   72),
  ('normal control 1', [2000, 900, {'cap': 900, 'per_km': 90, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   150),
  ('normal control 2', [2000, 300, {'cap': 900, 'per_km': 60, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   0),
  ('normal control 3', [4801, 600, {'cap': 600, 'per_km': 90, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   0),
  ('normal control 4', [4800, 600, {'cap': 600, 'per_km': 90, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   0)]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
regression: time part started minutes432462Failed
partial repair probe: time part started minutes4545Passed
second regression600600Passed
normal control 100Passed
normal control 200Passed
normal control 300Passed
normal control 4225225Passed

SHA-256 / 7b943723fead980eb0988bc8cf8ecc61ab6f4ab478767b6d6f0ef12e42165665

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(pickup_m, pickup_s, policy):
    ex_m = max(0, pickup_m - policy['thr_m'])
    ex_s = max(0, pickup_s - policy['thr_s'])
    fee = (ex_m * policy['per_km'] * 2 + 1000) // 2000 + (ex_s + 59) // 60 * policy['per_min'] if ex_s > 60 else 0
    return min(fee, policy['cap'])
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: time part started minutes',
   [12000, 601, {'cap': 600, 'per_km': 60, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}], 462),
  ('partial repair probe: time part started minutes',
   [3000, 660, {'cap': 600, 'per_km': 90, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}], 45),
  ('second regression', [12000, 660, {'cap': 600, 'per_km': 90, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   600),
  ('normal control 1', [4800, 300, {'cap': 600, 'per_km': 90, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   0),
  ('normal control 2', [4801, 600, {'cap': 900, 'per_km': 90, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   0),
  ('normal control 3', [4801, 600, {'cap': 900, 'per_km': 90, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   0),
  ('normal control 4', [3000, 900, {'cap': 900, 'per_km': 90, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   225)],
 [('regression: time part started minutes',
   [3000, 601, {'cap': 900, 'per_km': 90, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}], 30),
  ('partial repair probe: time part started minutes',
   [12000, 600, {'cap': 600, 'per_km': 60, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}], 432),
  ('second regression', [4800, 660, {'cap': 900, 'per_km': 60, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   30),
  ('normal control 1', [4801, 900, {'cap': 900, 'per_km': 90, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   225),
  ('normal control 2', [4800, 400, {'cap': 600, 'per_km': 90, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   0),
  ('normal control 3', [6000, 900, {'cap': 900, 'per_km': 60, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   297),
  ('normal control 4', [4800, 300, {'cap': 600, 'per_km': 60, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   0)],
 [('regression: time part started minutes',
   [4800, 601, {'cap': 600, 'per_km': 90, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}], 45),
  ('partial repair probe: time part started minutes',
   [4801, 660, {'cap': 900, 'per_km': 60, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}], 30),
  ('second regression', [2000, 601, {'cap': 600, 'per_km': 60, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   30),
  ('normal control 1', [4801, 600, {'cap': 900, 'per_km': 60, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   0),
  ('normal control 2', [4801, 600, {'cap': 600, 'per_km': 60, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   0),
  ('normal control 3', [4800, 900, {'cap': 600, 'per_km': 60, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   225),
  ('normal control 4', [12000, 900, {'cap': 600, 'per_km': 90, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   600)],
 [('regression: time part started minutes',
   [4801, 601, {'cap': 600, 'per_km': 60, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}], 45),
  ('partial repair probe: time part started minutes',
   [6000, 660, {'cap': 600, 'per_km': 90, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}], 138),
  ('second regression', [6000, 600, {'cap': 900, 'per_km': 60, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   72),
  ('normal control 1', [2000, 600, {'cap': 600, 'per_km': 90, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   0),
  ('normal control 2', [4800, 600, {'cap': 600, 'per_km': 90, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   0),
  ('normal control 3', [4801, 900, {'cap': 600, 'per_km': 60, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   225),
  ('normal control 4', [2000, 600, {'cap': 600, 'per_km': 60, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   0)],
 [('regression: time part started minutes',
   [4800, 601, {'cap': 600, 'per_km': 90, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}], 45),
  ('partial repair probe: time part started minutes',
   [4800, 660, {'cap': 900, 'per_km': 90, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}], 30),
  ('second regression', [6000, 600, {'cap': 600, 'per_km': 60, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   72),
  ('normal control 1', [2000, 900, {'cap': 900, 'per_km': 90, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   150),
  ('normal control 2', [2000, 300, {'cap': 900, 'per_km': 60, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   0),
  ('normal control 3', [4801, 600, {'cap': 600, 'per_km': 90, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   0),
  ('normal control 4', [4800, 600, {'cap': 600, 'per_km': 90, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   0)]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
regression: time part started minutes0462Failed
partial repair probe: time part started minutes045Failed
second regression0600Failed
normal control 100Passed
normal control 200Passed
normal control 300Passed
normal control 4225225Passed

SHA-256 / 2cb3cd381b08cbcf1055e9b6324151d08a24a44c8e8bc92e8df1c9fcc6d71a13

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(pickup_m, pickup_s, policy):
    ex_m = max(0, pickup_m - policy['thr_m'])
    ex_s = max(0, pickup_s - policy['thr_s'])
    fee = (ex_m * policy['per_km'] * 2 + 1000) // 2000 + -(-ex_s // 60) * policy['per_min']
    return min(fee, policy['cap'])
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: time part started minutes',
   [12000, 601, {'cap': 600, 'per_km': 60, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}], 462),
  ('partial repair probe: time part started minutes',
   [3000, 660, {'cap': 600, 'per_km': 90, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}], 45),
  ('second regression', [12000, 660, {'cap': 600, 'per_km': 90, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   600),
  ('normal control 1', [4800, 300, {'cap': 600, 'per_km': 90, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   0),
  ('normal control 2', [4801, 600, {'cap': 900, 'per_km': 90, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   0),
  ('normal control 3', [4801, 600, {'cap': 900, 'per_km': 90, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   0),
  ('normal control 4', [3000, 900, {'cap': 900, 'per_km': 90, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   225)],
 [('regression: time part started minutes',
   [3000, 601, {'cap': 900, 'per_km': 90, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}], 30),
  ('partial repair probe: time part started minutes',
   [12000, 600, {'cap': 600, 'per_km': 60, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}], 432),
  ('second regression', [4800, 660, {'cap': 900, 'per_km': 60, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   30),
  ('normal control 1', [4801, 900, {'cap': 900, 'per_km': 90, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   225),
  ('normal control 2', [4800, 400, {'cap': 600, 'per_km': 90, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   0),
  ('normal control 3', [6000, 900, {'cap': 900, 'per_km': 60, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   297),
  ('normal control 4', [4800, 300, {'cap': 600, 'per_km': 60, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   0)],
 [('regression: time part started minutes',
   [4800, 601, {'cap': 600, 'per_km': 90, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}], 45),
  ('partial repair probe: time part started minutes',
   [4801, 660, {'cap': 900, 'per_km': 60, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}], 30),
  ('second regression', [2000, 601, {'cap': 600, 'per_km': 60, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   30),
  ('normal control 1', [4801, 600, {'cap': 900, 'per_km': 60, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   0),
  ('normal control 2', [4801, 600, {'cap': 600, 'per_km': 60, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   0),
  ('normal control 3', [4800, 900, {'cap': 600, 'per_km': 60, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   225),
  ('normal control 4', [12000, 900, {'cap': 600, 'per_km': 90, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   600)],
 [('regression: time part started minutes',
   [4801, 601, {'cap': 600, 'per_km': 60, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}], 45),
  ('partial repair probe: time part started minutes',
   [6000, 660, {'cap': 600, 'per_km': 90, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}], 138),
  ('second regression', [6000, 600, {'cap': 900, 'per_km': 60, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   72),
  ('normal control 1', [2000, 600, {'cap': 600, 'per_km': 90, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   0),
  ('normal control 2', [4800, 600, {'cap': 600, 'per_km': 90, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   0),
  ('normal control 3', [4801, 900, {'cap': 600, 'per_km': 60, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   225),
  ('normal control 4', [2000, 600, {'cap': 600, 'per_km': 60, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   0)],
 [('regression: time part started minutes',
   [4800, 601, {'cap': 600, 'per_km': 90, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}], 45),
  ('partial repair probe: time part started minutes',
   [4800, 660, {'cap': 900, 'per_km': 90, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}], 30),
  ('second regression', [6000, 600, {'cap': 600, 'per_km': 60, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   72),
  ('normal control 1', [2000, 900, {'cap': 900, 'per_km': 90, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   150),
  ('normal control 2', [2000, 300, {'cap': 900, 'per_km': 60, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   0),
  ('normal control 3', [4801, 600, {'cap': 600, 'per_km': 90, 'per_min': 45, 'thr_m': 4800, 'thr_s': 600}],
   0),
  ('normal control 4', [4800, 600, {'cap': 600, 'per_km': 90, 'per_min': 30, 'thr_m': 4800, 'thr_s': 600}],
   0)]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
regression: time part started minutes462462Passed
partial repair probe: time part started minutes4545Passed
second regression600600Passed
normal control 100Passed
normal control 200Passed
normal control 300Passed
normal control 4225225Passed

SHA-256 / e31e3e06f9895ac7ce32293d1ad2f6ba8d1e9c737ca3751d27781eead25f4056

Verification & scope

A deterministic toy pricing contract stipulated for this example; it does not reproduce the pricing of any real ride-hailing operator or regulator. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.

Observations recorded using Python 3.12.14 at 2026-09-29T14:50:42.523045+00:00.

Case digest / 7c0b4b56654ebc3be20a255f412e15127ded3ae18cb6547e9b2310a99c019e76