FAILURE MAP
← Case archive

FA-73996 / Feature flag rollout bucketing / Open access

Scheduled rollout ramp: The earliest-listed step wins a timestamp tie · case 01

A correction appended with the same timestamp as a mistaken step never takes effect.

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

ROOT CAUSE

Ties are ordered by descending list position, so the earlier entry is applied last.

VERIFIED REPAIR

Break equal-time ties by ascending list position so later entries apply later.

Unsuccessful approach: Breaking ties by percentage makes the larger value win regardless of which was written last.

Case contract

steps is a possibly unsorted list of [epoch second, percent or None]. Order steps by time, breaking ties by list position (later entries apply later). Every step with time <= now is active in that order; a None percent is a hold that keeps the previous value; numeric percents are clamped to [0, 100]. Before the first step the percentage is 0. Return [percent, original list index of the last active step or -1].

Why this case matters

Scheduled ramps move production traffic unattended, so the percentage at any instant must be exact.

1 / The failure

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

N = 1
observations = []
def solve(steps, now):
    order = sorted(range(len(steps)), key=lambda i: (steps[i][0], -i))
    current = 0
    active = -1
    for i in order:
        at, pct = steps[i]
        if at > now:
            break
        active = i
        if pct is not None:
            current = min(max(pct, 0), 100)
    return [current, active]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('step scheduled exactly now is active', [[[0, 5], [60, 25]], 60], [25, 1]),
  ('unsorted schedule is ordered by time', [[[60, 50], [0, 10], [30, 25]], 45], [25, 2]),
  ('later entry wins a timestamp tie', [[[0, 5], [30, 50], [30, 20]], 40], [20, 2]),
  ('hold step keeps previous percentage', [[[0, 25], [30, None]], 40], [25, 1]),
  ('explicit rollback to zero percent', [[[0, 25], [30, 0]], 40], [0, 1]),
  ('duplicate identical steps report the later entry', [[[10, 10], [10, 10]], 15], [10, 1]),
  ('ramp schedule sample 1', [[[45, 0], [45, 5], [20, None], [45, 25], [60, -10], [45, None]], 45], [25, 5]),
  ('ramp schedule sample 2', [[[20, 0], [30, 50]], 10], [0, -1])],
 [('unsorted schedule is ordered by time', [[[60, 50], [0, 10], [30, 25]], 45], [25, 2]),
  ('later entry wins a timestamp tie', [[[0, 5], [30, 50], [30, 20]], 40], [20, 2]),
  ('hold step keeps previous percentage', [[[0, 25], [30, None]], 40], [25, 1]),
  ('explicit rollback to zero percent', [[[0, 25], [30, 0]], 40], [0, 1]),
  ('over-hundred percent is clamped', [[[0, 150]], 10], [100, 0]),
  ('duplicate identical steps report the later entry', [[[10, 10], [10, 10]], 15], [10, 1]),
  ('ramp schedule sample 29', [[[60, 100], [60, 120], [20, 25], [20, 50], [60, 75]], 60], [75, 4]),
  ('ramp schedule sample 43', [[[20, 5], [20, 0]], 20], [0, 1])],
 [('later entry wins a timestamp tie', [[[0, 5], [30, 50], [30, 20]], 40], [20, 2]),
  ('hold step keeps previous percentage', [[[0, 25], [30, None]], 40], [25, 1]),
  ('explicit rollback to zero percent', [[[0, 25], [30, 0]], 40], [0, 1]),
  ('over-hundred percent is clamped', [[[0, 150]], 10], [100, 0]),
  ('negative percent is clamped to zero', [[[0, 10], [5, -20]], 10], [0, 1]),
  ('ramp schedule sample 11', [[[0, 5]], -5], [0, -1]),
  ('ramp schedule sample 30', [[[20, 120], [10, 120], [0, 50], [20, None]], 20], [100, 3]),
  ('ramp schedule sample 46', [[[30, 100], [20, 25], [30, -10], [30, 50], [30, None]], 30], [50, 4])],
 [('hold step keeps previous percentage', [[[0, 25], [30, None]], 40], [25, 1]),
  ('explicit rollback to zero percent', [[[0, 25], [30, 0]], 40], [0, 1]),
  ('over-hundred percent is clamped', [[[0, 150]], 10], [100, 0]),
  ('negative percent is clamped to zero', [[[0, 10], [5, -20]], 10], [0, 1]),
  ('before first step is zero', [[[10, 50]], 5], [0, -1]),
  ('ramp schedule sample 1', [[[45, 0], [45, 5], [20, None], [45, 25], [60, -10], [45, None]], 45], [25, 5]),
  ('ramp schedule sample 16', [[[60, 120]], 60], [100, 0]),
  ('ramp schedule sample 20', [[[45, 25], [45, 75]], 45], [75, 1])],
 [('explicit rollback to zero percent', [[[0, 25], [30, 0]], 40], [0, 1]),
  ('over-hundred percent is clamped', [[[0, 150]], 10], [100, 0]),
  ('negative percent is clamped to zero', [[[0, 10], [5, -20]], 10], [0, 1]),
  ('before first step is zero', [[[10, 50]], 5], [0, -1]),
  ('active index refers to original position', [[[20, 30], [10, 10]], 15], [10, 1]),
  ('ramp schedule sample 21', [[], 0], [0, -1]),
  ('ramp schedule sample 44', [[[60, 5], [45, -10], [30, 100], [30, 50], [60, 25]], 100], [25, 4]),
  ('ramp schedule sample 46', [[[30, 100], [20, 25], [30, -10], [30, 50], [30, None]], 30], [50, 4])]]
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
step scheduled exactly now is active[25, 1][25, 1]Passed
unsorted schedule is ordered by time[25, 2][25, 2]Passed
later entry wins a timestamp tie[50, 1][20, 2]Failed
hold step keeps previous percentage[25, 1][25, 1]Passed
explicit rollback to zero percent[0, 1][0, 1]Passed
duplicate identical steps report the later entry[10, 0][10, 1]Failed
ramp schedule sample 1[0, 0][25, 5]Failed
ramp schedule sample 2[0, -1][0, -1]Passed

SHA-256 / 86258f559561cac52bbd46df988b90906db9b465f489c21ee65cb5bed1edb99a

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(steps, now):
    order = sorted(range(len(steps)), key=lambda i: (steps[i][0], steps[i][1] if steps[i][1] is not None else -1))
    current = 0
    active = -1
    for i in order:
        at, pct = steps[i]
        if at > now:
            break
        active = i
        if pct is not None:
            current = min(max(pct, 0), 100)
    return [current, active]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('step scheduled exactly now is active', [[[0, 5], [60, 25]], 60], [25, 1]),
  ('unsorted schedule is ordered by time', [[[60, 50], [0, 10], [30, 25]], 45], [25, 2]),
  ('later entry wins a timestamp tie', [[[0, 5], [30, 50], [30, 20]], 40], [20, 2]),
  ('hold step keeps previous percentage', [[[0, 25], [30, None]], 40], [25, 1]),
  ('explicit rollback to zero percent', [[[0, 25], [30, 0]], 40], [0, 1]),
  ('duplicate identical steps report the later entry', [[[10, 10], [10, 10]], 15], [10, 1]),
  ('ramp schedule sample 1', [[[45, 0], [45, 5], [20, None], [45, 25], [60, -10], [45, None]], 45], [25, 5]),
  ('ramp schedule sample 2', [[[20, 0], [30, 50]], 10], [0, -1])],
 [('unsorted schedule is ordered by time', [[[60, 50], [0, 10], [30, 25]], 45], [25, 2]),
  ('later entry wins a timestamp tie', [[[0, 5], [30, 50], [30, 20]], 40], [20, 2]),
  ('hold step keeps previous percentage', [[[0, 25], [30, None]], 40], [25, 1]),
  ('explicit rollback to zero percent', [[[0, 25], [30, 0]], 40], [0, 1]),
  ('over-hundred percent is clamped', [[[0, 150]], 10], [100, 0]),
  ('duplicate identical steps report the later entry', [[[10, 10], [10, 10]], 15], [10, 1]),
  ('ramp schedule sample 29', [[[60, 100], [60, 120], [20, 25], [20, 50], [60, 75]], 60], [75, 4]),
  ('ramp schedule sample 43', [[[20, 5], [20, 0]], 20], [0, 1])],
 [('later entry wins a timestamp tie', [[[0, 5], [30, 50], [30, 20]], 40], [20, 2]),
  ('hold step keeps previous percentage', [[[0, 25], [30, None]], 40], [25, 1]),
  ('explicit rollback to zero percent', [[[0, 25], [30, 0]], 40], [0, 1]),
  ('over-hundred percent is clamped', [[[0, 150]], 10], [100, 0]),
  ('negative percent is clamped to zero', [[[0, 10], [5, -20]], 10], [0, 1]),
  ('ramp schedule sample 11', [[[0, 5]], -5], [0, -1]),
  ('ramp schedule sample 30', [[[20, 120], [10, 120], [0, 50], [20, None]], 20], [100, 3]),
  ('ramp schedule sample 46', [[[30, 100], [20, 25], [30, -10], [30, 50], [30, None]], 30], [50, 4])],
 [('hold step keeps previous percentage', [[[0, 25], [30, None]], 40], [25, 1]),
  ('explicit rollback to zero percent', [[[0, 25], [30, 0]], 40], [0, 1]),
  ('over-hundred percent is clamped', [[[0, 150]], 10], [100, 0]),
  ('negative percent is clamped to zero', [[[0, 10], [5, -20]], 10], [0, 1]),
  ('before first step is zero', [[[10, 50]], 5], [0, -1]),
  ('ramp schedule sample 1', [[[45, 0], [45, 5], [20, None], [45, 25], [60, -10], [45, None]], 45], [25, 5]),
  ('ramp schedule sample 16', [[[60, 120]], 60], [100, 0]),
  ('ramp schedule sample 20', [[[45, 25], [45, 75]], 45], [75, 1])],
 [('explicit rollback to zero percent', [[[0, 25], [30, 0]], 40], [0, 1]),
  ('over-hundred percent is clamped', [[[0, 150]], 10], [100, 0]),
  ('negative percent is clamped to zero', [[[0, 10], [5, -20]], 10], [0, 1]),
  ('before first step is zero', [[[10, 50]], 5], [0, -1]),
  ('active index refers to original position', [[[20, 30], [10, 10]], 15], [10, 1]),
  ('ramp schedule sample 21', [[], 0], [0, -1]),
  ('ramp schedule sample 44', [[[60, 5], [45, -10], [30, 100], [30, 50], [60, 25]], 100], [25, 4]),
  ('ramp schedule sample 46', [[[30, 100], [20, 25], [30, -10], [30, 50], [30, None]], 30], [50, 4])]]
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
step scheduled exactly now is active[25, 1][25, 1]Passed
unsorted schedule is ordered by time[25, 2][25, 2]Passed
later entry wins a timestamp tie[50, 1][20, 2]Failed
hold step keeps previous percentage[25, 1][25, 1]Passed
explicit rollback to zero percent[0, 1][0, 1]Passed
duplicate identical steps report the later entry[10, 1][10, 1]Passed
ramp schedule sample 1[25, 3][25, 5]Failed
ramp schedule sample 2[0, -1][0, -1]Passed

SHA-256 / 56ee13539b8f8405662f8000899e90c006eb6c11bfbe10bb857f301f4425bd16

3 / The verified repair

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

N = 1
observations = []
def solve(steps, now):
    order = sorted(range(len(steps)), key=lambda i: (steps[i][0], i))
    current = 0
    active = -1
    for i in order:
        at, pct = steps[i]
        if at > now:
            break
        active = i
        if pct is not None:
            current = min(max(pct, 0), 100)
    return [current, active]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('step scheduled exactly now is active', [[[0, 5], [60, 25]], 60], [25, 1]),
  ('unsorted schedule is ordered by time', [[[60, 50], [0, 10], [30, 25]], 45], [25, 2]),
  ('later entry wins a timestamp tie', [[[0, 5], [30, 50], [30, 20]], 40], [20, 2]),
  ('hold step keeps previous percentage', [[[0, 25], [30, None]], 40], [25, 1]),
  ('explicit rollback to zero percent', [[[0, 25], [30, 0]], 40], [0, 1]),
  ('duplicate identical steps report the later entry', [[[10, 10], [10, 10]], 15], [10, 1]),
  ('ramp schedule sample 1', [[[45, 0], [45, 5], [20, None], [45, 25], [60, -10], [45, None]], 45], [25, 5]),
  ('ramp schedule sample 2', [[[20, 0], [30, 50]], 10], [0, -1])],
 [('unsorted schedule is ordered by time', [[[60, 50], [0, 10], [30, 25]], 45], [25, 2]),
  ('later entry wins a timestamp tie', [[[0, 5], [30, 50], [30, 20]], 40], [20, 2]),
  ('hold step keeps previous percentage', [[[0, 25], [30, None]], 40], [25, 1]),
  ('explicit rollback to zero percent', [[[0, 25], [30, 0]], 40], [0, 1]),
  ('over-hundred percent is clamped', [[[0, 150]], 10], [100, 0]),
  ('duplicate identical steps report the later entry', [[[10, 10], [10, 10]], 15], [10, 1]),
  ('ramp schedule sample 29', [[[60, 100], [60, 120], [20, 25], [20, 50], [60, 75]], 60], [75, 4]),
  ('ramp schedule sample 43', [[[20, 5], [20, 0]], 20], [0, 1])],
 [('later entry wins a timestamp tie', [[[0, 5], [30, 50], [30, 20]], 40], [20, 2]),
  ('hold step keeps previous percentage', [[[0, 25], [30, None]], 40], [25, 1]),
  ('explicit rollback to zero percent', [[[0, 25], [30, 0]], 40], [0, 1]),
  ('over-hundred percent is clamped', [[[0, 150]], 10], [100, 0]),
  ('negative percent is clamped to zero', [[[0, 10], [5, -20]], 10], [0, 1]),
  ('ramp schedule sample 11', [[[0, 5]], -5], [0, -1]),
  ('ramp schedule sample 30', [[[20, 120], [10, 120], [0, 50], [20, None]], 20], [100, 3]),
  ('ramp schedule sample 46', [[[30, 100], [20, 25], [30, -10], [30, 50], [30, None]], 30], [50, 4])],
 [('hold step keeps previous percentage', [[[0, 25], [30, None]], 40], [25, 1]),
  ('explicit rollback to zero percent', [[[0, 25], [30, 0]], 40], [0, 1]),
  ('over-hundred percent is clamped', [[[0, 150]], 10], [100, 0]),
  ('negative percent is clamped to zero', [[[0, 10], [5, -20]], 10], [0, 1]),
  ('before first step is zero', [[[10, 50]], 5], [0, -1]),
  ('ramp schedule sample 1', [[[45, 0], [45, 5], [20, None], [45, 25], [60, -10], [45, None]], 45], [25, 5]),
  ('ramp schedule sample 16', [[[60, 120]], 60], [100, 0]),
  ('ramp schedule sample 20', [[[45, 25], [45, 75]], 45], [75, 1])],
 [('explicit rollback to zero percent', [[[0, 25], [30, 0]], 40], [0, 1]),
  ('over-hundred percent is clamped', [[[0, 150]], 10], [100, 0]),
  ('negative percent is clamped to zero', [[[0, 10], [5, -20]], 10], [0, 1]),
  ('before first step is zero', [[[10, 50]], 5], [0, -1]),
  ('active index refers to original position', [[[20, 30], [10, 10]], 15], [10, 1]),
  ('ramp schedule sample 21', [[], 0], [0, -1]),
  ('ramp schedule sample 44', [[[60, 5], [45, -10], [30, 100], [30, 50], [60, 25]], 100], [25, 4]),
  ('ramp schedule sample 46', [[[30, 100], [20, 25], [30, -10], [30, 50], [30, None]], 30], [50, 4])]]
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
step scheduled exactly now is active[25, 1][25, 1]Passed
unsorted schedule is ordered by time[25, 2][25, 2]Passed
later entry wins a timestamp tie[20, 2][20, 2]Passed
hold step keeps previous percentage[25, 1][25, 1]Passed
explicit rollback to zero percent[0, 1][0, 1]Passed
duplicate identical steps report the later entry[10, 1][10, 1]Passed
ramp schedule sample 1[25, 5][25, 5]Passed
ramp schedule sample 2[0, -1][0, -1]Passed

SHA-256 / e7c76f2a218ff1bdd87a82db00b179071d21f2703d6b12394e6821e56aa2e580

Verification & scope

A deterministic toy flag-evaluation model with a stipulated contract; it does not reproduce any vendor SDK byte for byte. 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:48:52.625211+00:00.

Case digest / fc15fc21064cd53d52ae45e90b5b91767aabb70d5be9d70d8fed20e14f191700