FAILURE MAP
← Case archive

FA-21136 / Assistive announcements / Open access

One-use consent permits repeated speech · case 01

The announcement trace violates the stated confirmation-gate contract.

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

ROOT CAUSE

Fault site: grants.pop(e[1],None) return is implemented as pass return

VERIFIED REPAIR

Restore the stated transition: grants.pop(e[1],None) return

Unsuccessful approach: The attempted repair substitutes grants.clear() return and still violates a regression oracle.

Case contract

Sensitive announcements require a one-use consent token bound to message ID and text revision. Draft replaces text and increments revision. Grant captures current revision. Speak requires current matching consent, emits text and consumes consent. Revoke removes consent; delete removes draft and consent. Nonsensitive preview emits only fixed redacted cue without consuming consent. Expire removes all grants but preserves drafts. Return speech and remaining grant/draft revisions.

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):
    drafts={}; grants={}; out=[]
    for e in events:
        if e[0]=='draft': drafts[e[1]]=[drafts.get(e[1],[0,''])[0]+1,e[2]]
        elif e[0]=='grant' and e[1] in drafts: grants[e[1]]=drafts[e[1]][0]
        elif e[0]=='revoke': grants.pop(e[1],None)
        elif e[0]=='delete': drafts.pop(e[1],None); grants.pop(e[1],None)
        elif e[0]=='expire': grants.clear()
        elif e[0]=='preview' and e[1] in drafts: out.append('private announcement available')
        elif e[0]=='speak':
            if e[1] not in drafts: continue
            if grants.get(e[1])!=drafts[e[1]][0]: continue
            out.append(drafts[e[1]][1])
            pass
    return [out,sorted(grants.items()),[[k,v[0]] for k,v in drafts.items()]]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = ["[['draft','a','secret'*N],['grant','a'],['speak','a'],['speak','a']]", "[['draft','a','old'],['grant','a'],['draft','a','new'*N],['speak','a'],['grant','a'],['speak','a']]", "[['draft','a','secret'*N],['draft','b','other'],['grant','a'],['grant','b'],['revoke','a'],['speak','b']]", "[['draft','a','secret'*N],['grant','a'],['preview','a'],['speak','a']]", "[['draft','a','secret'*N],['grant','a'],['delete','a'],['speak','a']]", "[['draft','a','secret'*N],['grant','a'],['expire'],['speak','a']]", "[['speak','missing']]", "[['draft','a','a'*N],['draft','b','b'],['grant','a'],['grant','b'],['speak','a']]"]
expected = {1: [[['secret'], [], [['a', 1]]], [['new'], [], [['a', 2]]], [['other'], [], [['a', 1], ['b', 1]]], [['private announcement available', 'secret'], [], [['a', 1]]], [[], [], []], [[], [], [['a', 1]]], [[], [], []], [['a'], [('b', 1)], [['a', 1], ['b', 1]]]], 2: [[['secretsecret'], [], [['a', 1]]], [['newnew'], [], [['a', 2]]], [['other'], [], [['a', 1], ['b', 1]]], [['private announcement available', 'secretsecret'], [], [['a', 1]]], [[], [], []], [[], [], [['a', 1]]], [[], [], []], [['aa'], [('b', 1)], [['a', 1], ['b', 1]]]], 3: [[['secretsecretsecret'], [], [['a', 1]]], [['newnewnew'], [], [['a', 2]]], [['other'], [], [['a', 1], ['b', 1]]], [['private announcement available', 'secretsecretsecret'], [], [['a', 1]]], [[], [], []], [[], [], [['a', 1]]], [[], [], []], [['aaa'], [('b', 1)], [['a', 1], ['b', 1]]]], 4: [[['secretsecretsecretsecret'], [], [['a', 1]]], [['newnewnewnew'], [], [['a', 2]]], [['other'], [], [['a', 1], ['b', 1]]], [['private announcement available', 'secretsecretsecretsecret'], [], [['a', 1]]], [[], [], []], [[], [], [['a', 1]]], [[], [], []], [['aaaa'], [('b', 1)], [['a', 1], ['b', 1]]]], 5: [[['secretsecretsecretsecretsecret'], [], [['a', 1]]], [['newnewnewnewnew'], [], [['a', 2]]], [['other'], [], [['a', 1], ['b', 1]]], [['private announcement available', 'secretsecretsecretsecretsecret'], [], [['a', 1]]], [[], [], []], [[], [], [['a', 1]]], [[], [], []], [['aaaaa'], [('b', 1)], [['a', 1], ['b', 1]]]]}[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[['secret', 'secret'], [['a', 1]], [['a', 1]]][['secret'], [], [['a', 1]]]Failed
trace-2[['new'], [['a', 2]], [['a', 2]]][['new'], [], [['a', 2]]]Failed
trace-3[['other'], [['b', 1]], [['a', 1], ['b', 1]]][['other'], [], [['a', 1], ['b', 1]]]Failed
trace-4[['private announcement available', 'secret'], [['a', 1]], [['a', 1]]][['private announcement available', 'secret'], [], [['a', 1]]]Failed
trace-5[[], [], []][[], [], []]Passed
trace-6[[], [], [['a', 1]]][[], [], [['a', 1]]]Passed
trace-7[[], [], []][[], [], []]Passed
trace-8[['a'], [['a', 1], ['b', 1]], [['a', 1], ['b', 1]]][['a'], [['b', 1]], [['a', 1], ['b', 1]]]Failed

SHA-256 / 6683a6a35d51a75e5fc0b81520a6abbc29e8f67b4b0b62d55b130b73255613ff

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(events):
    drafts={}; grants={}; out=[]
    for e in events:
        if e[0]=='draft': drafts[e[1]]=[drafts.get(e[1],[0,''])[0]+1,e[2]]
        elif e[0]=='grant' and e[1] in drafts: grants[e[1]]=drafts[e[1]][0]
        elif e[0]=='revoke': grants.pop(e[1],None)
        elif e[0]=='delete': drafts.pop(e[1],None); grants.pop(e[1],None)
        elif e[0]=='expire': grants.clear()
        elif e[0]=='preview' and e[1] in drafts: out.append('private announcement available')
        elif e[0]=='speak':
            if e[1] not in drafts: continue
            if grants.get(e[1])!=drafts[e[1]][0]: continue
            out.append(drafts[e[1]][1])
            grants.clear()
    return [out,sorted(grants.items()),[[k,v[0]] for k,v in drafts.items()]]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = ["[['draft','a','secret'*N],['grant','a'],['speak','a'],['speak','a']]", "[['draft','a','old'],['grant','a'],['draft','a','new'*N],['speak','a'],['grant','a'],['speak','a']]", "[['draft','a','secret'*N],['draft','b','other'],['grant','a'],['grant','b'],['revoke','a'],['speak','b']]", "[['draft','a','secret'*N],['grant','a'],['preview','a'],['speak','a']]", "[['draft','a','secret'*N],['grant','a'],['delete','a'],['speak','a']]", "[['draft','a','secret'*N],['grant','a'],['expire'],['speak','a']]", "[['speak','missing']]", "[['draft','a','a'*N],['draft','b','b'],['grant','a'],['grant','b'],['speak','a']]"]
expected = {1: [[['secret'], [], [['a', 1]]], [['new'], [], [['a', 2]]], [['other'], [], [['a', 1], ['b', 1]]], [['private announcement available', 'secret'], [], [['a', 1]]], [[], [], []], [[], [], [['a', 1]]], [[], [], []], [['a'], [('b', 1)], [['a', 1], ['b', 1]]]], 2: [[['secretsecret'], [], [['a', 1]]], [['newnew'], [], [['a', 2]]], [['other'], [], [['a', 1], ['b', 1]]], [['private announcement available', 'secretsecret'], [], [['a', 1]]], [[], [], []], [[], [], [['a', 1]]], [[], [], []], [['aa'], [('b', 1)], [['a', 1], ['b', 1]]]], 3: [[['secretsecretsecret'], [], [['a', 1]]], [['newnewnew'], [], [['a', 2]]], [['other'], [], [['a', 1], ['b', 1]]], [['private announcement available', 'secretsecretsecret'], [], [['a', 1]]], [[], [], []], [[], [], [['a', 1]]], [[], [], []], [['aaa'], [('b', 1)], [['a', 1], ['b', 1]]]], 4: [[['secretsecretsecretsecret'], [], [['a', 1]]], [['newnewnewnew'], [], [['a', 2]]], [['other'], [], [['a', 1], ['b', 1]]], [['private announcement available', 'secretsecretsecretsecret'], [], [['a', 1]]], [[], [], []], [[], [], [['a', 1]]], [[], [], []], [['aaaa'], [('b', 1)], [['a', 1], ['b', 1]]]], 5: [[['secretsecretsecretsecretsecret'], [], [['a', 1]]], [['newnewnewnewnew'], [], [['a', 2]]], [['other'], [], [['a', 1], ['b', 1]]], [['private announcement available', 'secretsecretsecretsecretsecret'], [], [['a', 1]]], [[], [], []], [[], [], [['a', 1]]], [[], [], []], [['aaaaa'], [('b', 1)], [['a', 1], ['b', 1]]]]}[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[['secret'], [], [['a', 1]]][['secret'], [], [['a', 1]]]Passed
trace-2[['new'], [], [['a', 2]]][['new'], [], [['a', 2]]]Passed
trace-3[['other'], [], [['a', 1], ['b', 1]]][['other'], [], [['a', 1], ['b', 1]]]Passed
trace-4[['private announcement available', 'secret'], [], [['a', 1]]][['private announcement available', 'secret'], [], [['a', 1]]]Passed
trace-5[[], [], []][[], [], []]Passed
trace-6[[], [], [['a', 1]]][[], [], [['a', 1]]]Passed
trace-7[[], [], []][[], [], []]Passed
trace-8[['a'], [], [['a', 1], ['b', 1]]][['a'], [['b', 1]], [['a', 1], ['b', 1]]]Failed

SHA-256 / 3d0a31262e9a1202c40ec3a54b83e2c7011e80f8286d4b67d1c54dc35aeef1de

3 / The verified repair

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

N = 1
observations = []
def solve(events):
    drafts={}; grants={}; out=[]
    for e in events:
        if e[0]=='draft': drafts[e[1]]=[drafts.get(e[1],[0,''])[0]+1,e[2]]
        elif e[0]=='grant' and e[1] in drafts: grants[e[1]]=drafts[e[1]][0]
        elif e[0]=='revoke': grants.pop(e[1],None)
        elif e[0]=='delete': drafts.pop(e[1],None); grants.pop(e[1],None)
        elif e[0]=='expire': grants.clear()
        elif e[0]=='preview' and e[1] in drafts: out.append('private announcement available')
        elif e[0]=='speak':
            if e[1] not in drafts: continue
            if grants.get(e[1])!=drafts[e[1]][0]: continue
            out.append(drafts[e[1]][1])
            grants.pop(e[1],None)
    return [out,sorted(grants.items()),[[k,v[0]] for k,v in drafts.items()]]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = ["[['draft','a','secret'*N],['grant','a'],['speak','a'],['speak','a']]", "[['draft','a','old'],['grant','a'],['draft','a','new'*N],['speak','a'],['grant','a'],['speak','a']]", "[['draft','a','secret'*N],['draft','b','other'],['grant','a'],['grant','b'],['revoke','a'],['speak','b']]", "[['draft','a','secret'*N],['grant','a'],['preview','a'],['speak','a']]", "[['draft','a','secret'*N],['grant','a'],['delete','a'],['speak','a']]", "[['draft','a','secret'*N],['grant','a'],['expire'],['speak','a']]", "[['speak','missing']]", "[['draft','a','a'*N],['draft','b','b'],['grant','a'],['grant','b'],['speak','a']]"]
expected = {1: [[['secret'], [], [['a', 1]]], [['new'], [], [['a', 2]]], [['other'], [], [['a', 1], ['b', 1]]], [['private announcement available', 'secret'], [], [['a', 1]]], [[], [], []], [[], [], [['a', 1]]], [[], [], []], [['a'], [('b', 1)], [['a', 1], ['b', 1]]]], 2: [[['secretsecret'], [], [['a', 1]]], [['newnew'], [], [['a', 2]]], [['other'], [], [['a', 1], ['b', 1]]], [['private announcement available', 'secretsecret'], [], [['a', 1]]], [[], [], []], [[], [], [['a', 1]]], [[], [], []], [['aa'], [('b', 1)], [['a', 1], ['b', 1]]]], 3: [[['secretsecretsecret'], [], [['a', 1]]], [['newnewnew'], [], [['a', 2]]], [['other'], [], [['a', 1], ['b', 1]]], [['private announcement available', 'secretsecretsecret'], [], [['a', 1]]], [[], [], []], [[], [], [['a', 1]]], [[], [], []], [['aaa'], [('b', 1)], [['a', 1], ['b', 1]]]], 4: [[['secretsecretsecretsecret'], [], [['a', 1]]], [['newnewnewnew'], [], [['a', 2]]], [['other'], [], [['a', 1], ['b', 1]]], [['private announcement available', 'secretsecretsecretsecret'], [], [['a', 1]]], [[], [], []], [[], [], [['a', 1]]], [[], [], []], [['aaaa'], [('b', 1)], [['a', 1], ['b', 1]]]], 5: [[['secretsecretsecretsecretsecret'], [], [['a', 1]]], [['newnewnewnewnew'], [], [['a', 2]]], [['other'], [], [['a', 1], ['b', 1]]], [['private announcement available', 'secretsecretsecretsecretsecret'], [], [['a', 1]]], [[], [], []], [[], [], [['a', 1]]], [[], [], []], [['aaaaa'], [('b', 1)], [['a', 1], ['b', 1]]]]}[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[['secret'], [], [['a', 1]]][['secret'], [], [['a', 1]]]Passed
trace-2[['new'], [], [['a', 2]]][['new'], [], [['a', 2]]]Passed
trace-3[['other'], [], [['a', 1], ['b', 1]]][['other'], [], [['a', 1], ['b', 1]]]Passed
trace-4[['private announcement available', 'secret'], [], [['a', 1]]][['private announcement available', 'secret'], [], [['a', 1]]]Passed
trace-5[[], [], []][[], [], []]Passed
trace-6[[], [], [['a', 1]]][[], [], [['a', 1]]]Passed
trace-7[[], [], []][[], [], []]Passed
trace-8[['a'], [['b', 1]], [['a', 1], ['b', 1]]][['a'], [['b', 1]], [['a', 1], ['b', 1]]]Passed

SHA-256 / 65dcfa94088a4b077d65c157fa3bf0ff8d2f6c61aeba16d9fc18dce9ecf8d1da

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

Case digest / 475f69e52d2ab05488524f22ee4fb9d0a6a219c80c90a3091a785e45c0ee1e03