FA-30401 / HTTP retries / Open access
Logical request deadline across retry phases: Queue expiry violates retry transition semantics · case 01
Queue expiry violates retry transition semantics
ROOT CAUSE
Queue expiry violates retry transition semantics
VERIFIED REPAIR
Restore the specified transition if now>=deadline: state='expired'; out.append('expired'); continue due.
Unsuccessful approach: The attempted repair changes the faulty site to if False: state='expired'; out.append('expired'); continue due but still violates a regression oracle.
Case contract
begin(now,budget) pins a logical deadline. advance(time) uses monotonic logical time. queue(delay) schedules retry only for live request, wake starts only after due and strictly before deadline, complete succeeds only for running attempt before deadline. finish/cancel are terminal. Admission at expired time reports expired and closes request; queue never extends deadline. Return scheduling/attempt dispositions.
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):
now=0; deadline=0; due=None; state='idle'; out=[]
for e in events:
if e[0]=='begin':
now=e[1]; deadline=now+e[2]; due=None; state='ready'
elif e[0]=='advance': now=max(now,e[1])
elif e[0]=='cancel': state='cancelled'; due=None
elif e[0]=='queue':
if state not in ('ready','failed'): out.append('blocked'); continue
if now>deadline: state='expired'; out.append('expired'); continue
due=now+e[1]; state='queued'; out.append(['queued',due])
elif e[0]=='wake':
if state!='queued': out.append('blocked'); continue
if now>=deadline: state='expired'; due=None; out.append('expired'); continue
if now<due: out.append('early'); continue
state='running'; due=None; out.append('started')
elif e[0]=='fail':
if state=='running': state='failed'
elif e[0]=='complete':
if state!='running': out.append('blocked'); continue
if now>=deadline: state='expired'; out.append('expired'); continue
state='done'; out.append('success')
return [out,deadline,state]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('0', solve([]), [[],0,'idle'])
check('1', solve([('begin',N,5),('queue',2),('wake',),('advance',N+2),('wake',),('complete',),('queue',0)]), [[['queued',N+2],'early','started','success','blocked'],N+5,'done'])
check('2', solve([('begin',N,2),('queue',2),('advance',N+2),('wake',)]), [[['queued',N+2],'expired'],N+2,'expired'])
check('3', solve([('begin',N,2),('advance',N+2),('queue',0)]), [['expired'],N+2,'expired'])
check('4', solve([('begin',N,2),('queue',0),('wake',),('advance',N+2),('complete',)]), [[['queued',N],'started','expired'],N+2,'expired'])
check('5', solve([('begin',N,5),('queue',0),('wake',),('fail',),('queue',1),('advance',N+1),('wake',),('cancel',),('queue',0)]), [[['queued',N],'started',['queued',N+1],'started','blocked'],N+5,'cancelled'])
check('6', solve([('begin',N,2),('advance',N+3),('advance',N),('queue',0)]), [['expired'],N+2,'expired'])
check('7', solve([('begin',N,3),('cancel',),('fail',),('queue',0)]), [['blocked'],N+3,'cancelled'])
check('8', solve([('begin',N,5),('queue',0),('wake',),('fail',)]), [[['queued',N],'started'],N+5,'failed'])
check('9', solve([('begin',N,5),('cancel',),('wake',)]), [['blocked'],N+5,'cancelled'])
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, 'idle'] | [[], 0, 'idle'] | Passed |
| 1 | [[['queued', 3], 'early', 'started', 'success', 'blocked'], 6, 'done'] | [[['queued', 3], 'early', 'started', 'success', 'blocked'], 6, 'done'] | Passed |
| 2 | [[['queued', 3], 'expired'], 3, 'expired'] | [[['queued', 3], 'expired'], 3, 'expired'] | Passed |
| 3 | [[['queued', 3]], 3, 'queued'] | [['expired'], 3, 'expired'] | Failed |
| 4 | [[['queued', 1], 'started', 'expired'], 3, 'expired'] | [[['queued', 1], 'started', 'expired'], 3, 'expired'] | Passed |
| 5 | [[['queued', 1], 'started', ['queued', 2], 'started', 'blocked'], 6, 'cancelled'] | [[['queued', 1], 'started', ['queued', 2], 'started', 'blocked'], 6, 'cancelled'] | Passed |
| 6 | [['expired'], 3, 'expired'] | [['expired'], 3, 'expired'] | Passed |
| 7 | [['blocked'], 4, 'cancelled'] | [['blocked'], 4, 'cancelled'] | Passed |
| 8 | [[['queued', 1], 'started'], 6, 'failed'] | [[['queued', 1], 'started'], 6, 'failed'] | Passed |
| 9 | [['blocked'], 6, 'cancelled'] | [['blocked'], 6, 'cancelled'] | Passed |
SHA-256 / 35e4a4cf5f6946843ff18e6183b424b6450b6542309189d4ee0642de95188b10
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(events):
now=0; deadline=0; due=None; state='idle'; out=[]
for e in events:
if e[0]=='begin':
now=e[1]; deadline=now+e[2]; due=None; state='ready'
elif e[0]=='advance': now=max(now,e[1])
elif e[0]=='cancel': state='cancelled'; due=None
elif e[0]=='queue':
if state not in ('ready','failed'): out.append('blocked'); continue
if False: state='expired'; out.append('expired'); continue
due=now+e[1]; state='queued'; out.append(['queued',due])
elif e[0]=='wake':
if state!='queued': out.append('blocked'); continue
if now>=deadline: state='expired'; due=None; out.append('expired'); continue
if now<due: out.append('early'); continue
state='running'; due=None; out.append('started')
elif e[0]=='fail':
if state=='running': state='failed'
elif e[0]=='complete':
if state!='running': out.append('blocked'); continue
if now>=deadline: state='expired'; out.append('expired'); continue
state='done'; out.append('success')
return [out,deadline,state]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('0', solve([]), [[],0,'idle'])
check('1', solve([('begin',N,5),('queue',2),('wake',),('advance',N+2),('wake',),('complete',),('queue',0)]), [[['queued',N+2],'early','started','success','blocked'],N+5,'done'])
check('2', solve([('begin',N,2),('queue',2),('advance',N+2),('wake',)]), [[['queued',N+2],'expired'],N+2,'expired'])
check('3', solve([('begin',N,2),('advance',N+2),('queue',0)]), [['expired'],N+2,'expired'])
check('4', solve([('begin',N,2),('queue',0),('wake',),('advance',N+2),('complete',)]), [[['queued',N],'started','expired'],N+2,'expired'])
check('5', solve([('begin',N,5),('queue',0),('wake',),('fail',),('queue',1),('advance',N+1),('wake',),('cancel',),('queue',0)]), [[['queued',N],'started',['queued',N+1],'started','blocked'],N+5,'cancelled'])
check('6', solve([('begin',N,2),('advance',N+3),('advance',N),('queue',0)]), [['expired'],N+2,'expired'])
check('7', solve([('begin',N,3),('cancel',),('fail',),('queue',0)]), [['blocked'],N+3,'cancelled'])
check('8', solve([('begin',N,5),('queue',0),('wake',),('fail',)]), [[['queued',N],'started'],N+5,'failed'])
check('9', solve([('begin',N,5),('cancel',),('wake',)]), [['blocked'],N+5,'cancelled'])
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, 'idle'] | [[], 0, 'idle'] | Passed |
| 1 | [[['queued', 3], 'early', 'started', 'success', 'blocked'], 6, 'done'] | [[['queued', 3], 'early', 'started', 'success', 'blocked'], 6, 'done'] | Passed |
| 2 | [[['queued', 3], 'expired'], 3, 'expired'] | [[['queued', 3], 'expired'], 3, 'expired'] | Passed |
| 3 | [[['queued', 3]], 3, 'queued'] | [['expired'], 3, 'expired'] | Failed |
| 4 | [[['queued', 1], 'started', 'expired'], 3, 'expired'] | [[['queued', 1], 'started', 'expired'], 3, 'expired'] | Passed |
| 5 | [[['queued', 1], 'started', ['queued', 2], 'started', 'blocked'], 6, 'cancelled'] | [[['queued', 1], 'started', ['queued', 2], 'started', 'blocked'], 6, 'cancelled'] | Passed |
| 6 | [[['queued', 4]], 3, 'queued'] | [['expired'], 3, 'expired'] | Failed |
| 7 | [['blocked'], 4, 'cancelled'] | [['blocked'], 4, 'cancelled'] | Passed |
| 8 | [[['queued', 1], 'started'], 6, 'failed'] | [[['queued', 1], 'started'], 6, 'failed'] | Passed |
| 9 | [['blocked'], 6, 'cancelled'] | [['blocked'], 6, 'cancelled'] | Passed |
SHA-256 / 0feade9f2203bbf2d2359131963704d5920ed275db0cd31070d1f612d0d9ea0b
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(events):
now=0; deadline=0; due=None; state='idle'; out=[]
for e in events:
if e[0]=='begin':
now=e[1]; deadline=now+e[2]; due=None; state='ready'
elif e[0]=='advance': now=max(now,e[1])
elif e[0]=='cancel': state='cancelled'; due=None
elif e[0]=='queue':
if state not in ('ready','failed'): out.append('blocked'); continue
if now>=deadline: state='expired'; out.append('expired'); continue
due=now+e[1]; state='queued'; out.append(['queued',due])
elif e[0]=='wake':
if state!='queued': out.append('blocked'); continue
if now>=deadline: state='expired'; due=None; out.append('expired'); continue
if now<due: out.append('early'); continue
state='running'; due=None; out.append('started')
elif e[0]=='fail':
if state=='running': state='failed'
elif e[0]=='complete':
if state!='running': out.append('blocked'); continue
if now>=deadline: state='expired'; out.append('expired'); continue
state='done'; out.append('success')
return [out,deadline,state]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('0', solve([]), [[],0,'idle'])
check('1', solve([('begin',N,5),('queue',2),('wake',),('advance',N+2),('wake',),('complete',),('queue',0)]), [[['queued',N+2],'early','started','success','blocked'],N+5,'done'])
check('2', solve([('begin',N,2),('queue',2),('advance',N+2),('wake',)]), [[['queued',N+2],'expired'],N+2,'expired'])
check('3', solve([('begin',N,2),('advance',N+2),('queue',0)]), [['expired'],N+2,'expired'])
check('4', solve([('begin',N,2),('queue',0),('wake',),('advance',N+2),('complete',)]), [[['queued',N],'started','expired'],N+2,'expired'])
check('5', solve([('begin',N,5),('queue',0),('wake',),('fail',),('queue',1),('advance',N+1),('wake',),('cancel',),('queue',0)]), [[['queued',N],'started',['queued',N+1],'started','blocked'],N+5,'cancelled'])
check('6', solve([('begin',N,2),('advance',N+3),('advance',N),('queue',0)]), [['expired'],N+2,'expired'])
check('7', solve([('begin',N,3),('cancel',),('fail',),('queue',0)]), [['blocked'],N+3,'cancelled'])
check('8', solve([('begin',N,5),('queue',0),('wake',),('fail',)]), [[['queued',N],'started'],N+5,'failed'])
check('9', solve([('begin',N,5),('cancel',),('wake',)]), [['blocked'],N+5,'cancelled'])
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, 'idle'] | [[], 0, 'idle'] | Passed |
| 1 | [[['queued', 3], 'early', 'started', 'success', 'blocked'], 6, 'done'] | [[['queued', 3], 'early', 'started', 'success', 'blocked'], 6, 'done'] | Passed |
| 2 | [[['queued', 3], 'expired'], 3, 'expired'] | [[['queued', 3], 'expired'], 3, 'expired'] | Passed |
| 3 | [['expired'], 3, 'expired'] | [['expired'], 3, 'expired'] | Passed |
| 4 | [[['queued', 1], 'started', 'expired'], 3, 'expired'] | [[['queued', 1], 'started', 'expired'], 3, 'expired'] | Passed |
| 5 | [[['queued', 1], 'started', ['queued', 2], 'started', 'blocked'], 6, 'cancelled'] | [[['queued', 1], 'started', ['queued', 2], 'started', 'blocked'], 6, 'cancelled'] | Passed |
| 6 | [['expired'], 3, 'expired'] | [['expired'], 3, 'expired'] | Passed |
| 7 | [['blocked'], 4, 'cancelled'] | [['blocked'], 4, 'cancelled'] | Passed |
| 8 | [[['queued', 1], 'started'], 6, 'failed'] | [[['queued', 1], 'started'], 6, 'failed'] | Passed |
| 9 | [['blocked'], 6, 'cancelled'] | [['blocked'], 6, 'cancelled'] | Passed |
SHA-256 / e6f1aa764c2dfd68929b23b7f3e64ecda5d21dbc3576297149619285c013b3b0
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:52.611519+00:00.
Case digest / d879c2d376ce2e34de363f5c1e1c6c96bce9177600e6baf57efafd957edec90a