FAILURE MAP
← Case archive

FA-21381 / Assistive announcements / Open access

Cooldown deadline is measured from zero rather than emission time · case 01

The announcement trace violates the stated speech-cooldown contract.

Verified by executionVariant 1 · 7 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

Fault site: deadlines[e[1]]=now+durations.get(e[1],0) is implemented as deadlines[e[1]]=durations.get(e[1],0)

VERIFIED REPAIR

Restore the stated transition: deadlines[e[1]]=now+durations.get(e[1],0)

Unsuccessful approach: The attempted repair substitutes deadlines[e[1]]=now+durations.get(e[1],0)+1 and still violates a regression oracle.

Case contract

Each cue kind has its own cooldown duration. Emit [kind,text] speaks only when now reaches that kinds next allowed time; successful emission sets next to now+duration, suppression does not slide it. Tick is monotone. Configure affects future emissions only. Force speaks and resets its deadline. Reset-kind removes one cooldown history. Suspend blocks normal emission but preserves timestamps; resume enables it. Return output, next deadlines and now.

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):
    now=0; durations={}; deadlines={}; suspended=False; out=[]
    for e in events:
        if e[0]=='configure': durations[e[1]]=max(0,e[2])
        elif e[0]=='tick': now=max(now,e[1])
        elif e[0]=='reset': deadlines.pop(e[1],None)
        elif e[0]=='suspend': suspended=True
        elif e[0]=='resume': suspended=False
        elif e[0] in ('emit','force'):
            if e[0]=='emit' and suspended: continue
            if e[0]=='emit' and now<deadlines.get(e[1],0): continue
            out.append([e[1],e[2]])
            deadlines[e[1]]=durations.get(e[1],0)
    return [out,sorted(deadlines.items()),now,suspended]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = ["[['configure','a',N],['emit','a','first'],['emit','a','suppressed'],['tick',N],['emit','a','next']]", "[['configure','a',N+4],['configure','b',1],['emit','a','alpha'],['emit','b','beta'],['reset','b'],['emit','a','blocked']]", "[['configure','a',N],['emit','a','first'],['suspend']]", "[['configure','a',N],['emit','a','first'],['suspend'],['emit','c','muted'],['force','b','urgent'],['tick',N+2],['resume'],['emit','a','ready']]", "[['configure','a',N+5],['configure','a',0],['emit','a','first'],['emit','a','second']]", "[['tick',N+3],['tick',1],['configure','a',2],['emit','a','later']]", '[]']
expected = {1: [[[['a', 'first'], ['a', 'next']], [('a', 2)], 1, False], [[['a', 'alpha'], ['b', 'beta']], [('a', 5)], 0, False], [[['a', 'first']], [('a', 1)], 0, True], [[['a', 'first'], ['b', 'urgent'], ['a', 'ready']], [('a', 4), ('b', 0)], 3, False], [[['a', 'first'], ['a', 'second']], [('a', 0)], 0, False], [[['a', 'later']], [('a', 6)], 4, False], [[], [], 0, False]], 2: [[[['a', 'first'], ['a', 'next']], [('a', 4)], 2, False], [[['a', 'alpha'], ['b', 'beta']], [('a', 6)], 0, False], [[['a', 'first']], [('a', 2)], 0, True], [[['a', 'first'], ['b', 'urgent'], ['a', 'ready']], [('a', 6), ('b', 0)], 4, False], [[['a', 'first'], ['a', 'second']], [('a', 0)], 0, False], [[['a', 'later']], [('a', 7)], 5, False], [[], [], 0, False]], 3: [[[['a', 'first'], ['a', 'next']], [('a', 6)], 3, False], [[['a', 'alpha'], ['b', 'beta']], [('a', 7)], 0, False], [[['a', 'first']], [('a', 3)], 0, True], [[['a', 'first'], ['b', 'urgent'], ['a', 'ready']], [('a', 8), ('b', 0)], 5, False], [[['a', 'first'], ['a', 'second']], [('a', 0)], 0, False], [[['a', 'later']], [('a', 8)], 6, False], [[], [], 0, False]], 4: [[[['a', 'first'], ['a', 'next']], [('a', 8)], 4, False], [[['a', 'alpha'], ['b', 'beta']], [('a', 8)], 0, False], [[['a', 'first']], [('a', 4)], 0, True], [[['a', 'first'], ['b', 'urgent'], ['a', 'ready']], [('a', 10), ('b', 0)], 6, False], [[['a', 'first'], ['a', 'second']], [('a', 0)], 0, False], [[['a', 'later']], [('a', 9)], 7, False], [[], [], 0, False]], 5: [[[['a', 'first'], ['a', 'next']], [('a', 10)], 5, False], [[['a', 'alpha'], ['b', 'beta']], [('a', 9)], 0, False], [[['a', 'first']], [('a', 5)], 0, True], [[['a', 'first'], ['b', 'urgent'], ['a', 'ready']], [('a', 12), ('b', 0)], 7, False], [[['a', 'first'], ['a', 'second']], [('a', 0)], 0, False], [[['a', 'later']], [('a', 10)], 8, False], [[], [], 0, False]]}[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 fixtureActualExpectedOutcome
trace-1[[['a', 'first'], ['a', 'next']], [['a', 1]], 1, False][[['a', 'first'], ['a', 'next']], [['a', 2]], 1, False]Failed
trace-2[[['a', 'alpha'], ['b', 'beta']], [['a', 5]], 0, False][[['a', 'alpha'], ['b', 'beta']], [['a', 5]], 0, False]Passed
trace-3[[['a', 'first']], [['a', 1]], 0, True][[['a', 'first']], [['a', 1]], 0, True]Passed
trace-4[[['a', 'first'], ['b', 'urgent'], ['a', 'ready']], [['a', 1], ['b', 0]], 3, False][[['a', 'first'], ['b', 'urgent'], ['a', 'ready']], [['a', 4], ['b', 0]], 3, False]Failed
trace-5[[['a', 'first'], ['a', 'second']], [['a', 0]], 0, False][[['a', 'first'], ['a', 'second']], [['a', 0]], 0, False]Passed
trace-6[[['a', 'later']], [['a', 2]], 4, False][[['a', 'later']], [['a', 6]], 4, False]Failed
trace-7[[], [], 0, False][[], [], 0, False]Passed

SHA-256 / af17922383524bbab1d726807cb6b0145a5d5dde3fd3d03c5c407de404ec2331

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(events):
    now=0; durations={}; deadlines={}; suspended=False; out=[]
    for e in events:
        if e[0]=='configure': durations[e[1]]=max(0,e[2])
        elif e[0]=='tick': now=max(now,e[1])
        elif e[0]=='reset': deadlines.pop(e[1],None)
        elif e[0]=='suspend': suspended=True
        elif e[0]=='resume': suspended=False
        elif e[0] in ('emit','force'):
            if e[0]=='emit' and suspended: continue
            if e[0]=='emit' and now<deadlines.get(e[1],0): continue
            out.append([e[1],e[2]])
            deadlines[e[1]]=now+durations.get(e[1],0)+1
    return [out,sorted(deadlines.items()),now,suspended]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = ["[['configure','a',N],['emit','a','first'],['emit','a','suppressed'],['tick',N],['emit','a','next']]", "[['configure','a',N+4],['configure','b',1],['emit','a','alpha'],['emit','b','beta'],['reset','b'],['emit','a','blocked']]", "[['configure','a',N],['emit','a','first'],['suspend']]", "[['configure','a',N],['emit','a','first'],['suspend'],['emit','c','muted'],['force','b','urgent'],['tick',N+2],['resume'],['emit','a','ready']]", "[['configure','a',N+5],['configure','a',0],['emit','a','first'],['emit','a','second']]", "[['tick',N+3],['tick',1],['configure','a',2],['emit','a','later']]", '[]']
expected = {1: [[[['a', 'first'], ['a', 'next']], [('a', 2)], 1, False], [[['a', 'alpha'], ['b', 'beta']], [('a', 5)], 0, False], [[['a', 'first']], [('a', 1)], 0, True], [[['a', 'first'], ['b', 'urgent'], ['a', 'ready']], [('a', 4), ('b', 0)], 3, False], [[['a', 'first'], ['a', 'second']], [('a', 0)], 0, False], [[['a', 'later']], [('a', 6)], 4, False], [[], [], 0, False]], 2: [[[['a', 'first'], ['a', 'next']], [('a', 4)], 2, False], [[['a', 'alpha'], ['b', 'beta']], [('a', 6)], 0, False], [[['a', 'first']], [('a', 2)], 0, True], [[['a', 'first'], ['b', 'urgent'], ['a', 'ready']], [('a', 6), ('b', 0)], 4, False], [[['a', 'first'], ['a', 'second']], [('a', 0)], 0, False], [[['a', 'later']], [('a', 7)], 5, False], [[], [], 0, False]], 3: [[[['a', 'first'], ['a', 'next']], [('a', 6)], 3, False], [[['a', 'alpha'], ['b', 'beta']], [('a', 7)], 0, False], [[['a', 'first']], [('a', 3)], 0, True], [[['a', 'first'], ['b', 'urgent'], ['a', 'ready']], [('a', 8), ('b', 0)], 5, False], [[['a', 'first'], ['a', 'second']], [('a', 0)], 0, False], [[['a', 'later']], [('a', 8)], 6, False], [[], [], 0, False]], 4: [[[['a', 'first'], ['a', 'next']], [('a', 8)], 4, False], [[['a', 'alpha'], ['b', 'beta']], [('a', 8)], 0, False], [[['a', 'first']], [('a', 4)], 0, True], [[['a', 'first'], ['b', 'urgent'], ['a', 'ready']], [('a', 10), ('b', 0)], 6, False], [[['a', 'first'], ['a', 'second']], [('a', 0)], 0, False], [[['a', 'later']], [('a', 9)], 7, False], [[], [], 0, False]], 5: [[[['a', 'first'], ['a', 'next']], [('a', 10)], 5, False], [[['a', 'alpha'], ['b', 'beta']], [('a', 9)], 0, False], [[['a', 'first']], [('a', 5)], 0, True], [[['a', 'first'], ['b', 'urgent'], ['a', 'ready']], [('a', 12), ('b', 0)], 7, False], [[['a', 'first'], ['a', 'second']], [('a', 0)], 0, False], [[['a', 'later']], [('a', 10)], 8, False], [[], [], 0, False]]}[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 fixtureActualExpectedOutcome
trace-1[[['a', 'first']], [['a', 2]], 1, False][[['a', 'first'], ['a', 'next']], [['a', 2]], 1, False]Failed
trace-2[[['a', 'alpha'], ['b', 'beta']], [['a', 6]], 0, False][[['a', 'alpha'], ['b', 'beta']], [['a', 5]], 0, False]Failed
trace-3[[['a', 'first']], [['a', 2]], 0, True][[['a', 'first']], [['a', 1]], 0, True]Failed
trace-4[[['a', 'first'], ['b', 'urgent'], ['a', 'ready']], [['a', 5], ['b', 1]], 3, False][[['a', 'first'], ['b', 'urgent'], ['a', 'ready']], [['a', 4], ['b', 0]], 3, False]Failed
trace-5[[['a', 'first']], [['a', 1]], 0, False][[['a', 'first'], ['a', 'second']], [['a', 0]], 0, False]Failed
trace-6[[['a', 'later']], [['a', 7]], 4, False][[['a', 'later']], [['a', 6]], 4, False]Failed
trace-7[[], [], 0, False][[], [], 0, False]Passed

SHA-256 / 8e4a02487e82bb3aaae97652bec48ea94587e2fc6af3c6465f70549945cf72b6

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(events):
    now=0; durations={}; deadlines={}; suspended=False; out=[]
    for e in events:
        if e[0]=='configure': durations[e[1]]=max(0,e[2])
        elif e[0]=='tick': now=max(now,e[1])
        elif e[0]=='reset': deadlines.pop(e[1],None)
        elif e[0]=='suspend': suspended=True
        elif e[0]=='resume': suspended=False
        elif e[0] in ('emit','force'):
            if e[0]=='emit' and suspended: continue
            if e[0]=='emit' and now<deadlines.get(e[1],0): continue
            out.append([e[1],e[2]])
            deadlines[e[1]]=now+durations.get(e[1],0)
    return [out,sorted(deadlines.items()),now,suspended]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = ["[['configure','a',N],['emit','a','first'],['emit','a','suppressed'],['tick',N],['emit','a','next']]", "[['configure','a',N+4],['configure','b',1],['emit','a','alpha'],['emit','b','beta'],['reset','b'],['emit','a','blocked']]", "[['configure','a',N],['emit','a','first'],['suspend']]", "[['configure','a',N],['emit','a','first'],['suspend'],['emit','c','muted'],['force','b','urgent'],['tick',N+2],['resume'],['emit','a','ready']]", "[['configure','a',N+5],['configure','a',0],['emit','a','first'],['emit','a','second']]", "[['tick',N+3],['tick',1],['configure','a',2],['emit','a','later']]", '[]']
expected = {1: [[[['a', 'first'], ['a', 'next']], [('a', 2)], 1, False], [[['a', 'alpha'], ['b', 'beta']], [('a', 5)], 0, False], [[['a', 'first']], [('a', 1)], 0, True], [[['a', 'first'], ['b', 'urgent'], ['a', 'ready']], [('a', 4), ('b', 0)], 3, False], [[['a', 'first'], ['a', 'second']], [('a', 0)], 0, False], [[['a', 'later']], [('a', 6)], 4, False], [[], [], 0, False]], 2: [[[['a', 'first'], ['a', 'next']], [('a', 4)], 2, False], [[['a', 'alpha'], ['b', 'beta']], [('a', 6)], 0, False], [[['a', 'first']], [('a', 2)], 0, True], [[['a', 'first'], ['b', 'urgent'], ['a', 'ready']], [('a', 6), ('b', 0)], 4, False], [[['a', 'first'], ['a', 'second']], [('a', 0)], 0, False], [[['a', 'later']], [('a', 7)], 5, False], [[], [], 0, False]], 3: [[[['a', 'first'], ['a', 'next']], [('a', 6)], 3, False], [[['a', 'alpha'], ['b', 'beta']], [('a', 7)], 0, False], [[['a', 'first']], [('a', 3)], 0, True], [[['a', 'first'], ['b', 'urgent'], ['a', 'ready']], [('a', 8), ('b', 0)], 5, False], [[['a', 'first'], ['a', 'second']], [('a', 0)], 0, False], [[['a', 'later']], [('a', 8)], 6, False], [[], [], 0, False]], 4: [[[['a', 'first'], ['a', 'next']], [('a', 8)], 4, False], [[['a', 'alpha'], ['b', 'beta']], [('a', 8)], 0, False], [[['a', 'first']], [('a', 4)], 0, True], [[['a', 'first'], ['b', 'urgent'], ['a', 'ready']], [('a', 10), ('b', 0)], 6, False], [[['a', 'first'], ['a', 'second']], [('a', 0)], 0, False], [[['a', 'later']], [('a', 9)], 7, False], [[], [], 0, False]], 5: [[[['a', 'first'], ['a', 'next']], [('a', 10)], 5, False], [[['a', 'alpha'], ['b', 'beta']], [('a', 9)], 0, False], [[['a', 'first']], [('a', 5)], 0, True], [[['a', 'first'], ['b', 'urgent'], ['a', 'ready']], [('a', 12), ('b', 0)], 7, False], [[['a', 'first'], ['a', 'second']], [('a', 0)], 0, False], [[['a', 'later']], [('a', 10)], 8, False], [[], [], 0, False]]}[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 fixtureActualExpectedOutcome
trace-1[[['a', 'first'], ['a', 'next']], [['a', 2]], 1, False][[['a', 'first'], ['a', 'next']], [['a', 2]], 1, False]Passed
trace-2[[['a', 'alpha'], ['b', 'beta']], [['a', 5]], 0, False][[['a', 'alpha'], ['b', 'beta']], [['a', 5]], 0, False]Passed
trace-3[[['a', 'first']], [['a', 1]], 0, True][[['a', 'first']], [['a', 1]], 0, True]Passed
trace-4[[['a', 'first'], ['b', 'urgent'], ['a', 'ready']], [['a', 4], ['b', 0]], 3, False][[['a', 'first'], ['b', 'urgent'], ['a', 'ready']], [['a', 4], ['b', 0]], 3, False]Passed
trace-5[[['a', 'first'], ['a', 'second']], [['a', 0]], 0, False][[['a', 'first'], ['a', 'second']], [['a', 0]], 0, False]Passed
trace-6[[['a', 'later']], [['a', 6]], 4, False][[['a', 'later']], [['a', 6]], 4, False]Passed
trace-7[[], [], 0, False][[], [], 0, False]Passed

SHA-256 / df84c2b6a01be458a2d9cf218c4039ce12808fdb34be2c285de5e8b9e4f05d06

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:28.257766+00:00.

Case digest / 68a467745bebf03a4ca07471a6bef7e79bfc6ac81fa356f0328d30eaaa3c0397