FA-30496 / HTTP retries / Open access
Retry routing with origin affinity: Candidate first violates retry transition semantics · case 01
Candidate first violates retry transition semantics
ROOT CAUSE
Candidate first violates retry transition semantics
VERIFIED REPAIR
Restore the specified transition active=options[0].
Unsuccessful approach: The attempted repair changes the faulty site to active=options[len(options)//2] but still violates a regression oracle.
Case contract
pool(endpoint IDs) sets ordered available endpoints. begin(request,affinity bool) resets attempted endpoint set and pin. pick selects first healthy untried endpoint; an affinity request must reuse its first endpoint on subsequent retries while healthy. down/up alter health. fail marks current endpoint attempted and clears active route. success finalizes. No route changes are HTTP redirects. Return chosen endpoint or exhausted/terminal/active.
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):
pool=[]; down=set(); tried=set(); pin=None; active=None; affinity=False; terminal=True; out=[]
for e in events:
if e[0]=='pool': pool=list(e[1]); down=set()
elif e[0]=='begin': tried=set(); pin=None; active=None; affinity=e[2]; terminal=False
elif e[0]=='down': down.add(e[1])
elif e[0]=='up': down.discard(e[1])
elif e[0]=='pick':
if terminal: out.append('terminal'); continue
if active is not None: out.append('active'); continue
if affinity and pin is not None:
options=[pin] if pin not in down and pin in pool else []
else: options=[p for p in pool if p not in down and p not in tried]
if not options: out.append('exhausted'); continue
active=options[-1]
if pin is None: pin=active
out.append(active)
elif e[0]=='fail':
if active is not None: tried.add(active)
active=None
elif e[0]=='success': terminal=True; active=None
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('0', solve([]), [])
check('1', solve([('pool',['b','a','c']),('begin','r',False),('pick',),('pick',),('fail',),('pick',),('fail',),('pick',),('fail',),('pick',)]), ['b','active','a','c','exhausted'])
check('2', solve([('pool',['a','b']),('begin','r',True),('pick',),('fail',),('pick',),('fail',),('down','a'),('pick',)]), ['a','a','exhausted'])
check('3', solve([('pool',['a','b','c']),('down','a'),('down','b'),('up','a'),('begin','r',False),('pick',),('fail',),('pick',)]), ['a','c'])
check('4', solve([('pool',['a','b']),('begin','r',True),('pick',),('fail',),('pool',['b']),('pick',),('begin','s',True),('pick',)]), ['a','exhausted','b'])
check('5', solve([('pool',[N,N+1]),('begin','r',False),('pick',),('success',),('pick',),('begin','s',False),('pick',)]), [N,'terminal',N])
check('6', solve([('pool',['a']),('down','a'),('pool',['a']),('begin','r',False),('pick',)]), ['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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| 0 | [] | [] | Passed |
| 1 | ['c', 'active', 'a', 'b', 'exhausted'] | ['b', 'active', 'a', 'c', 'exhausted'] | Failed |
| 2 | ['b', 'b', 'b'] | ['a', 'a', 'exhausted'] | Failed |
| 3 | ['c', 'a'] | ['a', 'c'] | Failed |
| 4 | ['b', 'b', 'b'] | ['a', 'exhausted', 'b'] | Failed |
| 5 | [2, 'terminal', 2] | [1, 'terminal', 1] | Failed |
| 6 | ['a'] | ['a'] | Passed |
SHA-256 / 27d82a44da8b4aa7f762ac9594afdf9146e315f65c61e1c879fc30d5bc4a9f13
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(events):
pool=[]; down=set(); tried=set(); pin=None; active=None; affinity=False; terminal=True; out=[]
for e in events:
if e[0]=='pool': pool=list(e[1]); down=set()
elif e[0]=='begin': tried=set(); pin=None; active=None; affinity=e[2]; terminal=False
elif e[0]=='down': down.add(e[1])
elif e[0]=='up': down.discard(e[1])
elif e[0]=='pick':
if terminal: out.append('terminal'); continue
if active is not None: out.append('active'); continue
if affinity and pin is not None:
options=[pin] if pin not in down and pin in pool else []
else: options=[p for p in pool if p not in down and p not in tried]
if not options: out.append('exhausted'); continue
active=options[len(options)//2]
if pin is None: pin=active
out.append(active)
elif e[0]=='fail':
if active is not None: tried.add(active)
active=None
elif e[0]=='success': terminal=True; active=None
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('0', solve([]), [])
check('1', solve([('pool',['b','a','c']),('begin','r',False),('pick',),('pick',),('fail',),('pick',),('fail',),('pick',),('fail',),('pick',)]), ['b','active','a','c','exhausted'])
check('2', solve([('pool',['a','b']),('begin','r',True),('pick',),('fail',),('pick',),('fail',),('down','a'),('pick',)]), ['a','a','exhausted'])
check('3', solve([('pool',['a','b','c']),('down','a'),('down','b'),('up','a'),('begin','r',False),('pick',),('fail',),('pick',)]), ['a','c'])
check('4', solve([('pool',['a','b']),('begin','r',True),('pick',),('fail',),('pool',['b']),('pick',),('begin','s',True),('pick',)]), ['a','exhausted','b'])
check('5', solve([('pool',[N,N+1]),('begin','r',False),('pick',),('success',),('pick',),('begin','s',False),('pick',)]), [N,'terminal',N])
check('6', solve([('pool',['a']),('down','a'),('pool',['a']),('begin','r',False),('pick',)]), ['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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| 0 | [] | [] | Passed |
| 1 | ['a', 'active', 'c', 'b', 'exhausted'] | ['b', 'active', 'a', 'c', 'exhausted'] | Failed |
| 2 | ['b', 'b', 'b'] | ['a', 'a', 'exhausted'] | Failed |
| 3 | ['c', 'a'] | ['a', 'c'] | Failed |
| 4 | ['b', 'b', 'b'] | ['a', 'exhausted', 'b'] | Failed |
| 5 | [2, 'terminal', 2] | [1, 'terminal', 1] | Failed |
| 6 | ['a'] | ['a'] | Passed |
SHA-256 / e10e817b1579d6104cd0b58a6100f055df367067ee8635f1c1ea491b4be46541
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(events):
pool=[]; down=set(); tried=set(); pin=None; active=None; affinity=False; terminal=True; out=[]
for e in events:
if e[0]=='pool': pool=list(e[1]); down=set()
elif e[0]=='begin': tried=set(); pin=None; active=None; affinity=e[2]; terminal=False
elif e[0]=='down': down.add(e[1])
elif e[0]=='up': down.discard(e[1])
elif e[0]=='pick':
if terminal: out.append('terminal'); continue
if active is not None: out.append('active'); continue
if affinity and pin is not None:
options=[pin] if pin not in down and pin in pool else []
else: options=[p for p in pool if p not in down and p not in tried]
if not options: out.append('exhausted'); continue
active=options[0]
if pin is None: pin=active
out.append(active)
elif e[0]=='fail':
if active is not None: tried.add(active)
active=None
elif e[0]=='success': terminal=True; active=None
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('0', solve([]), [])
check('1', solve([('pool',['b','a','c']),('begin','r',False),('pick',),('pick',),('fail',),('pick',),('fail',),('pick',),('fail',),('pick',)]), ['b','active','a','c','exhausted'])
check('2', solve([('pool',['a','b']),('begin','r',True),('pick',),('fail',),('pick',),('fail',),('down','a'),('pick',)]), ['a','a','exhausted'])
check('3', solve([('pool',['a','b','c']),('down','a'),('down','b'),('up','a'),('begin','r',False),('pick',),('fail',),('pick',)]), ['a','c'])
check('4', solve([('pool',['a','b']),('begin','r',True),('pick',),('fail',),('pool',['b']),('pick',),('begin','s',True),('pick',)]), ['a','exhausted','b'])
check('5', solve([('pool',[N,N+1]),('begin','r',False),('pick',),('success',),('pick',),('begin','s',False),('pick',)]), [N,'terminal',N])
check('6', solve([('pool',['a']),('down','a'),('pool',['a']),('begin','r',False),('pick',)]), ['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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| 0 | [] | [] | Passed |
| 1 | ['b', 'active', 'a', 'c', 'exhausted'] | ['b', 'active', 'a', 'c', 'exhausted'] | Passed |
| 2 | ['a', 'a', 'exhausted'] | ['a', 'a', 'exhausted'] | Passed |
| 3 | ['a', 'c'] | ['a', 'c'] | Passed |
| 4 | ['a', 'exhausted', 'b'] | ['a', 'exhausted', 'b'] | Passed |
| 5 | [1, 'terminal', 1] | [1, 'terminal', 1] | Passed |
| 6 | ['a'] | ['a'] | Passed |
SHA-256 / d433c3d9153f50c3ac08692cbfe212634a37294d0cd82aabb185450f7c4bb3c9
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:53.472392+00:00.
Case digest / 9d8d797e7095cc01ebb58b180e91c9c4bdba1709a61751e0116b69a045d8ee00