FA-29541 / HTTP retries / Open access
Late response fencing between retry attempts: An old timeout invalidates a newer retry attempt · case 01
An old timeout invalidates a newer retry attempt
ROOT CAUSE
An old timeout invalidates a newer retry attempt
VERIFIED REPAIR
Restore the specified transition if e[1]==generation: active=False.
Unsuccessful approach: The attempted repair changes the faulty site to if e[1]<=generation: active=False but still violates a regression oracle.
Case contract
start allocates a strictly increasing generation. complete(generation,value) publishes only the current active generation and terminates it; duplicate/stale results are rejected. timeout(generation) deactivates only that generation. cancel terminates the logical request permanently. Return accepted/rejected results plus current generation and cancellation flag.
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):
generation=0; active=False; cancelled=False; out=[]
for e in events:
if e[0]=='start':
if cancelled: out.append('cancelled'); continue
generation+=1
active=True
out.append(['started',generation])
elif e[0]=='timeout':
active=False
elif e[0]=='cancel':
cancelled=True
active=False
elif e[0]=='complete':
if cancelled: out.append('cancelled'); continue
if e[1]!=generation or not active:
out.append('stale'); continue
out.append(['accepted',e[2]])
active=False
return [out,generation,cancelled]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('0', solve([]), [[],0,False])
check('1', solve([('start',),('complete',1,N),('complete',1,N+1)]), [[['started',1],['accepted',N],'stale'],1,False])
check('2', solve([('start',),('start',),('timeout',1),('complete',1,0),('complete',2,N+5)]), [[['started',1],['started',2],'stale',['accepted',N+5]],2,False])
check('3', solve([('start',),('timeout',1),('complete',1,N)]), [[['started',1],'stale'],1,False])
check('4', solve([('start',),('cancel',),('complete',1,N),('start',)]), [[['started',1],'cancelled','cancelled'],1,True])
check('5', solve([('start',),('complete',2,N),('complete',1,N+3)]), [[['started',1],'stale',['accepted',N+3]],1,False])
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| 0 | [[], 0, False] | [[], 0, False] | Passed |
| 1 | [[['started', 1], ['accepted', 1], 'stale'], 1, False] | [[['started', 1], ['accepted', 1], 'stale'], 1, False] | Passed |
| 2 | [[['started', 1], ['started', 2], 'stale', 'stale'], 2, False] | [[['started', 1], ['started', 2], 'stale', ['accepted', 6]], 2, False] | Failed |
| 3 | [[['started', 1], 'stale'], 1, False] | [[['started', 1], 'stale'], 1, False] | Passed |
| 4 | [[['started', 1], 'cancelled', 'cancelled'], 1, True] | [[['started', 1], 'cancelled', 'cancelled'], 1, True] | Passed |
| 5 | [[['started', 1], 'stale', ['accepted', 4]], 1, False] | [[['started', 1], 'stale', ['accepted', 4]], 1, False] | Passed |
SHA-256 / bb4ac95945e684936e3c71b1b1fe76709abc3ef227d93971a1d2aaa1758d1307
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(events):
generation=0; active=False; cancelled=False; out=[]
for e in events:
if e[0]=='start':
if cancelled: out.append('cancelled'); continue
generation+=1
active=True
out.append(['started',generation])
elif e[0]=='timeout':
if e[1]<=generation: active=False
elif e[0]=='cancel':
cancelled=True
active=False
elif e[0]=='complete':
if cancelled: out.append('cancelled'); continue
if e[1]!=generation or not active:
out.append('stale'); continue
out.append(['accepted',e[2]])
active=False
return [out,generation,cancelled]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('0', solve([]), [[],0,False])
check('1', solve([('start',),('complete',1,N),('complete',1,N+1)]), [[['started',1],['accepted',N],'stale'],1,False])
check('2', solve([('start',),('start',),('timeout',1),('complete',1,0),('complete',2,N+5)]), [[['started',1],['started',2],'stale',['accepted',N+5]],2,False])
check('3', solve([('start',),('timeout',1),('complete',1,N)]), [[['started',1],'stale'],1,False])
check('4', solve([('start',),('cancel',),('complete',1,N),('start',)]), [[['started',1],'cancelled','cancelled'],1,True])
check('5', solve([('start',),('complete',2,N),('complete',1,N+3)]), [[['started',1],'stale',['accepted',N+3]],1,False])
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| 0 | [[], 0, False] | [[], 0, False] | Passed |
| 1 | [[['started', 1], ['accepted', 1], 'stale'], 1, False] | [[['started', 1], ['accepted', 1], 'stale'], 1, False] | Passed |
| 2 | [[['started', 1], ['started', 2], 'stale', 'stale'], 2, False] | [[['started', 1], ['started', 2], 'stale', ['accepted', 6]], 2, False] | Failed |
| 3 | [[['started', 1], 'stale'], 1, False] | [[['started', 1], 'stale'], 1, False] | Passed |
| 4 | [[['started', 1], 'cancelled', 'cancelled'], 1, True] | [[['started', 1], 'cancelled', 'cancelled'], 1, True] | Passed |
| 5 | [[['started', 1], 'stale', ['accepted', 4]], 1, False] | [[['started', 1], 'stale', ['accepted', 4]], 1, False] | Passed |
SHA-256 / d4cb865f9e59dbfca5cfd76c591a55ba72be9b3ca8ac54a6d8feb711f4dc9056
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(events):
generation=0; active=False; cancelled=False; out=[]
for e in events:
if e[0]=='start':
if cancelled: out.append('cancelled'); continue
generation+=1
active=True
out.append(['started',generation])
elif e[0]=='timeout':
if e[1]==generation: active=False
elif e[0]=='cancel':
cancelled=True
active=False
elif e[0]=='complete':
if cancelled: out.append('cancelled'); continue
if e[1]!=generation or not active:
out.append('stale'); continue
out.append(['accepted',e[2]])
active=False
return [out,generation,cancelled]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('0', solve([]), [[],0,False])
check('1', solve([('start',),('complete',1,N),('complete',1,N+1)]), [[['started',1],['accepted',N],'stale'],1,False])
check('2', solve([('start',),('start',),('timeout',1),('complete',1,0),('complete',2,N+5)]), [[['started',1],['started',2],'stale',['accepted',N+5]],2,False])
check('3', solve([('start',),('timeout',1),('complete',1,N)]), [[['started',1],'stale'],1,False])
check('4', solve([('start',),('cancel',),('complete',1,N),('start',)]), [[['started',1],'cancelled','cancelled'],1,True])
check('5', solve([('start',),('complete',2,N),('complete',1,N+3)]), [[['started',1],'stale',['accepted',N+3]],1,False])
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| 0 | [[], 0, False] | [[], 0, False] | Passed |
| 1 | [[['started', 1], ['accepted', 1], 'stale'], 1, False] | [[['started', 1], ['accepted', 1], 'stale'], 1, False] | Passed |
| 2 | [[['started', 1], ['started', 2], 'stale', ['accepted', 6]], 2, False] | [[['started', 1], ['started', 2], 'stale', ['accepted', 6]], 2, False] | Passed |
| 3 | [[['started', 1], 'stale'], 1, False] | [[['started', 1], 'stale'], 1, False] | Passed |
| 4 | [[['started', 1], 'cancelled', 'cancelled'], 1, True] | [[['started', 1], 'cancelled', 'cancelled'], 1, True] | Passed |
| 5 | [[['started', 1], 'stale', ['accepted', 4]], 1, False] | [[['started', 1], 'stale', ['accepted', 4]], 1, False] | Passed |
SHA-256 / 8e8a2bf9e28bc971355127f54fa2c3ceb07446320764b1c5ecca727355503ee9
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:44.205493+00:00.
Case digest / 42181ce953224d2796e7a9e361cc7d6696894433bb7c40c229979a27b7ad1267