FA-20776 / Assistive announcements / Open access
Equal urgency messages are selected newest first · case 01
The announcement trace violates the stated priority-inheritance contract.
ROOT CAUSE
Fault site: index=scores.index(max(scores)) is implemented as index=len(scores)-1-scores[::-1].index(max(scores))
VERIFIED REPAIR
Restore the stated transition: index=scores.index(max(scores))
Unsuccessful approach: The attempted repair substitutes index=scores.index(min(scores)) and still violates a regression oracle.
Case contract
Messages belong to groups. Set group priority affects future selection, not stored base. Enqueue [id,group,base,text]. Group floor combines with base using max. Drain picks largest effective priority, then earliest position; repeat drains remove only winner. Drop-group removes its messages and floor. Move changes only a message group. Reset-floor removes inheritance but retains messages. Report spoken IDs and pending [id,group].
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):
floors={}; q=[]; spoken=[]
for e in events:
if e[0]=='floor': floors[e[1]]=e[2]
elif e[0]=='enqueue': q.append(e[1:])
elif e[0]=='drop':
q=[x for x in q if x[1]!=e[1]]
floors.pop(e[1],None)
elif e[0]=='move':
for x in q:
if x[0]==e[1]: x[1]=e[2]
elif e[0]=='reset': floors.pop(e[1],None)
elif e[0]=='drain' and q:
scores=[max(x[2],floors.get(x[1],0)) for x in q]
index=len(scores)-1-scores[::-1].index(max(scores))
chosen=q.pop(index)
spoken.append([chosen[0],chosen[3]])
return [spoken,[x[:2] for x in q],sorted(floors.items())]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = ["[['floor','g',4],['enqueue','a','g',N+1,'alpha'],['enqueue','b','h',6,'beta'],['drain'],['drain']]", "[['enqueue','a','g',1,'first'*N],['enqueue','b','g',1,'second'],['drain']]", "[['floor','g',9],['floor','g',1],['enqueue','a','g',2,'a'*N],['enqueue','b','h',3,'b'],['drain']]", "[['floor','g',9],['floor','h',3],['enqueue','a','g',1,'x'*N],['enqueue','foreign','h',2,'foreign'],['drop','g'],['enqueue','b','g',1,'new'],['enqueue','c','h',2,'keep'],['drain']]", "[['floor','g',9],['floor','h',4],['enqueue','a','g',1,'a'*N],['enqueue','b','h',2,'b'],['move','a','h'],['reset','g'],['drain']]", '[]', "[['floor','g',2],['enqueue','a','g',8,'a'*N],['enqueue','b','h',7,'b'],['drain']]"]
expected = {1: [[[['b', 'beta'], ['a', 'alpha']], [], [('g', 4)]], [[['a', 'first']], [['b', 'g']], []], [[['b', 'b']], [['a', 'g']], [('g', 1)]], [[['foreign', 'foreign']], [['b', 'g'], ['c', 'h']], [('h', 3)]], [[['a', 'a']], [['b', 'h']], [('h', 4)]], [[], [], []], [[['a', 'a']], [['b', 'h']], [('g', 2)]]], 2: [[[['b', 'beta'], ['a', 'alpha']], [], [('g', 4)]], [[['a', 'firstfirst']], [['b', 'g']], []], [[['b', 'b']], [['a', 'g']], [('g', 1)]], [[['foreign', 'foreign']], [['b', 'g'], ['c', 'h']], [('h', 3)]], [[['a', 'aa']], [['b', 'h']], [('h', 4)]], [[], [], []], [[['a', 'aa']], [['b', 'h']], [('g', 2)]]], 3: [[[['b', 'beta'], ['a', 'alpha']], [], [('g', 4)]], [[['a', 'firstfirstfirst']], [['b', 'g']], []], [[['b', 'b']], [['a', 'g']], [('g', 1)]], [[['foreign', 'foreign']], [['b', 'g'], ['c', 'h']], [('h', 3)]], [[['a', 'aaa']], [['b', 'h']], [('h', 4)]], [[], [], []], [[['a', 'aaa']], [['b', 'h']], [('g', 2)]]], 4: [[[['b', 'beta'], ['a', 'alpha']], [], [('g', 4)]], [[['a', 'firstfirstfirstfirst']], [['b', 'g']], []], [[['b', 'b']], [['a', 'g']], [('g', 1)]], [[['foreign', 'foreign']], [['b', 'g'], ['c', 'h']], [('h', 3)]], [[['a', 'aaaa']], [['b', 'h']], [('h', 4)]], [[], [], []], [[['a', 'aaaa']], [['b', 'h']], [('g', 2)]]], 5: [[[['a', 'alpha'], ['b', 'beta']], [], [('g', 4)]], [[['a', 'firstfirstfirstfirstfirst']], [['b', 'g']], []], [[['b', 'b']], [['a', 'g']], [('g', 1)]], [[['foreign', 'foreign']], [['b', 'g'], ['c', 'h']], [('h', 3)]], [[['a', 'aaaaa']], [['b', 'h']], [('h', 4)]], [[], [], []], [[['a', 'aaaaa']], [['b', 'h']], [('g', 2)]]]}[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 | [[['b', 'beta'], ['a', 'alpha']], [], [['g', 4]]] | [[['b', 'beta'], ['a', 'alpha']], [], [['g', 4]]] | Passed |
| trace-2 | [[['b', 'second']], [['a', 'g']], []] | [[['a', 'first']], [['b', 'g']], []] | Failed |
| trace-3 | [[['b', 'b']], [['a', 'g']], [['g', 1]]] | [[['b', 'b']], [['a', 'g']], [['g', 1]]] | Passed |
| trace-4 | [[['c', 'keep']], [['foreign', 'h'], ['b', 'g']], [['h', 3]]] | [[['foreign', 'foreign']], [['b', 'g'], ['c', 'h']], [['h', 3]]] | Failed |
| trace-5 | [[['b', 'b']], [['a', 'h']], [['h', 4]]] | [[['a', 'a']], [['b', 'h']], [['h', 4]]] | Failed |
| trace-6 | [[], [], []] | [[], [], []] | Passed |
| trace-7 | [[['a', 'a']], [['b', 'h']], [['g', 2]]] | [[['a', 'a']], [['b', 'h']], [['g', 2]]] | Passed |
SHA-256 / f3750d26d89dfc377881dcb942996c049bdcfb9c33f0dc4a7d794ac8e676ca4b
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(events):
floors={}; q=[]; spoken=[]
for e in events:
if e[0]=='floor': floors[e[1]]=e[2]
elif e[0]=='enqueue': q.append(e[1:])
elif e[0]=='drop':
q=[x for x in q if x[1]!=e[1]]
floors.pop(e[1],None)
elif e[0]=='move':
for x in q:
if x[0]==e[1]: x[1]=e[2]
elif e[0]=='reset': floors.pop(e[1],None)
elif e[0]=='drain' and q:
scores=[max(x[2],floors.get(x[1],0)) for x in q]
index=scores.index(min(scores))
chosen=q.pop(index)
spoken.append([chosen[0],chosen[3]])
return [spoken,[x[:2] for x in q],sorted(floors.items())]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = ["[['floor','g',4],['enqueue','a','g',N+1,'alpha'],['enqueue','b','h',6,'beta'],['drain'],['drain']]", "[['enqueue','a','g',1,'first'*N],['enqueue','b','g',1,'second'],['drain']]", "[['floor','g',9],['floor','g',1],['enqueue','a','g',2,'a'*N],['enqueue','b','h',3,'b'],['drain']]", "[['floor','g',9],['floor','h',3],['enqueue','a','g',1,'x'*N],['enqueue','foreign','h',2,'foreign'],['drop','g'],['enqueue','b','g',1,'new'],['enqueue','c','h',2,'keep'],['drain']]", "[['floor','g',9],['floor','h',4],['enqueue','a','g',1,'a'*N],['enqueue','b','h',2,'b'],['move','a','h'],['reset','g'],['drain']]", '[]', "[['floor','g',2],['enqueue','a','g',8,'a'*N],['enqueue','b','h',7,'b'],['drain']]"]
expected = {1: [[[['b', 'beta'], ['a', 'alpha']], [], [('g', 4)]], [[['a', 'first']], [['b', 'g']], []], [[['b', 'b']], [['a', 'g']], [('g', 1)]], [[['foreign', 'foreign']], [['b', 'g'], ['c', 'h']], [('h', 3)]], [[['a', 'a']], [['b', 'h']], [('h', 4)]], [[], [], []], [[['a', 'a']], [['b', 'h']], [('g', 2)]]], 2: [[[['b', 'beta'], ['a', 'alpha']], [], [('g', 4)]], [[['a', 'firstfirst']], [['b', 'g']], []], [[['b', 'b']], [['a', 'g']], [('g', 1)]], [[['foreign', 'foreign']], [['b', 'g'], ['c', 'h']], [('h', 3)]], [[['a', 'aa']], [['b', 'h']], [('h', 4)]], [[], [], []], [[['a', 'aa']], [['b', 'h']], [('g', 2)]]], 3: [[[['b', 'beta'], ['a', 'alpha']], [], [('g', 4)]], [[['a', 'firstfirstfirst']], [['b', 'g']], []], [[['b', 'b']], [['a', 'g']], [('g', 1)]], [[['foreign', 'foreign']], [['b', 'g'], ['c', 'h']], [('h', 3)]], [[['a', 'aaa']], [['b', 'h']], [('h', 4)]], [[], [], []], [[['a', 'aaa']], [['b', 'h']], [('g', 2)]]], 4: [[[['b', 'beta'], ['a', 'alpha']], [], [('g', 4)]], [[['a', 'firstfirstfirstfirst']], [['b', 'g']], []], [[['b', 'b']], [['a', 'g']], [('g', 1)]], [[['foreign', 'foreign']], [['b', 'g'], ['c', 'h']], [('h', 3)]], [[['a', 'aaaa']], [['b', 'h']], [('h', 4)]], [[], [], []], [[['a', 'aaaa']], [['b', 'h']], [('g', 2)]]], 5: [[[['a', 'alpha'], ['b', 'beta']], [], [('g', 4)]], [[['a', 'firstfirstfirstfirstfirst']], [['b', 'g']], []], [[['b', 'b']], [['a', 'g']], [('g', 1)]], [[['foreign', 'foreign']], [['b', 'g'], ['c', 'h']], [('h', 3)]], [[['a', 'aaaaa']], [['b', 'h']], [('h', 4)]], [[], [], []], [[['a', 'aaaaa']], [['b', 'h']], [('g', 2)]]]}[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 | [[['a', 'alpha'], ['b', 'beta']], [], [['g', 4]]] | [[['b', 'beta'], ['a', 'alpha']], [], [['g', 4]]] | Failed |
| trace-2 | [[['a', 'first']], [['b', 'g']], []] | [[['a', 'first']], [['b', 'g']], []] | Passed |
| trace-3 | [[['a', 'a']], [['b', 'h']], [['g', 1]]] | [[['b', 'b']], [['a', 'g']], [['g', 1]]] | Failed |
| trace-4 | [[['b', 'new']], [['foreign', 'h'], ['c', 'h']], [['h', 3]]] | [[['foreign', 'foreign']], [['b', 'g'], ['c', 'h']], [['h', 3]]] | Failed |
| trace-5 | [[['a', 'a']], [['b', 'h']], [['h', 4]]] | [[['a', 'a']], [['b', 'h']], [['h', 4]]] | Passed |
| trace-6 | [[], [], []] | [[], [], []] | Passed |
| trace-7 | [[['b', 'b']], [['a', 'g']], [['g', 2]]] | [[['a', 'a']], [['b', 'h']], [['g', 2]]] | Failed |
SHA-256 / 743353c80536a46c34a990fe5a6bced5709acf5ffd4f892f08a42cf28ce82eab
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(events):
floors={}; q=[]; spoken=[]
for e in events:
if e[0]=='floor': floors[e[1]]=e[2]
elif e[0]=='enqueue': q.append(e[1:])
elif e[0]=='drop':
q=[x for x in q if x[1]!=e[1]]
floors.pop(e[1],None)
elif e[0]=='move':
for x in q:
if x[0]==e[1]: x[1]=e[2]
elif e[0]=='reset': floors.pop(e[1],None)
elif e[0]=='drain' and q:
scores=[max(x[2],floors.get(x[1],0)) for x in q]
index=scores.index(max(scores))
chosen=q.pop(index)
spoken.append([chosen[0],chosen[3]])
return [spoken,[x[:2] for x in q],sorted(floors.items())]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = ["[['floor','g',4],['enqueue','a','g',N+1,'alpha'],['enqueue','b','h',6,'beta'],['drain'],['drain']]", "[['enqueue','a','g',1,'first'*N],['enqueue','b','g',1,'second'],['drain']]", "[['floor','g',9],['floor','g',1],['enqueue','a','g',2,'a'*N],['enqueue','b','h',3,'b'],['drain']]", "[['floor','g',9],['floor','h',3],['enqueue','a','g',1,'x'*N],['enqueue','foreign','h',2,'foreign'],['drop','g'],['enqueue','b','g',1,'new'],['enqueue','c','h',2,'keep'],['drain']]", "[['floor','g',9],['floor','h',4],['enqueue','a','g',1,'a'*N],['enqueue','b','h',2,'b'],['move','a','h'],['reset','g'],['drain']]", '[]', "[['floor','g',2],['enqueue','a','g',8,'a'*N],['enqueue','b','h',7,'b'],['drain']]"]
expected = {1: [[[['b', 'beta'], ['a', 'alpha']], [], [('g', 4)]], [[['a', 'first']], [['b', 'g']], []], [[['b', 'b']], [['a', 'g']], [('g', 1)]], [[['foreign', 'foreign']], [['b', 'g'], ['c', 'h']], [('h', 3)]], [[['a', 'a']], [['b', 'h']], [('h', 4)]], [[], [], []], [[['a', 'a']], [['b', 'h']], [('g', 2)]]], 2: [[[['b', 'beta'], ['a', 'alpha']], [], [('g', 4)]], [[['a', 'firstfirst']], [['b', 'g']], []], [[['b', 'b']], [['a', 'g']], [('g', 1)]], [[['foreign', 'foreign']], [['b', 'g'], ['c', 'h']], [('h', 3)]], [[['a', 'aa']], [['b', 'h']], [('h', 4)]], [[], [], []], [[['a', 'aa']], [['b', 'h']], [('g', 2)]]], 3: [[[['b', 'beta'], ['a', 'alpha']], [], [('g', 4)]], [[['a', 'firstfirstfirst']], [['b', 'g']], []], [[['b', 'b']], [['a', 'g']], [('g', 1)]], [[['foreign', 'foreign']], [['b', 'g'], ['c', 'h']], [('h', 3)]], [[['a', 'aaa']], [['b', 'h']], [('h', 4)]], [[], [], []], [[['a', 'aaa']], [['b', 'h']], [('g', 2)]]], 4: [[[['b', 'beta'], ['a', 'alpha']], [], [('g', 4)]], [[['a', 'firstfirstfirstfirst']], [['b', 'g']], []], [[['b', 'b']], [['a', 'g']], [('g', 1)]], [[['foreign', 'foreign']], [['b', 'g'], ['c', 'h']], [('h', 3)]], [[['a', 'aaaa']], [['b', 'h']], [('h', 4)]], [[], [], []], [[['a', 'aaaa']], [['b', 'h']], [('g', 2)]]], 5: [[[['a', 'alpha'], ['b', 'beta']], [], [('g', 4)]], [[['a', 'firstfirstfirstfirstfirst']], [['b', 'g']], []], [[['b', 'b']], [['a', 'g']], [('g', 1)]], [[['foreign', 'foreign']], [['b', 'g'], ['c', 'h']], [('h', 3)]], [[['a', 'aaaaa']], [['b', 'h']], [('h', 4)]], [[], [], []], [[['a', 'aaaaa']], [['b', 'h']], [('g', 2)]]]}[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 | [[['b', 'beta'], ['a', 'alpha']], [], [['g', 4]]] | [[['b', 'beta'], ['a', 'alpha']], [], [['g', 4]]] | Passed |
| trace-2 | [[['a', 'first']], [['b', 'g']], []] | [[['a', 'first']], [['b', 'g']], []] | Passed |
| trace-3 | [[['b', 'b']], [['a', 'g']], [['g', 1]]] | [[['b', 'b']], [['a', 'g']], [['g', 1]]] | Passed |
| trace-4 | [[['foreign', 'foreign']], [['b', 'g'], ['c', 'h']], [['h', 3]]] | [[['foreign', 'foreign']], [['b', 'g'], ['c', 'h']], [['h', 3]]] | Passed |
| trace-5 | [[['a', 'a']], [['b', 'h']], [['h', 4]]] | [[['a', 'a']], [['b', 'h']], [['h', 4]]] | Passed |
| trace-6 | [[], [], []] | [[], [], []] | Passed |
| trace-7 | [[['a', 'a']], [['b', 'h']], [['g', 2]]] | [[['a', 'a']], [['b', 'h']], [['g', 2]]] | Passed |
SHA-256 / 0b045e13fca29327f27f5052e457874caaaa9dba403999216ff46892f52904b2
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:22.239114+00:00.
Case digest / e667f380a9dd67b72070916e40b8b5944eb118d0fc598c1470e8a06de2db30f8