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 = {('valid', 'deadline-near'): 'expiring', ('expiring', 'deadline-reached'): 'expired', ('valid', 'open-action'): 'action-pending', ('action-pending', 'deadline-reached'): 'pending-at-expiry', ('pending-at-expiry', 'action-success'): 'expired', ('pending-at-expiry', 'action-failure'): 'expired-action-error', ('expired', 'deadline-extension'): 'revalidation-pending', ('revalidation-pending', 'extension-validated'): 'valid', ('revalidation-pending', 'extension-rejected'): 'expired', ('completed', 'late-expiry'): 'completed'}
    data = json.loads(json.dumps({'deadline': 20, 'now': 5, 'started': None, 'completed': False})) if payload is None else {**json.loads(json.dumps({'deadline': 20, 'now': 5, 'started': None, 'completed': 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
            data['now'] = max(data['now'],arg.get('now',data['now']))
            if event == 'open-action':
                if data['now'] >= data['deadline']: event = 'unknown-event'
                else: data['started'] = data['now']
            if event == 'deadline-reached' and data['now'] < data['deadline'] and 'now' in arg: event = 'unknown-event'
            if event == 'extension-validated': data['deadline'] = max(data['deadline'],arg.get('deadline',data['deadline']+10))
            state = table.get((state, event), state)
            if state == 'completed': data['completed'] = True
    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('valid / deadline-near', solve('valid', [('deadline-near', N)], N), 'expiring')
check('expiring / deadline-reached', solve('expiring', [('deadline-reached', N)], N), 'expired')
check('valid / open-action', solve('valid', [('open-action', N)], N), 'action-pending')
check('action-pending / deadline-reached', solve('action-pending', [('deadline-reached', N)], N), 'pending-at-expiry')
check('pending-at-expiry / action-success', solve('pending-at-expiry', [('action-success', N)], N), 'completed')
check('pending-at-expiry / action-failure', solve('pending-at-expiry', [('action-failure', N)], N), 'expired-action-error')
check('expired / deadline-extension', solve('expired', [('deadline-extension', N)], N), 'revalidation-pending')
check('revalidation-pending / extension-validated', solve('revalidation-pending', [('extension-validated', N)], N), 'valid')
check('revalidation-pending / extension-rejected', solve('revalidation-pending', [('extension-rejected', N)], N), 'expired')
check('completed / late-expiry', solve('completed', [('late-expiry', N)], N), 'completed')
check('older notification incarnation', solve('valid', [('deadline-near', N - 1)], N), 'valid')
check('future notification incarnation', solve('valid', [('deadline-near', N + 1)], N), 'valid')
check('unknown event is inert', solve('valid', [('unknown-event', N)], N), 'valid')
check('empty delivery batch', solve('valid', [], N), 'valid')
check('N stale deliveries before current delivery', solve('valid', [('deadline-near', N - 1)] * N + [('deadline-near', N)], N), 'expiring')
check('trace deadline-near then deadline-reached', solve('valid', [('deadline-near', N), ('deadline-reached', N)], N), 'expired')
check('trace deadline-reached then deadline-extension', solve('expiring', [('deadline-reached', N), ('deadline-extension', N)], N), 'revalidation-pending')
check('trace open-action then deadline-reached', solve('valid', [('open-action', N), ('deadline-reached', N)], N), 'pending-at-expiry')
check('trace deadline-reached then action-success', solve('action-pending', [('deadline-reached', N), ('action-success', N)], N), 'completed')
check('trace deadline-reached then action-failure', solve('action-pending', [('deadline-reached', N), ('action-failure', N)], N), 'expired-action-error')
check('trace action-success then late-expiry', solve('pending-at-expiry', [('action-success', N), ('late-expiry', N)], N), 'completed')
check('trace deadline-extension then extension-validated', solve('expired', [('deadline-extension', N), ('extension-validated', N)], N), 'valid')
check('trace deadline-extension then extension-rejected', solve('expired', [('deadline-extension', N), ('extension-rejected', N)], N), 'expired')
check('trace extension-validated then deadline-near', solve('revalidation-pending', [('extension-validated', N), ('deadline-near', N)], N), 'expiring')
check('trace extension-validated then open-action', solve('revalidation-pending', [('extension-validated', N), ('open-action', N)], N), 'action-pending')
check('trace extension-rejected then deadline-extension', solve('revalidation-pending', [('extension-rejected', N), ('deadline-extension', N)], N), 'revalidation-pending')
check('trace late-expiry then late-expiry', solve('completed', [('late-expiry', N), ('late-expiry', N)], N), 'completed')
check('domain state regression 1: started', solve('valid', [('open-action', N, {'now': 19})], N, {}, 'started'), {'phase': 'action-pending', 'value': 19})
check('domain state regression 2: started', solve('valid', [('open-action', N, {'now': 20})], N, {}, 'started'), {'phase': 'valid', 'value': None})
check('domain state regression 3: now', solve('expiring', [('deadline-reached', N, {'now': 19})], N, {}, 'now'), {'phase': 'expiring', 'value': 19})
check('domain state regression 4: completed', solve('pending-at-expiry', [('action-success', N, {})], N, {'started': 19, 'now': 21}, 'completed'), {'phase': 'completed', 'value': True})
check('domain state regression 5: deadline', solve('revalidation-pending', [('extension-validated', N, {'deadline': 15})], N, {}, 'deadline'), {'phase': 'valid', 'value': 20})
check('domain state regression 6: completed', solve('completed', [('late-expiry', N, {})], N, {'completed': True}, 'completed'), {'phase': 'completed', 'value': True})
check('domain state regression 7: started', solve('valid', [('open-action', N, {'now': 19}), ('deadline-reached', N, {'now': 20}), ('action-success', N, {})], N, {}, 'started'), {'phase': 'completed', 'value': 19})
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 = {('valid', 'deadline-near'): 'expiring', ('expiring', 'deadline-reached'): 'expired', ('valid', 'open-action'): 'action-pending', ('action-pending', 'deadline-reached'): 'pending-at-expiry', ('pending-at-expiry', 'action-success'): 'valid', ('pending-at-expiry', 'action-failure'): 'expired-action-error', ('expired', 'deadline-extension'): 'revalidation-pending', ('revalidation-pending', 'extension-validated'): 'valid', ('revalidation-pending', 'extension-rejected'): 'expired', ('completed', 'late-expiry'): 'completed'}
    data = json.loads(json.dumps({'deadline': 20, 'now': 5, 'started': None, 'completed': False})) if payload is None else {**json.loads(json.dumps({'deadline': 20, 'now': 5, 'started': None, 'completed': 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
            data['now'] = max(data['now'],arg.get('now',data['now']))
            if event == 'open-action':
                if data['now'] >= data['deadline']: event = 'unknown-event'
                else: data['started'] = data['now']
            if event == 'deadline-reached' and data['now'] < data['deadline'] and 'now' in arg: event = 'unknown-event'
            if event == 'extension-validated': data['deadline'] = max(data['deadline'],arg.get('deadline',data['deadline']+10))
            state = table.get((state, event), state)
            if state == 'completed': data['completed'] = True
    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('valid / deadline-near', solve('valid', [('deadline-near', N)], N), 'expiring')
check('expiring / deadline-reached', solve('expiring', [('deadline-reached', N)], N), 'expired')
check('valid / open-action', solve('valid', [('open-action', N)], N), 'action-pending')
check('action-pending / deadline-reached', solve('action-pending', [('deadline-reached', N)], N), 'pending-at-expiry')
check('pending-at-expiry / action-success', solve('pending-at-expiry', [('action-success', N)], N), 'completed')
check('pending-at-expiry / action-failure', solve('pending-at-expiry', [('action-failure', N)], N), 'expired-action-error')
check('expired / deadline-extension', solve('expired', [('deadline-extension', N)], N), 'revalidation-pending')
check('revalidation-pending / extension-validated', solve('revalidation-pending', [('extension-validated', N)], N), 'valid')
check('revalidation-pending / extension-rejected', solve('revalidation-pending', [('extension-rejected', N)], N), 'expired')
check('completed / late-expiry', solve('completed', [('late-expiry', N)], N), 'completed')
check('older notification incarnation', solve('valid', [('deadline-near', N - 1)], N), 'valid')
check('future notification incarnation', solve('valid', [('deadline-near', N + 1)], N), 'valid')
check('unknown event is inert', solve('valid', [('unknown-event', N)], N), 'valid')
check('empty delivery batch', solve('valid', [], N), 'valid')
check('N stale deliveries before current delivery', solve('valid', [('deadline-near', N - 1)] * N + [('deadline-near', N)], N), 'expiring')
check('trace deadline-near then deadline-reached', solve('valid', [('deadline-near', N), ('deadline-reached', N)], N), 'expired')
check('trace deadline-reached then deadline-extension', solve('expiring', [('deadline-reached', N), ('deadline-extension', N)], N), 'revalidation-pending')
check('trace open-action then deadline-reached', solve('valid', [('open-action', N), ('deadline-reached', N)], N), 'pending-at-expiry')
check('trace deadline-reached then action-success', solve('action-pending', [('deadline-reached', N), ('action-success', N)], N), 'completed')
check('trace deadline-reached then action-failure', solve('action-pending', [('deadline-reached', N), ('action-failure', N)], N), 'expired-action-error')
check('trace action-success then late-expiry', solve('pending-at-expiry', [('action-success', N), ('late-expiry', N)], N), 'completed')
check('trace deadline-extension then extension-validated', solve('expired', [('deadline-extension', N), ('extension-validated', N)], N), 'valid')
check('trace deadline-extension then extension-rejected', solve('expired', [('deadline-extension', N), ('extension-rejected', N)], N), 'expired')
check('trace extension-validated then deadline-near', solve('revalidation-pending', [('extension-validated', N), ('deadline-near', N)], N), 'expiring')
check('trace extension-validated then open-action', solve('revalidation-pending', [('extension-validated', N), ('open-action', N)], N), 'action-pending')
check('trace extension-rejected then deadline-extension', solve('revalidation-pending', [('extension-rejected', N), ('deadline-extension', N)], N), 'revalidation-pending')
check('trace late-expiry then late-expiry', solve('completed', [('late-expiry', N), ('late-expiry', N)], N), 'completed')
check('domain state regression 1: started', solve('valid', [('open-action', N, {'now': 19})], N, {}, 'started'), {'phase': 'action-pending', 'value': 19})
check('domain state regression 2: started', solve('valid', [('open-action', N, {'now': 20})], N, {}, 'started'), {'phase': 'valid', 'value': None})
check('domain state regression 3: now', solve('expiring', [('deadline-reached', N, {'now': 19})], N, {}, 'now'), {'phase': 'expiring', 'value': 19})
check('domain state regression 4: completed', solve('pending-at-expiry', [('action-success', N, {})], N, {'started': 19, 'now': 21}, 'completed'), {'phase': 'completed', 'value': True})
check('domain state regression 5: deadline', solve('revalidation-pending', [('extension-validated', N, {'deadline': 15})], N, {}, 'deadline'), {'phase': 'valid', 'value': 20})
check('domain state regression 6: completed', solve('completed', [('late-expiry', N, {})], N, {'completed': True}, 'completed'), {'phase': 'completed', 'value': True})
check('domain state regression 7: started', solve('valid', [('open-action', N, {'now': 19}), ('deadline-reached', N, {'now': 20}), ('action-success', N, {})], N, {}, 'started'), {'phase': 'completed', 'value': 19})
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 action-success event leaves a notification in expired instead of completed.

Time-limited notification content expiry is a bounded visual-notification workflow with mutable policy state {'deadline': 20, 'now': 5, 'started': None, 'completed': False}. Its default transition relation is {('valid', 'deadline-near'): 'expiring', ('expiring', 'deadline-reached'): 'expired', ('valid', 'open-action'): 'action-pending', ('action-pending', 'deadline-reached'): 'pending-at-expiry', ('pending-at-expiry', 'action-success'): 'completed', ('pending-at-expiry', 'action-failure'): 'expired-action-error', ('expired', 'deadline-extension'): 'revalidation-pending', ('revalidation-pending', 'extension-validated'): 'valid', ('revalidation-pending', 'extension-rejected'): 'expired', ('completed', 'late-expiry'): 'completed'}; 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 = {('valid', 'deadline-near'): 'expiring', ('expiring', 'deadline-reached'): 'expired', ('valid', 'open-action'): 'action-pending', ('action-pending', 'deadline-reached'): 'pending-at-expiry', ('pending-at-expiry', 'action-success'): 'completed', ('pending-at-expiry', 'action-failure'): 'expired', ('expired', 'deadline-extension'): 'revalidation-pending', ('revalidation-pending', 'extension-validated'): 'valid', ('revalidation-pending', 'extension-rejected'): 'expired', ('completed', 'late-expiry'): 'completed'}
    data = json.loads(json.dumps({'deadline': 20, 'now': 5, 'started': None, 'completed': False})) if payload is None else {**json.loads(json.dumps({'deadline': 20, 'now': 5, 'started': None, 'completed': 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
            data['now'] = max(data['now'],arg.get('now',data['now']))
            if event == 'open-action':
                if data['now'] >= data['deadline']: event = 'unknown-event'
                else: data['started'] = data['now']
            if event == 'deadline-reached' and data['now'] < data['deadline'] and 'now' in arg: event = 'unknown-event'
            if event == 'extension-validated': data['deadline'] = max(data['deadline'],arg.get('deadline',data['deadline']+10))
            state = table.get((state, event), state)
            if state == 'completed': data['completed'] = True
    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('valid / deadline-near', solve('valid', [('deadline-near', N)], N), 'expiring')
check('expiring / deadline-reached', solve('expiring', [('deadline-reached', N)], N), 'expired')
check('valid / open-action', solve('valid', [('open-action', N)], N), 'action-pending')
check('action-pending / deadline-reached', solve('action-pending', [('deadline-reached', N)], N), 'pending-at-expiry')
check('pending-at-expiry / action-success', solve('pending-at-expiry', [('action-success', N)], N), 'completed')
check('pending-at-expiry / action-failure', solve('pending-at-expiry', [('action-failure', N)], N), 'expired-action-error')
check('expired / deadline-extension', solve('expired', [('deadline-extension', N)], N), 'revalidation-pending')
check('revalidation-pending / extension-validated', solve('revalidation-pending', [('extension-validated', N)], N), 'valid')
check('revalidation-pending / extension-rejected', solve('revalidation-pending', [('extension-rejected', N)], N), 'expired')
check('completed / late-expiry', solve('completed', [('late-expiry', N)], N), 'completed')
check('older notification incarnation', solve('valid', [('deadline-near', N - 1)], N), 'valid')
check('future notification incarnation', solve('valid', [('deadline-near', N + 1)], N), 'valid')
check('unknown event is inert', solve('valid', [('unknown-event', N)], N), 'valid')
check('empty delivery batch', solve('valid', [], N), 'valid')
check('N stale deliveries before current delivery', solve('valid', [('deadline-near', N - 1)] * N + [('deadline-near', N)], N), 'expiring')
check('trace deadline-near then deadline-reached', solve('valid', [('deadline-near', N), ('deadline-reached', N)], N), 'expired')
check('trace deadline-reached then deadline-extension', solve('expiring', [('deadline-reached', N), ('deadline-extension', N)], N), 'revalidation-pending')
check('trace open-action then deadline-reached', solve('valid', [('open-action', N), ('deadline-reached', N)], N), 'pending-at-expiry')
check('trace deadline-reached then action-success', solve('action-pending', [('deadline-reached', N), ('action-success', N)], N), 'completed')
check('trace deadline-reached then action-failure', solve('action-pending', [('deadline-reached', N), ('action-failure', N)], N), 'expired-action-error')
check('trace action-success then late-expiry', solve('pending-at-expiry', [('action-success', N), ('late-expiry', N)], N), 'completed')
check('trace deadline-extension then extension-validated', solve('expired', [('deadline-extension', N), ('extension-validated', N)], N), 'valid')
check('trace deadline-extension then extension-rejected', solve('expired', [('deadline-extension', N), ('extension-rejected', N)], N), 'expired')
check('trace extension-validated then deadline-near', solve('revalidation-pending', [('extension-validated', N), ('deadline-near', N)], N), 'expiring')
check('trace extension-validated then open-action', solve('revalidation-pending', [('extension-validated', N), ('open-action', N)], N), 'action-pending')
check('trace extension-rejected then deadline-extension', solve('revalidation-pending', [('extension-rejected', N), ('deadline-extension', N)], N), 'revalidation-pending')
check('trace late-expiry then late-expiry', solve('completed', [('late-expiry', N), ('late-expiry', N)], N), 'completed')
check('domain state regression 1: started', solve('valid', [('open-action', N, {'now': 19})], N, {}, 'started'), {'phase': 'action-pending', 'value': 19})
check('domain state regression 2: started', solve('valid', [('open-action', N, {'now': 20})], N, {}, 'started'), {'phase': 'valid', 'value': None})
check('domain state regression 3: now', solve('expiring', [('deadline-reached', N, {'now': 19})], N, {}, 'now'), {'phase': 'expiring', 'value': 19})
check('domain state regression 4: completed', solve('pending-at-expiry', [('action-success', N, {})], N, {'started': 19, 'now': 21}, 'completed'), {'phase': 'completed', 'value': True})
check('domain state regression 5: deadline', solve('revalidation-pending', [('extension-validated', N, {'deadline': 15})], N, {}, 'deadline'), {'phase': 'valid', 'value': 20})
check('domain state regression 6: completed', solve('completed', [('late-expiry', N, {})], N, {'completed': True}, 'completed'), {'phase': 'completed', 'value': True})
check('domain state regression 7: started', solve('valid', [('open-action', N, {'now': 19}), ('deadline-reached', N, {'now': 20}), ('action-success', N, {})], N, {}, 'started'), {'phase': 'completed', 'value': 19})
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 = {('valid', 'deadline-near'): 'expiring', ('expiring', 'deadline-reached'): 'expired', ('valid', 'open-action'): 'action-pending', ('action-pending', 'deadline-reached'): 'pending-at-expiry', ('pending-at-expiry', 'action-success'): 'completed', ('pending-at-expiry', 'action-failure'): 'valid', ('expired', 'deadline-extension'): 'revalidation-pending', ('revalidation-pending', 'extension-validated'): 'valid', ('revalidation-pending', 'extension-rejected'): 'expired', ('completed', 'late-expiry'): 'completed'}
    data = json.loads(json.dumps({'deadline': 20, 'now': 5, 'started': None, 'completed': False})) if payload is None else {**json.loads(json.dumps({'deadline': 20, 'now': 5, 'started': None, 'completed': 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
            data['now'] = max(data['now'],arg.get('now',data['now']))
            if event == 'open-action':
                if data['now'] >= data['deadline']: event = 'unknown-event'
                else: data['started'] = data['now']
            if event == 'deadline-reached' and data['now'] < data['deadline'] and 'now' in arg: event = 'unknown-event'
            if event == 'extension-validated': data['deadline'] = max(data['deadline'],arg.get('deadline',data['deadline']+10))
            state = table.get((state, event), state)
            if state == 'completed': data['completed'] = True
    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('valid / deadline-near', solve('valid', [('deadline-near', N)], N), 'expiring')
check('expiring / deadline-reached', solve('expiring', [('deadline-reached', N)], N), 'expired')
check('valid / open-action', solve('valid', [('open-action', N)], N), 'action-pending')
check('action-pending / deadline-reached', solve('action-pending', [('deadline-reached', N)], N), 'pending-at-expiry')
check('pending-at-expiry / action-success', solve('pending-at-expiry', [('action-success', N)], N), 'completed')
check('pending-at-expiry / action-failure', solve('pending-at-expiry', [('action-failure', N)], N), 'expired-action-error')
check('expired / deadline-extension', solve('expired', [('deadline-extension', N)], N), 'revalidation-pending')
check('revalidation-pending / extension-validated', solve('revalidation-pending', [('extension-validated', N)], N), 'valid')
check('revalidation-pending / extension-rejected', solve('revalidation-pending', [('extension-rejected', N)], N), 'expired')
check('completed / late-expiry', solve('completed', [('late-expiry', N)], N), 'completed')
check('older notification incarnation', solve('valid', [('deadline-near', N - 1)], N), 'valid')
check('future notification incarnation', solve('valid', [('deadline-near', N + 1)], N), 'valid')
check('unknown event is inert', solve('valid', [('unknown-event', N)], N), 'valid')
check('empty delivery batch', solve('valid', [], N), 'valid')
check('N stale deliveries before current delivery', solve('valid', [('deadline-near', N - 1)] * N + [('deadline-near', N)], N), 'expiring')
check('trace deadline-near then deadline-reached', solve('valid', [('deadline-near', N), ('deadline-reached', N)], N), 'expired')
check('trace deadline-reached then deadline-extension', solve('expiring', [('deadline-reached', N), ('deadline-extension', N)], N), 'revalidation-pending')
check('trace open-action then deadline-reached', solve('valid', [('open-action', N), ('deadline-reached', N)], N), 'pending-at-expiry')
check('trace deadline-reached then action-success', solve('action-pending', [('deadline-reached', N), ('action-success', N)], N), 'completed')
check('trace deadline-reached then action-failure', solve('action-pending', [('deadline-reached', N), ('action-failure', N)], N), 'expired-action-error')
check('trace action-success then late-expiry', solve('pending-at-expiry', [('action-success', N), ('late-expiry', N)], N), 'completed')
check('trace deadline-extension then extension-validated', solve('expired', [('deadline-extension', N), ('extension-validated', N)], N), 'valid')
check('trace deadline-extension then extension-rejected', solve('expired', [('deadline-extension', N), ('extension-rejected', N)], N), 'expired')
check('trace extension-validated then deadline-near', solve('revalidation-pending', [('extension-validated', N), ('deadline-near', N)], N), 'expiring')
check('trace extension-validated then open-action', solve('revalidation-pending', [('extension-validated', N), ('open-action', N)], N), 'action-pending')
check('trace extension-rejected then deadline-extension', solve('revalidation-pending', [('extension-rejected', N), ('deadline-extension', N)], N), 'revalidation-pending')
check('trace late-expiry then late-expiry', solve('completed', [('late-expiry', N), ('late-expiry', N)], N), 'completed')
check('domain state regression 1: started', solve('valid', [('open-action', N, {'now': 19})], N, {}, 'started'), {'phase': 'action-pending', 'value': 19})
check('domain state regression 2: started', solve('valid', [('open-action', N, {'now': 20})], N, {}, 'started'), {'phase': 'valid', 'value': None})
check('domain state regression 3: now', solve('expiring', [('deadline-reached', N, {'now': 19})], N, {}, 'now'), {'phase': 'expiring', 'value': 19})
check('domain state regression 4: completed', solve('pending-at-expiry', [('action-success', N, {})], N, {'started': 19, 'now': 21}, 'completed'), {'phase': 'completed', 'value': True})
check('domain state regression 5: deadline', solve('revalidation-pending', [('extension-validated', N, {'deadline': 15})], N, {}, 'deadline'), {'phase': 'valid', 'value': 20})
check('domain state regression 6: completed', solve('completed', [('late-expiry', N, {})], N, {'completed': True}, 'completed'), {'phase': 'completed', 'value': True})
check('domain state regression 7: started', solve('valid', [('open-action', N, {'now': 19}), ('deadline-reached', N, {'now': 20}), ('action-success', N, {})], N, {}, 'started'), {'phase': 'completed', 'value': 19})
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 action-failure event leaves a notification in expired instead of expired-action-error.

Time-limited notification content expiry is a bounded visual-notification workflow with mutable policy state {'deadline': 20, 'now': 5, 'started': None, 'completed': False}. Its default transition relation is {('valid', 'deadline-near'): 'expiring', ('expiring', 'deadline-reached'): 'expired', ('valid', 'open-action'): 'action-pending', ('action-pending', 'deadline-reached'): 'pending-at-expiry', ('pending-at-expiry', 'action-success'): 'completed', ('pending-at-expiry', 'action-failure'): 'expired-action-error', ('expired', 'deadline-extension'): 'revalidation-pending', ('revalidation-pending', 'extension-validated'): 'valid', ('revalidation-pending', 'extension-rejected'): 'expired', ('completed', 'late-expiry'): 'completed'}; 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 = {('valid', 'deadline-near'): 'expiring', ('expiring', 'deadline-reached'): 'expired', ('valid', 'open-action'): 'action-pending', ('action-pending', 'deadline-reached'): 'pending-at-expiry', ('pending-at-expiry', 'action-success'): 'completed', ('pending-at-expiry', 'action-failure'): 'expired-action-error', ('expired', 'deadline-extension'): 'valid', ('revalidation-pending', 'extension-validated'): 'valid', ('revalidation-pending', 'extension-rejected'): 'expired', ('completed', 'late-expiry'): 'completed'}
    data = json.loads(json.dumps({'deadline': 20, 'now': 5, 'started': None, 'completed': False})) if payload is None else {**json.loads(json.dumps({'deadline': 20, 'now': 5, 'started': None, 'completed': 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
            data['now'] = max(data['now'],arg.get('now',data['now']))
            if event == 'open-action':
                if data['now'] >= data['deadline']: event = 'unknown-event'
                else: data['started'] = data['now']
            if event == 'deadline-reached' and data['now'] < data['deadline'] and 'now' in arg: event = 'unknown-event'
            if event == 'extension-validated': data['deadline'] = max(data['deadline'],arg.get('deadline',data['deadline']+10))
            state = table.get((state, event), state)
            if state == 'completed': data['completed'] = True
    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('valid / deadline-near', solve('valid', [('deadline-near', N)], N), 'expiring')
check('expiring / deadline-reached', solve('expiring', [('deadline-reached', N)], N), 'expired')
check('valid / open-action', solve('valid', [('open-action', N)], N), 'action-pending')
check('action-pending / deadline-reached', solve('action-pending', [('deadline-reached', N)], N), 'pending-at-expiry')
check('pending-at-expiry / action-success', solve('pending-at-expiry', [('action-success', N)], N), 'completed')
check('pending-at-expiry / action-failure', solve('pending-at-expiry', [('action-failure', N)], N), 'expired-action-error')
check('expired / deadline-extension', solve('expired', [('deadline-extension', N)], N), 'revalidation-pending')
check('revalidation-pending / extension-validated', solve('revalidation-pending', [('extension-validated', N)], N), 'valid')
check('revalidation-pending / extension-rejected', solve('revalidation-pending', [('extension-rejected', N)], N), 'expired')
check('completed / late-expiry', solve('completed', [('late-expiry', N)], N), 'completed')
check('older notification incarnation', solve('valid', [('deadline-near', N - 1)], N), 'valid')
check('future notification incarnation', solve('valid', [('deadline-near', N + 1)], N), 'valid')
check('unknown event is inert', solve('valid', [('unknown-event', N)], N), 'valid')
check('empty delivery batch', solve('valid', [], N), 'valid')
check('N stale deliveries before current delivery', solve('valid', [('deadline-near', N - 1)] * N + [('deadline-near', N)], N), 'expiring')
check('trace deadline-near then deadline-reached', solve('valid', [('deadline-near', N), ('deadline-reached', N)], N), 'expired')
check('trace deadline-reached then deadline-extension', solve('expiring', [('deadline-reached', N), ('deadline-extension', N)], N), 'revalidation-pending')
check('trace open-action then deadline-reached', solve('valid', [('open-action', N), ('deadline-reached', N)], N), 'pending-at-expiry')
check('trace deadline-reached then action-success', solve('action-pending', [('deadline-reached', N), ('action-success', N)], N), 'completed')
check('trace deadline-reached then action-failure', solve('action-pending', [('deadline-reached', N), ('action-failure', N)], N), 'expired-action-error')
check('trace action-success then late-expiry', solve('pending-at-expiry', [('action-success', N), ('late-expiry', N)], N), 'completed')
check('trace deadline-extension then extension-validated', solve('expired', [('deadline-extension', N), ('extension-validated', N)], N), 'valid')
check('trace deadline-extension then extension-rejected', solve('expired', [('deadline-extension', N), ('extension-rejected', N)], N), 'expired')
check('trace extension-validated then deadline-near', solve('revalidation-pending', [('extension-validated', N), ('deadline-near', N)], N), 'expiring')
check('trace extension-validated then open-action', solve('revalidation-pending', [('extension-validated', N), ('open-action', N)], N), 'action-pending')
check('trace extension-rejected then deadline-extension', solve('revalidation-pending', [('extension-rejected', N), ('deadline-extension', N)], N), 'revalidation-pending')
check('trace late-expiry then late-expiry', solve('completed', [('late-expiry', N), ('late-expiry', N)], N), 'completed')
check('domain state regression 1: started', solve('valid', [('open-action', N, {'now': 19})], N, {}, 'started'), {'phase': 'action-pending', 'value': 19})
check('domain state regression 2: started', solve('valid', [('open-action', N, {'now': 20})], N, {}, 'started'), {'phase': 'valid', 'value': None})
check('domain state regression 3: now', solve('expiring', [('deadline-reached', N, {'now': 19})], N, {}, 'now'), {'phase': 'expiring', 'value': 19})
check('domain state regression 4: completed', solve('pending-at-expiry', [('action-success', N, {})], N, {'started': 19, 'now': 21}, 'completed'), {'phase': 'completed', 'value': True})
check('domain state regression 5: deadline', solve('revalidation-pending', [('extension-validated', N, {'deadline': 15})], N, {}, 'deadline'), {'phase': 'valid', 'value': 20})
check('domain state regression 6: completed', solve('completed', [('late-expiry', N, {})], N, {'completed': True}, 'completed'), {'phase': 'completed', 'value': True})
check('domain state regression 7: started', solve('valid', [('open-action', N, {'now': 19}), ('deadline-reached', N, {'now': 20}), ('action-success', N, {})], N, {}, 'started'), {'phase': 'completed', 'value': 19})
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 = {('valid', 'deadline-near'): 'expiring', ('expiring', 'deadline-reached'): 'expired', ('valid', 'open-action'): 'action-pending', ('action-pending', 'deadline-reached'): 'pending-at-expiry', ('pending-at-expiry', 'action-success'): 'completed', ('pending-at-expiry', 'action-failure'): 'expired-action-error', ('expired', 'deadline-extension'): 'completed', ('revalidation-pending', 'extension-validated'): 'valid', ('revalidation-pending', 'extension-rejected'): 'expired', ('completed', 'late-expiry'): 'completed'}
    data = json.loads(json.dumps({'deadline': 20, 'now': 5, 'started': None, 'completed': False})) if payload is None else {**json.loads(json.dumps({'deadline': 20, 'now': 5, 'started': None, 'completed': 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
            data['now'] = max(data['now'],arg.get('now',data['now']))
            if event == 'open-action':
                if data['now'] >= data['deadline']: event = 'unknown-event'
                else: data['started'] = data['now']
            if event == 'deadline-reached' and data['now'] < data['deadline'] and 'now' in arg: event = 'unknown-event'
            if event == 'extension-validated': data['deadline'] = max(data['deadline'],arg.get('deadline',data['deadline']+10))
            state = table.get((state, event), state)
            if state == 'completed': data['completed'] = True
    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('valid / deadline-near', solve('valid', [('deadline-near', N)], N), 'expiring')
check('expiring / deadline-reached', solve('expiring', [('deadline-reached', N)], N), 'expired')
check('valid / open-action', solve('valid', [('open-action', N)], N), 'action-pending')
check('action-pending / deadline-reached', solve('action-pending', [('deadline-reached', N)], N), 'pending-at-expiry')
check('pending-at-expiry / action-success', solve('pending-at-expiry', [('action-success', N)], N), 'completed')
check('pending-at-expiry / action-failure', solve('pending-at-expiry', [('action-failure', N)], N), 'expired-action-error')
check('expired / deadline-extension', solve('expired', [('deadline-extension', N)], N), 'revalidation-pending')
check('revalidation-pending / extension-validated', solve('revalidation-pending', [('extension-validated', N)], N), 'valid')
check('revalidation-pending / extension-rejected', solve('revalidation-pending', [('extension-rejected', N)], N), 'expired')
check('completed / late-expiry', solve('completed', [('late-expiry', N)], N), 'completed')
check('older notification incarnation', solve('valid', [('deadline-near', N - 1)], N), 'valid')
check('future notification incarnation', solve('valid', [('deadline-near', N + 1)], N), 'valid')
check('unknown event is inert', solve('valid', [('unknown-event', N)], N), 'valid')
check('empty delivery batch', solve('valid', [], N), 'valid')
check('N stale deliveries before current delivery', solve('valid', [('deadline-near', N - 1)] * N + [('deadline-near', N)], N), 'expiring')
check('trace deadline-near then deadline-reached', solve('valid', [('deadline-near', N), ('deadline-reached', N)], N), 'expired')
check('trace deadline-reached then deadline-extension', solve('expiring', [('deadline-reached', N), ('deadline-extension', N)], N), 'revalidation-pending')
check('trace open-action then deadline-reached', solve('valid', [('open-action', N), ('deadline-reached', N)], N), 'pending-at-expiry')
check('trace deadline-reached then action-success', solve('action-pending', [('deadline-reached', N), ('action-success', N)], N), 'completed')
check('trace deadline-reached then action-failure', solve('action-pending', [('deadline-reached', N), ('action-failure', N)], N), 'expired-action-error')
check('trace action-success then late-expiry', solve('pending-at-expiry', [('action-success', N), ('late-expiry', N)], N), 'completed')
check('trace deadline-extension then extension-validated', solve('expired', [('deadline-extension', N), ('extension-validated', N)], N), 'valid')
check('trace deadline-extension then extension-rejected', solve('expired', [('deadline-extension', N), ('extension-rejected', N)], N), 'expired')
check('trace extension-validated then deadline-near', solve('revalidation-pending', [('extension-validated', N), ('deadline-near', N)], N), 'expiring')
check('trace extension-validated then open-action', solve('revalidation-pending', [('extension-validated', N), ('open-action', N)], N), 'action-pending')
check('trace extension-rejected then deadline-extension', solve('revalidation-pending', [('extension-rejected', N), ('deadline-extension', N)], N), 'revalidation-pending')
check('trace late-expiry then late-expiry', solve('completed', [('late-expiry', N), ('late-expiry', N)], N), 'completed')
check('domain state regression 1: started', solve('valid', [('open-action', N, {'now': 19})], N, {}, 'started'), {'phase': 'action-pending', 'value': 19})
check('domain state regression 2: started', solve('valid', [('open-action', N, {'now': 20})], N, {}, 'started'), {'phase': 'valid', 'value': None})
check('domain state regression 3: now', solve('expiring', [('deadline-reached', N, {'now': 19})], N, {}, 'now'), {'phase': 'expiring', 'value': 19})
check('domain state regression 4: completed', solve('pending-at-expiry', [('action-success', N, {})], N, {'started': 19, 'now': 21}, 'completed'), {'phase': 'completed', 'value': True})
check('domain state regression 5: deadline', solve('revalidation-pending', [('extension-validated', N, {'deadline': 15})], N, {}, 'deadline'), {'phase': 'valid', 'value': 20})
check('domain state regression 6: completed', solve('completed', [('late-expiry', N, {})], N, {'completed': True}, 'completed'), {'phase': 'completed', 'value': True})
check('domain state regression 7: started', solve('valid', [('open-action', N, {'now': 19}), ('deadline-reached', N, {'now': 20}), ('action-success', N, {})], N, {}, 'started'), {'phase': 'completed', 'value': 19})
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 deadline-extension event leaves a notification in valid instead of revalidation-pending.

Time-limited notification content expiry is a bounded visual-notification workflow with mutable policy state {'deadline': 20, 'now': 5, 'started': None, 'completed': False}. Its default transition relation is {('valid', 'deadline-near'): 'expiring', ('expiring', 'deadline-reached'): 'expired', ('valid', 'open-action'): 'action-pending', ('action-pending', 'deadline-reached'): 'pending-at-expiry', ('pending-at-expiry', 'action-success'): 'completed', ('pending-at-expiry', 'action-failure'): 'expired-action-error', ('expired', 'deadline-extension'): 'revalidation-pending', ('revalidation-pending', 'extension-validated'): 'valid', ('revalidation-pending', 'extension-rejected'): 'expired', ('completed', 'late-expiry'): 'completed'}; 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 = {('valid', 'deadline-near'): 'expiring', ('expiring', 'deadline-reached'): 'expired', ('valid', 'open-action'): 'action-pending', ('action-pending', 'deadline-reached'): 'pending-at-expiry', ('pending-at-expiry', 'action-success'): 'completed', ('pending-at-expiry', 'action-failure'): 'expired-action-error', ('expired', 'deadline-extension'): 'revalidation-pending', ('revalidation-pending', 'extension-validated'): 'expired', ('revalidation-pending', 'extension-rejected'): 'expired', ('completed', 'late-expiry'): 'completed'}
    data = json.loads(json.dumps({'deadline': 20, 'now': 5, 'started': None, 'completed': False})) if payload is None else {**json.loads(json.dumps({'deadline': 20, 'now': 5, 'started': None, 'completed': 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
            data['now'] = max(data['now'],arg.get('now',data['now']))
            if event == 'open-action':
                if data['now'] >= data['deadline']: event = 'unknown-event'
                else: data['started'] = data['now']
            if event == 'deadline-reached' and data['now'] < data['deadline'] and 'now' in arg: event = 'unknown-event'
            if event == 'extension-validated': data['deadline'] = max(data['deadline'],arg.get('deadline',data['deadline']+10))
            state = table.get((state, event), state)
            if state == 'completed': data['completed'] = True
    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('valid / deadline-near', solve('valid', [('deadline-near', N)], N), 'expiring')
check('expiring / deadline-reached', solve('expiring', [('deadline-reached', N)], N), 'expired')
check('valid / open-action', solve('valid', [('open-action', N)], N), 'action-pending')
check('action-pending / deadline-reached', solve('action-pending', [('deadline-reached', N)], N), 'pending-at-expiry')
check('pending-at-expiry / action-success', solve('pending-at-expiry', [('action-success', N)], N), 'completed')
check('pending-at-expiry / action-failure', solve('pending-at-expiry', [('action-failure', N)], N), 'expired-action-error')
check('expired / deadline-extension', solve('expired', [('deadline-extension', N)], N), 'revalidation-pending')
check('revalidation-pending / extension-validated', solve('revalidation-pending', [('extension-validated', N)], N), 'valid')
check('revalidation-pending / extension-rejected', solve('revalidation-pending', [('extension-rejected', N)], N), 'expired')
check('completed / late-expiry', solve('completed', [('late-expiry', N)], N), 'completed')
check('older notification incarnation', solve('valid', [('deadline-near', N - 1)], N), 'valid')
check('future notification incarnation', solve('valid', [('deadline-near', N + 1)], N), 'valid')
check('unknown event is inert', solve('valid', [('unknown-event', N)], N), 'valid')
check('empty delivery batch', solve('valid', [], N), 'valid')
check('N stale deliveries before current delivery', solve('valid', [('deadline-near', N - 1)] * N + [('deadline-near', N)], N), 'expiring')
check('trace deadline-near then deadline-reached', solve('valid', [('deadline-near', N), ('deadline-reached', N)], N), 'expired')
check('trace deadline-reached then deadline-extension', solve('expiring', [('deadline-reached', N), ('deadline-extension', N)], N), 'revalidation-pending')
check('trace open-action then deadline-reached', solve('valid', [('open-action', N), ('deadline-reached', N)], N), 'pending-at-expiry')
check('trace deadline-reached then action-success', solve('action-pending', [('deadline-reached', N), ('action-success', N)], N), 'completed')
check('trace deadline-reached then action-failure', solve('action-pending', [('deadline-reached', N), ('action-failure', N)], N), 'expired-action-error')
check('trace action-success then late-expiry', solve('pending-at-expiry', [('action-success', N), ('late-expiry', N)], N), 'completed')
check('trace deadline-extension then extension-validated', solve('expired', [('deadline-extension', N), ('extension-validated', N)], N), 'valid')
check('trace deadline-extension then extension-rejected', solve('expired', [('deadline-extension', N), ('extension-rejected', N)], N), 'expired')
check('trace extension-validated then deadline-near', solve('revalidation-pending', [('extension-validated', N), ('deadline-near', N)], N), 'expiring')
check('trace extension-validated then open-action', solve('revalidation-pending', [('extension-validated', N), ('open-action', N)], N), 'action-pending')
check('trace extension-rejected then deadline-extension', solve('revalidation-pending', [('extension-rejected', N), ('deadline-extension', N)], N), 'revalidation-pending')
check('trace late-expiry then late-expiry', solve('completed', [('late-expiry', N), ('late-expiry', N)], N), 'completed')
check('domain state regression 1: started', solve('valid', [('open-action', N, {'now': 19})], N, {}, 'started'), {'phase': 'action-pending', 'value': 19})
check('domain state regression 2: started', solve('valid', [('open-action', N, {'now': 20})], N, {}, 'started'), {'phase': 'valid', 'value': None})
check('domain state regression 3: now', solve('expiring', [('deadline-reached', N, {'now': 19})], N, {}, 'now'), {'phase': 'expiring', 'value': 19})
check('domain state regression 4: completed', solve('pending-at-expiry', [('action-success', N, {})], N, {'started': 19, 'now': 21}, 'completed'), {'phase': 'completed', 'value': True})
check('domain state regression 5: deadline', solve('revalidation-pending', [('extension-validated', N, {'deadline': 15})], N, {}, 'deadline'), {'phase': 'valid', 'value': 20})
check('domain state regression 6: completed', solve('completed', [('late-expiry', N, {})], N, {'completed': True}, 'completed'), {'phase': 'completed', 'value': True})
check('domain state regression 7: started', solve('valid', [('open-action', N, {'now': 19}), ('deadline-reached', N, {'now': 20}), ('action-success', N, {})], N, {}, 'started'), {'phase': 'completed', 'value': 19})
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 = {('valid', 'deadline-near'): 'expiring', ('expiring', 'deadline-reached'): 'expired', ('valid', 'open-action'): 'action-pending', ('action-pending', 'deadline-reached'): 'pending-at-expiry', ('pending-at-expiry', 'action-success'): 'completed', ('pending-at-expiry', 'action-failure'): 'expired-action-error', ('expired', 'deadline-extension'): 'revalidation-pending', ('revalidation-pending', 'extension-validated'): 'expiring', ('revalidation-pending', 'extension-rejected'): 'expired', ('completed', 'late-expiry'): 'completed'}
    data = json.loads(json.dumps({'deadline': 20, 'now': 5, 'started': None, 'completed': False})) if payload is None else {**json.loads(json.dumps({'deadline': 20, 'now': 5, 'started': None, 'completed': 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
            data['now'] = max(data['now'],arg.get('now',data['now']))
            if event == 'open-action':
                if data['now'] >= data['deadline']: event = 'unknown-event'
                else: data['started'] = data['now']
            if event == 'deadline-reached' and data['now'] < data['deadline'] and 'now' in arg: event = 'unknown-event'
            if event == 'extension-validated': data['deadline'] = max(data['deadline'],arg.get('deadline',data['deadline']+10))
            state = table.get((state, event), state)
            if state == 'completed': data['completed'] = True
    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('valid / deadline-near', solve('valid', [('deadline-near', N)], N), 'expiring')
check('expiring / deadline-reached', solve('expiring', [('deadline-reached', N)], N), 'expired')
check('valid / open-action', solve('valid', [('open-action', N)], N), 'action-pending')
check('action-pending / deadline-reached', solve('action-pending', [('deadline-reached', N)], N), 'pending-at-expiry')
check('pending-at-expiry / action-success', solve('pending-at-expiry', [('action-success', N)], N), 'completed')
check('pending-at-expiry / action-failure', solve('pending-at-expiry', [('action-failure', N)], N), 'expired-action-error')
check('expired / deadline-extension', solve('expired', [('deadline-extension', N)], N), 'revalidation-pending')
check('revalidation-pending / extension-validated', solve('revalidation-pending', [('extension-validated', N)], N), 'valid')
check('revalidation-pending / extension-rejected', solve('revalidation-pending', [('extension-rejected', N)], N), 'expired')
check('completed / late-expiry', solve('completed', [('late-expiry', N)], N), 'completed')
check('older notification incarnation', solve('valid', [('deadline-near', N - 1)], N), 'valid')
check('future notification incarnation', solve('valid', [('deadline-near', N + 1)], N), 'valid')
check('unknown event is inert', solve('valid', [('unknown-event', N)], N), 'valid')
check('empty delivery batch', solve('valid', [], N), 'valid')
check('N stale deliveries before current delivery', solve('valid', [('deadline-near', N - 1)] * N + [('deadline-near', N)], N), 'expiring')
check('trace deadline-near then deadline-reached', solve('valid', [('deadline-near', N), ('deadline-reached', N)], N), 'expired')
check('trace deadline-reached then deadline-extension', solve('expiring', [('deadline-reached', N), ('deadline-extension', N)], N), 'revalidation-pending')
check('trace open-action then deadline-reached', solve('valid', [('open-action', N), ('deadline-reached', N)], N), 'pending-at-expiry')
check('trace deadline-reached then action-success', solve('action-pending', [('deadline-reached', N), ('action-success', N)], N), 'completed')
check('trace deadline-reached then action-failure', solve('action-pending', [('deadline-reached', N), ('action-failure', N)], N), 'expired-action-error')
check('trace action-success then late-expiry', solve('pending-at-expiry', [('action-success', N), ('late-expiry', N)], N), 'completed')
check('trace deadline-extension then extension-validated', solve('expired', [('deadline-extension', N), ('extension-validated', N)], N), 'valid')
check('trace deadline-extension then extension-rejected', solve('expired', [('deadline-extension', N), ('extension-rejected', N)], N), 'expired')
check('trace extension-validated then deadline-near', solve('revalidation-pending', [('extension-validated', N), ('deadline-near', N)], N), 'expiring')
check('trace extension-validated then open-action', solve('revalidation-pending', [('extension-validated', N), ('open-action', N)], N), 'action-pending')
check('trace extension-rejected then deadline-extension', solve('revalidation-pending', [('extension-rejected', N), ('deadline-extension', N)], N), 'revalidation-pending')
check('trace late-expiry then late-expiry', solve('completed', [('late-expiry', N), ('late-expiry', N)], N), 'completed')
check('domain state regression 1: started', solve('valid', [('open-action', N, {'now': 19})], N, {}, 'started'), {'phase': 'action-pending', 'value': 19})
check('domain state regression 2: started', solve('valid', [('open-action', N, {'now': 20})], N, {}, 'started'), {'phase': 'valid', 'value': None})
check('domain state regression 3: now', solve('expiring', [('deadline-reached', N, {'now': 19})], N, {}, 'now'), {'phase': 'expiring', 'value': 19})
check('domain state regression 4: completed', solve('pending-at-expiry', [('action-success', N, {})], N, {'started': 19, 'now': 21}, 'completed'), {'phase': 'completed', 'value': True})
check('domain state regression 5: deadline', solve('revalidation-pending', [('extension-validated', N, {'deadline': 15})], N, {}, 'deadline'), {'phase': 'valid', 'value': 20})
check('domain state regression 6: completed', solve('completed', [('late-expiry', N, {})], N, {'completed': True}, 'completed'), {'phase': 'completed', 'value': True})
check('domain state regression 7: started', solve('valid', [('open-action', N, {'now': 19}), ('deadline-reached', N, {'now': 20}), ('action-success', N, {})], N, {}, 'started'), {'phase': 'completed', 'value': 19})
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 extension-validated event leaves a notification in expired instead of valid.

Time-limited notification content expiry is a bounded visual-notification workflow with mutable policy state {'deadline': 20, 'now': 5, 'started': None, 'completed': False}. Its default transition relation is {('valid', 'deadline-near'): 'expiring', ('expiring', 'deadline-reached'): 'expired', ('valid', 'open-action'): 'action-pending', ('action-pending', 'deadline-reached'): 'pending-at-expiry', ('pending-at-expiry', 'action-success'): 'completed', ('pending-at-expiry', 'action-failure'): 'expired-action-error', ('expired', 'deadline-extension'): 'revalidation-pending', ('revalidation-pending', 'extension-validated'): 'valid', ('revalidation-pending', 'extension-rejected'): 'expired', ('completed', 'late-expiry'): 'completed'}; 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 = {('valid', 'deadline-near'): 'expiring', ('expiring', 'deadline-reached'): 'expired', ('valid', 'open-action'): 'action-pending', ('action-pending', 'deadline-reached'): 'pending-at-expiry', ('pending-at-expiry', 'action-success'): 'completed', ('pending-at-expiry', 'action-failure'): 'expired-action-error', ('expired', 'deadline-extension'): 'revalidation-pending', ('revalidation-pending', 'extension-validated'): 'valid', ('revalidation-pending', 'extension-rejected'): 'valid', ('completed', 'late-expiry'): 'completed'}
    data = json.loads(json.dumps({'deadline': 20, 'now': 5, 'started': None, 'completed': False})) if payload is None else {**json.loads(json.dumps({'deadline': 20, 'now': 5, 'started': None, 'completed': 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
            data['now'] = max(data['now'],arg.get('now',data['now']))
            if event == 'open-action':
                if data['now'] >= data['deadline']: event = 'unknown-event'
                else: data['started'] = data['now']
            if event == 'deadline-reached' and data['now'] < data['deadline'] and 'now' in arg: event = 'unknown-event'
            if event == 'extension-validated': data['deadline'] = max(data['deadline'],arg.get('deadline',data['deadline']+10))
            state = table.get((state, event), state)
            if state == 'completed': data['completed'] = True
    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('valid / deadline-near', solve('valid', [('deadline-near', N)], N), 'expiring')
check('expiring / deadline-reached', solve('expiring', [('deadline-reached', N)], N), 'expired')
check('valid / open-action', solve('valid', [('open-action', N)], N), 'action-pending')
check('action-pending / deadline-reached', solve('action-pending', [('deadline-reached', N)], N), 'pending-at-expiry')
check('pending-at-expiry / action-success', solve('pending-at-expiry', [('action-success', N)], N), 'completed')
check('pending-at-expiry / action-failure', solve('pending-at-expiry', [('action-failure', N)], N), 'expired-action-error')
check('expired / deadline-extension', solve('expired', [('deadline-extension', N)], N), 'revalidation-pending')
check('revalidation-pending / extension-validated', solve('revalidation-pending', [('extension-validated', N)], N), 'valid')
check('revalidation-pending / extension-rejected', solve('revalidation-pending', [('extension-rejected', N)], N), 'expired')
check('completed / late-expiry', solve('completed', [('late-expiry', N)], N), 'completed')
check('older notification incarnation', solve('valid', [('deadline-near', N - 1)], N), 'valid')
check('future notification incarnation', solve('valid', [('deadline-near', N + 1)], N), 'valid')
check('unknown event is inert', solve('valid', [('unknown-event', N)], N), 'valid')
check('empty delivery batch', solve('valid', [], N), 'valid')
check('N stale deliveries before current delivery', solve('valid', [('deadline-near', N - 1)] * N + [('deadline-near', N)], N), 'expiring')
check('trace deadline-near then deadline-reached', solve('valid', [('deadline-near', N), ('deadline-reached', N)], N), 'expired')
check('trace deadline-reached then deadline-extension', solve('expiring', [('deadline-reached', N), ('deadline-extension', N)], N), 'revalidation-pending')
check('trace open-action then deadline-reached', solve('valid', [('open-action', N), ('deadline-reached', N)], N), 'pending-at-expiry')
check('trace deadline-reached then action-success', solve('action-pending', [('deadline-reached', N), ('action-success', N)], N), 'completed')
check('trace deadline-reached then action-failure', solve('action-pending', [('deadline-reached', N), ('action-failure', N)], N), 'expired-action-error')
check('trace action-success then late-expiry', solve('pending-at-expiry', [('action-success', N), ('late-expiry', N)], N), 'completed')
check('trace deadline-extension then extension-validated', solve('expired', [('deadline-extension', N), ('extension-validated', N)], N), 'valid')
check('trace deadline-extension then extension-rejected', solve('expired', [('deadline-extension', N), ('extension-rejected', N)], N), 'expired')
check('trace extension-validated then deadline-near', solve('revalidation-pending', [('extension-validated', N), ('deadline-near', N)], N), 'expiring')
check('trace extension-validated then open-action', solve('revalidation-pending', [('extension-validated', N), ('open-action', N)], N), 'action-pending')
check('trace extension-rejected then deadline-extension', solve('revalidation-pending', [('extension-rejected', N), ('deadline-extension', N)], N), 'revalidation-pending')
check('trace late-expiry then late-expiry', solve('completed', [('late-expiry', N), ('late-expiry', N)], N), 'completed')
check('domain state regression 1: started', solve('valid', [('open-action', N, {'now': 19})], N, {}, 'started'), {'phase': 'action-pending', 'value': 19})
check('domain state regression 2: started', solve('valid', [('open-action', N, {'now': 20})], N, {}, 'started'), {'phase': 'valid', 'value': None})
check('domain state regression 3: now', solve('expiring', [('deadline-reached', N, {'now': 19})], N, {}, 'now'), {'phase': 'expiring', 'value': 19})
check('domain state regression 4: completed', solve('pending-at-expiry', [('action-success', N, {})], N, {'started': 19, 'now': 21}, 'completed'), {'phase': 'completed', 'value': True})
check('domain state regression 5: deadline', solve('revalidation-pending', [('extension-validated', N, {'deadline': 15})], N, {}, 'deadline'), {'phase': 'valid', 'value': 20})
check('domain state regression 6: completed', solve('completed', [('late-expiry', N, {})], N, {'completed': True}, 'completed'), {'phase': 'completed', 'value': True})
check('domain state regression 7: started', solve('valid', [('open-action', N, {'now': 19}), ('deadline-reached', N, {'now': 20}), ('action-success', N, {})], N, {}, 'started'), {'phase': 'completed', 'value': 19})
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 = {('valid', 'deadline-near'): 'expiring', ('expiring', 'deadline-reached'): 'expired', ('valid', 'open-action'): 'action-pending', ('action-pending', 'deadline-reached'): 'pending-at-expiry', ('pending-at-expiry', 'action-success'): 'completed', ('pending-at-expiry', 'action-failure'): 'expired-action-error', ('expired', 'deadline-extension'): 'revalidation-pending', ('revalidation-pending', 'extension-validated'): 'valid', ('revalidation-pending', 'extension-rejected'): 'completed', ('completed', 'late-expiry'): 'completed'}
    data = json.loads(json.dumps({'deadline': 20, 'now': 5, 'started': None, 'completed': False})) if payload is None else {**json.loads(json.dumps({'deadline': 20, 'now': 5, 'started': None, 'completed': 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
            data['now'] = max(data['now'],arg.get('now',data['now']))
            if event == 'open-action':
                if data['now'] >= data['deadline']: event = 'unknown-event'
                else: data['started'] = data['now']
            if event == 'deadline-reached' and data['now'] < data['deadline'] and 'now' in arg: event = 'unknown-event'
            if event == 'extension-validated': data['deadline'] = max(data['deadline'],arg.get('deadline',data['deadline']+10))
            state = table.get((state, event), state)
            if state == 'completed': data['completed'] = True
    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('valid / deadline-near', solve('valid', [('deadline-near', N)], N), 'expiring')
check('expiring / deadline-reached', solve('expiring', [('deadline-reached', N)], N), 'expired')
check('valid / open-action', solve('valid', [('open-action', N)], N), 'action-pending')
check('action-pending / deadline-reached', solve('action-pending', [('deadline-reached', N)], N), 'pending-at-expiry')
check('pending-at-expiry / action-success', solve('pending-at-expiry', [('action-success', N)], N), 'completed')
check('pending-at-expiry / action-failure', solve('pending-at-expiry', [('action-failure', N)], N), 'expired-action-error')
check('expired / deadline-extension', solve('expired', [('deadline-extension', N)], N), 'revalidation-pending')
check('revalidation-pending / extension-validated', solve('revalidation-pending', [('extension-validated', N)], N), 'valid')
check('revalidation-pending / extension-rejected', solve('revalidation-pending', [('extension-rejected', N)], N), 'expired')
check('completed / late-expiry', solve('completed', [('late-expiry', N)], N), 'completed')
check('older notification incarnation', solve('valid', [('deadline-near', N - 1)], N), 'valid')
check('future notification incarnation', solve('valid', [('deadline-near', N + 1)], N), 'valid')
check('unknown event is inert', solve('valid', [('unknown-event', N)], N), 'valid')
check('empty delivery batch', solve('valid', [], N), 'valid')
check('N stale deliveries before current delivery', solve('valid', [('deadline-near', N - 1)] * N + [('deadline-near', N)], N), 'expiring')
check('trace deadline-near then deadline-reached', solve('valid', [('deadline-near', N), ('deadline-reached', N)], N), 'expired')
check('trace deadline-reached then deadline-extension', solve('expiring', [('deadline-reached', N), ('deadline-extension', N)], N), 'revalidation-pending')
check('trace open-action then deadline-reached', solve('valid', [('open-action', N), ('deadline-reached', N)], N), 'pending-at-expiry')
check('trace deadline-reached then action-success', solve('action-pending', [('deadline-reached', N), ('action-success', N)], N), 'completed')
check('trace deadline-reached then action-failure', solve('action-pending', [('deadline-reached', N), ('action-failure', N)], N), 'expired-action-error')
check('trace action-success then late-expiry', solve('pending-at-expiry', [('action-success', N), ('late-expiry', N)], N), 'completed')
check('trace deadline-extension then extension-validated', solve('expired', [('deadline-extension', N), ('extension-validated', N)], N), 'valid')
check('trace deadline-extension then extension-rejected', solve('expired', [('deadline-extension', N), ('extension-rejected', N)], N), 'expired')
check('trace extension-validated then deadline-near', solve('revalidation-pending', [('extension-validated', N), ('deadline-near', N)], N), 'expiring')
check('trace extension-validated then open-action', solve('revalidation-pending', [('extension-validated', N), ('open-action', N)], N), 'action-pending')
check('trace extension-rejected then deadline-extension', solve('revalidation-pending', [('extension-rejected', N), ('deadline-extension', N)], N), 'revalidation-pending')
check('trace late-expiry then late-expiry', solve('completed', [('late-expiry', N), ('late-expiry', N)], N), 'completed')
check('domain state regression 1: started', solve('valid', [('open-action', N, {'now': 19})], N, {}, 'started'), {'phase': 'action-pending', 'value': 19})
check('domain state regression 2: started', solve('valid', [('open-action', N, {'now': 20})], N, {}, 'started'), {'phase': 'valid', 'value': None})
check('domain state regression 3: now', solve('expiring', [('deadline-reached', N, {'now': 19})], N, {}, 'now'), {'phase': 'expiring', 'value': 19})
check('domain state regression 4: completed', solve('pending-at-expiry', [('action-success', N, {})], N, {'started': 19, 'now': 21}, 'completed'), {'phase': 'completed', 'value': True})
check('domain state regression 5: deadline', solve('revalidation-pending', [('extension-validated', N, {'deadline': 15})], N, {}, 'deadline'), {'phase': 'valid', 'value': 20})
check('domain state regression 6: completed', solve('completed', [('late-expiry', N, {})], N, {'completed': True}, 'completed'), {'phase': 'completed', 'value': True})
check('domain state regression 7: started', solve('valid', [('open-action', N, {'now': 19}), ('deadline-reached', N, {'now': 20}), ('action-success', N, {})], N, {}, 'started'), {'phase': 'completed', 'value': 19})
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 extension-rejected event leaves a notification in valid instead of expired.

Time-limited notification content expiry is a bounded visual-notification workflow with mutable policy state {'deadline': 20, 'now': 5, 'started': None, 'completed': False}. Its default transition relation is {('valid', 'deadline-near'): 'expiring', ('expiring', 'deadline-reached'): 'expired', ('valid', 'open-action'): 'action-pending', ('action-pending', 'deadline-reached'): 'pending-at-expiry', ('pending-at-expiry', 'action-success'): 'completed', ('pending-at-expiry', 'action-failure'): 'expired-action-error', ('expired', 'deadline-extension'): 'revalidation-pending', ('revalidation-pending', 'extension-validated'): 'valid', ('revalidation-pending', 'extension-rejected'): 'expired', ('completed', 'late-expiry'): 'completed'}; 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 = {('valid', 'deadline-near'): 'expiring', ('expiring', 'deadline-reached'): 'expired', ('valid', 'open-action'): 'action-pending', ('action-pending', 'deadline-reached'): 'pending-at-expiry', ('pending-at-expiry', 'action-success'): 'completed', ('pending-at-expiry', 'action-failure'): 'expired-action-error', ('expired', 'deadline-extension'): 'revalidation-pending', ('revalidation-pending', 'extension-validated'): 'valid', ('revalidation-pending', 'extension-rejected'): 'expired', ('completed', 'late-expiry'): 'expired'}
    data = json.loads(json.dumps({'deadline': 20, 'now': 5, 'started': None, 'completed': False})) if payload is None else {**json.loads(json.dumps({'deadline': 20, 'now': 5, 'started': None, 'completed': 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
            data['now'] = max(data['now'],arg.get('now',data['now']))
            if event == 'open-action':
                if data['now'] >= data['deadline']: event = 'unknown-event'
                else: data['started'] = data['now']
            if event == 'deadline-reached' and data['now'] < data['deadline'] and 'now' in arg: event = 'unknown-event'
            if event == 'extension-validated': data['deadline'] = max(data['deadline'],arg.get('deadline',data['deadline']+10))
            state = table.get((state, event), state)
            if state == 'completed': data['completed'] = True
    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('valid / deadline-near', solve('valid', [('deadline-near', N)], N), 'expiring')
check('expiring / deadline-reached', solve('expiring', [('deadline-reached', N)], N), 'expired')
check('valid / open-action', solve('valid', [('open-action', N)], N), 'action-pending')
check('action-pending / deadline-reached', solve('action-pending', [('deadline-reached', N)], N), 'pending-at-expiry')
check('pending-at-expiry / action-success', solve('pending-at-expiry', [('action-success', N)], N), 'completed')
check('pending-at-expiry / action-failure', solve('pending-at-expiry', [('action-failure', N)], N), 'expired-action-error')
check('expired / deadline-extension', solve('expired', [('deadline-extension', N)], N), 'revalidation-pending')
check('revalidation-pending / extension-validated', solve('revalidation-pending', [('extension-validated', N)], N), 'valid')
check('revalidation-pending / extension-rejected', solve('revalidation-pending', [('extension-rejected', N)], N), 'expired')
check('completed / late-expiry', solve('completed', [('late-expiry', N)], N), 'completed')
check('older notification incarnation', solve('valid', [('deadline-near', N - 1)], N), 'valid')
check('future notification incarnation', solve('valid', [('deadline-near', N + 1)], N), 'valid')
check('unknown event is inert', solve('valid', [('unknown-event', N)], N), 'valid')
check('empty delivery batch', solve('valid', [], N), 'valid')
check('N stale deliveries before current delivery', solve('valid', [('deadline-near', N - 1)] * N + [('deadline-near', N)], N), 'expiring')
check('trace deadline-near then deadline-reached', solve('valid', [('deadline-near', N), ('deadline-reached', N)], N), 'expired')
check('trace deadline-reached then deadline-extension', solve('expiring', [('deadline-reached', N), ('deadline-extension', N)], N), 'revalidation-pending')
check('trace open-action then deadline-reached', solve('valid', [('open-action', N), ('deadline-reached', N)], N), 'pending-at-expiry')
check('trace deadline-reached then action-success', solve('action-pending', [('deadline-reached', N), ('action-success', N)], N), 'completed')
check('trace deadline-reached then action-failure', solve('action-pending', [('deadline-reached', N), ('action-failure', N)], N), 'expired-action-error')
check('trace action-success then late-expiry', solve('pending-at-expiry', [('action-success', N), ('late-expiry', N)], N), 'completed')
check('trace deadline-extension then extension-validated', solve('expired', [('deadline-extension', N), ('extension-validated', N)], N), 'valid')
check('trace deadline-extension then extension-rejected', solve('expired', [('deadline-extension', N), ('extension-rejected', N)], N), 'expired')
check('trace extension-validated then deadline-near', solve('revalidation-pending', [('extension-validated', N), ('deadline-near', N)], N), 'expiring')
check('trace extension-validated then open-action', solve('revalidation-pending', [('extension-validated', N), ('open-action', N)], N), 'action-pending')
check('trace extension-rejected then deadline-extension', solve('revalidation-pending', [('extension-rejected', N), ('deadline-extension', N)], N), 'revalidation-pending')
check('trace late-expiry then late-expiry', solve('completed', [('late-expiry', N), ('late-expiry', N)], N), 'completed')
check('domain state regression 1: started', solve('valid', [('open-action', N, {'now': 19})], N, {}, 'started'), {'phase': 'action-pending', 'value': 19})
check('domain state regression 2: started', solve('valid', [('open-action', N, {'now': 20})], N, {}, 'started'), {'phase': 'valid', 'value': None})
check('domain state regression 3: now', solve('expiring', [('deadline-reached', N, {'now': 19})], N, {}, 'now'), {'phase': 'expiring', 'value': 19})
check('domain state regression 4: completed', solve('pending-at-expiry', [('action-success', N, {})], N, {'started': 19, 'now': 21}, 'completed'), {'phase': 'completed', 'value': True})
check('domain state regression 5: deadline', solve('revalidation-pending', [('extension-validated', N, {'deadline': 15})], N, {}, 'deadline'), {'phase': 'valid', 'value': 20})
check('domain state regression 6: completed', solve('completed', [('late-expiry', N, {})], N, {'completed': True}, 'completed'), {'phase': 'completed', 'value': True})
check('domain state regression 7: started', solve('valid', [('open-action', N, {'now': 19}), ('deadline-reached', N, {'now': 20}), ('action-success', N, {})], N, {}, 'started'), {'phase': 'completed', 'value': 19})
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 = {('valid', 'deadline-near'): 'expiring', ('expiring', 'deadline-reached'): 'expired', ('valid', 'open-action'): 'action-pending', ('action-pending', 'deadline-reached'): 'pending-at-expiry', ('pending-at-expiry', 'action-success'): 'completed', ('pending-at-expiry', 'action-failure'): 'expired-action-error', ('expired', 'deadline-extension'): 'revalidation-pending', ('revalidation-pending', 'extension-validated'): 'valid', ('revalidation-pending', 'extension-rejected'): 'expired', ('completed', 'late-expiry'): 'valid'}
    data = json.loads(json.dumps({'deadline': 20, 'now': 5, 'started': None, 'completed': False})) if payload is None else {**json.loads(json.dumps({'deadline': 20, 'now': 5, 'started': None, 'completed': 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
            data['now'] = max(data['now'],arg.get('now',data['now']))
            if event == 'open-action':
                if data['now'] >= data['deadline']: event = 'unknown-event'
                else: data['started'] = data['now']
            if event == 'deadline-reached' and data['now'] < data['deadline'] and 'now' in arg: event = 'unknown-event'
            if event == 'extension-validated': data['deadline'] = max(data['deadline'],arg.get('deadline',data['deadline']+10))
            state = table.get((state, event), state)
            if state == 'completed': data['completed'] = True
    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('valid / deadline-near', solve('valid', [('deadline-near', N)], N), 'expiring')
check('expiring / deadline-reached', solve('expiring', [('deadline-reached', N)], N), 'expired')
check('valid / open-action', solve('valid', [('open-action', N)], N), 'action-pending')
check('action-pending / deadline-reached', solve('action-pending', [('deadline-reached', N)], N), 'pending-at-expiry')
check('pending-at-expiry / action-success', solve('pending-at-expiry', [('action-success', N)], N), 'completed')
check('pending-at-expiry / action-failure', solve('pending-at-expiry', [('action-failure', N)], N), 'expired-action-error')
check('expired / deadline-extension', solve('expired', [('deadline-extension', N)], N), 'revalidation-pending')
check('revalidation-pending / extension-validated', solve('revalidation-pending', [('extension-validated', N)], N), 'valid')
check('revalidation-pending / extension-rejected', solve('revalidation-pending', [('extension-rejected', N)], N), 'expired')
check('completed / late-expiry', solve('completed', [('late-expiry', N)], N), 'completed')
check('older notification incarnation', solve('valid', [('deadline-near', N - 1)], N), 'valid')
check('future notification incarnation', solve('valid', [('deadline-near', N + 1)], N), 'valid')
check('unknown event is inert', solve('valid', [('unknown-event', N)], N), 'valid')
check('empty delivery batch', solve('valid', [], N), 'valid')
check('N stale deliveries before current delivery', solve('valid', [('deadline-near', N - 1)] * N + [('deadline-near', N)], N), 'expiring')
check('trace deadline-near then deadline-reached', solve('valid', [('deadline-near', N), ('deadline-reached', N)], N), 'expired')
check('trace deadline-reached then deadline-extension', solve('expiring', [('deadline-reached', N), ('deadline-extension', N)], N), 'revalidation-pending')
check('trace open-action then deadline-reached', solve('valid', [('open-action', N), ('deadline-reached', N)], N), 'pending-at-expiry')
check('trace deadline-reached then action-success', solve('action-pending', [('deadline-reached', N), ('action-success', N)], N), 'completed')
check('trace deadline-reached then action-failure', solve('action-pending', [('deadline-reached', N), ('action-failure', N)], N), 'expired-action-error')
check('trace action-success then late-expiry', solve('pending-at-expiry', [('action-success', N), ('late-expiry', N)], N), 'completed')
check('trace deadline-extension then extension-validated', solve('expired', [('deadline-extension', N), ('extension-validated', N)], N), 'valid')
check('trace deadline-extension then extension-rejected', solve('expired', [('deadline-extension', N), ('extension-rejected', N)], N), 'expired')
check('trace extension-validated then deadline-near', solve('revalidation-pending', [('extension-validated', N), ('deadline-near', N)], N), 'expiring')
check('trace extension-validated then open-action', solve('revalidation-pending', [('extension-validated', N), ('open-action', N)], N), 'action-pending')
check('trace extension-rejected then deadline-extension', solve('revalidation-pending', [('extension-rejected', N), ('deadline-extension', N)], N), 'revalidation-pending')
check('trace late-expiry then late-expiry', solve('completed', [('late-expiry', N), ('late-expiry', N)], N), 'completed')
check('domain state regression 1: started', solve('valid', [('open-action', N, {'now': 19})], N, {}, 'started'), {'phase': 'action-pending', 'value': 19})
check('domain state regression 2: started', solve('valid', [('open-action', N, {'now': 20})], N, {}, 'started'), {'phase': 'valid', 'value': None})
check('domain state regression 3: now', solve('expiring', [('deadline-reached', N, {'now': 19})], N, {}, 'now'), {'phase': 'expiring', 'value': 19})
check('domain state regression 4: completed', solve('pending-at-expiry', [('action-success', N, {})], N, {'started': 19, 'now': 21}, 'completed'), {'phase': 'completed', 'value': True})
check('domain state regression 5: deadline', solve('revalidation-pending', [('extension-validated', N, {'deadline': 15})], N, {}, 'deadline'), {'phase': 'valid', 'value': 20})
check('domain state regression 6: completed', solve('completed', [('late-expiry', N, {})], N, {'completed': True}, 'completed'), {'phase': 'completed', 'value': True})
check('domain state regression 7: started', solve('valid', [('open-action', N, {'now': 19}), ('deadline-reached', N, {'now': 20}), ('action-success', N, {})], N, {}, 'started'), {'phase': 'completed', 'value': 19})
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 late-expiry event leaves a notification in expired instead of completed.

Time-limited notification content expiry is a bounded visual-notification workflow with mutable policy state {'deadline': 20, 'now': 5, 'started': None, 'completed': False}. Its default transition relation is {('valid', 'deadline-near'): 'expiring', ('expiring', 'deadline-reached'): 'expired', ('valid', 'open-action'): 'action-pending', ('action-pending', 'deadline-reached'): 'pending-at-expiry', ('pending-at-expiry', 'action-success'): 'completed', ('pending-at-expiry', 'action-failure'): 'expired-action-error', ('expired', 'deadline-extension'): 'revalidation-pending', ('revalidation-pending', 'extension-validated'): 'valid', ('revalidation-pending', 'extension-rejected'): 'expired', ('completed', 'late-expiry'): 'completed'}; 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