broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(initial, events, generation, payload=None, observe=None):
    table = {('revealed', 'screen-locked'): 'revealed', ('redacting', 'redaction-applied'): 'redacted', ('redacted', 'reveal-click'): 'reveal-pending', ('reveal-pending', 'confirmation-accepted'): 'revealed', ('reveal-pending', 'confirmation-denied'): 'redacted', ('revealed', 'sensitive-update'): 'redacting-update', ('redacting-update', 'redaction-applied'): 'redacted-updated', ('redacted-updated', 'reveal-click'): 'updated-reveal-pending', ('updated-reveal-pending', 'confirmation-accepted'): 'revealed-updated', ('reveal-pending', 'screen-locked'): 'redacted'}
    data = json.loads(json.dumps({'secret': 'message', 'rendered': 'message', 'revision': 1, 'approved': 0, 'locked': False})) if payload is None else {**json.loads(json.dumps({'secret': 'message', 'rendered': 'message', 'revision': 1, 'approved': 0, 'locked': False})), **json.loads(json.dumps(payload))}
    state = initial
    for delivery in events:
        event, event_generation = delivery[:2]
        arg = delivery[2] if len(delivery) > 2 else {}
        if event_generation == generation:
            previous = state
            if event == 'screen-locked': data['locked'] = True
            if event == 'sensitive-update':
                data['revision'] += 1
                data['secret'] = arg.get('text','updated')
            if event == 'confirmation-accepted':
                if data['locked'] or arg.get('revision',data['revision']) != data['revision']: event = 'confirmation-denied'
                else: data['approved'] = data['revision']
            state = table.get((state, event), state)
            if state in ('redacted','redacted-updated','redacting','redacting-update','hidden'): data['rendered'] = None
            if state in ('revealed','revealed-updated'): data['rendered'] = data['secret']
    return {'phase': state, 'value': data[observe]} if observe else state
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('revealed / screen-locked', solve('revealed', [('screen-locked', N)], N), 'redacting')
check('redacting / redaction-applied', solve('redacting', [('redaction-applied', N)], N), 'redacted')
check('redacted / reveal-click', solve('redacted', [('reveal-click', N)], N), 'reveal-pending')
check('reveal-pending / confirmation-accepted', solve('reveal-pending', [('confirmation-accepted', N)], N), 'revealed')
check('reveal-pending / confirmation-denied', solve('reveal-pending', [('confirmation-denied', N)], N), 'redacted')
check('revealed / sensitive-update', solve('revealed', [('sensitive-update', N)], N), 'redacting-update')
check('redacting-update / redaction-applied', solve('redacting-update', [('redaction-applied', N)], N), 'redacted-updated')
check('redacted-updated / reveal-click', solve('redacted-updated', [('reveal-click', N)], N), 'updated-reveal-pending')
check('updated-reveal-pending / confirmation-accepted', solve('updated-reveal-pending', [('confirmation-accepted', N)], N), 'revealed-updated')
check('reveal-pending / screen-locked', solve('reveal-pending', [('screen-locked', N)], N), 'redacted')
check('older notification incarnation', solve('revealed', [('screen-locked', N - 1)], N), 'revealed')
check('future notification incarnation', solve('revealed', [('screen-locked', N + 1)], N), 'revealed')
check('unknown event is inert', solve('revealed', [('unknown-event', N)], N), 'revealed')
check('empty delivery batch', solve('revealed', [], N), 'revealed')
check('N stale deliveries before current delivery', solve('revealed', [('screen-locked', N - 1)] * N + [('screen-locked', N)], N), 'redacting')
check('trace screen-locked then redaction-applied', solve('revealed', [('screen-locked', N), ('redaction-applied', N)], N), 'redacted')
check('trace redaction-applied then reveal-click', solve('redacting', [('redaction-applied', N), ('reveal-click', N)], N), 'reveal-pending')
check('trace reveal-click then confirmation-accepted', solve('redacted', [('reveal-click', N), ('confirmation-accepted', N)], N), 'revealed')
check('trace reveal-click then confirmation-denied', solve('redacted', [('reveal-click', N), ('confirmation-denied', N)], N), 'redacted')
check('trace reveal-click then screen-locked', solve('redacted', [('reveal-click', N), ('screen-locked', N)], N), 'redacted')
check('trace confirmation-accepted then screen-locked', solve('reveal-pending', [('confirmation-accepted', N), ('screen-locked', N)], N), 'redacting')
check('trace confirmation-accepted then sensitive-update', solve('reveal-pending', [('confirmation-accepted', N), ('sensitive-update', N)], N), 'redacting-update')
check('trace confirmation-denied then reveal-click', solve('reveal-pending', [('confirmation-denied', N), ('reveal-click', N)], N), 'reveal-pending')
check('trace sensitive-update then redaction-applied', solve('revealed', [('sensitive-update', N), ('redaction-applied', N)], N), 'redacted-updated')
check('trace redaction-applied then reveal-click', solve('redacting-update', [('redaction-applied', N), ('reveal-click', N)], N), 'updated-reveal-pending')
check('trace reveal-click then confirmation-accepted', solve('redacted-updated', [('reveal-click', N), ('confirmation-accepted', N)], N), 'revealed-updated')
check('trace screen-locked then reveal-click', solve('reveal-pending', [('screen-locked', N), ('reveal-click', N)], N), 'reveal-pending')
check('domain state regression 1: rendered', solve('revealed', [('screen-locked', N, {})], N, {}, 'rendered'), {'phase': 'redacting', 'value': None})
check('domain state regression 2: rendered', solve('reveal-pending', [('confirmation-accepted', N, {})], N, {'locked': True, 'rendered': None}, 'rendered'), {'phase': 'redacted', 'value': None})
check('domain state regression 3: approved', solve('reveal-pending', [('confirmation-accepted', N, {'revision': 0})], N, {'rendered': None}, 'approved'), {'phase': 'redacted', 'value': 0})
check('domain state regression 4: rendered', solve('reveal-pending', [('confirmation-accepted', N, {'revision': 1})], N, {'rendered': None}, 'rendered'), {'phase': 'revealed', 'value': 'message'})
check('domain state regression 5: rendered', solve('revealed', [('sensitive-update', N, {'text': 'new secret'})], N, {}, 'rendered'), {'phase': 'redacting-update', 'value': None})
check('domain state regression 6: rendered', solve('updated-reveal-pending', [('confirmation-accepted', N, {'revision': 2})], N, {'revision': 2, 'secret': 'new', 'rendered': None}, 'rendered'), {'phase': 'revealed-updated', 'value': 'new'})
check('domain state regression 7: rendered', solve('revealed', [('sensitive-update', N, {'text': 'replacement'}), ('redaction-applied', N, {}), ('reveal-click', N, {}), ('confirmation-accepted', N, {'revision': 2})], N, {}, 'rendered'), {'phase': 'revealed-updated', 'value': 'replacement'})
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(initial, events, generation, payload=None, observe=None):
    table = {('revealed', 'screen-locked'): 'hidden', ('redacting', 'redaction-applied'): 'redacted', ('redacted', 'reveal-click'): 'reveal-pending', ('reveal-pending', 'confirmation-accepted'): 'revealed', ('reveal-pending', 'confirmation-denied'): 'redacted', ('revealed', 'sensitive-update'): 'redacting-update', ('redacting-update', 'redaction-applied'): 'redacted-updated', ('redacted-updated', 'reveal-click'): 'updated-reveal-pending', ('updated-reveal-pending', 'confirmation-accepted'): 'revealed-updated', ('reveal-pending', 'screen-locked'): 'redacted'}
    data = json.loads(json.dumps({'secret': 'message', 'rendered': 'message', 'revision': 1, 'approved': 0, 'locked': False})) if payload is None else {**json.loads(json.dumps({'secret': 'message', 'rendered': 'message', 'revision': 1, 'approved': 0, 'locked': False})), **json.loads(json.dumps(payload))}
    state = initial
    for delivery in events:
        event, event_generation = delivery[:2]
        arg = delivery[2] if len(delivery) > 2 else {}
        if event_generation == generation:
            previous = state
            if event == 'screen-locked': data['locked'] = True
            if event == 'sensitive-update':
                data['revision'] += 1
                data['secret'] = arg.get('text','updated')
            if event == 'confirmation-accepted':
                if data['locked'] or arg.get('revision',data['revision']) != data['revision']: event = 'confirmation-denied'
                else: data['approved'] = data['revision']
            state = table.get((state, event), state)
            if state in ('redacted','redacted-updated','redacting','redacting-update','hidden'): data['rendered'] = None
            if state in ('revealed','revealed-updated'): data['rendered'] = data['secret']
    return {'phase': state, 'value': data[observe]} if observe else state
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('revealed / screen-locked', solve('revealed', [('screen-locked', N)], N), 'redacting')
check('redacting / redaction-applied', solve('redacting', [('redaction-applied', N)], N), 'redacted')
check('redacted / reveal-click', solve('redacted', [('reveal-click', N)], N), 'reveal-pending')
check('reveal-pending / confirmation-accepted', solve('reveal-pending', [('confirmation-accepted', N)], N), 'revealed')
check('reveal-pending / confirmation-denied', solve('reveal-pending', [('confirmation-denied', N)], N), 'redacted')
check('revealed / sensitive-update', solve('revealed', [('sensitive-update', N)], N), 'redacting-update')
check('redacting-update / redaction-applied', solve('redacting-update', [('redaction-applied', N)], N), 'redacted-updated')
check('redacted-updated / reveal-click', solve('redacted-updated', [('reveal-click', N)], N), 'updated-reveal-pending')
check('updated-reveal-pending / confirmation-accepted', solve('updated-reveal-pending', [('confirmation-accepted', N)], N), 'revealed-updated')
check('reveal-pending / screen-locked', solve('reveal-pending', [('screen-locked', N)], N), 'redacted')
check('older notification incarnation', solve('revealed', [('screen-locked', N - 1)], N), 'revealed')
check('future notification incarnation', solve('revealed', [('screen-locked', N + 1)], N), 'revealed')
check('unknown event is inert', solve('revealed', [('unknown-event', N)], N), 'revealed')
check('empty delivery batch', solve('revealed', [], N), 'revealed')
check('N stale deliveries before current delivery', solve('revealed', [('screen-locked', N - 1)] * N + [('screen-locked', N)], N), 'redacting')
check('trace screen-locked then redaction-applied', solve('revealed', [('screen-locked', N), ('redaction-applied', N)], N), 'redacted')
check('trace redaction-applied then reveal-click', solve('redacting', [('redaction-applied', N), ('reveal-click', N)], N), 'reveal-pending')
check('trace reveal-click then confirmation-accepted', solve('redacted', [('reveal-click', N), ('confirmation-accepted', N)], N), 'revealed')
check('trace reveal-click then confirmation-denied', solve('redacted', [('reveal-click', N), ('confirmation-denied', N)], N), 'redacted')
check('trace reveal-click then screen-locked', solve('redacted', [('reveal-click', N), ('screen-locked', N)], N), 'redacted')
check('trace confirmation-accepted then screen-locked', solve('reveal-pending', [('confirmation-accepted', N), ('screen-locked', N)], N), 'redacting')
check('trace confirmation-accepted then sensitive-update', solve('reveal-pending', [('confirmation-accepted', N), ('sensitive-update', N)], N), 'redacting-update')
check('trace confirmation-denied then reveal-click', solve('reveal-pending', [('confirmation-denied', N), ('reveal-click', N)], N), 'reveal-pending')
check('trace sensitive-update then redaction-applied', solve('revealed', [('sensitive-update', N), ('redaction-applied', N)], N), 'redacted-updated')
check('trace redaction-applied then reveal-click', solve('redacting-update', [('redaction-applied', N), ('reveal-click', N)], N), 'updated-reveal-pending')
check('trace reveal-click then confirmation-accepted', solve('redacted-updated', [('reveal-click', N), ('confirmation-accepted', N)], N), 'revealed-updated')
check('trace screen-locked then reveal-click', solve('reveal-pending', [('screen-locked', N), ('reveal-click', N)], N), 'reveal-pending')
check('domain state regression 1: rendered', solve('revealed', [('screen-locked', N, {})], N, {}, 'rendered'), {'phase': 'redacting', 'value': None})
check('domain state regression 2: rendered', solve('reveal-pending', [('confirmation-accepted', N, {})], N, {'locked': True, 'rendered': None}, 'rendered'), {'phase': 'redacted', 'value': None})
check('domain state regression 3: approved', solve('reveal-pending', [('confirmation-accepted', N, {'revision': 0})], N, {'rendered': None}, 'approved'), {'phase': 'redacted', 'value': 0})
check('domain state regression 4: rendered', solve('reveal-pending', [('confirmation-accepted', N, {'revision': 1})], N, {'rendered': None}, 'rendered'), {'phase': 'revealed', 'value': 'message'})
check('domain state regression 5: rendered', solve('revealed', [('sensitive-update', N, {'text': 'new secret'})], N, {}, 'rendered'), {'phase': 'redacting-update', 'value': None})
check('domain state regression 6: rendered', solve('updated-reveal-pending', [('confirmation-accepted', N, {'revision': 2})], N, {'revision': 2, 'secret': 'new', 'rendered': None}, 'rendered'), {'phase': 'revealed-updated', 'value': 'new'})
check('domain state regression 7: rendered', solve('revealed', [('sensitive-update', N, {'text': 'replacement'}), ('redaction-applied', N, {}), ('reveal-click', N, {}), ('confirmation-accepted', N, {'revision': 2})], N, {}, 'rendered'), {'phase': 'revealed-updated', 'value': 'replacement'})
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)

prompt:
The screen-locked event leaves a notification in revealed instead of redacting.

Sensitive notification preview redaction is a bounded visual-notification workflow with mutable policy state {'secret': 'message', 'rendered': 'message', 'revision': 1, 'approved': 0, 'locked': False}. Its default transition relation is {('revealed', 'screen-locked'): 'redacting', ('redacting', 'redaction-applied'): 'redacted', ('redacted', 'reveal-click'): 'reveal-pending', ('reveal-pending', 'confirmation-accepted'): 'revealed', ('reveal-pending', 'confirmation-denied'): 'redacted', ('revealed', 'sensitive-update'): 'redacting-update', ('redacting-update', 'redaction-applied'): 'redacted-updated', ('redacted-updated', 'reveal-click'): 'updated-reveal-pending', ('updated-reveal-pending', 'confirmation-accepted'): 'revealed-updated', ('reveal-pending', 'screen-locked'): 'redacted'}; domain inputs can suppress or redirect transitions and update policy fields, as specified in solve. Different-generation events are inert. Batches apply in order. Optional observe returns the selected policy field alongside the phase.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(initial, events, generation, payload=None, observe=None):
    table = {('revealed', 'screen-locked'): 'redacting', ('redacting', 'redaction-applied'): 'revealed', ('redacted', 'reveal-click'): 'reveal-pending', ('reveal-pending', 'confirmation-accepted'): 'revealed', ('reveal-pending', 'confirmation-denied'): 'redacted', ('revealed', 'sensitive-update'): 'redacting-update', ('redacting-update', 'redaction-applied'): 'redacted-updated', ('redacted-updated', 'reveal-click'): 'updated-reveal-pending', ('updated-reveal-pending', 'confirmation-accepted'): 'revealed-updated', ('reveal-pending', 'screen-locked'): 'redacted'}
    data = json.loads(json.dumps({'secret': 'message', 'rendered': 'message', 'revision': 1, 'approved': 0, 'locked': False})) if payload is None else {**json.loads(json.dumps({'secret': 'message', 'rendered': 'message', 'revision': 1, 'approved': 0, 'locked': False})), **json.loads(json.dumps(payload))}
    state = initial
    for delivery in events:
        event, event_generation = delivery[:2]
        arg = delivery[2] if len(delivery) > 2 else {}
        if event_generation == generation:
            previous = state
            if event == 'screen-locked': data['locked'] = True
            if event == 'sensitive-update':
                data['revision'] += 1
                data['secret'] = arg.get('text','updated')
            if event == 'confirmation-accepted':
                if data['locked'] or arg.get('revision',data['revision']) != data['revision']: event = 'confirmation-denied'
                else: data['approved'] = data['revision']
            state = table.get((state, event), state)
            if state in ('redacted','redacted-updated','redacting','redacting-update','hidden'): data['rendered'] = None
            if state in ('revealed','revealed-updated'): data['rendered'] = data['secret']
    return {'phase': state, 'value': data[observe]} if observe else state
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('revealed / screen-locked', solve('revealed', [('screen-locked', N)], N), 'redacting')
check('redacting / redaction-applied', solve('redacting', [('redaction-applied', N)], N), 'redacted')
check('redacted / reveal-click', solve('redacted', [('reveal-click', N)], N), 'reveal-pending')
check('reveal-pending / confirmation-accepted', solve('reveal-pending', [('confirmation-accepted', N)], N), 'revealed')
check('reveal-pending / confirmation-denied', solve('reveal-pending', [('confirmation-denied', N)], N), 'redacted')
check('revealed / sensitive-update', solve('revealed', [('sensitive-update', N)], N), 'redacting-update')
check('redacting-update / redaction-applied', solve('redacting-update', [('redaction-applied', N)], N), 'redacted-updated')
check('redacted-updated / reveal-click', solve('redacted-updated', [('reveal-click', N)], N), 'updated-reveal-pending')
check('updated-reveal-pending / confirmation-accepted', solve('updated-reveal-pending', [('confirmation-accepted', N)], N), 'revealed-updated')
check('reveal-pending / screen-locked', solve('reveal-pending', [('screen-locked', N)], N), 'redacted')
check('older notification incarnation', solve('revealed', [('screen-locked', N - 1)], N), 'revealed')
check('future notification incarnation', solve('revealed', [('screen-locked', N + 1)], N), 'revealed')
check('unknown event is inert', solve('revealed', [('unknown-event', N)], N), 'revealed')
check('empty delivery batch', solve('revealed', [], N), 'revealed')
check('N stale deliveries before current delivery', solve('revealed', [('screen-locked', N - 1)] * N + [('screen-locked', N)], N), 'redacting')
check('trace screen-locked then redaction-applied', solve('revealed', [('screen-locked', N), ('redaction-applied', N)], N), 'redacted')
check('trace redaction-applied then reveal-click', solve('redacting', [('redaction-applied', N), ('reveal-click', N)], N), 'reveal-pending')
check('trace reveal-click then confirmation-accepted', solve('redacted', [('reveal-click', N), ('confirmation-accepted', N)], N), 'revealed')
check('trace reveal-click then confirmation-denied', solve('redacted', [('reveal-click', N), ('confirmation-denied', N)], N), 'redacted')
check('trace reveal-click then screen-locked', solve('redacted', [('reveal-click', N), ('screen-locked', N)], N), 'redacted')
check('trace confirmation-accepted then screen-locked', solve('reveal-pending', [('confirmation-accepted', N), ('screen-locked', N)], N), 'redacting')
check('trace confirmation-accepted then sensitive-update', solve('reveal-pending', [('confirmation-accepted', N), ('sensitive-update', N)], N), 'redacting-update')
check('trace confirmation-denied then reveal-click', solve('reveal-pending', [('confirmation-denied', N), ('reveal-click', N)], N), 'reveal-pending')
check('trace sensitive-update then redaction-applied', solve('revealed', [('sensitive-update', N), ('redaction-applied', N)], N), 'redacted-updated')
check('trace redaction-applied then reveal-click', solve('redacting-update', [('redaction-applied', N), ('reveal-click', N)], N), 'updated-reveal-pending')
check('trace reveal-click then confirmation-accepted', solve('redacted-updated', [('reveal-click', N), ('confirmation-accepted', N)], N), 'revealed-updated')
check('trace screen-locked then reveal-click', solve('reveal-pending', [('screen-locked', N), ('reveal-click', N)], N), 'reveal-pending')
check('domain state regression 1: rendered', solve('revealed', [('screen-locked', N, {})], N, {}, 'rendered'), {'phase': 'redacting', 'value': None})
check('domain state regression 2: rendered', solve('reveal-pending', [('confirmation-accepted', N, {})], N, {'locked': True, 'rendered': None}, 'rendered'), {'phase': 'redacted', 'value': None})
check('domain state regression 3: approved', solve('reveal-pending', [('confirmation-accepted', N, {'revision': 0})], N, {'rendered': None}, 'approved'), {'phase': 'redacted', 'value': 0})
check('domain state regression 4: rendered', solve('reveal-pending', [('confirmation-accepted', N, {'revision': 1})], N, {'rendered': None}, 'rendered'), {'phase': 'revealed', 'value': 'message'})
check('domain state regression 5: rendered', solve('revealed', [('sensitive-update', N, {'text': 'new secret'})], N, {}, 'rendered'), {'phase': 'redacting-update', 'value': None})
check('domain state regression 6: rendered', solve('updated-reveal-pending', [('confirmation-accepted', N, {'revision': 2})], N, {'revision': 2, 'secret': 'new', 'rendered': None}, 'rendered'), {'phase': 'revealed-updated', 'value': 'new'})
check('domain state regression 7: rendered', solve('revealed', [('sensitive-update', N, {'text': 'replacement'}), ('redaction-applied', N, {}), ('reveal-click', N, {}), ('confirmation-accepted', N, {'revision': 2})], N, {}, 'rendered'), {'phase': 'revealed-updated', 'value': 'replacement'})
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)

meaning: Fixture-count band, not measured model difficulty

deps: stdlib

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(initial, events, generation, payload=None, observe=None):
    table = {('revealed', 'screen-locked'): 'redacting', ('redacting', 'redaction-applied'): 'reveal-pending', ('redacted', 'reveal-click'): 'reveal-pending', ('reveal-pending', 'confirmation-accepted'): 'revealed', ('reveal-pending', 'confirmation-denied'): 'redacted', ('revealed', 'sensitive-update'): 'redacting-update', ('redacting-update', 'redaction-applied'): 'redacted-updated', ('redacted-updated', 'reveal-click'): 'updated-reveal-pending', ('updated-reveal-pending', 'confirmation-accepted'): 'revealed-updated', ('reveal-pending', 'screen-locked'): 'redacted'}
    data = json.loads(json.dumps({'secret': 'message', 'rendered': 'message', 'revision': 1, 'approved': 0, 'locked': False})) if payload is None else {**json.loads(json.dumps({'secret': 'message', 'rendered': 'message', 'revision': 1, 'approved': 0, 'locked': False})), **json.loads(json.dumps(payload))}
    state = initial
    for delivery in events:
        event, event_generation = delivery[:2]
        arg = delivery[2] if len(delivery) > 2 else {}
        if event_generation == generation:
            previous = state
            if event == 'screen-locked': data['locked'] = True
            if event == 'sensitive-update':
                data['revision'] += 1
                data['secret'] = arg.get('text','updated')
            if event == 'confirmation-accepted':
                if data['locked'] or arg.get('revision',data['revision']) != data['revision']: event = 'confirmation-denied'
                else: data['approved'] = data['revision']
            state = table.get((state, event), state)
            if state in ('redacted','redacted-updated','redacting','redacting-update','hidden'): data['rendered'] = None
            if state in ('revealed','revealed-updated'): data['rendered'] = data['secret']
    return {'phase': state, 'value': data[observe]} if observe else state
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('revealed / screen-locked', solve('revealed', [('screen-locked', N)], N), 'redacting')
check('redacting / redaction-applied', solve('redacting', [('redaction-applied', N)], N), 'redacted')
check('redacted / reveal-click', solve('redacted', [('reveal-click', N)], N), 'reveal-pending')
check('reveal-pending / confirmation-accepted', solve('reveal-pending', [('confirmation-accepted', N)], N), 'revealed')
check('reveal-pending / confirmation-denied', solve('reveal-pending', [('confirmation-denied', N)], N), 'redacted')
check('revealed / sensitive-update', solve('revealed', [('sensitive-update', N)], N), 'redacting-update')
check('redacting-update / redaction-applied', solve('redacting-update', [('redaction-applied', N)], N), 'redacted-updated')
check('redacted-updated / reveal-click', solve('redacted-updated', [('reveal-click', N)], N), 'updated-reveal-pending')
check('updated-reveal-pending / confirmation-accepted', solve('updated-reveal-pending', [('confirmation-accepted', N)], N), 'revealed-updated')
check('reveal-pending / screen-locked', solve('reveal-pending', [('screen-locked', N)], N), 'redacted')
check('older notification incarnation', solve('revealed', [('screen-locked', N - 1)], N), 'revealed')
check('future notification incarnation', solve('revealed', [('screen-locked', N + 1)], N), 'revealed')
check('unknown event is inert', solve('revealed', [('unknown-event', N)], N), 'revealed')
check('empty delivery batch', solve('revealed', [], N), 'revealed')
check('N stale deliveries before current delivery', solve('revealed', [('screen-locked', N - 1)] * N + [('screen-locked', N)], N), 'redacting')
check('trace screen-locked then redaction-applied', solve('revealed', [('screen-locked', N), ('redaction-applied', N)], N), 'redacted')
check('trace redaction-applied then reveal-click', solve('redacting', [('redaction-applied', N), ('reveal-click', N)], N), 'reveal-pending')
check('trace reveal-click then confirmation-accepted', solve('redacted', [('reveal-click', N), ('confirmation-accepted', N)], N), 'revealed')
check('trace reveal-click then confirmation-denied', solve('redacted', [('reveal-click', N), ('confirmation-denied', N)], N), 'redacted')
check('trace reveal-click then screen-locked', solve('redacted', [('reveal-click', N), ('screen-locked', N)], N), 'redacted')
check('trace confirmation-accepted then screen-locked', solve('reveal-pending', [('confirmation-accepted', N), ('screen-locked', N)], N), 'redacting')
check('trace confirmation-accepted then sensitive-update', solve('reveal-pending', [('confirmation-accepted', N), ('sensitive-update', N)], N), 'redacting-update')
check('trace confirmation-denied then reveal-click', solve('reveal-pending', [('confirmation-denied', N), ('reveal-click', N)], N), 'reveal-pending')
check('trace sensitive-update then redaction-applied', solve('revealed', [('sensitive-update', N), ('redaction-applied', N)], N), 'redacted-updated')
check('trace redaction-applied then reveal-click', solve('redacting-update', [('redaction-applied', N), ('reveal-click', N)], N), 'updated-reveal-pending')
check('trace reveal-click then confirmation-accepted', solve('redacted-updated', [('reveal-click', N), ('confirmation-accepted', N)], N), 'revealed-updated')
check('trace screen-locked then reveal-click', solve('reveal-pending', [('screen-locked', N), ('reveal-click', N)], N), 'reveal-pending')
check('domain state regression 1: rendered', solve('revealed', [('screen-locked', N, {})], N, {}, 'rendered'), {'phase': 'redacting', 'value': None})
check('domain state regression 2: rendered', solve('reveal-pending', [('confirmation-accepted', N, {})], N, {'locked': True, 'rendered': None}, 'rendered'), {'phase': 'redacted', 'value': None})
check('domain state regression 3: approved', solve('reveal-pending', [('confirmation-accepted', N, {'revision': 0})], N, {'rendered': None}, 'approved'), {'phase': 'redacted', 'value': 0})
check('domain state regression 4: rendered', solve('reveal-pending', [('confirmation-accepted', N, {'revision': 1})], N, {'rendered': None}, 'rendered'), {'phase': 'revealed', 'value': 'message'})
check('domain state regression 5: rendered', solve('revealed', [('sensitive-update', N, {'text': 'new secret'})], N, {}, 'rendered'), {'phase': 'redacting-update', 'value': None})
check('domain state regression 6: rendered', solve('updated-reveal-pending', [('confirmation-accepted', N, {'revision': 2})], N, {'revision': 2, 'secret': 'new', 'rendered': None}, 'rendered'), {'phase': 'revealed-updated', 'value': 'new'})
check('domain state regression 7: rendered', solve('revealed', [('sensitive-update', N, {'text': 'replacement'}), ('redaction-applied', N, {}), ('reveal-click', N, {}), ('confirmation-accepted', N, {'revision': 2})], N, {}, 'rendered'), {'phase': 'revealed-updated', 'value': 'replacement'})
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)

prompt:
The redaction-applied event leaves a notification in revealed instead of redacted.

Sensitive notification preview redaction is a bounded visual-notification workflow with mutable policy state {'secret': 'message', 'rendered': 'message', 'revision': 1, 'approved': 0, 'locked': False}. Its default transition relation is {('revealed', 'screen-locked'): 'redacting', ('redacting', 'redaction-applied'): 'redacted', ('redacted', 'reveal-click'): 'reveal-pending', ('reveal-pending', 'confirmation-accepted'): 'revealed', ('reveal-pending', 'confirmation-denied'): 'redacted', ('revealed', 'sensitive-update'): 'redacting-update', ('redacting-update', 'redaction-applied'): 'redacted-updated', ('redacted-updated', 'reveal-click'): 'updated-reveal-pending', ('updated-reveal-pending', 'confirmation-accepted'): 'revealed-updated', ('reveal-pending', 'screen-locked'): 'redacted'}; domain inputs can suppress or redirect transitions and update policy fields, as specified in solve. Different-generation events are inert. Batches apply in order. Optional observe returns the selected policy field alongside the phase.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(initial, events, generation, payload=None, observe=None):
    table = {('revealed', 'screen-locked'): 'redacting', ('redacting', 'redaction-applied'): 'redacted', ('redacted', 'reveal-click'): 'revealed', ('reveal-pending', 'confirmation-accepted'): 'revealed', ('reveal-pending', 'confirmation-denied'): 'redacted', ('revealed', 'sensitive-update'): 'redacting-update', ('redacting-update', 'redaction-applied'): 'redacted-updated', ('redacted-updated', 'reveal-click'): 'updated-reveal-pending', ('updated-reveal-pending', 'confirmation-accepted'): 'revealed-updated', ('reveal-pending', 'screen-locked'): 'redacted'}
    data = json.loads(json.dumps({'secret': 'message', 'rendered': 'message', 'revision': 1, 'approved': 0, 'locked': False})) if payload is None else {**json.loads(json.dumps({'secret': 'message', 'rendered': 'message', 'revision': 1, 'approved': 0, 'locked': False})), **json.loads(json.dumps(payload))}
    state = initial
    for delivery in events:
        event, event_generation = delivery[:2]
        arg = delivery[2] if len(delivery) > 2 else {}
        if event_generation == generation:
            previous = state
            if event == 'screen-locked': data['locked'] = True
            if event == 'sensitive-update':
                data['revision'] += 1
                data['secret'] = arg.get('text','updated')
            if event == 'confirmation-accepted':
                if data['locked'] or arg.get('revision',data['revision']) != data['revision']: event = 'confirmation-denied'
                else: data['approved'] = data['revision']
            state = table.get((state, event), state)
            if state in ('redacted','redacted-updated','redacting','redacting-update','hidden'): data['rendered'] = None
            if state in ('revealed','revealed-updated'): data['rendered'] = data['secret']
    return {'phase': state, 'value': data[observe]} if observe else state
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('revealed / screen-locked', solve('revealed', [('screen-locked', N)], N), 'redacting')
check('redacting / redaction-applied', solve('redacting', [('redaction-applied', N)], N), 'redacted')
check('redacted / reveal-click', solve('redacted', [('reveal-click', N)], N), 'reveal-pending')
check('reveal-pending / confirmation-accepted', solve('reveal-pending', [('confirmation-accepted', N)], N), 'revealed')
check('reveal-pending / confirmation-denied', solve('reveal-pending', [('confirmation-denied', N)], N), 'redacted')
check('revealed / sensitive-update', solve('revealed', [('sensitive-update', N)], N), 'redacting-update')
check('redacting-update / redaction-applied', solve('redacting-update', [('redaction-applied', N)], N), 'redacted-updated')
check('redacted-updated / reveal-click', solve('redacted-updated', [('reveal-click', N)], N), 'updated-reveal-pending')
check('updated-reveal-pending / confirmation-accepted', solve('updated-reveal-pending', [('confirmation-accepted', N)], N), 'revealed-updated')
check('reveal-pending / screen-locked', solve('reveal-pending', [('screen-locked', N)], N), 'redacted')
check('older notification incarnation', solve('revealed', [('screen-locked', N - 1)], N), 'revealed')
check('future notification incarnation', solve('revealed', [('screen-locked', N + 1)], N), 'revealed')
check('unknown event is inert', solve('revealed', [('unknown-event', N)], N), 'revealed')
check('empty delivery batch', solve('revealed', [], N), 'revealed')
check('N stale deliveries before current delivery', solve('revealed', [('screen-locked', N - 1)] * N + [('screen-locked', N)], N), 'redacting')
check('trace screen-locked then redaction-applied', solve('revealed', [('screen-locked', N), ('redaction-applied', N)], N), 'redacted')
check('trace redaction-applied then reveal-click', solve('redacting', [('redaction-applied', N), ('reveal-click', N)], N), 'reveal-pending')
check('trace reveal-click then confirmation-accepted', solve('redacted', [('reveal-click', N), ('confirmation-accepted', N)], N), 'revealed')
check('trace reveal-click then confirmation-denied', solve('redacted', [('reveal-click', N), ('confirmation-denied', N)], N), 'redacted')
check('trace reveal-click then screen-locked', solve('redacted', [('reveal-click', N), ('screen-locked', N)], N), 'redacted')
check('trace confirmation-accepted then screen-locked', solve('reveal-pending', [('confirmation-accepted', N), ('screen-locked', N)], N), 'redacting')
check('trace confirmation-accepted then sensitive-update', solve('reveal-pending', [('confirmation-accepted', N), ('sensitive-update', N)], N), 'redacting-update')
check('trace confirmation-denied then reveal-click', solve('reveal-pending', [('confirmation-denied', N), ('reveal-click', N)], N), 'reveal-pending')
check('trace sensitive-update then redaction-applied', solve('revealed', [('sensitive-update', N), ('redaction-applied', N)], N), 'redacted-updated')
check('trace redaction-applied then reveal-click', solve('redacting-update', [('redaction-applied', N), ('reveal-click', N)], N), 'updated-reveal-pending')
check('trace reveal-click then confirmation-accepted', solve('redacted-updated', [('reveal-click', N), ('confirmation-accepted', N)], N), 'revealed-updated')
check('trace screen-locked then reveal-click', solve('reveal-pending', [('screen-locked', N), ('reveal-click', N)], N), 'reveal-pending')
check('domain state regression 1: rendered', solve('revealed', [('screen-locked', N, {})], N, {}, 'rendered'), {'phase': 'redacting', 'value': None})
check('domain state regression 2: rendered', solve('reveal-pending', [('confirmation-accepted', N, {})], N, {'locked': True, 'rendered': None}, 'rendered'), {'phase': 'redacted', 'value': None})
check('domain state regression 3: approved', solve('reveal-pending', [('confirmation-accepted', N, {'revision': 0})], N, {'rendered': None}, 'approved'), {'phase': 'redacted', 'value': 0})
check('domain state regression 4: rendered', solve('reveal-pending', [('confirmation-accepted', N, {'revision': 1})], N, {'rendered': None}, 'rendered'), {'phase': 'revealed', 'value': 'message'})
check('domain state regression 5: rendered', solve('revealed', [('sensitive-update', N, {'text': 'new secret'})], N, {}, 'rendered'), {'phase': 'redacting-update', 'value': None})
check('domain state regression 6: rendered', solve('updated-reveal-pending', [('confirmation-accepted', N, {'revision': 2})], N, {'revision': 2, 'secret': 'new', 'rendered': None}, 'rendered'), {'phase': 'revealed-updated', 'value': 'new'})
check('domain state regression 7: rendered', solve('revealed', [('sensitive-update', N, {'text': 'replacement'}), ('redaction-applied', N, {}), ('reveal-click', N, {}), ('confirmation-accepted', N, {'revision': 2})], N, {}, 'rendered'), {'phase': 'revealed-updated', 'value': 'replacement'})
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(initial, events, generation, payload=None, observe=None):
    table = {('revealed', 'screen-locked'): 'redacting', ('redacting', 'redaction-applied'): 'redacted', ('redacted', 'reveal-click'): 'hidden', ('reveal-pending', 'confirmation-accepted'): 'revealed', ('reveal-pending', 'confirmation-denied'): 'redacted', ('revealed', 'sensitive-update'): 'redacting-update', ('redacting-update', 'redaction-applied'): 'redacted-updated', ('redacted-updated', 'reveal-click'): 'updated-reveal-pending', ('updated-reveal-pending', 'confirmation-accepted'): 'revealed-updated', ('reveal-pending', 'screen-locked'): 'redacted'}
    data = json.loads(json.dumps({'secret': 'message', 'rendered': 'message', 'revision': 1, 'approved': 0, 'locked': False})) if payload is None else {**json.loads(json.dumps({'secret': 'message', 'rendered': 'message', 'revision': 1, 'approved': 0, 'locked': False})), **json.loads(json.dumps(payload))}
    state = initial
    for delivery in events:
        event, event_generation = delivery[:2]
        arg = delivery[2] if len(delivery) > 2 else {}
        if event_generation == generation:
            previous = state
            if event == 'screen-locked': data['locked'] = True
            if event == 'sensitive-update':
                data['revision'] += 1
                data['secret'] = arg.get('text','updated')
            if event == 'confirmation-accepted':
                if data['locked'] or arg.get('revision',data['revision']) != data['revision']: event = 'confirmation-denied'
                else: data['approved'] = data['revision']
            state = table.get((state, event), state)
            if state in ('redacted','redacted-updated','redacting','redacting-update','hidden'): data['rendered'] = None
            if state in ('revealed','revealed-updated'): data['rendered'] = data['secret']
    return {'phase': state, 'value': data[observe]} if observe else state
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('revealed / screen-locked', solve('revealed', [('screen-locked', N)], N), 'redacting')
check('redacting / redaction-applied', solve('redacting', [('redaction-applied', N)], N), 'redacted')
check('redacted / reveal-click', solve('redacted', [('reveal-click', N)], N), 'reveal-pending')
check('reveal-pending / confirmation-accepted', solve('reveal-pending', [('confirmation-accepted', N)], N), 'revealed')
check('reveal-pending / confirmation-denied', solve('reveal-pending', [('confirmation-denied', N)], N), 'redacted')
check('revealed / sensitive-update', solve('revealed', [('sensitive-update', N)], N), 'redacting-update')
check('redacting-update / redaction-applied', solve('redacting-update', [('redaction-applied', N)], N), 'redacted-updated')
check('redacted-updated / reveal-click', solve('redacted-updated', [('reveal-click', N)], N), 'updated-reveal-pending')
check('updated-reveal-pending / confirmation-accepted', solve('updated-reveal-pending', [('confirmation-accepted', N)], N), 'revealed-updated')
check('reveal-pending / screen-locked', solve('reveal-pending', [('screen-locked', N)], N), 'redacted')
check('older notification incarnation', solve('revealed', [('screen-locked', N - 1)], N), 'revealed')
check('future notification incarnation', solve('revealed', [('screen-locked', N + 1)], N), 'revealed')
check('unknown event is inert', solve('revealed', [('unknown-event', N)], N), 'revealed')
check('empty delivery batch', solve('revealed', [], N), 'revealed')
check('N stale deliveries before current delivery', solve('revealed', [('screen-locked', N - 1)] * N + [('screen-locked', N)], N), 'redacting')
check('trace screen-locked then redaction-applied', solve('revealed', [('screen-locked', N), ('redaction-applied', N)], N), 'redacted')
check('trace redaction-applied then reveal-click', solve('redacting', [('redaction-applied', N), ('reveal-click', N)], N), 'reveal-pending')
check('trace reveal-click then confirmation-accepted', solve('redacted', [('reveal-click', N), ('confirmation-accepted', N)], N), 'revealed')
check('trace reveal-click then confirmation-denied', solve('redacted', [('reveal-click', N), ('confirmation-denied', N)], N), 'redacted')
check('trace reveal-click then screen-locked', solve('redacted', [('reveal-click', N), ('screen-locked', N)], N), 'redacted')
check('trace confirmation-accepted then screen-locked', solve('reveal-pending', [('confirmation-accepted', N), ('screen-locked', N)], N), 'redacting')
check('trace confirmation-accepted then sensitive-update', solve('reveal-pending', [('confirmation-accepted', N), ('sensitive-update', N)], N), 'redacting-update')
check('trace confirmation-denied then reveal-click', solve('reveal-pending', [('confirmation-denied', N), ('reveal-click', N)], N), 'reveal-pending')
check('trace sensitive-update then redaction-applied', solve('revealed', [('sensitive-update', N), ('redaction-applied', N)], N), 'redacted-updated')
check('trace redaction-applied then reveal-click', solve('redacting-update', [('redaction-applied', N), ('reveal-click', N)], N), 'updated-reveal-pending')
check('trace reveal-click then confirmation-accepted', solve('redacted-updated', [('reveal-click', N), ('confirmation-accepted', N)], N), 'revealed-updated')
check('trace screen-locked then reveal-click', solve('reveal-pending', [('screen-locked', N), ('reveal-click', N)], N), 'reveal-pending')
check('domain state regression 1: rendered', solve('revealed', [('screen-locked', N, {})], N, {}, 'rendered'), {'phase': 'redacting', 'value': None})
check('domain state regression 2: rendered', solve('reveal-pending', [('confirmation-accepted', N, {})], N, {'locked': True, 'rendered': None}, 'rendered'), {'phase': 'redacted', 'value': None})
check('domain state regression 3: approved', solve('reveal-pending', [('confirmation-accepted', N, {'revision': 0})], N, {'rendered': None}, 'approved'), {'phase': 'redacted', 'value': 0})
check('domain state regression 4: rendered', solve('reveal-pending', [('confirmation-accepted', N, {'revision': 1})], N, {'rendered': None}, 'rendered'), {'phase': 'revealed', 'value': 'message'})
check('domain state regression 5: rendered', solve('revealed', [('sensitive-update', N, {'text': 'new secret'})], N, {}, 'rendered'), {'phase': 'redacting-update', 'value': None})
check('domain state regression 6: rendered', solve('updated-reveal-pending', [('confirmation-accepted', N, {'revision': 2})], N, {'revision': 2, 'secret': 'new', 'rendered': None}, 'rendered'), {'phase': 'revealed-updated', 'value': 'new'})
check('domain state regression 7: rendered', solve('revealed', [('sensitive-update', N, {'text': 'replacement'}), ('redaction-applied', N, {}), ('reveal-click', N, {}), ('confirmation-accepted', N, {'revision': 2})], N, {}, 'rendered'), {'phase': 'revealed-updated', 'value': 'replacement'})
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)

prompt:
The reveal-click event leaves a notification in revealed instead of reveal-pending.

Sensitive notification preview redaction is a bounded visual-notification workflow with mutable policy state {'secret': 'message', 'rendered': 'message', 'revision': 1, 'approved': 0, 'locked': False}. Its default transition relation is {('revealed', 'screen-locked'): 'redacting', ('redacting', 'redaction-applied'): 'redacted', ('redacted', 'reveal-click'): 'reveal-pending', ('reveal-pending', 'confirmation-accepted'): 'revealed', ('reveal-pending', 'confirmation-denied'): 'redacted', ('revealed', 'sensitive-update'): 'redacting-update', ('redacting-update', 'redaction-applied'): 'redacted-updated', ('redacted-updated', 'reveal-click'): 'updated-reveal-pending', ('updated-reveal-pending', 'confirmation-accepted'): 'revealed-updated', ('reveal-pending', 'screen-locked'): 'redacted'}; domain inputs can suppress or redirect transitions and update policy fields, as specified in solve. Different-generation events are inert. Batches apply in order. Optional observe returns the selected policy field alongside the phase.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(initial, events, generation, payload=None, observe=None):
    table = {('revealed', 'screen-locked'): 'redacting', ('redacting', 'redaction-applied'): 'redacted', ('redacted', 'reveal-click'): 'reveal-pending', ('reveal-pending', 'confirmation-accepted'): 'redacted', ('reveal-pending', 'confirmation-denied'): 'redacted', ('revealed', 'sensitive-update'): 'redacting-update', ('redacting-update', 'redaction-applied'): 'redacted-updated', ('redacted-updated', 'reveal-click'): 'updated-reveal-pending', ('updated-reveal-pending', 'confirmation-accepted'): 'revealed-updated', ('reveal-pending', 'screen-locked'): 'redacted'}
    data = json.loads(json.dumps({'secret': 'message', 'rendered': 'message', 'revision': 1, 'approved': 0, 'locked': False})) if payload is None else {**json.loads(json.dumps({'secret': 'message', 'rendered': 'message', 'revision': 1, 'approved': 0, 'locked': False})), **json.loads(json.dumps(payload))}
    state = initial
    for delivery in events:
        event, event_generation = delivery[:2]
        arg = delivery[2] if len(delivery) > 2 else {}
        if event_generation == generation:
            previous = state
            if event == 'screen-locked': data['locked'] = True
            if event == 'sensitive-update':
                data['revision'] += 1
                data['secret'] = arg.get('text','updated')
            if event == 'confirmation-accepted':
                if data['locked'] or arg.get('revision',data['revision']) != data['revision']: event = 'confirmation-denied'
                else: data['approved'] = data['revision']
            state = table.get((state, event), state)
            if state in ('redacted','redacted-updated','redacting','redacting-update','hidden'): data['rendered'] = None
            if state in ('revealed','revealed-updated'): data['rendered'] = data['secret']
    return {'phase': state, 'value': data[observe]} if observe else state
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('revealed / screen-locked', solve('revealed', [('screen-locked', N)], N), 'redacting')
check('redacting / redaction-applied', solve('redacting', [('redaction-applied', N)], N), 'redacted')
check('redacted / reveal-click', solve('redacted', [('reveal-click', N)], N), 'reveal-pending')
check('reveal-pending / confirmation-accepted', solve('reveal-pending', [('confirmation-accepted', N)], N), 'revealed')
check('reveal-pending / confirmation-denied', solve('reveal-pending', [('confirmation-denied', N)], N), 'redacted')
check('revealed / sensitive-update', solve('revealed', [('sensitive-update', N)], N), 'redacting-update')
check('redacting-update / redaction-applied', solve('redacting-update', [('redaction-applied', N)], N), 'redacted-updated')
check('redacted-updated / reveal-click', solve('redacted-updated', [('reveal-click', N)], N), 'updated-reveal-pending')
check('updated-reveal-pending / confirmation-accepted', solve('updated-reveal-pending', [('confirmation-accepted', N)], N), 'revealed-updated')
check('reveal-pending / screen-locked', solve('reveal-pending', [('screen-locked', N)], N), 'redacted')
check('older notification incarnation', solve('revealed', [('screen-locked', N - 1)], N), 'revealed')
check('future notification incarnation', solve('revealed', [('screen-locked', N + 1)], N), 'revealed')
check('unknown event is inert', solve('revealed', [('unknown-event', N)], N), 'revealed')
check('empty delivery batch', solve('revealed', [], N), 'revealed')
check('N stale deliveries before current delivery', solve('revealed', [('screen-locked', N - 1)] * N + [('screen-locked', N)], N), 'redacting')
check('trace screen-locked then redaction-applied', solve('revealed', [('screen-locked', N), ('redaction-applied', N)], N), 'redacted')
check('trace redaction-applied then reveal-click', solve('redacting', [('redaction-applied', N), ('reveal-click', N)], N), 'reveal-pending')
check('trace reveal-click then confirmation-accepted', solve('redacted', [('reveal-click', N), ('confirmation-accepted', N)], N), 'revealed')
check('trace reveal-click then confirmation-denied', solve('redacted', [('reveal-click', N), ('confirmation-denied', N)], N), 'redacted')
check('trace reveal-click then screen-locked', solve('redacted', [('reveal-click', N), ('screen-locked', N)], N), 'redacted')
check('trace confirmation-accepted then screen-locked', solve('reveal-pending', [('confirmation-accepted', N), ('screen-locked', N)], N), 'redacting')
check('trace confirmation-accepted then sensitive-update', solve('reveal-pending', [('confirmation-accepted', N), ('sensitive-update', N)], N), 'redacting-update')
check('trace confirmation-denied then reveal-click', solve('reveal-pending', [('confirmation-denied', N), ('reveal-click', N)], N), 'reveal-pending')
check('trace sensitive-update then redaction-applied', solve('revealed', [('sensitive-update', N), ('redaction-applied', N)], N), 'redacted-updated')
check('trace redaction-applied then reveal-click', solve('redacting-update', [('redaction-applied', N), ('reveal-click', N)], N), 'updated-reveal-pending')
check('trace reveal-click then confirmation-accepted', solve('redacted-updated', [('reveal-click', N), ('confirmation-accepted', N)], N), 'revealed-updated')
check('trace screen-locked then reveal-click', solve('reveal-pending', [('screen-locked', N), ('reveal-click', N)], N), 'reveal-pending')
check('domain state regression 1: rendered', solve('revealed', [('screen-locked', N, {})], N, {}, 'rendered'), {'phase': 'redacting', 'value': None})
check('domain state regression 2: rendered', solve('reveal-pending', [('confirmation-accepted', N, {})], N, {'locked': True, 'rendered': None}, 'rendered'), {'phase': 'redacted', 'value': None})
check('domain state regression 3: approved', solve('reveal-pending', [('confirmation-accepted', N, {'revision': 0})], N, {'rendered': None}, 'approved'), {'phase': 'redacted', 'value': 0})
check('domain state regression 4: rendered', solve('reveal-pending', [('confirmation-accepted', N, {'revision': 1})], N, {'rendered': None}, 'rendered'), {'phase': 'revealed', 'value': 'message'})
check('domain state regression 5: rendered', solve('revealed', [('sensitive-update', N, {'text': 'new secret'})], N, {}, 'rendered'), {'phase': 'redacting-update', 'value': None})
check('domain state regression 6: rendered', solve('updated-reveal-pending', [('confirmation-accepted', N, {'revision': 2})], N, {'revision': 2, 'secret': 'new', 'rendered': None}, 'rendered'), {'phase': 'revealed-updated', 'value': 'new'})
check('domain state regression 7: rendered', solve('revealed', [('sensitive-update', N, {'text': 'replacement'}), ('redaction-applied', N, {}), ('reveal-click', N, {}), ('confirmation-accepted', N, {'revision': 2})], N, {}, 'rendered'), {'phase': 'revealed-updated', 'value': 'replacement'})
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(initial, events, generation, payload=None, observe=None):
    table = {('revealed', 'screen-locked'): 'redacting', ('redacting', 'redaction-applied'): 'redacted', ('redacted', 'reveal-click'): 'reveal-pending', ('reveal-pending', 'confirmation-accepted'): 'hidden', ('reveal-pending', 'confirmation-denied'): 'redacted', ('revealed', 'sensitive-update'): 'redacting-update', ('redacting-update', 'redaction-applied'): 'redacted-updated', ('redacted-updated', 'reveal-click'): 'updated-reveal-pending', ('updated-reveal-pending', 'confirmation-accepted'): 'revealed-updated', ('reveal-pending', 'screen-locked'): 'redacted'}
    data = json.loads(json.dumps({'secret': 'message', 'rendered': 'message', 'revision': 1, 'approved': 0, 'locked': False})) if payload is None else {**json.loads(json.dumps({'secret': 'message', 'rendered': 'message', 'revision': 1, 'approved': 0, 'locked': False})), **json.loads(json.dumps(payload))}
    state = initial
    for delivery in events:
        event, event_generation = delivery[:2]
        arg = delivery[2] if len(delivery) > 2 else {}
        if event_generation == generation:
            previous = state
            if event == 'screen-locked': data['locked'] = True
            if event == 'sensitive-update':
                data['revision'] += 1
                data['secret'] = arg.get('text','updated')
            if event == 'confirmation-accepted':
                if data['locked'] or arg.get('revision',data['revision']) != data['revision']: event = 'confirmation-denied'
                else: data['approved'] = data['revision']
            state = table.get((state, event), state)
            if state in ('redacted','redacted-updated','redacting','redacting-update','hidden'): data['rendered'] = None
            if state in ('revealed','revealed-updated'): data['rendered'] = data['secret']
    return {'phase': state, 'value': data[observe]} if observe else state
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('revealed / screen-locked', solve('revealed', [('screen-locked', N)], N), 'redacting')
check('redacting / redaction-applied', solve('redacting', [('redaction-applied', N)], N), 'redacted')
check('redacted / reveal-click', solve('redacted', [('reveal-click', N)], N), 'reveal-pending')
check('reveal-pending / confirmation-accepted', solve('reveal-pending', [('confirmation-accepted', N)], N), 'revealed')
check('reveal-pending / confirmation-denied', solve('reveal-pending', [('confirmation-denied', N)], N), 'redacted')
check('revealed / sensitive-update', solve('revealed', [('sensitive-update', N)], N), 'redacting-update')
check('redacting-update / redaction-applied', solve('redacting-update', [('redaction-applied', N)], N), 'redacted-updated')
check('redacted-updated / reveal-click', solve('redacted-updated', [('reveal-click', N)], N), 'updated-reveal-pending')
check('updated-reveal-pending / confirmation-accepted', solve('updated-reveal-pending', [('confirmation-accepted', N)], N), 'revealed-updated')
check('reveal-pending / screen-locked', solve('reveal-pending', [('screen-locked', N)], N), 'redacted')
check('older notification incarnation', solve('revealed', [('screen-locked', N - 1)], N), 'revealed')
check('future notification incarnation', solve('revealed', [('screen-locked', N + 1)], N), 'revealed')
check('unknown event is inert', solve('revealed', [('unknown-event', N)], N), 'revealed')
check('empty delivery batch', solve('revealed', [], N), 'revealed')
check('N stale deliveries before current delivery', solve('revealed', [('screen-locked', N - 1)] * N + [('screen-locked', N)], N), 'redacting')
check('trace screen-locked then redaction-applied', solve('revealed', [('screen-locked', N), ('redaction-applied', N)], N), 'redacted')
check('trace redaction-applied then reveal-click', solve('redacting', [('redaction-applied', N), ('reveal-click', N)], N), 'reveal-pending')
check('trace reveal-click then confirmation-accepted', solve('redacted', [('reveal-click', N), ('confirmation-accepted', N)], N), 'revealed')
check('trace reveal-click then confirmation-denied', solve('redacted', [('reveal-click', N), ('confirmation-denied', N)], N), 'redacted')
check('trace reveal-click then screen-locked', solve('redacted', [('reveal-click', N), ('screen-locked', N)], N), 'redacted')
check('trace confirmation-accepted then screen-locked', solve('reveal-pending', [('confirmation-accepted', N), ('screen-locked', N)], N), 'redacting')
check('trace confirmation-accepted then sensitive-update', solve('reveal-pending', [('confirmation-accepted', N), ('sensitive-update', N)], N), 'redacting-update')
check('trace confirmation-denied then reveal-click', solve('reveal-pending', [('confirmation-denied', N), ('reveal-click', N)], N), 'reveal-pending')
check('trace sensitive-update then redaction-applied', solve('revealed', [('sensitive-update', N), ('redaction-applied', N)], N), 'redacted-updated')
check('trace redaction-applied then reveal-click', solve('redacting-update', [('redaction-applied', N), ('reveal-click', N)], N), 'updated-reveal-pending')
check('trace reveal-click then confirmation-accepted', solve('redacted-updated', [('reveal-click', N), ('confirmation-accepted', N)], N), 'revealed-updated')
check('trace screen-locked then reveal-click', solve('reveal-pending', [('screen-locked', N), ('reveal-click', N)], N), 'reveal-pending')
check('domain state regression 1: rendered', solve('revealed', [('screen-locked', N, {})], N, {}, 'rendered'), {'phase': 'redacting', 'value': None})
check('domain state regression 2: rendered', solve('reveal-pending', [('confirmation-accepted', N, {})], N, {'locked': True, 'rendered': None}, 'rendered'), {'phase': 'redacted', 'value': None})
check('domain state regression 3: approved', solve('reveal-pending', [('confirmation-accepted', N, {'revision': 0})], N, {'rendered': None}, 'approved'), {'phase': 'redacted', 'value': 0})
check('domain state regression 4: rendered', solve('reveal-pending', [('confirmation-accepted', N, {'revision': 1})], N, {'rendered': None}, 'rendered'), {'phase': 'revealed', 'value': 'message'})
check('domain state regression 5: rendered', solve('revealed', [('sensitive-update', N, {'text': 'new secret'})], N, {}, 'rendered'), {'phase': 'redacting-update', 'value': None})
check('domain state regression 6: rendered', solve('updated-reveal-pending', [('confirmation-accepted', N, {'revision': 2})], N, {'revision': 2, 'secret': 'new', 'rendered': None}, 'rendered'), {'phase': 'revealed-updated', 'value': 'new'})
check('domain state regression 7: rendered', solve('revealed', [('sensitive-update', N, {'text': 'replacement'}), ('redaction-applied', N, {}), ('reveal-click', N, {}), ('confirmation-accepted', N, {'revision': 2})], N, {}, 'rendered'), {'phase': 'revealed-updated', 'value': 'replacement'})
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)

prompt:
The confirmation-accepted event leaves a notification in redacted instead of revealed.

Sensitive notification preview redaction is a bounded visual-notification workflow with mutable policy state {'secret': 'message', 'rendered': 'message', 'revision': 1, 'approved': 0, 'locked': False}. Its default transition relation is {('revealed', 'screen-locked'): 'redacting', ('redacting', 'redaction-applied'): 'redacted', ('redacted', 'reveal-click'): 'reveal-pending', ('reveal-pending', 'confirmation-accepted'): 'revealed', ('reveal-pending', 'confirmation-denied'): 'redacted', ('revealed', 'sensitive-update'): 'redacting-update', ('redacting-update', 'redaction-applied'): 'redacted-updated', ('redacted-updated', 'reveal-click'): 'updated-reveal-pending', ('updated-reveal-pending', 'confirmation-accepted'): 'revealed-updated', ('reveal-pending', 'screen-locked'): 'redacted'}; domain inputs can suppress or redirect transitions and update policy fields, as specified in solve. Different-generation events are inert. Batches apply in order. Optional observe returns the selected policy field alongside the phase.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(initial, events, generation, payload=None, observe=None):
    table = {('revealed', 'screen-locked'): 'redacting', ('redacting', 'redaction-applied'): 'redacted', ('redacted', 'reveal-click'): 'reveal-pending', ('reveal-pending', 'confirmation-accepted'): 'revealed', ('reveal-pending', 'confirmation-denied'): 'revealed', ('revealed', 'sensitive-update'): 'redacting-update', ('redacting-update', 'redaction-applied'): 'redacted-updated', ('redacted-updated', 'reveal-click'): 'updated-reveal-pending', ('updated-reveal-pending', 'confirmation-accepted'): 'revealed-updated', ('reveal-pending', 'screen-locked'): 'redacted'}
    data = json.loads(json.dumps({'secret': 'message', 'rendered': 'message', 'revision': 1, 'approved': 0, 'locked': False})) if payload is None else {**json.loads(json.dumps({'secret': 'message', 'rendered': 'message', 'revision': 1, 'approved': 0, 'locked': False})), **json.loads(json.dumps(payload))}
    state = initial
    for delivery in events:
        event, event_generation = delivery[:2]
        arg = delivery[2] if len(delivery) > 2 else {}
        if event_generation == generation:
            previous = state
            if event == 'screen-locked': data['locked'] = True
            if event == 'sensitive-update':
                data['revision'] += 1
                data['secret'] = arg.get('text','updated')
            if event == 'confirmation-accepted':
                if data['locked'] or arg.get('revision',data['revision']) != data['revision']: event = 'confirmation-denied'
                else: data['approved'] = data['revision']
            state = table.get((state, event), state)
            if state in ('redacted','redacted-updated','redacting','redacting-update','hidden'): data['rendered'] = None
            if state in ('revealed','revealed-updated'): data['rendered'] = data['secret']
    return {'phase': state, 'value': data[observe]} if observe else state
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('revealed / screen-locked', solve('revealed', [('screen-locked', N)], N), 'redacting')
check('redacting / redaction-applied', solve('redacting', [('redaction-applied', N)], N), 'redacted')
check('redacted / reveal-click', solve('redacted', [('reveal-click', N)], N), 'reveal-pending')
check('reveal-pending / confirmation-accepted', solve('reveal-pending', [('confirmation-accepted', N)], N), 'revealed')
check('reveal-pending / confirmation-denied', solve('reveal-pending', [('confirmation-denied', N)], N), 'redacted')
check('revealed / sensitive-update', solve('revealed', [('sensitive-update', N)], N), 'redacting-update')
check('redacting-update / redaction-applied', solve('redacting-update', [('redaction-applied', N)], N), 'redacted-updated')
check('redacted-updated / reveal-click', solve('redacted-updated', [('reveal-click', N)], N), 'updated-reveal-pending')
check('updated-reveal-pending / confirmation-accepted', solve('updated-reveal-pending', [('confirmation-accepted', N)], N), 'revealed-updated')
check('reveal-pending / screen-locked', solve('reveal-pending', [('screen-locked', N)], N), 'redacted')
check('older notification incarnation', solve('revealed', [('screen-locked', N - 1)], N), 'revealed')
check('future notification incarnation', solve('revealed', [('screen-locked', N + 1)], N), 'revealed')
check('unknown event is inert', solve('revealed', [('unknown-event', N)], N), 'revealed')
check('empty delivery batch', solve('revealed', [], N), 'revealed')
check('N stale deliveries before current delivery', solve('revealed', [('screen-locked', N - 1)] * N + [('screen-locked', N)], N), 'redacting')
check('trace screen-locked then redaction-applied', solve('revealed', [('screen-locked', N), ('redaction-applied', N)], N), 'redacted')
check('trace redaction-applied then reveal-click', solve('redacting', [('redaction-applied', N), ('reveal-click', N)], N), 'reveal-pending')
check('trace reveal-click then confirmation-accepted', solve('redacted', [('reveal-click', N), ('confirmation-accepted', N)], N), 'revealed')
check('trace reveal-click then confirmation-denied', solve('redacted', [('reveal-click', N), ('confirmation-denied', N)], N), 'redacted')
check('trace reveal-click then screen-locked', solve('redacted', [('reveal-click', N), ('screen-locked', N)], N), 'redacted')
check('trace confirmation-accepted then screen-locked', solve('reveal-pending', [('confirmation-accepted', N), ('screen-locked', N)], N), 'redacting')
check('trace confirmation-accepted then sensitive-update', solve('reveal-pending', [('confirmation-accepted', N), ('sensitive-update', N)], N), 'redacting-update')
check('trace confirmation-denied then reveal-click', solve('reveal-pending', [('confirmation-denied', N), ('reveal-click', N)], N), 'reveal-pending')
check('trace sensitive-update then redaction-applied', solve('revealed', [('sensitive-update', N), ('redaction-applied', N)], N), 'redacted-updated')
check('trace redaction-applied then reveal-click', solve('redacting-update', [('redaction-applied', N), ('reveal-click', N)], N), 'updated-reveal-pending')
check('trace reveal-click then confirmation-accepted', solve('redacted-updated', [('reveal-click', N), ('confirmation-accepted', N)], N), 'revealed-updated')
check('trace screen-locked then reveal-click', solve('reveal-pending', [('screen-locked', N), ('reveal-click', N)], N), 'reveal-pending')
check('domain state regression 1: rendered', solve('revealed', [('screen-locked', N, {})], N, {}, 'rendered'), {'phase': 'redacting', 'value': None})
check('domain state regression 2: rendered', solve('reveal-pending', [('confirmation-accepted', N, {})], N, {'locked': True, 'rendered': None}, 'rendered'), {'phase': 'redacted', 'value': None})
check('domain state regression 3: approved', solve('reveal-pending', [('confirmation-accepted', N, {'revision': 0})], N, {'rendered': None}, 'approved'), {'phase': 'redacted', 'value': 0})
check('domain state regression 4: rendered', solve('reveal-pending', [('confirmation-accepted', N, {'revision': 1})], N, {'rendered': None}, 'rendered'), {'phase': 'revealed', 'value': 'message'})
check('domain state regression 5: rendered', solve('revealed', [('sensitive-update', N, {'text': 'new secret'})], N, {}, 'rendered'), {'phase': 'redacting-update', 'value': None})
check('domain state regression 6: rendered', solve('updated-reveal-pending', [('confirmation-accepted', N, {'revision': 2})], N, {'revision': 2, 'secret': 'new', 'rendered': None}, 'rendered'), {'phase': 'revealed-updated', 'value': 'new'})
check('domain state regression 7: rendered', solve('revealed', [('sensitive-update', N, {'text': 'replacement'}), ('redaction-applied', N, {}), ('reveal-click', N, {}), ('confirmation-accepted', N, {'revision': 2})], N, {}, 'rendered'), {'phase': 'revealed-updated', 'value': 'replacement'})
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(initial, events, generation, payload=None, observe=None):
    table = {('revealed', 'screen-locked'): 'redacting', ('redacting', 'redaction-applied'): 'redacted', ('redacted', 'reveal-click'): 'reveal-pending', ('reveal-pending', 'confirmation-accepted'): 'revealed', ('reveal-pending', 'confirmation-denied'): 'redacting', ('revealed', 'sensitive-update'): 'redacting-update', ('redacting-update', 'redaction-applied'): 'redacted-updated', ('redacted-updated', 'reveal-click'): 'updated-reveal-pending', ('updated-reveal-pending', 'confirmation-accepted'): 'revealed-updated', ('reveal-pending', 'screen-locked'): 'redacted'}
    data = json.loads(json.dumps({'secret': 'message', 'rendered': 'message', 'revision': 1, 'approved': 0, 'locked': False})) if payload is None else {**json.loads(json.dumps({'secret': 'message', 'rendered': 'message', 'revision': 1, 'approved': 0, 'locked': False})), **json.loads(json.dumps(payload))}
    state = initial
    for delivery in events:
        event, event_generation = delivery[:2]
        arg = delivery[2] if len(delivery) > 2 else {}
        if event_generation == generation:
            previous = state
            if event == 'screen-locked': data['locked'] = True
            if event == 'sensitive-update':
                data['revision'] += 1
                data['secret'] = arg.get('text','updated')
            if event == 'confirmation-accepted':
                if data['locked'] or arg.get('revision',data['revision']) != data['revision']: event = 'confirmation-denied'
                else: data['approved'] = data['revision']
            state = table.get((state, event), state)
            if state in ('redacted','redacted-updated','redacting','redacting-update','hidden'): data['rendered'] = None
            if state in ('revealed','revealed-updated'): data['rendered'] = data['secret']
    return {'phase': state, 'value': data[observe]} if observe else state
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('revealed / screen-locked', solve('revealed', [('screen-locked', N)], N), 'redacting')
check('redacting / redaction-applied', solve('redacting', [('redaction-applied', N)], N), 'redacted')
check('redacted / reveal-click', solve('redacted', [('reveal-click', N)], N), 'reveal-pending')
check('reveal-pending / confirmation-accepted', solve('reveal-pending', [('confirmation-accepted', N)], N), 'revealed')
check('reveal-pending / confirmation-denied', solve('reveal-pending', [('confirmation-denied', N)], N), 'redacted')
check('revealed / sensitive-update', solve('revealed', [('sensitive-update', N)], N), 'redacting-update')
check('redacting-update / redaction-applied', solve('redacting-update', [('redaction-applied', N)], N), 'redacted-updated')
check('redacted-updated / reveal-click', solve('redacted-updated', [('reveal-click', N)], N), 'updated-reveal-pending')
check('updated-reveal-pending / confirmation-accepted', solve('updated-reveal-pending', [('confirmation-accepted', N)], N), 'revealed-updated')
check('reveal-pending / screen-locked', solve('reveal-pending', [('screen-locked', N)], N), 'redacted')
check('older notification incarnation', solve('revealed', [('screen-locked', N - 1)], N), 'revealed')
check('future notification incarnation', solve('revealed', [('screen-locked', N + 1)], N), 'revealed')
check('unknown event is inert', solve('revealed', [('unknown-event', N)], N), 'revealed')
check('empty delivery batch', solve('revealed', [], N), 'revealed')
check('N stale deliveries before current delivery', solve('revealed', [('screen-locked', N - 1)] * N + [('screen-locked', N)], N), 'redacting')
check('trace screen-locked then redaction-applied', solve('revealed', [('screen-locked', N), ('redaction-applied', N)], N), 'redacted')
check('trace redaction-applied then reveal-click', solve('redacting', [('redaction-applied', N), ('reveal-click', N)], N), 'reveal-pending')
check('trace reveal-click then confirmation-accepted', solve('redacted', [('reveal-click', N), ('confirmation-accepted', N)], N), 'revealed')
check('trace reveal-click then confirmation-denied', solve('redacted', [('reveal-click', N), ('confirmation-denied', N)], N), 'redacted')
check('trace reveal-click then screen-locked', solve('redacted', [('reveal-click', N), ('screen-locked', N)], N), 'redacted')
check('trace confirmation-accepted then screen-locked', solve('reveal-pending', [('confirmation-accepted', N), ('screen-locked', N)], N), 'redacting')
check('trace confirmation-accepted then sensitive-update', solve('reveal-pending', [('confirmation-accepted', N), ('sensitive-update', N)], N), 'redacting-update')
check('trace confirmation-denied then reveal-click', solve('reveal-pending', [('confirmation-denied', N), ('reveal-click', N)], N), 'reveal-pending')
check('trace sensitive-update then redaction-applied', solve('revealed', [('sensitive-update', N), ('redaction-applied', N)], N), 'redacted-updated')
check('trace redaction-applied then reveal-click', solve('redacting-update', [('redaction-applied', N), ('reveal-click', N)], N), 'updated-reveal-pending')
check('trace reveal-click then confirmation-accepted', solve('redacted-updated', [('reveal-click', N), ('confirmation-accepted', N)], N), 'revealed-updated')
check('trace screen-locked then reveal-click', solve('reveal-pending', [('screen-locked', N), ('reveal-click', N)], N), 'reveal-pending')
check('domain state regression 1: rendered', solve('revealed', [('screen-locked', N, {})], N, {}, 'rendered'), {'phase': 'redacting', 'value': None})
check('domain state regression 2: rendered', solve('reveal-pending', [('confirmation-accepted', N, {})], N, {'locked': True, 'rendered': None}, 'rendered'), {'phase': 'redacted', 'value': None})
check('domain state regression 3: approved', solve('reveal-pending', [('confirmation-accepted', N, {'revision': 0})], N, {'rendered': None}, 'approved'), {'phase': 'redacted', 'value': 0})
check('domain state regression 4: rendered', solve('reveal-pending', [('confirmation-accepted', N, {'revision': 1})], N, {'rendered': None}, 'rendered'), {'phase': 'revealed', 'value': 'message'})
check('domain state regression 5: rendered', solve('revealed', [('sensitive-update', N, {'text': 'new secret'})], N, {}, 'rendered'), {'phase': 'redacting-update', 'value': None})
check('domain state regression 6: rendered', solve('updated-reveal-pending', [('confirmation-accepted', N, {'revision': 2})], N, {'revision': 2, 'secret': 'new', 'rendered': None}, 'rendered'), {'phase': 'revealed-updated', 'value': 'new'})
check('domain state regression 7: rendered', solve('revealed', [('sensitive-update', N, {'text': 'replacement'}), ('redaction-applied', N, {}), ('reveal-click', N, {}), ('confirmation-accepted', N, {'revision': 2})], N, {}, 'rendered'), {'phase': 'revealed-updated', 'value': 'replacement'})
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)

prompt:
The confirmation-denied event leaves a notification in revealed instead of redacted.

Sensitive notification preview redaction is a bounded visual-notification workflow with mutable policy state {'secret': 'message', 'rendered': 'message', 'revision': 1, 'approved': 0, 'locked': False}. Its default transition relation is {('revealed', 'screen-locked'): 'redacting', ('redacting', 'redaction-applied'): 'redacted', ('redacted', 'reveal-click'): 'reveal-pending', ('reveal-pending', 'confirmation-accepted'): 'revealed', ('reveal-pending', 'confirmation-denied'): 'redacted', ('revealed', 'sensitive-update'): 'redacting-update', ('redacting-update', 'redaction-applied'): 'redacted-updated', ('redacted-updated', 'reveal-click'): 'updated-reveal-pending', ('updated-reveal-pending', 'confirmation-accepted'): 'revealed-updated', ('reveal-pending', 'screen-locked'): 'redacted'}; domain inputs can suppress or redirect transitions and update policy fields, as specified in solve. Different-generation events are inert. Batches apply in order. Optional observe returns the selected policy field alongside the phase.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(initial, events, generation, payload=None, observe=None):
    table = {('revealed', 'screen-locked'): 'redacting', ('redacting', 'redaction-applied'): 'redacted', ('redacted', 'reveal-click'): 'reveal-pending', ('reveal-pending', 'confirmation-accepted'): 'revealed', ('reveal-pending', 'confirmation-denied'): 'redacted', ('revealed', 'sensitive-update'): 'revealed', ('redacting-update', 'redaction-applied'): 'redacted-updated', ('redacted-updated', 'reveal-click'): 'updated-reveal-pending', ('updated-reveal-pending', 'confirmation-accepted'): 'revealed-updated', ('reveal-pending', 'screen-locked'): 'redacted'}
    data = json.loads(json.dumps({'secret': 'message', 'rendered': 'message', 'revision': 1, 'approved': 0, 'locked': False})) if payload is None else {**json.loads(json.dumps({'secret': 'message', 'rendered': 'message', 'revision': 1, 'approved': 0, 'locked': False})), **json.loads(json.dumps(payload))}
    state = initial
    for delivery in events:
        event, event_generation = delivery[:2]
        arg = delivery[2] if len(delivery) > 2 else {}
        if event_generation == generation:
            previous = state
            if event == 'screen-locked': data['locked'] = True
            if event == 'sensitive-update':
                data['revision'] += 1
                data['secret'] = arg.get('text','updated')
            if event == 'confirmation-accepted':
                if data['locked'] or arg.get('revision',data['revision']) != data['revision']: event = 'confirmation-denied'
                else: data['approved'] = data['revision']
            state = table.get((state, event), state)
            if state in ('redacted','redacted-updated','redacting','redacting-update','hidden'): data['rendered'] = None
            if state in ('revealed','revealed-updated'): data['rendered'] = data['secret']
    return {'phase': state, 'value': data[observe]} if observe else state
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('revealed / screen-locked', solve('revealed', [('screen-locked', N)], N), 'redacting')
check('redacting / redaction-applied', solve('redacting', [('redaction-applied', N)], N), 'redacted')
check('redacted / reveal-click', solve('redacted', [('reveal-click', N)], N), 'reveal-pending')
check('reveal-pending / confirmation-accepted', solve('reveal-pending', [('confirmation-accepted', N)], N), 'revealed')
check('reveal-pending / confirmation-denied', solve('reveal-pending', [('confirmation-denied', N)], N), 'redacted')
check('revealed / sensitive-update', solve('revealed', [('sensitive-update', N)], N), 'redacting-update')
check('redacting-update / redaction-applied', solve('redacting-update', [('redaction-applied', N)], N), 'redacted-updated')
check('redacted-updated / reveal-click', solve('redacted-updated', [('reveal-click', N)], N), 'updated-reveal-pending')
check('updated-reveal-pending / confirmation-accepted', solve('updated-reveal-pending', [('confirmation-accepted', N)], N), 'revealed-updated')
check('reveal-pending / screen-locked', solve('reveal-pending', [('screen-locked', N)], N), 'redacted')
check('older notification incarnation', solve('revealed', [('screen-locked', N - 1)], N), 'revealed')
check('future notification incarnation', solve('revealed', [('screen-locked', N + 1)], N), 'revealed')
check('unknown event is inert', solve('revealed', [('unknown-event', N)], N), 'revealed')
check('empty delivery batch', solve('revealed', [], N), 'revealed')
check('N stale deliveries before current delivery', solve('revealed', [('screen-locked', N - 1)] * N + [('screen-locked', N)], N), 'redacting')
check('trace screen-locked then redaction-applied', solve('revealed', [('screen-locked', N), ('redaction-applied', N)], N), 'redacted')
check('trace redaction-applied then reveal-click', solve('redacting', [('redaction-applied', N), ('reveal-click', N)], N), 'reveal-pending')
check('trace reveal-click then confirmation-accepted', solve('redacted', [('reveal-click', N), ('confirmation-accepted', N)], N), 'revealed')
check('trace reveal-click then confirmation-denied', solve('redacted', [('reveal-click', N), ('confirmation-denied', N)], N), 'redacted')
check('trace reveal-click then screen-locked', solve('redacted', [('reveal-click', N), ('screen-locked', N)], N), 'redacted')
check('trace confirmation-accepted then screen-locked', solve('reveal-pending', [('confirmation-accepted', N), ('screen-locked', N)], N), 'redacting')
check('trace confirmation-accepted then sensitive-update', solve('reveal-pending', [('confirmation-accepted', N), ('sensitive-update', N)], N), 'redacting-update')
check('trace confirmation-denied then reveal-click', solve('reveal-pending', [('confirmation-denied', N), ('reveal-click', N)], N), 'reveal-pending')
check('trace sensitive-update then redaction-applied', solve('revealed', [('sensitive-update', N), ('redaction-applied', N)], N), 'redacted-updated')
check('trace redaction-applied then reveal-click', solve('redacting-update', [('redaction-applied', N), ('reveal-click', N)], N), 'updated-reveal-pending')
check('trace reveal-click then confirmation-accepted', solve('redacted-updated', [('reveal-click', N), ('confirmation-accepted', N)], N), 'revealed-updated')
check('trace screen-locked then reveal-click', solve('reveal-pending', [('screen-locked', N), ('reveal-click', N)], N), 'reveal-pending')
check('domain state regression 1: rendered', solve('revealed', [('screen-locked', N, {})], N, {}, 'rendered'), {'phase': 'redacting', 'value': None})
check('domain state regression 2: rendered', solve('reveal-pending', [('confirmation-accepted', N, {})], N, {'locked': True, 'rendered': None}, 'rendered'), {'phase': 'redacted', 'value': None})
check('domain state regression 3: approved', solve('reveal-pending', [('confirmation-accepted', N, {'revision': 0})], N, {'rendered': None}, 'approved'), {'phase': 'redacted', 'value': 0})
check('domain state regression 4: rendered', solve('reveal-pending', [('confirmation-accepted', N, {'revision': 1})], N, {'rendered': None}, 'rendered'), {'phase': 'revealed', 'value': 'message'})
check('domain state regression 5: rendered', solve('revealed', [('sensitive-update', N, {'text': 'new secret'})], N, {}, 'rendered'), {'phase': 'redacting-update', 'value': None})
check('domain state regression 6: rendered', solve('updated-reveal-pending', [('confirmation-accepted', N, {'revision': 2})], N, {'revision': 2, 'secret': 'new', 'rendered': None}, 'rendered'), {'phase': 'revealed-updated', 'value': 'new'})
check('domain state regression 7: rendered', solve('revealed', [('sensitive-update', N, {'text': 'replacement'}), ('redaction-applied', N, {}), ('reveal-click', N, {}), ('confirmation-accepted', N, {'revision': 2})], N, {}, 'rendered'), {'phase': 'revealed-updated', 'value': 'replacement'})
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(initial, events, generation, payload=None, observe=None):
    table = {('revealed', 'screen-locked'): 'redacting', ('redacting', 'redaction-applied'): 'redacted', ('redacted', 'reveal-click'): 'reveal-pending', ('reveal-pending', 'confirmation-accepted'): 'revealed', ('reveal-pending', 'confirmation-denied'): 'redacted', ('revealed', 'sensitive-update'): 'hidden', ('redacting-update', 'redaction-applied'): 'redacted-updated', ('redacted-updated', 'reveal-click'): 'updated-reveal-pending', ('updated-reveal-pending', 'confirmation-accepted'): 'revealed-updated', ('reveal-pending', 'screen-locked'): 'redacted'}
    data = json.loads(json.dumps({'secret': 'message', 'rendered': 'message', 'revision': 1, 'approved': 0, 'locked': False})) if payload is None else {**json.loads(json.dumps({'secret': 'message', 'rendered': 'message', 'revision': 1, 'approved': 0, 'locked': False})), **json.loads(json.dumps(payload))}
    state = initial
    for delivery in events:
        event, event_generation = delivery[:2]
        arg = delivery[2] if len(delivery) > 2 else {}
        if event_generation == generation:
            previous = state
            if event == 'screen-locked': data['locked'] = True
            if event == 'sensitive-update':
                data['revision'] += 1
                data['secret'] = arg.get('text','updated')
            if event == 'confirmation-accepted':
                if data['locked'] or arg.get('revision',data['revision']) != data['revision']: event = 'confirmation-denied'
                else: data['approved'] = data['revision']
            state = table.get((state, event), state)
            if state in ('redacted','redacted-updated','redacting','redacting-update','hidden'): data['rendered'] = None
            if state in ('revealed','revealed-updated'): data['rendered'] = data['secret']
    return {'phase': state, 'value': data[observe]} if observe else state
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('revealed / screen-locked', solve('revealed', [('screen-locked', N)], N), 'redacting')
check('redacting / redaction-applied', solve('redacting', [('redaction-applied', N)], N), 'redacted')
check('redacted / reveal-click', solve('redacted', [('reveal-click', N)], N), 'reveal-pending')
check('reveal-pending / confirmation-accepted', solve('reveal-pending', [('confirmation-accepted', N)], N), 'revealed')
check('reveal-pending / confirmation-denied', solve('reveal-pending', [('confirmation-denied', N)], N), 'redacted')
check('revealed / sensitive-update', solve('revealed', [('sensitive-update', N)], N), 'redacting-update')
check('redacting-update / redaction-applied', solve('redacting-update', [('redaction-applied', N)], N), 'redacted-updated')
check('redacted-updated / reveal-click', solve('redacted-updated', [('reveal-click', N)], N), 'updated-reveal-pending')
check('updated-reveal-pending / confirmation-accepted', solve('updated-reveal-pending', [('confirmation-accepted', N)], N), 'revealed-updated')
check('reveal-pending / screen-locked', solve('reveal-pending', [('screen-locked', N)], N), 'redacted')
check('older notification incarnation', solve('revealed', [('screen-locked', N - 1)], N), 'revealed')
check('future notification incarnation', solve('revealed', [('screen-locked', N + 1)], N), 'revealed')
check('unknown event is inert', solve('revealed', [('unknown-event', N)], N), 'revealed')
check('empty delivery batch', solve('revealed', [], N), 'revealed')
check('N stale deliveries before current delivery', solve('revealed', [('screen-locked', N - 1)] * N + [('screen-locked', N)], N), 'redacting')
check('trace screen-locked then redaction-applied', solve('revealed', [('screen-locked', N), ('redaction-applied', N)], N), 'redacted')
check('trace redaction-applied then reveal-click', solve('redacting', [('redaction-applied', N), ('reveal-click', N)], N), 'reveal-pending')
check('trace reveal-click then confirmation-accepted', solve('redacted', [('reveal-click', N), ('confirmation-accepted', N)], N), 'revealed')
check('trace reveal-click then confirmation-denied', solve('redacted', [('reveal-click', N), ('confirmation-denied', N)], N), 'redacted')
check('trace reveal-click then screen-locked', solve('redacted', [('reveal-click', N), ('screen-locked', N)], N), 'redacted')
check('trace confirmation-accepted then screen-locked', solve('reveal-pending', [('confirmation-accepted', N), ('screen-locked', N)], N), 'redacting')
check('trace confirmation-accepted then sensitive-update', solve('reveal-pending', [('confirmation-accepted', N), ('sensitive-update', N)], N), 'redacting-update')
check('trace confirmation-denied then reveal-click', solve('reveal-pending', [('confirmation-denied', N), ('reveal-click', N)], N), 'reveal-pending')
check('trace sensitive-update then redaction-applied', solve('revealed', [('sensitive-update', N), ('redaction-applied', N)], N), 'redacted-updated')
check('trace redaction-applied then reveal-click', solve('redacting-update', [('redaction-applied', N), ('reveal-click', N)], N), 'updated-reveal-pending')
check('trace reveal-click then confirmation-accepted', solve('redacted-updated', [('reveal-click', N), ('confirmation-accepted', N)], N), 'revealed-updated')
check('trace screen-locked then reveal-click', solve('reveal-pending', [('screen-locked', N), ('reveal-click', N)], N), 'reveal-pending')
check('domain state regression 1: rendered', solve('revealed', [('screen-locked', N, {})], N, {}, 'rendered'), {'phase': 'redacting', 'value': None})
check('domain state regression 2: rendered', solve('reveal-pending', [('confirmation-accepted', N, {})], N, {'locked': True, 'rendered': None}, 'rendered'), {'phase': 'redacted', 'value': None})
check('domain state regression 3: approved', solve('reveal-pending', [('confirmation-accepted', N, {'revision': 0})], N, {'rendered': None}, 'approved'), {'phase': 'redacted', 'value': 0})
check('domain state regression 4: rendered', solve('reveal-pending', [('confirmation-accepted', N, {'revision': 1})], N, {'rendered': None}, 'rendered'), {'phase': 'revealed', 'value': 'message'})
check('domain state regression 5: rendered', solve('revealed', [('sensitive-update', N, {'text': 'new secret'})], N, {}, 'rendered'), {'phase': 'redacting-update', 'value': None})
check('domain state regression 6: rendered', solve('updated-reveal-pending', [('confirmation-accepted', N, {'revision': 2})], N, {'revision': 2, 'secret': 'new', 'rendered': None}, 'rendered'), {'phase': 'revealed-updated', 'value': 'new'})
check('domain state regression 7: rendered', solve('revealed', [('sensitive-update', N, {'text': 'replacement'}), ('redaction-applied', N, {}), ('reveal-click', N, {}), ('confirmation-accepted', N, {'revision': 2})], N, {}, 'rendered'), {'phase': 'revealed-updated', 'value': 'replacement'})
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)

prompt:
The sensitive-update event leaves a notification in revealed instead of redacting-update.

Sensitive notification preview redaction is a bounded visual-notification workflow with mutable policy state {'secret': 'message', 'rendered': 'message', 'revision': 1, 'approved': 0, 'locked': False}. Its default transition relation is {('revealed', 'screen-locked'): 'redacting', ('redacting', 'redaction-applied'): 'redacted', ('redacted', 'reveal-click'): 'reveal-pending', ('reveal-pending', 'confirmation-accepted'): 'revealed', ('reveal-pending', 'confirmation-denied'): 'redacted', ('revealed', 'sensitive-update'): 'redacting-update', ('redacting-update', 'redaction-applied'): 'redacted-updated', ('redacted-updated', 'reveal-click'): 'updated-reveal-pending', ('updated-reveal-pending', 'confirmation-accepted'): 'revealed-updated', ('reveal-pending', 'screen-locked'): 'redacted'}; domain inputs can suppress or redirect transitions and update policy fields, as specified in solve. Different-generation events are inert. Batches apply in order. Optional observe returns the selected policy field alongside the phase.

split: open-access