FAILURE MAP
← Case archive

FA-21121 / Assistive announcements / Open access

Unknown speak creates a phantom private draft · 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: if e[1] not in drafts: continue is implemented as if e[1] not in drafts: drafts[e[1]]=[0,'']; continue

VERIFIED REPAIR

Restore the stated transition: if e[1] not in drafts: continue

Unsuccessful approach: The attempted repair substitutes if e[1] not in drafts: out.append('missing'); continue 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: drafts[e[1]]=[0,'']; 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[[], [], [['a', 0]]][[], [], []]Failed
trace-6[[], [], [['a', 1]]][[], [], [['a', 1]]]Passed
trace-7[[], [], [['missing', 0]]][[], [], []]Failed
trace-8[['a'], [['b', 1]], [['a', 1], ['b', 1]]][['a'], [['b', 1]], [['a', 1], ['b', 1]]]Passed

SHA-256 / 43a2fb73afc1022b7b9ba2bf5fa0904010b2c9935c52b9126a6ee357f230086c

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: out.append('missing'); 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[['missing'], [], []][[], [], []]Failed
trace-6[[], [], [['a', 1]]][[], [], [['a', 1]]]Passed
trace-7[['missing'], [], []][[], [], []]Failed
trace-8[['a'], [['b', 1]], [['a', 1], ['b', 1]]][['a'], [['b', 1]], [['a', 1], ['b', 1]]]Passed

SHA-256 / 020ccf6d92fbd478dd6d8497cfd38d9323de8816390c76a1c2a2d9201bed57bd

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

Case digest / 8ef061fcad2b1441ea2ddce7647b1667d7b2c752b0222995430fa44ceebe8bfa