FAILURE MAP
← Case archive

FA-24131 / Client state / Open access

Page freeze and resume lifecycle: Resource disposal on unload · case 01

Resource disposal on unload.

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

ROOT CAUSE

The resource-disposal-on-unload client decision evaluates `active if event=='pagehide' else []` instead of `active if event=='pagehide' and not persisted else []`.

VERIFIED REPAIR

Apply the modeled resource-disposal-on-unload rule: `active if event=='pagehide' and not persisted else []`.

Unsuccessful approach: The partial repair `active if not persisted else []` still violates the explicit fixture contract.

Case contract

The stipulated page lifecycle distinguishes a cached pagehide from final disposal. Timers pause on hide/freeze, dirty snapshots flush on any pagehide, and resume/pageshow may revalidate and drain retained work. Operation resource-disposal-on-unload has the six explicit input/output oracles below.

Why this case matters

An offline client lifecycle model that isolates a state-management defect without DOM rendering or network services.

1 / The failure

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

N = 1
observations = []
def solve(operation, s):
    event, persisted, dirty, active, queued, revision, observed = s
    if operation == 'preserved-page-disposition':
        return 'suspend' if event=='pagehide' and persisted else ('dispose' if event=='pagehide' else 'keep')
    if operation == 'resume-revalidation':
        return event in ('resume','pageshow') and (persisted or revision!=observed)
    if operation == 'freeze-timer-shutdown':
        return [x for x in active if x!='timer'] if event in ('freeze','pagehide') else active
    if operation == 'dirty-pagehide-flush':
        return dirty and event=='pagehide'
    if operation == 'preserved-client-queue':
        return queued if persisted or event!='pagehide' else []
    if operation == 'resume-queue-drain':
        return queued if event in ('resume','pageshow') else []
    if operation == 'resume-event-source':
        return 'bfcache' if event=='pageshow' and persisted else ('thaw' if event=='resume' else 'ordinary')
    if operation == 'resource-disposal-on-unload':
        return active if event=='pagehide' else []
    if operation == 'suspended-work-reason':
        return 'frozen' if event=='freeze' else ('cached' if event=='pagehide' and persisted else None)
    if operation == 'revalidation-observed-version':
        return revision if event in ('resume','pageshow') else observed
    raise ValueError('unknown modeled operation')
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('preserved-page-disposition scenario 1', solve('preserved-page-disposition', ('pagehide',True,True,['timer','socket'],['a']*N,3,2)), 'suspend')
check('preserved-page-disposition scenario 2', solve('preserved-page-disposition', ('pagehide',False,True,['timer'],[],1,1)), 'dispose')
check('preserved-page-disposition scenario 3', solve('preserved-page-disposition', ('pageshow',True,False,[],['a','b'],3,1)), 'keep')
check('preserved-page-disposition scenario 4', solve('preserved-page-disposition', ('pageshow',False,False,[],[],1,1)), 'keep')
check('preserved-page-disposition scenario 5', solve('preserved-page-disposition', ('freeze',False,True,['socket'],['a'],2,2)), 'keep')
check('preserved-page-disposition scenario 6', solve('preserved-page-disposition', ('resume',False,True,['timer'],['a'],2,3)), 'keep')
check('resume-revalidation scenario 1', solve('resume-revalidation', ('pagehide',True,True,['timer','socket'],['a']*N,3,2)), False)
check('resume-revalidation scenario 2', solve('resume-revalidation', ('pagehide',False,True,['timer'],[],1,1)), False)
check('resume-revalidation scenario 3', solve('resume-revalidation', ('pageshow',True,False,[],['a','b'],3,1)), True)
check('resume-revalidation scenario 4', solve('resume-revalidation', ('pageshow',False,False,[],[],1,1)), False)
check('resume-revalidation scenario 5', solve('resume-revalidation', ('freeze',False,True,['socket'],['a'],2,2)), False)
check('resume-revalidation scenario 6', solve('resume-revalidation', ('resume',False,True,['timer'],['a'],2,3)), True)
check('freeze-timer-shutdown scenario 1', solve('freeze-timer-shutdown', ('pagehide',True,True,['timer','socket'],['a']*N,3,2)), ['socket'])
check('freeze-timer-shutdown scenario 2', solve('freeze-timer-shutdown', ('pagehide',False,True,['timer'],[],1,1)), [])
check('freeze-timer-shutdown scenario 3', solve('freeze-timer-shutdown', ('pageshow',True,False,[],['a','b'],3,1)), [])
check('freeze-timer-shutdown scenario 4', solve('freeze-timer-shutdown', ('pageshow',False,False,[],[],1,1)), [])
check('freeze-timer-shutdown scenario 5', solve('freeze-timer-shutdown', ('freeze',False,True,['socket'],['a'],2,2)), ['socket'])
check('freeze-timer-shutdown scenario 6', solve('freeze-timer-shutdown', ('resume',False,True,['timer'],['a'],2,3)), ['timer'])
check('dirty-pagehide-flush scenario 1', solve('dirty-pagehide-flush', ('pagehide',True,True,['timer','socket'],['a']*N,3,2)), True)
check('dirty-pagehide-flush scenario 2', solve('dirty-pagehide-flush', ('pagehide',False,True,['timer'],[],1,1)), True)
check('dirty-pagehide-flush scenario 3', solve('dirty-pagehide-flush', ('pageshow',True,False,[],['a','b'],3,1)), False)
check('dirty-pagehide-flush scenario 4', solve('dirty-pagehide-flush', ('pageshow',False,False,[],[],1,1)), False)
check('dirty-pagehide-flush scenario 5', solve('dirty-pagehide-flush', ('freeze',False,True,['socket'],['a'],2,2)), False)
check('dirty-pagehide-flush scenario 6', solve('dirty-pagehide-flush', ('resume',False,True,['timer'],['a'],2,3)), False)
check('preserved-client-queue scenario 1', solve('preserved-client-queue', ('pagehide',True,True,['timer','socket'],['a']*N,3,2)), ['a']*N)
check('preserved-client-queue scenario 2', solve('preserved-client-queue', ('pagehide',False,True,['timer'],[],1,1)), [])
check('preserved-client-queue scenario 3', solve('preserved-client-queue', ('pageshow',True,False,[],['a','b'],3,1)), ['a','b'])
check('preserved-client-queue scenario 4', solve('preserved-client-queue', ('pageshow',False,False,[],[],1,1)), [])
check('preserved-client-queue scenario 5', solve('preserved-client-queue', ('freeze',False,True,['socket'],['a'],2,2)), ['a'])
check('preserved-client-queue scenario 6', solve('preserved-client-queue', ('resume',False,True,['timer'],['a'],2,3)), ['a'])
check('resume-queue-drain scenario 1', solve('resume-queue-drain', ('pagehide',True,True,['timer','socket'],['a']*N,3,2)), [])
check('resume-queue-drain scenario 2', solve('resume-queue-drain', ('pagehide',False,True,['timer'],[],1,1)), [])
check('resume-queue-drain scenario 3', solve('resume-queue-drain', ('pageshow',True,False,[],['a','b'],3,1)), ['a','b'])
check('resume-queue-drain scenario 4', solve('resume-queue-drain', ('pageshow',False,False,[],[],1,1)), [])
check('resume-queue-drain scenario 5', solve('resume-queue-drain', ('freeze',False,True,['socket'],['a'],2,2)), [])
check('resume-queue-drain scenario 6', solve('resume-queue-drain', ('resume',False,True,['timer'],['a'],2,3)), ['a'])
check('resume-event-source scenario 1', solve('resume-event-source', ('pagehide',True,True,['timer','socket'],['a']*N,3,2)), 'ordinary')
check('resume-event-source scenario 2', solve('resume-event-source', ('pagehide',False,True,['timer'],[],1,1)), 'ordinary')
check('resume-event-source scenario 3', solve('resume-event-source', ('pageshow',True,False,[],['a','b'],3,1)), 'bfcache')
check('resume-event-source scenario 4', solve('resume-event-source', ('pageshow',False,False,[],[],1,1)), 'ordinary')
check('resume-event-source scenario 5', solve('resume-event-source', ('freeze',False,True,['socket'],['a'],2,2)), 'ordinary')
check('resume-event-source scenario 6', solve('resume-event-source', ('resume',False,True,['timer'],['a'],2,3)), 'thaw')
check('resource-disposal-on-unload scenario 1', solve('resource-disposal-on-unload', ('pagehide',True,True,['timer','socket'],['a']*N,3,2)), [])
check('resource-disposal-on-unload scenario 2', solve('resource-disposal-on-unload', ('pagehide',False,True,['timer'],[],1,1)), ['timer'])
check('resource-disposal-on-unload scenario 3', solve('resource-disposal-on-unload', ('pageshow',True,False,[],['a','b'],3,1)), [])
check('resource-disposal-on-unload scenario 4', solve('resource-disposal-on-unload', ('pageshow',False,False,[],[],1,1)), [])
check('resource-disposal-on-unload scenario 5', solve('resource-disposal-on-unload', ('freeze',False,True,['socket'],['a'],2,2)), [])
check('resource-disposal-on-unload scenario 6', solve('resource-disposal-on-unload', ('resume',False,True,['timer'],['a'],2,3)), [])
check('suspended-work-reason scenario 1', solve('suspended-work-reason', ('pagehide',True,True,['timer','socket'],['a']*N,3,2)), 'cached')
check('suspended-work-reason scenario 2', solve('suspended-work-reason', ('pagehide',False,True,['timer'],[],1,1)), None)
check('suspended-work-reason scenario 3', solve('suspended-work-reason', ('pageshow',True,False,[],['a','b'],3,1)), None)
check('suspended-work-reason scenario 4', solve('suspended-work-reason', ('pageshow',False,False,[],[],1,1)), None)
check('suspended-work-reason scenario 5', solve('suspended-work-reason', ('freeze',False,True,['socket'],['a'],2,2)), 'frozen')
check('suspended-work-reason scenario 6', solve('suspended-work-reason', ('resume',False,True,['timer'],['a'],2,3)), None)
check('revalidation-observed-version scenario 1', solve('revalidation-observed-version', ('pagehide',True,True,['timer','socket'],['a']*N,3,2)), 2)
check('revalidation-observed-version scenario 2', solve('revalidation-observed-version', ('pagehide',False,True,['timer'],[],1,1)), 1)
check('revalidation-observed-version scenario 3', solve('revalidation-observed-version', ('pageshow',True,False,[],['a','b'],3,1)), 3)
check('revalidation-observed-version scenario 4', solve('revalidation-observed-version', ('pageshow',False,False,[],[],1,1)), 1)
check('revalidation-observed-version scenario 5', solve('revalidation-observed-version', ('freeze',False,True,['socket'],['a'],2,2)), 2)
check('revalidation-observed-version scenario 6', solve('revalidation-observed-version', ('resume',False,True,['timer'],['a'],2,3)), 2)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
preserved-page-disposition scenario 1suspendsuspendPassed
preserved-page-disposition scenario 2disposedisposePassed
preserved-page-disposition scenario 3keepkeepPassed
preserved-page-disposition scenario 4keepkeepPassed
preserved-page-disposition scenario 5keepkeepPassed
preserved-page-disposition scenario 6keepkeepPassed
resume-revalidation scenario 1FalseFalsePassed
resume-revalidation scenario 2FalseFalsePassed
resume-revalidation scenario 3TrueTruePassed
resume-revalidation scenario 4FalseFalsePassed
resume-revalidation scenario 5FalseFalsePassed
resume-revalidation scenario 6TrueTruePassed
freeze-timer-shutdown scenario 1['socket']['socket']Passed
freeze-timer-shutdown scenario 2[][]Passed
freeze-timer-shutdown scenario 3[][]Passed
freeze-timer-shutdown scenario 4[][]Passed
freeze-timer-shutdown scenario 5['socket']['socket']Passed
freeze-timer-shutdown scenario 6['timer']['timer']Passed
dirty-pagehide-flush scenario 1TrueTruePassed
dirty-pagehide-flush scenario 2TrueTruePassed
dirty-pagehide-flush scenario 3FalseFalsePassed
dirty-pagehide-flush scenario 4FalseFalsePassed
dirty-pagehide-flush scenario 5FalseFalsePassed
dirty-pagehide-flush scenario 6FalseFalsePassed
preserved-client-queue scenario 1['a']['a']Passed
preserved-client-queue scenario 2[][]Passed
preserved-client-queue scenario 3['a', 'b']['a', 'b']Passed
preserved-client-queue scenario 4[][]Passed
preserved-client-queue scenario 5['a']['a']Passed
preserved-client-queue scenario 6['a']['a']Passed
resume-queue-drain scenario 1[][]Passed
resume-queue-drain scenario 2[][]Passed
resume-queue-drain scenario 3['a', 'b']['a', 'b']Passed
resume-queue-drain scenario 4[][]Passed
resume-queue-drain scenario 5[][]Passed
resume-queue-drain scenario 6['a']['a']Passed
resume-event-source scenario 1ordinaryordinaryPassed
resume-event-source scenario 2ordinaryordinaryPassed
resume-event-source scenario 3bfcachebfcachePassed
resume-event-source scenario 4ordinaryordinaryPassed
resume-event-source scenario 5ordinaryordinaryPassed
resume-event-source scenario 6thawthawPassed
resource-disposal-on-unload scenario 1['timer', 'socket'][]Failed
resource-disposal-on-unload scenario 2['timer']['timer']Passed
resource-disposal-on-unload scenario 3[][]Passed
resource-disposal-on-unload scenario 4[][]Passed
resource-disposal-on-unload scenario 5[][]Passed
resource-disposal-on-unload scenario 6[][]Passed
suspended-work-reason scenario 1cachedcachedPassed
suspended-work-reason scenario 2NoneNonePassed
suspended-work-reason scenario 3NoneNonePassed
suspended-work-reason scenario 4NoneNonePassed
suspended-work-reason scenario 5frozenfrozenPassed
suspended-work-reason scenario 6NoneNonePassed
revalidation-observed-version scenario 122Passed
revalidation-observed-version scenario 211Passed
revalidation-observed-version scenario 333Passed
revalidation-observed-version scenario 411Passed
revalidation-observed-version scenario 522Passed
revalidation-observed-version scenario 622Passed

SHA-256 / e83513a34c9b37cd3e549f744de6f5a973be52013c2262c2f425f9c8d8b3c9f4

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(operation, s):
    event, persisted, dirty, active, queued, revision, observed = s
    if operation == 'preserved-page-disposition':
        return 'suspend' if event=='pagehide' and persisted else ('dispose' if event=='pagehide' else 'keep')
    if operation == 'resume-revalidation':
        return event in ('resume','pageshow') and (persisted or revision!=observed)
    if operation == 'freeze-timer-shutdown':
        return [x for x in active if x!='timer'] if event in ('freeze','pagehide') else active
    if operation == 'dirty-pagehide-flush':
        return dirty and event=='pagehide'
    if operation == 'preserved-client-queue':
        return queued if persisted or event!='pagehide' else []
    if operation == 'resume-queue-drain':
        return queued if event in ('resume','pageshow') else []
    if operation == 'resume-event-source':
        return 'bfcache' if event=='pageshow' and persisted else ('thaw' if event=='resume' else 'ordinary')
    if operation == 'resource-disposal-on-unload':
        return active if not persisted else []
    if operation == 'suspended-work-reason':
        return 'frozen' if event=='freeze' else ('cached' if event=='pagehide' and persisted else None)
    if operation == 'revalidation-observed-version':
        return revision if event in ('resume','pageshow') else observed
    raise ValueError('unknown modeled operation')
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('preserved-page-disposition scenario 1', solve('preserved-page-disposition', ('pagehide',True,True,['timer','socket'],['a']*N,3,2)), 'suspend')
check('preserved-page-disposition scenario 2', solve('preserved-page-disposition', ('pagehide',False,True,['timer'],[],1,1)), 'dispose')
check('preserved-page-disposition scenario 3', solve('preserved-page-disposition', ('pageshow',True,False,[],['a','b'],3,1)), 'keep')
check('preserved-page-disposition scenario 4', solve('preserved-page-disposition', ('pageshow',False,False,[],[],1,1)), 'keep')
check('preserved-page-disposition scenario 5', solve('preserved-page-disposition', ('freeze',False,True,['socket'],['a'],2,2)), 'keep')
check('preserved-page-disposition scenario 6', solve('preserved-page-disposition', ('resume',False,True,['timer'],['a'],2,3)), 'keep')
check('resume-revalidation scenario 1', solve('resume-revalidation', ('pagehide',True,True,['timer','socket'],['a']*N,3,2)), False)
check('resume-revalidation scenario 2', solve('resume-revalidation', ('pagehide',False,True,['timer'],[],1,1)), False)
check('resume-revalidation scenario 3', solve('resume-revalidation', ('pageshow',True,False,[],['a','b'],3,1)), True)
check('resume-revalidation scenario 4', solve('resume-revalidation', ('pageshow',False,False,[],[],1,1)), False)
check('resume-revalidation scenario 5', solve('resume-revalidation', ('freeze',False,True,['socket'],['a'],2,2)), False)
check('resume-revalidation scenario 6', solve('resume-revalidation', ('resume',False,True,['timer'],['a'],2,3)), True)
check('freeze-timer-shutdown scenario 1', solve('freeze-timer-shutdown', ('pagehide',True,True,['timer','socket'],['a']*N,3,2)), ['socket'])
check('freeze-timer-shutdown scenario 2', solve('freeze-timer-shutdown', ('pagehide',False,True,['timer'],[],1,1)), [])
check('freeze-timer-shutdown scenario 3', solve('freeze-timer-shutdown', ('pageshow',True,False,[],['a','b'],3,1)), [])
check('freeze-timer-shutdown scenario 4', solve('freeze-timer-shutdown', ('pageshow',False,False,[],[],1,1)), [])
check('freeze-timer-shutdown scenario 5', solve('freeze-timer-shutdown', ('freeze',False,True,['socket'],['a'],2,2)), ['socket'])
check('freeze-timer-shutdown scenario 6', solve('freeze-timer-shutdown', ('resume',False,True,['timer'],['a'],2,3)), ['timer'])
check('dirty-pagehide-flush scenario 1', solve('dirty-pagehide-flush', ('pagehide',True,True,['timer','socket'],['a']*N,3,2)), True)
check('dirty-pagehide-flush scenario 2', solve('dirty-pagehide-flush', ('pagehide',False,True,['timer'],[],1,1)), True)
check('dirty-pagehide-flush scenario 3', solve('dirty-pagehide-flush', ('pageshow',True,False,[],['a','b'],3,1)), False)
check('dirty-pagehide-flush scenario 4', solve('dirty-pagehide-flush', ('pageshow',False,False,[],[],1,1)), False)
check('dirty-pagehide-flush scenario 5', solve('dirty-pagehide-flush', ('freeze',False,True,['socket'],['a'],2,2)), False)
check('dirty-pagehide-flush scenario 6', solve('dirty-pagehide-flush', ('resume',False,True,['timer'],['a'],2,3)), False)
check('preserved-client-queue scenario 1', solve('preserved-client-queue', ('pagehide',True,True,['timer','socket'],['a']*N,3,2)), ['a']*N)
check('preserved-client-queue scenario 2', solve('preserved-client-queue', ('pagehide',False,True,['timer'],[],1,1)), [])
check('preserved-client-queue scenario 3', solve('preserved-client-queue', ('pageshow',True,False,[],['a','b'],3,1)), ['a','b'])
check('preserved-client-queue scenario 4', solve('preserved-client-queue', ('pageshow',False,False,[],[],1,1)), [])
check('preserved-client-queue scenario 5', solve('preserved-client-queue', ('freeze',False,True,['socket'],['a'],2,2)), ['a'])
check('preserved-client-queue scenario 6', solve('preserved-client-queue', ('resume',False,True,['timer'],['a'],2,3)), ['a'])
check('resume-queue-drain scenario 1', solve('resume-queue-drain', ('pagehide',True,True,['timer','socket'],['a']*N,3,2)), [])
check('resume-queue-drain scenario 2', solve('resume-queue-drain', ('pagehide',False,True,['timer'],[],1,1)), [])
check('resume-queue-drain scenario 3', solve('resume-queue-drain', ('pageshow',True,False,[],['a','b'],3,1)), ['a','b'])
check('resume-queue-drain scenario 4', solve('resume-queue-drain', ('pageshow',False,False,[],[],1,1)), [])
check('resume-queue-drain scenario 5', solve('resume-queue-drain', ('freeze',False,True,['socket'],['a'],2,2)), [])
check('resume-queue-drain scenario 6', solve('resume-queue-drain', ('resume',False,True,['timer'],['a'],2,3)), ['a'])
check('resume-event-source scenario 1', solve('resume-event-source', ('pagehide',True,True,['timer','socket'],['a']*N,3,2)), 'ordinary')
check('resume-event-source scenario 2', solve('resume-event-source', ('pagehide',False,True,['timer'],[],1,1)), 'ordinary')
check('resume-event-source scenario 3', solve('resume-event-source', ('pageshow',True,False,[],['a','b'],3,1)), 'bfcache')
check('resume-event-source scenario 4', solve('resume-event-source', ('pageshow',False,False,[],[],1,1)), 'ordinary')
check('resume-event-source scenario 5', solve('resume-event-source', ('freeze',False,True,['socket'],['a'],2,2)), 'ordinary')
check('resume-event-source scenario 6', solve('resume-event-source', ('resume',False,True,['timer'],['a'],2,3)), 'thaw')
check('resource-disposal-on-unload scenario 1', solve('resource-disposal-on-unload', ('pagehide',True,True,['timer','socket'],['a']*N,3,2)), [])
check('resource-disposal-on-unload scenario 2', solve('resource-disposal-on-unload', ('pagehide',False,True,['timer'],[],1,1)), ['timer'])
check('resource-disposal-on-unload scenario 3', solve('resource-disposal-on-unload', ('pageshow',True,False,[],['a','b'],3,1)), [])
check('resource-disposal-on-unload scenario 4', solve('resource-disposal-on-unload', ('pageshow',False,False,[],[],1,1)), [])
check('resource-disposal-on-unload scenario 5', solve('resource-disposal-on-unload', ('freeze',False,True,['socket'],['a'],2,2)), [])
check('resource-disposal-on-unload scenario 6', solve('resource-disposal-on-unload', ('resume',False,True,['timer'],['a'],2,3)), [])
check('suspended-work-reason scenario 1', solve('suspended-work-reason', ('pagehide',True,True,['timer','socket'],['a']*N,3,2)), 'cached')
check('suspended-work-reason scenario 2', solve('suspended-work-reason', ('pagehide',False,True,['timer'],[],1,1)), None)
check('suspended-work-reason scenario 3', solve('suspended-work-reason', ('pageshow',True,False,[],['a','b'],3,1)), None)
check('suspended-work-reason scenario 4', solve('suspended-work-reason', ('pageshow',False,False,[],[],1,1)), None)
check('suspended-work-reason scenario 5', solve('suspended-work-reason', ('freeze',False,True,['socket'],['a'],2,2)), 'frozen')
check('suspended-work-reason scenario 6', solve('suspended-work-reason', ('resume',False,True,['timer'],['a'],2,3)), None)
check('revalidation-observed-version scenario 1', solve('revalidation-observed-version', ('pagehide',True,True,['timer','socket'],['a']*N,3,2)), 2)
check('revalidation-observed-version scenario 2', solve('revalidation-observed-version', ('pagehide',False,True,['timer'],[],1,1)), 1)
check('revalidation-observed-version scenario 3', solve('revalidation-observed-version', ('pageshow',True,False,[],['a','b'],3,1)), 3)
check('revalidation-observed-version scenario 4', solve('revalidation-observed-version', ('pageshow',False,False,[],[],1,1)), 1)
check('revalidation-observed-version scenario 5', solve('revalidation-observed-version', ('freeze',False,True,['socket'],['a'],2,2)), 2)
check('revalidation-observed-version scenario 6', solve('revalidation-observed-version', ('resume',False,True,['timer'],['a'],2,3)), 2)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
preserved-page-disposition scenario 1suspendsuspendPassed
preserved-page-disposition scenario 2disposedisposePassed
preserved-page-disposition scenario 3keepkeepPassed
preserved-page-disposition scenario 4keepkeepPassed
preserved-page-disposition scenario 5keepkeepPassed
preserved-page-disposition scenario 6keepkeepPassed
resume-revalidation scenario 1FalseFalsePassed
resume-revalidation scenario 2FalseFalsePassed
resume-revalidation scenario 3TrueTruePassed
resume-revalidation scenario 4FalseFalsePassed
resume-revalidation scenario 5FalseFalsePassed
resume-revalidation scenario 6TrueTruePassed
freeze-timer-shutdown scenario 1['socket']['socket']Passed
freeze-timer-shutdown scenario 2[][]Passed
freeze-timer-shutdown scenario 3[][]Passed
freeze-timer-shutdown scenario 4[][]Passed
freeze-timer-shutdown scenario 5['socket']['socket']Passed
freeze-timer-shutdown scenario 6['timer']['timer']Passed
dirty-pagehide-flush scenario 1TrueTruePassed
dirty-pagehide-flush scenario 2TrueTruePassed
dirty-pagehide-flush scenario 3FalseFalsePassed
dirty-pagehide-flush scenario 4FalseFalsePassed
dirty-pagehide-flush scenario 5FalseFalsePassed
dirty-pagehide-flush scenario 6FalseFalsePassed
preserved-client-queue scenario 1['a']['a']Passed
preserved-client-queue scenario 2[][]Passed
preserved-client-queue scenario 3['a', 'b']['a', 'b']Passed
preserved-client-queue scenario 4[][]Passed
preserved-client-queue scenario 5['a']['a']Passed
preserved-client-queue scenario 6['a']['a']Passed
resume-queue-drain scenario 1[][]Passed
resume-queue-drain scenario 2[][]Passed
resume-queue-drain scenario 3['a', 'b']['a', 'b']Passed
resume-queue-drain scenario 4[][]Passed
resume-queue-drain scenario 5[][]Passed
resume-queue-drain scenario 6['a']['a']Passed
resume-event-source scenario 1ordinaryordinaryPassed
resume-event-source scenario 2ordinaryordinaryPassed
resume-event-source scenario 3bfcachebfcachePassed
resume-event-source scenario 4ordinaryordinaryPassed
resume-event-source scenario 5ordinaryordinaryPassed
resume-event-source scenario 6thawthawPassed
resource-disposal-on-unload scenario 1[][]Passed
resource-disposal-on-unload scenario 2['timer']['timer']Passed
resource-disposal-on-unload scenario 3[][]Passed
resource-disposal-on-unload scenario 4[][]Passed
resource-disposal-on-unload scenario 5['socket'][]Failed
resource-disposal-on-unload scenario 6['timer'][]Failed
suspended-work-reason scenario 1cachedcachedPassed
suspended-work-reason scenario 2NoneNonePassed
suspended-work-reason scenario 3NoneNonePassed
suspended-work-reason scenario 4NoneNonePassed
suspended-work-reason scenario 5frozenfrozenPassed
suspended-work-reason scenario 6NoneNonePassed
revalidation-observed-version scenario 122Passed
revalidation-observed-version scenario 211Passed
revalidation-observed-version scenario 333Passed
revalidation-observed-version scenario 411Passed
revalidation-observed-version scenario 522Passed
revalidation-observed-version scenario 622Passed

SHA-256 / 65b340b147149c6246677b028bfb77d2946f1c5f379040fe6bad8cdeba140698

3 / The verified repair

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

N = 1
observations = []
def solve(operation, s):
    event, persisted, dirty, active, queued, revision, observed = s
    if operation == 'preserved-page-disposition':
        return 'suspend' if event=='pagehide' and persisted else ('dispose' if event=='pagehide' else 'keep')
    if operation == 'resume-revalidation':
        return event in ('resume','pageshow') and (persisted or revision!=observed)
    if operation == 'freeze-timer-shutdown':
        return [x for x in active if x!='timer'] if event in ('freeze','pagehide') else active
    if operation == 'dirty-pagehide-flush':
        return dirty and event=='pagehide'
    if operation == 'preserved-client-queue':
        return queued if persisted or event!='pagehide' else []
    if operation == 'resume-queue-drain':
        return queued if event in ('resume','pageshow') else []
    if operation == 'resume-event-source':
        return 'bfcache' if event=='pageshow' and persisted else ('thaw' if event=='resume' else 'ordinary')
    if operation == 'resource-disposal-on-unload':
        return active if event=='pagehide' and not persisted else []
    if operation == 'suspended-work-reason':
        return 'frozen' if event=='freeze' else ('cached' if event=='pagehide' and persisted else None)
    if operation == 'revalidation-observed-version':
        return revision if event in ('resume','pageshow') else observed
    raise ValueError('unknown modeled operation')
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('preserved-page-disposition scenario 1', solve('preserved-page-disposition', ('pagehide',True,True,['timer','socket'],['a']*N,3,2)), 'suspend')
check('preserved-page-disposition scenario 2', solve('preserved-page-disposition', ('pagehide',False,True,['timer'],[],1,1)), 'dispose')
check('preserved-page-disposition scenario 3', solve('preserved-page-disposition', ('pageshow',True,False,[],['a','b'],3,1)), 'keep')
check('preserved-page-disposition scenario 4', solve('preserved-page-disposition', ('pageshow',False,False,[],[],1,1)), 'keep')
check('preserved-page-disposition scenario 5', solve('preserved-page-disposition', ('freeze',False,True,['socket'],['a'],2,2)), 'keep')
check('preserved-page-disposition scenario 6', solve('preserved-page-disposition', ('resume',False,True,['timer'],['a'],2,3)), 'keep')
check('resume-revalidation scenario 1', solve('resume-revalidation', ('pagehide',True,True,['timer','socket'],['a']*N,3,2)), False)
check('resume-revalidation scenario 2', solve('resume-revalidation', ('pagehide',False,True,['timer'],[],1,1)), False)
check('resume-revalidation scenario 3', solve('resume-revalidation', ('pageshow',True,False,[],['a','b'],3,1)), True)
check('resume-revalidation scenario 4', solve('resume-revalidation', ('pageshow',False,False,[],[],1,1)), False)
check('resume-revalidation scenario 5', solve('resume-revalidation', ('freeze',False,True,['socket'],['a'],2,2)), False)
check('resume-revalidation scenario 6', solve('resume-revalidation', ('resume',False,True,['timer'],['a'],2,3)), True)
check('freeze-timer-shutdown scenario 1', solve('freeze-timer-shutdown', ('pagehide',True,True,['timer','socket'],['a']*N,3,2)), ['socket'])
check('freeze-timer-shutdown scenario 2', solve('freeze-timer-shutdown', ('pagehide',False,True,['timer'],[],1,1)), [])
check('freeze-timer-shutdown scenario 3', solve('freeze-timer-shutdown', ('pageshow',True,False,[],['a','b'],3,1)), [])
check('freeze-timer-shutdown scenario 4', solve('freeze-timer-shutdown', ('pageshow',False,False,[],[],1,1)), [])
check('freeze-timer-shutdown scenario 5', solve('freeze-timer-shutdown', ('freeze',False,True,['socket'],['a'],2,2)), ['socket'])
check('freeze-timer-shutdown scenario 6', solve('freeze-timer-shutdown', ('resume',False,True,['timer'],['a'],2,3)), ['timer'])
check('dirty-pagehide-flush scenario 1', solve('dirty-pagehide-flush', ('pagehide',True,True,['timer','socket'],['a']*N,3,2)), True)
check('dirty-pagehide-flush scenario 2', solve('dirty-pagehide-flush', ('pagehide',False,True,['timer'],[],1,1)), True)
check('dirty-pagehide-flush scenario 3', solve('dirty-pagehide-flush', ('pageshow',True,False,[],['a','b'],3,1)), False)
check('dirty-pagehide-flush scenario 4', solve('dirty-pagehide-flush', ('pageshow',False,False,[],[],1,1)), False)
check('dirty-pagehide-flush scenario 5', solve('dirty-pagehide-flush', ('freeze',False,True,['socket'],['a'],2,2)), False)
check('dirty-pagehide-flush scenario 6', solve('dirty-pagehide-flush', ('resume',False,True,['timer'],['a'],2,3)), False)
check('preserved-client-queue scenario 1', solve('preserved-client-queue', ('pagehide',True,True,['timer','socket'],['a']*N,3,2)), ['a']*N)
check('preserved-client-queue scenario 2', solve('preserved-client-queue', ('pagehide',False,True,['timer'],[],1,1)), [])
check('preserved-client-queue scenario 3', solve('preserved-client-queue', ('pageshow',True,False,[],['a','b'],3,1)), ['a','b'])
check('preserved-client-queue scenario 4', solve('preserved-client-queue', ('pageshow',False,False,[],[],1,1)), [])
check('preserved-client-queue scenario 5', solve('preserved-client-queue', ('freeze',False,True,['socket'],['a'],2,2)), ['a'])
check('preserved-client-queue scenario 6', solve('preserved-client-queue', ('resume',False,True,['timer'],['a'],2,3)), ['a'])
check('resume-queue-drain scenario 1', solve('resume-queue-drain', ('pagehide',True,True,['timer','socket'],['a']*N,3,2)), [])
check('resume-queue-drain scenario 2', solve('resume-queue-drain', ('pagehide',False,True,['timer'],[],1,1)), [])
check('resume-queue-drain scenario 3', solve('resume-queue-drain', ('pageshow',True,False,[],['a','b'],3,1)), ['a','b'])
check('resume-queue-drain scenario 4', solve('resume-queue-drain', ('pageshow',False,False,[],[],1,1)), [])
check('resume-queue-drain scenario 5', solve('resume-queue-drain', ('freeze',False,True,['socket'],['a'],2,2)), [])
check('resume-queue-drain scenario 6', solve('resume-queue-drain', ('resume',False,True,['timer'],['a'],2,3)), ['a'])
check('resume-event-source scenario 1', solve('resume-event-source', ('pagehide',True,True,['timer','socket'],['a']*N,3,2)), 'ordinary')
check('resume-event-source scenario 2', solve('resume-event-source', ('pagehide',False,True,['timer'],[],1,1)), 'ordinary')
check('resume-event-source scenario 3', solve('resume-event-source', ('pageshow',True,False,[],['a','b'],3,1)), 'bfcache')
check('resume-event-source scenario 4', solve('resume-event-source', ('pageshow',False,False,[],[],1,1)), 'ordinary')
check('resume-event-source scenario 5', solve('resume-event-source', ('freeze',False,True,['socket'],['a'],2,2)), 'ordinary')
check('resume-event-source scenario 6', solve('resume-event-source', ('resume',False,True,['timer'],['a'],2,3)), 'thaw')
check('resource-disposal-on-unload scenario 1', solve('resource-disposal-on-unload', ('pagehide',True,True,['timer','socket'],['a']*N,3,2)), [])
check('resource-disposal-on-unload scenario 2', solve('resource-disposal-on-unload', ('pagehide',False,True,['timer'],[],1,1)), ['timer'])
check('resource-disposal-on-unload scenario 3', solve('resource-disposal-on-unload', ('pageshow',True,False,[],['a','b'],3,1)), [])
check('resource-disposal-on-unload scenario 4', solve('resource-disposal-on-unload', ('pageshow',False,False,[],[],1,1)), [])
check('resource-disposal-on-unload scenario 5', solve('resource-disposal-on-unload', ('freeze',False,True,['socket'],['a'],2,2)), [])
check('resource-disposal-on-unload scenario 6', solve('resource-disposal-on-unload', ('resume',False,True,['timer'],['a'],2,3)), [])
check('suspended-work-reason scenario 1', solve('suspended-work-reason', ('pagehide',True,True,['timer','socket'],['a']*N,3,2)), 'cached')
check('suspended-work-reason scenario 2', solve('suspended-work-reason', ('pagehide',False,True,['timer'],[],1,1)), None)
check('suspended-work-reason scenario 3', solve('suspended-work-reason', ('pageshow',True,False,[],['a','b'],3,1)), None)
check('suspended-work-reason scenario 4', solve('suspended-work-reason', ('pageshow',False,False,[],[],1,1)), None)
check('suspended-work-reason scenario 5', solve('suspended-work-reason', ('freeze',False,True,['socket'],['a'],2,2)), 'frozen')
check('suspended-work-reason scenario 6', solve('suspended-work-reason', ('resume',False,True,['timer'],['a'],2,3)), None)
check('revalidation-observed-version scenario 1', solve('revalidation-observed-version', ('pagehide',True,True,['timer','socket'],['a']*N,3,2)), 2)
check('revalidation-observed-version scenario 2', solve('revalidation-observed-version', ('pagehide',False,True,['timer'],[],1,1)), 1)
check('revalidation-observed-version scenario 3', solve('revalidation-observed-version', ('pageshow',True,False,[],['a','b'],3,1)), 3)
check('revalidation-observed-version scenario 4', solve('revalidation-observed-version', ('pageshow',False,False,[],[],1,1)), 1)
check('revalidation-observed-version scenario 5', solve('revalidation-observed-version', ('freeze',False,True,['socket'],['a'],2,2)), 2)
check('revalidation-observed-version scenario 6', solve('revalidation-observed-version', ('resume',False,True,['timer'],['a'],2,3)), 2)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
preserved-page-disposition scenario 1suspendsuspendPassed
preserved-page-disposition scenario 2disposedisposePassed
preserved-page-disposition scenario 3keepkeepPassed
preserved-page-disposition scenario 4keepkeepPassed
preserved-page-disposition scenario 5keepkeepPassed
preserved-page-disposition scenario 6keepkeepPassed
resume-revalidation scenario 1FalseFalsePassed
resume-revalidation scenario 2FalseFalsePassed
resume-revalidation scenario 3TrueTruePassed
resume-revalidation scenario 4FalseFalsePassed
resume-revalidation scenario 5FalseFalsePassed
resume-revalidation scenario 6TrueTruePassed
freeze-timer-shutdown scenario 1['socket']['socket']Passed
freeze-timer-shutdown scenario 2[][]Passed
freeze-timer-shutdown scenario 3[][]Passed
freeze-timer-shutdown scenario 4[][]Passed
freeze-timer-shutdown scenario 5['socket']['socket']Passed
freeze-timer-shutdown scenario 6['timer']['timer']Passed
dirty-pagehide-flush scenario 1TrueTruePassed
dirty-pagehide-flush scenario 2TrueTruePassed
dirty-pagehide-flush scenario 3FalseFalsePassed
dirty-pagehide-flush scenario 4FalseFalsePassed
dirty-pagehide-flush scenario 5FalseFalsePassed
dirty-pagehide-flush scenario 6FalseFalsePassed
preserved-client-queue scenario 1['a']['a']Passed
preserved-client-queue scenario 2[][]Passed
preserved-client-queue scenario 3['a', 'b']['a', 'b']Passed
preserved-client-queue scenario 4[][]Passed
preserved-client-queue scenario 5['a']['a']Passed
preserved-client-queue scenario 6['a']['a']Passed
resume-queue-drain scenario 1[][]Passed
resume-queue-drain scenario 2[][]Passed
resume-queue-drain scenario 3['a', 'b']['a', 'b']Passed
resume-queue-drain scenario 4[][]Passed
resume-queue-drain scenario 5[][]Passed
resume-queue-drain scenario 6['a']['a']Passed
resume-event-source scenario 1ordinaryordinaryPassed
resume-event-source scenario 2ordinaryordinaryPassed
resume-event-source scenario 3bfcachebfcachePassed
resume-event-source scenario 4ordinaryordinaryPassed
resume-event-source scenario 5ordinaryordinaryPassed
resume-event-source scenario 6thawthawPassed
resource-disposal-on-unload scenario 1[][]Passed
resource-disposal-on-unload scenario 2['timer']['timer']Passed
resource-disposal-on-unload scenario 3[][]Passed
resource-disposal-on-unload scenario 4[][]Passed
resource-disposal-on-unload scenario 5[][]Passed
resource-disposal-on-unload scenario 6[][]Passed
suspended-work-reason scenario 1cachedcachedPassed
suspended-work-reason scenario 2NoneNonePassed
suspended-work-reason scenario 3NoneNonePassed
suspended-work-reason scenario 4NoneNonePassed
suspended-work-reason scenario 5frozenfrozenPassed
suspended-work-reason scenario 6NoneNonePassed
revalidation-observed-version scenario 122Passed
revalidation-observed-version scenario 211Passed
revalidation-observed-version scenario 333Passed
revalidation-observed-version scenario 411Passed
revalidation-observed-version scenario 522Passed
revalidation-observed-version scenario 622Passed

SHA-256 / 7e024e630221a3ef5d052378af123ecbbf7e5eadb9b69492c28e19a81b3d71f2

Verification & scope

Only the explicitly specified operations and finite deterministic records are modeled; no browser or framework conformance is claimed. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.

Observations recorded using Python 3.12.14 at 2026-09-29T14:40:54.417056+00:00.

Case digest / c31a8c95f53bb9887cd18fb4cc9de96c908fa1de669a99a4f7a49a5d56fc43fb