FAILURE MAP
← Case archive

FA-24141 / Client state / Open access

Page freeze and resume lifecycle: Revalidation observed version · case 01

Revalidation observed version.

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

ROOT CAUSE

The revalidation-observed-version client decision evaluates `revision` instead of `revision if event in ('resume','pageshow') else observed`.

VERIFIED REPAIR

Apply the modeled revalidation-observed-version rule: `revision if event in ('resume','pageshow') else observed`.

Unsuccessful approach: The partial repair `observed` 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 revalidation-observed-version 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' 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
    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 132Failed
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 / 53426563ffac4b65396615700d30ee899789c4f186dc67be26c0a70e543c9e12

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 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 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 313Failed
revalidation-observed-version scenario 411Passed
revalidation-observed-version scenario 522Passed
revalidation-observed-version scenario 632Failed

SHA-256 / 4897b6c88ebb32b79fc49ebd4fe4746d1b104b1c5bbef1c43c043be1510658d0

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

Case digest / 87c139ae41aed576b66c3680c70d68f70b5782484fcc0c8c6cfc481aae5b133b