FAILURE MAP
← Case archive

FA-29941 / HTTP retries / Open access

Retry budget reservation lifecycle: Refill cap violates retry transition semantics · case 01

Refill cap violates retry transition semantics

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

ROOT CAUSE

Refill cap violates retry transition semantics

VERIFIED REPAIR

Restore the specified transition min(capacity-len(held),available+e[1]).

Unsuccessful approach: The attempted repair changes the faulty site to max(capacity-len(held),available+e[1]) but still violates a regression oracle.

Case contract

configure(capacity) resets a shared retry pool. reserve(request) consumes one token only for a new reservation; commit spends its token and removes the reservation, abort refunds exactly once, refill is capped. Repeated reserve is idempotent; unknown commit/abort does nothing. Return admissions and available token count.

Why this case matters

Offline deterministic model of HTTP request retries.

1 / The failure

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

N = 1
observations = []
def solve(events):
    capacity=0; available=0; held=set(); out=[]
    for e in events:
        if e[0]=='configure':
            capacity=e[1]; available=capacity; held.clear()
        elif e[0]=='reserve':
            if e[1] in held: out.append('held'); continue
            if available==0: out.append('denied'); continue
            available-=1
            held.add(e[1])
            out.append('reserved')
        elif e[0]=='commit':
            if e[1] in held:
                held.remove(e[1])
        elif e[0]=='abort':
            if e[1] in held:
                held.remove(e[1])
                available=min(capacity,available+1)
        elif e[0]=='refill':
            available=available+e[1]
    return [out,available,sorted(held)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('0', solve([('configure',3),('reserve','a'),('reserve','b'),('abort','a')]), [['reserved','reserved'],2,['b']])
check('1', solve([('configure',3),('reserve','a'),('commit','a'),('reserve','a'),('commit','a'),('reserve','a'),('commit','a'),('refill',2)]), [['reserved','reserved','reserved'],2,[]])
check('2', solve([]), [[],0,[]])
check('3', solve([('configure',0),('reserve','a')]), [['denied'],0,[]])
check('4', solve([('configure',2),('reserve','a'),('reserve','a'),('reserve','b'),('reserve','c')]), [['reserved','held','reserved','denied'],0,['a','b']])
check('5', solve([('configure',3),('reserve','a'),('reserve','b'),('commit','a'),('abort','a'),('abort','b'),('abort','b')]), [['reserved','reserved'],2,[]])
check('6', solve([('configure',N+3),('reserve','a'),('refill',N+10)]), [['reserved'],N+2,['a']])
check('7', solve([('configure',4),('reserve','a'),('commit','a'),('reserve','b'),('commit','b'),('refill',1)]), [['reserved','reserved'],3,[]])
check('8', solve([('configure',1),('reserve','a'),('configure',2),('reserve','a')]), [['reserved','reserved'],1,['a']])
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
0[['reserved', 'reserved'], 2, ['b']][['reserved', 'reserved'], 2, ['b']]Passed
1[['reserved', 'reserved', 'reserved'], 2, []][['reserved', 'reserved', 'reserved'], 2, []]Passed
2[[], 0, []][[], 0, []]Passed
3[['denied'], 0, []][['denied'], 0, []]Passed
4[['reserved', 'held', 'reserved', 'denied'], 0, ['a', 'b']][['reserved', 'held', 'reserved', 'denied'], 0, ['a', 'b']]Passed
5[['reserved', 'reserved'], 2, []][['reserved', 'reserved'], 2, []]Passed
6[['reserved'], 14, ['a']][['reserved'], 3, ['a']]Failed
7[['reserved', 'reserved'], 3, []][['reserved', 'reserved'], 3, []]Passed
8[['reserved', 'reserved'], 1, ['a']][['reserved', 'reserved'], 1, ['a']]Passed

SHA-256 / 90b4e25829eb31607781d550adade5741c24eb582bf505c17d53ad807b18cd49

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(events):
    capacity=0; available=0; held=set(); out=[]
    for e in events:
        if e[0]=='configure':
            capacity=e[1]; available=capacity; held.clear()
        elif e[0]=='reserve':
            if e[1] in held: out.append('held'); continue
            if available==0: out.append('denied'); continue
            available-=1
            held.add(e[1])
            out.append('reserved')
        elif e[0]=='commit':
            if e[1] in held:
                held.remove(e[1])
        elif e[0]=='abort':
            if e[1] in held:
                held.remove(e[1])
                available=min(capacity,available+1)
        elif e[0]=='refill':
            available=max(capacity-len(held),available+e[1])
    return [out,available,sorted(held)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('0', solve([('configure',3),('reserve','a'),('reserve','b'),('abort','a')]), [['reserved','reserved'],2,['b']])
check('1', solve([('configure',3),('reserve','a'),('commit','a'),('reserve','a'),('commit','a'),('reserve','a'),('commit','a'),('refill',2)]), [['reserved','reserved','reserved'],2,[]])
check('2', solve([]), [[],0,[]])
check('3', solve([('configure',0),('reserve','a')]), [['denied'],0,[]])
check('4', solve([('configure',2),('reserve','a'),('reserve','a'),('reserve','b'),('reserve','c')]), [['reserved','held','reserved','denied'],0,['a','b']])
check('5', solve([('configure',3),('reserve','a'),('reserve','b'),('commit','a'),('abort','a'),('abort','b'),('abort','b')]), [['reserved','reserved'],2,[]])
check('6', solve([('configure',N+3),('reserve','a'),('refill',N+10)]), [['reserved'],N+2,['a']])
check('7', solve([('configure',4),('reserve','a'),('commit','a'),('reserve','b'),('commit','b'),('refill',1)]), [['reserved','reserved'],3,[]])
check('8', solve([('configure',1),('reserve','a'),('configure',2),('reserve','a')]), [['reserved','reserved'],1,['a']])
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
0[['reserved', 'reserved'], 2, ['b']][['reserved', 'reserved'], 2, ['b']]Passed
1[['reserved', 'reserved', 'reserved'], 3, []][['reserved', 'reserved', 'reserved'], 2, []]Failed
2[[], 0, []][[], 0, []]Passed
3[['denied'], 0, []][['denied'], 0, []]Passed
4[['reserved', 'held', 'reserved', 'denied'], 0, ['a', 'b']][['reserved', 'held', 'reserved', 'denied'], 0, ['a', 'b']]Passed
5[['reserved', 'reserved'], 2, []][['reserved', 'reserved'], 2, []]Passed
6[['reserved'], 14, ['a']][['reserved'], 3, ['a']]Failed
7[['reserved', 'reserved'], 4, []][['reserved', 'reserved'], 3, []]Failed
8[['reserved', 'reserved'], 1, ['a']][['reserved', 'reserved'], 1, ['a']]Passed

SHA-256 / 4703a4d44e7f71aa19ee881820b8fe7ee6ac9f5e3d779276f8f8267254db4ed7

3 / The verified repair

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

N = 1
observations = []
def solve(events):
    capacity=0; available=0; held=set(); out=[]
    for e in events:
        if e[0]=='configure':
            capacity=e[1]; available=capacity; held.clear()
        elif e[0]=='reserve':
            if e[1] in held: out.append('held'); continue
            if available==0: out.append('denied'); continue
            available-=1
            held.add(e[1])
            out.append('reserved')
        elif e[0]=='commit':
            if e[1] in held:
                held.remove(e[1])
        elif e[0]=='abort':
            if e[1] in held:
                held.remove(e[1])
                available=min(capacity,available+1)
        elif e[0]=='refill':
            available=min(capacity-len(held),available+e[1])
    return [out,available,sorted(held)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('0', solve([('configure',3),('reserve','a'),('reserve','b'),('abort','a')]), [['reserved','reserved'],2,['b']])
check('1', solve([('configure',3),('reserve','a'),('commit','a'),('reserve','a'),('commit','a'),('reserve','a'),('commit','a'),('refill',2)]), [['reserved','reserved','reserved'],2,[]])
check('2', solve([]), [[],0,[]])
check('3', solve([('configure',0),('reserve','a')]), [['denied'],0,[]])
check('4', solve([('configure',2),('reserve','a'),('reserve','a'),('reserve','b'),('reserve','c')]), [['reserved','held','reserved','denied'],0,['a','b']])
check('5', solve([('configure',3),('reserve','a'),('reserve','b'),('commit','a'),('abort','a'),('abort','b'),('abort','b')]), [['reserved','reserved'],2,[]])
check('6', solve([('configure',N+3),('reserve','a'),('refill',N+10)]), [['reserved'],N+2,['a']])
check('7', solve([('configure',4),('reserve','a'),('commit','a'),('reserve','b'),('commit','b'),('refill',1)]), [['reserved','reserved'],3,[]])
check('8', solve([('configure',1),('reserve','a'),('configure',2),('reserve','a')]), [['reserved','reserved'],1,['a']])
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
0[['reserved', 'reserved'], 2, ['b']][['reserved', 'reserved'], 2, ['b']]Passed
1[['reserved', 'reserved', 'reserved'], 2, []][['reserved', 'reserved', 'reserved'], 2, []]Passed
2[[], 0, []][[], 0, []]Passed
3[['denied'], 0, []][['denied'], 0, []]Passed
4[['reserved', 'held', 'reserved', 'denied'], 0, ['a', 'b']][['reserved', 'held', 'reserved', 'denied'], 0, ['a', 'b']]Passed
5[['reserved', 'reserved'], 2, []][['reserved', 'reserved'], 2, []]Passed
6[['reserved'], 3, ['a']][['reserved'], 3, ['a']]Passed
7[['reserved', 'reserved'], 3, []][['reserved', 'reserved'], 3, []]Passed
8[['reserved', 'reserved'], 1, ['a']][['reserved', 'reserved'], 1, ['a']]Passed

SHA-256 / 7697ed66b0cd8c4c97edc64b0a4a54e1223e32323ce614329d3eea4f2672b5ce

Verification & scope

Stipulated bounded simulator, not a complete HTTP implementation or a standards conformance claim. 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:41:48.091230+00:00.

Case digest / 60fa66f0d6c5d287b5602ddb1693d216af461193ca8728063c2d377f72e5a08e