FA-29556 / HTTP retries / Open access
Late response fencing between retry attempts: A completion with a mismatched generation is accepted · case 01
A completion with a mismatched generation is accepted
ROOT CAUSE
A completion with a mismatched generation is accepted
VERIFIED REPAIR
Restore the specified transition if e[1]!=generation or not active:.
Unsuccessful approach: The attempted repair changes the faulty site to if e[1]<generation or not active: 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':
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], ['accepted', 0], '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 / dffee09f7677b890401b34483aecbeb8a63696dcfaae3c213b3147a26737def3
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', ['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], ['accepted', 1], 'stale'], 1, False] | [[['started', 1], 'stale', ['accepted', 4]], 1, False] | Failed |
SHA-256 / fd89692b53dfebb1878a8bc53efba14358b04b89b74bf6b63755a67aa2fbfd8f
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.316939+00:00.
Case digest / 936acb53f88a3fcceda24d71ff0bc93994cd382ab80d9525424d2bbbde212cd8