FA-20586 / Assistive announcements / Open access
Draining replays queued announcements at the next drain · case 01
The announcement trace violates the stated context-lease contract.
ROOT CAUSE
Fault site: queue.clear() is implemented as pass
VERIFIED REPAIR
Restore the stated transition: queue.clear()
Unsuccessful approach: The attempted repair substitutes queue[:]=queue[-1:] and still violates a regression oracle.
Case contract
Announcement context leases map source to [epoch,text]. Register increments the source epoch and clears its text; publish requires a live source and matching epoch. Queue snapshots text plus source epoch. Drain speaks only still-live matching leases. Remove revokes source. Rename transfers a source lease and invalidates queued old-source messages. Report spoken and queue depth.
Why this case matters
Deterministic controlled model of assistive announcement delivery.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(events):
leases={}; epochs={}; queue=[]; spoken=[]
for e in events:
if e[0]=='register':
epochs[e[1]]=epochs.get(e[1],0)+1
leases[e[1]]=[epochs[e[1]],'']
elif e[0]=='publish':
if e[1] not in leases: continue
if e[2]!=leases[e[1]][0]: continue
leases[e[1]][1]=e[3]
elif e[0]=='queue' and e[1] in leases:
queue.append([e[1],leases[e[1]][0],leases[e[1]][1]])
elif e[0]=='remove': leases.pop(e[1],None)
elif e[0]=='rename' and e[1] in leases:
leases[e[2]]=leases.pop(e[1])
elif e[0]=='drain':
for source,epoch,text in queue:
if source not in leases: continue
if leases[source][0]!=epoch: continue
if text: spoken.append(text)
pass
return [spoken,len(queue),sorted((k,v) for k,v in leases.items())]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = ["[['register','a'],['publish','a',1,'old'*N],['queue','a'],['publish','a',1,'new'],['drain'],['drain']]", "[['register','a'],['publish','a',1,'old'],['queue','a'],['register','a'],['publish','a',1,'stale'*N],['queue','a'],['drain']]", "[['register','a'],['register','b'],['publish','b',1,'keep'*N],['remove','a'],['queue','b'],['drain']]", "[['register','a'],['publish','a',1,'hello'*N],['queue','a'],['rename','a','b'],['queue','b'],['drain']]", "[['register','a'],['queue','a'],['drain'],['publish','a',1,' x '*N],['queue','a'],['drain']]", "[['publish','missing',1,'x'*N],['remove','missing'],['drain']]", "[['register','a'],['publish','a',1,'x'*N],['queue','a'],['remove','a'],['drain']]"]
expected = {1: [[['old'], 0, [('a', [1, 'new'])]], [[], 0, [('a', [2, ''])]], [['keep'], 0, [('b', [1, 'keep'])]], [['hello'], 0, [('b', [1, 'hello'])]], [[' x '], 0, [('a', [1, ' x '])]], [[], 0, []], [[], 0, []]], 2: [[['oldold'], 0, [('a', [1, 'new'])]], [[], 0, [('a', [2, ''])]], [['keepkeep'], 0, [('b', [1, 'keepkeep'])]], [['hellohello'], 0, [('b', [1, 'hellohello'])]], [[' x x '], 0, [('a', [1, ' x x '])]], [[], 0, []], [[], 0, []]], 3: [[['oldoldold'], 0, [('a', [1, 'new'])]], [[], 0, [('a', [2, ''])]], [['keepkeepkeep'], 0, [('b', [1, 'keepkeepkeep'])]], [['hellohellohello'], 0, [('b', [1, 'hellohellohello'])]], [[' x x x '], 0, [('a', [1, ' x x x '])]], [[], 0, []], [[], 0, []]], 4: [[['oldoldoldold'], 0, [('a', [1, 'new'])]], [[], 0, [('a', [2, ''])]], [['keepkeepkeepkeep'], 0, [('b', [1, 'keepkeepkeepkeep'])]], [['hellohellohellohello'], 0, [('b', [1, 'hellohellohellohello'])]], [[' x x x x '], 0, [('a', [1, ' x x x x '])]], [[], 0, []], [[], 0, []]], 5: [[['oldoldoldoldold'], 0, [('a', [1, 'new'])]], [[], 0, [('a', [2, ''])]], [['keepkeepkeepkeepkeep'], 0, [('b', [1, 'keepkeepkeepkeepkeep'])]], [['hellohellohellohellohello'], 0, [('b', [1, 'hellohellohellohellohello'])]], [[' x x x x x '], 0, [('a', [1, ' x x x x x '])]], [[], 0, []], [[], 0, []]]}[N]
for i, expression in enumerate(fixtures):
check("trace-"+str(i+1), solve(eval(expression)), expected[i])
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 |
|---|---|---|---|
| trace-1 | [['old', 'old'], 1, [['a', [1, 'new']]]] | [['old'], 0, [['a', [1, 'new']]]] | Failed |
| trace-2 | [[], 2, [['a', [2, '']]]] | [[], 0, [['a', [2, '']]]] | Failed |
| trace-3 | [['keep'], 1, [['b', [1, 'keep']]]] | [['keep'], 0, [['b', [1, 'keep']]]] | Failed |
| trace-4 | [['hello'], 2, [['b', [1, 'hello']]]] | [['hello'], 0, [['b', [1, 'hello']]]] | Failed |
| trace-5 | [[' x '], 2, [['a', [1, ' x ']]]] | [[' x '], 0, [['a', [1, ' x ']]]] | Failed |
| trace-6 | [[], 0, []] | [[], 0, []] | Passed |
| trace-7 | [[], 1, []] | [[], 0, []] | Failed |
SHA-256 / 59e2f73f0a8c59eaa37b923afc22203013af340825a3d5b84c722d8372b2845d
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(events):
leases={}; epochs={}; queue=[]; spoken=[]
for e in events:
if e[0]=='register':
epochs[e[1]]=epochs.get(e[1],0)+1
leases[e[1]]=[epochs[e[1]],'']
elif e[0]=='publish':
if e[1] not in leases: continue
if e[2]!=leases[e[1]][0]: continue
leases[e[1]][1]=e[3]
elif e[0]=='queue' and e[1] in leases:
queue.append([e[1],leases[e[1]][0],leases[e[1]][1]])
elif e[0]=='remove': leases.pop(e[1],None)
elif e[0]=='rename' and e[1] in leases:
leases[e[2]]=leases.pop(e[1])
elif e[0]=='drain':
for source,epoch,text in queue:
if source not in leases: continue
if leases[source][0]!=epoch: continue
if text: spoken.append(text)
queue[:]=queue[-1:]
return [spoken,len(queue),sorted((k,v) for k,v in leases.items())]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = ["[['register','a'],['publish','a',1,'old'*N],['queue','a'],['publish','a',1,'new'],['drain'],['drain']]", "[['register','a'],['publish','a',1,'old'],['queue','a'],['register','a'],['publish','a',1,'stale'*N],['queue','a'],['drain']]", "[['register','a'],['register','b'],['publish','b',1,'keep'*N],['remove','a'],['queue','b'],['drain']]", "[['register','a'],['publish','a',1,'hello'*N],['queue','a'],['rename','a','b'],['queue','b'],['drain']]", "[['register','a'],['queue','a'],['drain'],['publish','a',1,' x '*N],['queue','a'],['drain']]", "[['publish','missing',1,'x'*N],['remove','missing'],['drain']]", "[['register','a'],['publish','a',1,'x'*N],['queue','a'],['remove','a'],['drain']]"]
expected = {1: [[['old'], 0, [('a', [1, 'new'])]], [[], 0, [('a', [2, ''])]], [['keep'], 0, [('b', [1, 'keep'])]], [['hello'], 0, [('b', [1, 'hello'])]], [[' x '], 0, [('a', [1, ' x '])]], [[], 0, []], [[], 0, []]], 2: [[['oldold'], 0, [('a', [1, 'new'])]], [[], 0, [('a', [2, ''])]], [['keepkeep'], 0, [('b', [1, 'keepkeep'])]], [['hellohello'], 0, [('b', [1, 'hellohello'])]], [[' x x '], 0, [('a', [1, ' x x '])]], [[], 0, []], [[], 0, []]], 3: [[['oldoldold'], 0, [('a', [1, 'new'])]], [[], 0, [('a', [2, ''])]], [['keepkeepkeep'], 0, [('b', [1, 'keepkeepkeep'])]], [['hellohellohello'], 0, [('b', [1, 'hellohellohello'])]], [[' x x x '], 0, [('a', [1, ' x x x '])]], [[], 0, []], [[], 0, []]], 4: [[['oldoldoldold'], 0, [('a', [1, 'new'])]], [[], 0, [('a', [2, ''])]], [['keepkeepkeepkeep'], 0, [('b', [1, 'keepkeepkeepkeep'])]], [['hellohellohellohello'], 0, [('b', [1, 'hellohellohellohello'])]], [[' x x x x '], 0, [('a', [1, ' x x x x '])]], [[], 0, []], [[], 0, []]], 5: [[['oldoldoldoldold'], 0, [('a', [1, 'new'])]], [[], 0, [('a', [2, ''])]], [['keepkeepkeepkeepkeep'], 0, [('b', [1, 'keepkeepkeepkeepkeep'])]], [['hellohellohellohellohello'], 0, [('b', [1, 'hellohellohellohellohello'])]], [[' x x x x x '], 0, [('a', [1, ' x x x x x '])]], [[], 0, []], [[], 0, []]]}[N]
for i, expression in enumerate(fixtures):
check("trace-"+str(i+1), solve(eval(expression)), expected[i])
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 |
|---|---|---|---|
| trace-1 | [['old', 'old'], 1, [['a', [1, 'new']]]] | [['old'], 0, [['a', [1, 'new']]]] | Failed |
| trace-2 | [[], 1, [['a', [2, '']]]] | [[], 0, [['a', [2, '']]]] | Failed |
| trace-3 | [['keep'], 1, [['b', [1, 'keep']]]] | [['keep'], 0, [['b', [1, 'keep']]]] | Failed |
| trace-4 | [['hello'], 1, [['b', [1, 'hello']]]] | [['hello'], 0, [['b', [1, 'hello']]]] | Failed |
| trace-5 | [[' x '], 1, [['a', [1, ' x ']]]] | [[' x '], 0, [['a', [1, ' x ']]]] | Failed |
| trace-6 | [[], 0, []] | [[], 0, []] | Passed |
| trace-7 | [[], 1, []] | [[], 0, []] | Failed |
SHA-256 / b13c72d5ed081e6d5c8ab2eebd560d02055147e7fc78594ce724cb1e5a650a77
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(events):
leases={}; epochs={}; queue=[]; spoken=[]
for e in events:
if e[0]=='register':
epochs[e[1]]=epochs.get(e[1],0)+1
leases[e[1]]=[epochs[e[1]],'']
elif e[0]=='publish':
if e[1] not in leases: continue
if e[2]!=leases[e[1]][0]: continue
leases[e[1]][1]=e[3]
elif e[0]=='queue' and e[1] in leases:
queue.append([e[1],leases[e[1]][0],leases[e[1]][1]])
elif e[0]=='remove': leases.pop(e[1],None)
elif e[0]=='rename' and e[1] in leases:
leases[e[2]]=leases.pop(e[1])
elif e[0]=='drain':
for source,epoch,text in queue:
if source not in leases: continue
if leases[source][0]!=epoch: continue
if text: spoken.append(text)
queue.clear()
return [spoken,len(queue),sorted((k,v) for k,v in leases.items())]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = ["[['register','a'],['publish','a',1,'old'*N],['queue','a'],['publish','a',1,'new'],['drain'],['drain']]", "[['register','a'],['publish','a',1,'old'],['queue','a'],['register','a'],['publish','a',1,'stale'*N],['queue','a'],['drain']]", "[['register','a'],['register','b'],['publish','b',1,'keep'*N],['remove','a'],['queue','b'],['drain']]", "[['register','a'],['publish','a',1,'hello'*N],['queue','a'],['rename','a','b'],['queue','b'],['drain']]", "[['register','a'],['queue','a'],['drain'],['publish','a',1,' x '*N],['queue','a'],['drain']]", "[['publish','missing',1,'x'*N],['remove','missing'],['drain']]", "[['register','a'],['publish','a',1,'x'*N],['queue','a'],['remove','a'],['drain']]"]
expected = {1: [[['old'], 0, [('a', [1, 'new'])]], [[], 0, [('a', [2, ''])]], [['keep'], 0, [('b', [1, 'keep'])]], [['hello'], 0, [('b', [1, 'hello'])]], [[' x '], 0, [('a', [1, ' x '])]], [[], 0, []], [[], 0, []]], 2: [[['oldold'], 0, [('a', [1, 'new'])]], [[], 0, [('a', [2, ''])]], [['keepkeep'], 0, [('b', [1, 'keepkeep'])]], [['hellohello'], 0, [('b', [1, 'hellohello'])]], [[' x x '], 0, [('a', [1, ' x x '])]], [[], 0, []], [[], 0, []]], 3: [[['oldoldold'], 0, [('a', [1, 'new'])]], [[], 0, [('a', [2, ''])]], [['keepkeepkeep'], 0, [('b', [1, 'keepkeepkeep'])]], [['hellohellohello'], 0, [('b', [1, 'hellohellohello'])]], [[' x x x '], 0, [('a', [1, ' x x x '])]], [[], 0, []], [[], 0, []]], 4: [[['oldoldoldold'], 0, [('a', [1, 'new'])]], [[], 0, [('a', [2, ''])]], [['keepkeepkeepkeep'], 0, [('b', [1, 'keepkeepkeepkeep'])]], [['hellohellohellohello'], 0, [('b', [1, 'hellohellohellohello'])]], [[' x x x x '], 0, [('a', [1, ' x x x x '])]], [[], 0, []], [[], 0, []]], 5: [[['oldoldoldoldold'], 0, [('a', [1, 'new'])]], [[], 0, [('a', [2, ''])]], [['keepkeepkeepkeepkeep'], 0, [('b', [1, 'keepkeepkeepkeepkeep'])]], [['hellohellohellohellohello'], 0, [('b', [1, 'hellohellohellohellohello'])]], [[' x x x x x '], 0, [('a', [1, ' x x x x x '])]], [[], 0, []], [[], 0, []]]}[N]
for i, expression in enumerate(fixtures):
check("trace-"+str(i+1), solve(eval(expression)), expected[i])
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 |
|---|---|---|---|
| trace-1 | [['old'], 0, [['a', [1, 'new']]]] | [['old'], 0, [['a', [1, 'new']]]] | Passed |
| trace-2 | [[], 0, [['a', [2, '']]]] | [[], 0, [['a', [2, '']]]] | Passed |
| trace-3 | [['keep'], 0, [['b', [1, 'keep']]]] | [['keep'], 0, [['b', [1, 'keep']]]] | Passed |
| trace-4 | [['hello'], 0, [['b', [1, 'hello']]]] | [['hello'], 0, [['b', [1, 'hello']]]] | Passed |
| trace-5 | [[' x '], 0, [['a', [1, ' x ']]]] | [[' x '], 0, [['a', [1, ' x ']]]] | Passed |
| trace-6 | [[], 0, []] | [[], 0, []] | Passed |
| trace-7 | [[], 0, []] | [[], 0, []] | Passed |
SHA-256 / f1ab57995f15cbc8b447b4338b46bdd28756bfd55cb0d36cd48aca7b65a69243
Verification & scope
Stipulated bounded policy, not a browser, speech engine, platform API, or 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:40:20.463005+00:00.
Case digest / 446879a22c5a8041241e9f9dd993bcb50967dcd88bf8443d2396fbcb1e4ace71