FAILURE MAP
← Case archive

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

Early arrival for a scheduled ride billed as rider wait · case 01

A driver arriving five minutes before a scheduled pickup bills the rider for those minutes.

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

ROOT CAUSE

Wait always starts at driver arrival.

VERIFIED REPAIR

Start the clock at the later of arrival and the scheduled time.

Unsuccessful approach: Taking the earlier time bills even more of the pre-schedule wait.

Case contract

Wait time starts at driver arrival, or at the scheduled pickup time if the ride was scheduled and the driver arrived early. The first grace seconds are free; beyond that each started minute is billed at per_min cents, up to cap_min billed minutes. Return the wait fee in 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(ev, policy):
    start = ev['arrive']
    wait = ev['board'] - start
    if wait <= policy['grace']:
        return 0
    minutes = -(-(wait - policy['grace']) // 60)
    return min(minutes, policy['cap_min']) * policy['per_min']
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: scheduled pickup start',
   [{'arrive': 10000, 'board': 10300, 'scheduled': 10300}, {'cap_min': 10, 'grace': 120, 'per_min': 25}], 0),
  ('partial repair probe: scheduled pickup start',
   [{'arrive': 10000, 'board': 10900, 'scheduled': 10300}, {'cap_min': 10, 'grace': 120, 'per_min': 35}],
   280),
  ('second regression',
   [{'arrive': 10000, 'board': 10568, 'scheduled': 10120}, {'cap_min': 10, 'grace': 120, 'per_min': 35}],
   210),
  ('normal control 1',
   [{'arrive': 10000, 'board': 10720, 'scheduled': 10120}, {'cap_min': 5, 'grace': 120, 'per_min': 25}],
   125),
  ('normal control 2',
   [{'arrive': 10000, 'board': 10769, 'scheduled': 10300}, {'cap_min': 5, 'grace': 120, 'per_min': 35}],
   175),
  ('normal control 3',
   [{'arrive': 10000, 'board': 10181, 'scheduled': None}, {'cap_min': 5, 'grace': 120, 'per_min': 25}], 50),
  ('normal control 4',
   [{'arrive': 10000, 'board': 10120, 'scheduled': None}, {'cap_min': 5, 'grace': 120, 'per_min': 40}], 0)],
 [('regression: scheduled pickup start',
   [{'arrive': 10000, 'board': 10720, 'scheduled': 10120}, {'cap_min': 10, 'grace': 120, 'per_min': 40}],
   320),
  ('partial repair probe: scheduled pickup start',
   [{'arrive': 10000, 'board': 10180, 'scheduled': 9940}, {'cap_min': 5, 'grace': 120, 'per_min': 35}], 35),
  ('second regression',
   [{'arrive': 10000, 'board': 10180, 'scheduled': 9940}, {'cap_min': 10, 'grace': 120, 'per_min': 25}], 25),
  ('normal control 1',
   [{'arrive': 10000, 'board': 10000, 'scheduled': None}, {'cap_min': 5, 'grace': 120, 'per_min': 35}], 0),
  ('normal control 2',
   [{'arrive': 10000, 'board': 11090, 'scheduled': None}, {'cap_min': 5, 'grace': 120, 'per_min': 40}], 200),
  ('normal control 3',
   [{'arrive': 10000, 'board': 10600, 'scheduled': 9940}, {'cap_min': 5, 'grace': 120, 'per_min': 35}], 175),
  ('normal control 4',
   [{'arrive': 10000, 'board': 10705, 'scheduled': 9940}, {'cap_min': 10, 'grace': 120, 'per_min': 40}],
   400)],
 [('regression: scheduled pickup start',
   [{'arrive': 10000, 'board': 10301, 'scheduled': 10120}, {'cap_min': 5, 'grace': 120, 'per_min': 35}], 70),
  ('partial repair probe: scheduled pickup start',
   [{'arrive': 10000, 'board': 10360, 'scheduled': 10300}, {'cap_min': 5, 'grace': 120, 'per_min': 25}], 0),
  ('second regression',
   [{'arrive': 10000, 'board': 10421, 'scheduled': 10300}, {'cap_min': 5, 'grace': 120, 'per_min': 35}], 35),
  ('normal control 1',
   [{'arrive': 10000, 'board': 11020, 'scheduled': 10120}, {'cap_min': 5, 'grace': 120, 'per_min': 25}],
   125),
  ('normal control 2',
   [{'arrive': 10000, 'board': 10121, 'scheduled': None}, {'cap_min': 5, 'grace': 120, 'per_min': 35}], 35),
  ('normal control 3',
   [{'arrive': 10000, 'board': 10120, 'scheduled': None}, {'cap_min': 10, 'grace': 120, 'per_min': 25}], 0),
  ('normal control 4',
   [{'arrive': 10000, 'board': 10900, 'scheduled': None}, {'cap_min': 10, 'grace': 120, 'per_min': 35}],
   350)],
 [('regression: scheduled pickup start',
   [{'arrive': 10000, 'board': 10360, 'scheduled': 10300}, {'cap_min': 10, 'grace': 120, 'per_min': 25}], 0),
  ('partial repair probe: scheduled pickup start',
   [{'arrive': 10000, 'board': 10360, 'scheduled': 10300}, {'cap_min': 5, 'grace': 120, 'per_min': 40}], 0),
  ('second regression',
   [{'arrive': 10000, 'board': 10720, 'scheduled': 10120}, {'cap_min': 10, 'grace': 120, 'per_min': 35}],
   280),
  ('normal control 1',
   [{'arrive': 10000, 'board': 10900, 'scheduled': 9940}, {'cap_min': 10, 'grace': 120, 'per_min': 35}],
   350),
  ('normal control 2',
   [{'arrive': 10000, 'board': 10996, 'scheduled': 10120}, {'cap_min': 5, 'grace': 120, 'per_min': 25}],
   125),
  ('normal control 3',
   [{'arrive': 10000, 'board': 10180, 'scheduled': None}, {'cap_min': 10, 'grace': 120, 'per_min': 25}], 25),
  ('normal control 4',
   [{'arrive': 10000, 'board': 10800, 'scheduled': 9940}, {'cap_min': 5, 'grace': 120, 'per_min': 25}],
   125)],
 [('regression: scheduled pickup start',
   [{'arrive': 10000, 'board': 10301, 'scheduled': 10120}, {'cap_min': 5, 'grace': 120, 'per_min': 25}], 50),
  ('partial repair probe: scheduled pickup start',
   [{'arrive': 10000, 'board': 10121, 'scheduled': 9940}, {'cap_min': 10, 'grace': 120, 'per_min': 40}], 40),
  ('second regression',
   [{'arrive': 10000, 'board': 10481, 'scheduled': 10300}, {'cap_min': 10, 'grace': 120, 'per_min': 35}],
   70),
  ('normal control 1',
   [{'arrive': 10000, 'board': 10600, 'scheduled': None}, {'cap_min': 5, 'grace': 120, 'per_min': 40}], 200),
  ('normal control 2',
   [{'arrive': 10000, 'board': 11681, 'scheduled': 10300}, {'cap_min': 5, 'grace': 120, 'per_min': 35}],
   175),
  ('normal control 3',
   [{'arrive': 10000, 'board': 11243, 'scheduled': 10300}, {'cap_min': 10, 'grace': 120, 'per_min': 35}],
   350),
  ('normal control 4',
   [{'arrive': 10000, 'board': 10060, 'scheduled': None}, {'cap_min': 10, 'grace': 120, 'per_min': 35}], 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: scheduled pickup start750Failed
partial repair probe: scheduled pickup start350280Failed
second regression280210Failed
normal control 1125125Passed
normal control 2175175Passed
normal control 35050Passed
normal control 400Passed

SHA-256 / 553acd661db31b7f5c9f41c169246407b6f7c64f344dd77c82927974c238a2e1

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(ev, policy):
    start = ev['arrive'] if ev['scheduled'] is None else min(ev['arrive'], ev['scheduled'])
    wait = ev['board'] - start
    if wait <= policy['grace']:
        return 0
    minutes = -(-(wait - policy['grace']) // 60)
    return min(minutes, policy['cap_min']) * policy['per_min']
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: scheduled pickup start',
   [{'arrive': 10000, 'board': 10300, 'scheduled': 10300}, {'cap_min': 10, 'grace': 120, 'per_min': 25}], 0),
  ('partial repair probe: scheduled pickup start',
   [{'arrive': 10000, 'board': 10900, 'scheduled': 10300}, {'cap_min': 10, 'grace': 120, 'per_min': 35}],
   280),
  ('second regression',
   [{'arrive': 10000, 'board': 10568, 'scheduled': 10120}, {'cap_min': 10, 'grace': 120, 'per_min': 35}],
   210),
  ('normal control 1',
   [{'arrive': 10000, 'board': 10720, 'scheduled': 10120}, {'cap_min': 5, 'grace': 120, 'per_min': 25}],
   125),
  ('normal control 2',
   [{'arrive': 10000, 'board': 10769, 'scheduled': 10300}, {'cap_min': 5, 'grace': 120, 'per_min': 35}],
   175),
  ('normal control 3',
   [{'arrive': 10000, 'board': 10181, 'scheduled': None}, {'cap_min': 5, 'grace': 120, 'per_min': 25}], 50),
  ('normal control 4',
   [{'arrive': 10000, 'board': 10120, 'scheduled': None}, {'cap_min': 5, 'grace': 120, 'per_min': 40}], 0)],
 [('regression: scheduled pickup start',
   [{'arrive': 10000, 'board': 10720, 'scheduled': 10120}, {'cap_min': 10, 'grace': 120, 'per_min': 40}],
   320),
  ('partial repair probe: scheduled pickup start',
   [{'arrive': 10000, 'board': 10180, 'scheduled': 9940}, {'cap_min': 5, 'grace': 120, 'per_min': 35}], 35),
  ('second regression',
   [{'arrive': 10000, 'board': 10180, 'scheduled': 9940}, {'cap_min': 10, 'grace': 120, 'per_min': 25}], 25),
  ('normal control 1',
   [{'arrive': 10000, 'board': 10000, 'scheduled': None}, {'cap_min': 5, 'grace': 120, 'per_min': 35}], 0),
  ('normal control 2',
   [{'arrive': 10000, 'board': 11090, 'scheduled': None}, {'cap_min': 5, 'grace': 120, 'per_min': 40}], 200),
  ('normal control 3',
   [{'arrive': 10000, 'board': 10600, 'scheduled': 9940}, {'cap_min': 5, 'grace': 120, 'per_min': 35}], 175),
  ('normal control 4',
   [{'arrive': 10000, 'board': 10705, 'scheduled': 9940}, {'cap_min': 10, 'grace': 120, 'per_min': 40}],
   400)],
 [('regression: scheduled pickup start',
   [{'arrive': 10000, 'board': 10301, 'scheduled': 10120}, {'cap_min': 5, 'grace': 120, 'per_min': 35}], 70),
  ('partial repair probe: scheduled pickup start',
   [{'arrive': 10000, 'board': 10360, 'scheduled': 10300}, {'cap_min': 5, 'grace': 120, 'per_min': 25}], 0),
  ('second regression',
   [{'arrive': 10000, 'board': 10421, 'scheduled': 10300}, {'cap_min': 5, 'grace': 120, 'per_min': 35}], 35),
  ('normal control 1',
   [{'arrive': 10000, 'board': 11020, 'scheduled': 10120}, {'cap_min': 5, 'grace': 120, 'per_min': 25}],
   125),
  ('normal control 2',
   [{'arrive': 10000, 'board': 10121, 'scheduled': None}, {'cap_min': 5, 'grace': 120, 'per_min': 35}], 35),
  ('normal control 3',
   [{'arrive': 10000, 'board': 10120, 'scheduled': None}, {'cap_min': 10, 'grace': 120, 'per_min': 25}], 0),
  ('normal control 4',
   [{'arrive': 10000, 'board': 10900, 'scheduled': None}, {'cap_min': 10, 'grace': 120, 'per_min': 35}],
   350)],
 [('regression: scheduled pickup start',
   [{'arrive': 10000, 'board': 10360, 'scheduled': 10300}, {'cap_min': 10, 'grace': 120, 'per_min': 25}], 0),
  ('partial repair probe: scheduled pickup start',
   [{'arrive': 10000, 'board': 10360, 'scheduled': 10300}, {'cap_min': 5, 'grace': 120, 'per_min': 40}], 0),
  ('second regression',
   [{'arrive': 10000, 'board': 10720, 'scheduled': 10120}, {'cap_min': 10, 'grace': 120, 'per_min': 35}],
   280),
  ('normal control 1',
   [{'arrive': 10000, 'board': 10900, 'scheduled': 9940}, {'cap_min': 10, 'grace': 120, 'per_min': 35}],
   350),
  ('normal control 2',
   [{'arrive': 10000, 'board': 10996, 'scheduled': 10120}, {'cap_min': 5, 'grace': 120, 'per_min': 25}],
   125),
  ('normal control 3',
   [{'arrive': 10000, 'board': 10180, 'scheduled': None}, {'cap_min': 10, 'grace': 120, 'per_min': 25}], 25),
  ('normal control 4',
   [{'arrive': 10000, 'board': 10800, 'scheduled': 9940}, {'cap_min': 5, 'grace': 120, 'per_min': 25}],
   125)],
 [('regression: scheduled pickup start',
   [{'arrive': 10000, 'board': 10301, 'scheduled': 10120}, {'cap_min': 5, 'grace': 120, 'per_min': 25}], 50),
  ('partial repair probe: scheduled pickup start',
   [{'arrive': 10000, 'board': 10121, 'scheduled': 9940}, {'cap_min': 10, 'grace': 120, 'per_min': 40}], 40),
  ('second regression',
   [{'arrive': 10000, 'board': 10481, 'scheduled': 10300}, {'cap_min': 10, 'grace': 120, 'per_min': 35}],
   70),
  ('normal control 1',
   [{'arrive': 10000, 'board': 10600, 'scheduled': None}, {'cap_min': 5, 'grace': 120, 'per_min': 40}], 200),
  ('normal control 2',
   [{'arrive': 10000, 'board': 11681, 'scheduled': 10300}, {'cap_min': 5, 'grace': 120, 'per_min': 35}],
   175),
  ('normal control 3',
   [{'arrive': 10000, 'board': 11243, 'scheduled': 10300}, {'cap_min': 10, 'grace': 120, 'per_min': 35}],
   350),
  ('normal control 4',
   [{'arrive': 10000, 'board': 10060, 'scheduled': None}, {'cap_min': 10, 'grace': 120, 'per_min': 35}], 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: scheduled pickup start750Failed
partial repair probe: scheduled pickup start350280Failed
second regression280210Failed
normal control 1125125Passed
normal control 2175175Passed
normal control 35050Passed
normal control 400Passed

SHA-256 / 8ffe6c4f4cb72011ce6fcb2da272e96c4dbebd5c5f3d8ec5cabee8f4e83f1415

3 / The verified repair

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

N = 1
observations = []
def solve(ev, policy):
    start = ev['arrive'] if ev['scheduled'] is None else max(ev['arrive'], ev['scheduled'])
    wait = ev['board'] - start
    if wait <= policy['grace']:
        return 0
    minutes = -(-(wait - policy['grace']) // 60)
    return min(minutes, policy['cap_min']) * policy['per_min']
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: scheduled pickup start',
   [{'arrive': 10000, 'board': 10300, 'scheduled': 10300}, {'cap_min': 10, 'grace': 120, 'per_min': 25}], 0),
  ('partial repair probe: scheduled pickup start',
   [{'arrive': 10000, 'board': 10900, 'scheduled': 10300}, {'cap_min': 10, 'grace': 120, 'per_min': 35}],
   280),
  ('second regression',
   [{'arrive': 10000, 'board': 10568, 'scheduled': 10120}, {'cap_min': 10, 'grace': 120, 'per_min': 35}],
   210),
  ('normal control 1',
   [{'arrive': 10000, 'board': 10720, 'scheduled': 10120}, {'cap_min': 5, 'grace': 120, 'per_min': 25}],
   125),
  ('normal control 2',
   [{'arrive': 10000, 'board': 10769, 'scheduled': 10300}, {'cap_min': 5, 'grace': 120, 'per_min': 35}],
   175),
  ('normal control 3',
   [{'arrive': 10000, 'board': 10181, 'scheduled': None}, {'cap_min': 5, 'grace': 120, 'per_min': 25}], 50),
  ('normal control 4',
   [{'arrive': 10000, 'board': 10120, 'scheduled': None}, {'cap_min': 5, 'grace': 120, 'per_min': 40}], 0)],
 [('regression: scheduled pickup start',
   [{'arrive': 10000, 'board': 10720, 'scheduled': 10120}, {'cap_min': 10, 'grace': 120, 'per_min': 40}],
   320),
  ('partial repair probe: scheduled pickup start',
   [{'arrive': 10000, 'board': 10180, 'scheduled': 9940}, {'cap_min': 5, 'grace': 120, 'per_min': 35}], 35),
  ('second regression',
   [{'arrive': 10000, 'board': 10180, 'scheduled': 9940}, {'cap_min': 10, 'grace': 120, 'per_min': 25}], 25),
  ('normal control 1',
   [{'arrive': 10000, 'board': 10000, 'scheduled': None}, {'cap_min': 5, 'grace': 120, 'per_min': 35}], 0),
  ('normal control 2',
   [{'arrive': 10000, 'board': 11090, 'scheduled': None}, {'cap_min': 5, 'grace': 120, 'per_min': 40}], 200),
  ('normal control 3',
   [{'arrive': 10000, 'board': 10600, 'scheduled': 9940}, {'cap_min': 5, 'grace': 120, 'per_min': 35}], 175),
  ('normal control 4',
   [{'arrive': 10000, 'board': 10705, 'scheduled': 9940}, {'cap_min': 10, 'grace': 120, 'per_min': 40}],
   400)],
 [('regression: scheduled pickup start',
   [{'arrive': 10000, 'board': 10301, 'scheduled': 10120}, {'cap_min': 5, 'grace': 120, 'per_min': 35}], 70),
  ('partial repair probe: scheduled pickup start',
   [{'arrive': 10000, 'board': 10360, 'scheduled': 10300}, {'cap_min': 5, 'grace': 120, 'per_min': 25}], 0),
  ('second regression',
   [{'arrive': 10000, 'board': 10421, 'scheduled': 10300}, {'cap_min': 5, 'grace': 120, 'per_min': 35}], 35),
  ('normal control 1',
   [{'arrive': 10000, 'board': 11020, 'scheduled': 10120}, {'cap_min': 5, 'grace': 120, 'per_min': 25}],
   125),
  ('normal control 2',
   [{'arrive': 10000, 'board': 10121, 'scheduled': None}, {'cap_min': 5, 'grace': 120, 'per_min': 35}], 35),
  ('normal control 3',
   [{'arrive': 10000, 'board': 10120, 'scheduled': None}, {'cap_min': 10, 'grace': 120, 'per_min': 25}], 0),
  ('normal control 4',
   [{'arrive': 10000, 'board': 10900, 'scheduled': None}, {'cap_min': 10, 'grace': 120, 'per_min': 35}],
   350)],
 [('regression: scheduled pickup start',
   [{'arrive': 10000, 'board': 10360, 'scheduled': 10300}, {'cap_min': 10, 'grace': 120, 'per_min': 25}], 0),
  ('partial repair probe: scheduled pickup start',
   [{'arrive': 10000, 'board': 10360, 'scheduled': 10300}, {'cap_min': 5, 'grace': 120, 'per_min': 40}], 0),
  ('second regression',
   [{'arrive': 10000, 'board': 10720, 'scheduled': 10120}, {'cap_min': 10, 'grace': 120, 'per_min': 35}],
   280),
  ('normal control 1',
   [{'arrive': 10000, 'board': 10900, 'scheduled': 9940}, {'cap_min': 10, 'grace': 120, 'per_min': 35}],
   350),
  ('normal control 2',
   [{'arrive': 10000, 'board': 10996, 'scheduled': 10120}, {'cap_min': 5, 'grace': 120, 'per_min': 25}],
   125),
  ('normal control 3',
   [{'arrive': 10000, 'board': 10180, 'scheduled': None}, {'cap_min': 10, 'grace': 120, 'per_min': 25}], 25),
  ('normal control 4',
   [{'arrive': 10000, 'board': 10800, 'scheduled': 9940}, {'cap_min': 5, 'grace': 120, 'per_min': 25}],
   125)],
 [('regression: scheduled pickup start',
   [{'arrive': 10000, 'board': 10301, 'scheduled': 10120}, {'cap_min': 5, 'grace': 120, 'per_min': 25}], 50),
  ('partial repair probe: scheduled pickup start',
   [{'arrive': 10000, 'board': 10121, 'scheduled': 9940}, {'cap_min': 10, 'grace': 120, 'per_min': 40}], 40),
  ('second regression',
   [{'arrive': 10000, 'board': 10481, 'scheduled': 10300}, {'cap_min': 10, 'grace': 120, 'per_min': 35}],
   70),
  ('normal control 1',
   [{'arrive': 10000, 'board': 10600, 'scheduled': None}, {'cap_min': 5, 'grace': 120, 'per_min': 40}], 200),
  ('normal control 2',
   [{'arrive': 10000, 'board': 11681, 'scheduled': 10300}, {'cap_min': 5, 'grace': 120, 'per_min': 35}],
   175),
  ('normal control 3',
   [{'arrive': 10000, 'board': 11243, 'scheduled': 10300}, {'cap_min': 10, 'grace': 120, 'per_min': 35}],
   350),
  ('normal control 4',
   [{'arrive': 10000, 'board': 10060, 'scheduled': None}, {'cap_min': 10, 'grace': 120, 'per_min': 35}], 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: scheduled pickup start00Passed
partial repair probe: scheduled pickup start280280Passed
second regression210210Passed
normal control 1125125Passed
normal control 2175175Passed
normal control 35050Passed
normal control 400Passed

SHA-256 / 8ba97e5e80105ffdbf7f7aa9b1229cd6e15fadb16d1b81a3c7cddba00e418c01

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:40.361542+00:00.

Case digest / 3b686c7427b30dd441d7a973d25d3c3e657b2e400354e3beb0a7315b98057e46