FAILURE MAP
← Case archive

FA-24791 / Client state / Open access

Replacing generated file content revokes the blob URL still used by a reader · case 01

Replacing generated file content revokes the blob URL still used by a reader.

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

ROOT CAUSE

The faulty implementation violates Generated-file URL retirement preserves the active generation and every generation referenced by a reader; only unreferenced inactive generations are revoked.

VERIFIED REPAIR

Generated-file URL retirement preserves the active generation and every generation referenced by a reader; only unreferenced inactive generations are revoked.

Unsuccessful approach: The partial repair still violates at least one explicit regression oracle.

Case contract

Generated-file URL retirement preserves the active generation and every generation referenced by a reader; only unreferenced inactive generations are revoked.

Why this case matters

A bounded offline client-state transition with explicit lifecycle inputs.

1 / The failure

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

N = 1
observations = []
def solve(generations, active, readers):
    return [url for generation,url in generations if generation!=active]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('old generation still read', solve([(1,'old'),(2,'new')],2,{'preview':1}), [])
check('old unreferenced', solve([(1,'old'),(2,'new')],2,{}), ['old'])
check('active no reader', solve([(1,'active')],1,{}), [])
check('multiple stale generations', solve([(1,'a'),(2,'b'),(3,'c')],3,{'save':2}), ['a'])
check('empty', solve([],0,{}), [])
check('parameterized generations', solve([(i,str(i)) for i in range(N+2)],N+1,{'preview':N}), [str(i) for i in range(N)])
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
old generation still read['old'][]Failed
old unreferenced['old']['old']Passed
active no reader[][]Passed
multiple stale generations['a', 'b']['a']Failed
empty[][]Passed
parameterized generations['0', '1']['0']Failed

SHA-256 / cb0e970aa44497b6a82304cdc587ac88d327c87da07536c834f3e5a636ae9769

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(generations, active, readers):
    return [url for generation,url in generations if generation not in readers.values()]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('old generation still read', solve([(1,'old'),(2,'new')],2,{'preview':1}), [])
check('old unreferenced', solve([(1,'old'),(2,'new')],2,{}), ['old'])
check('active no reader', solve([(1,'active')],1,{}), [])
check('multiple stale generations', solve([(1,'a'),(2,'b'),(3,'c')],3,{'save':2}), ['a'])
check('empty', solve([],0,{}), [])
check('parameterized generations', solve([(i,str(i)) for i in range(N+2)],N+1,{'preview':N}), [str(i) for i in range(N)])
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
old generation still read['new'][]Failed
old unreferenced['old', 'new']['old']Failed
active no reader['active'][]Failed
multiple stale generations['a', 'c']['a']Failed
empty[][]Passed
parameterized generations['0', '2']['0']Failed

SHA-256 / b9841fc7c5a9d6076cbc8caf49e164459e8ca9d259056c5171454c3ad30c0bcd

3 / The verified repair

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

N = 1
observations = []
def solve(generations, active, readers):
    used=set(readers.values())|{active}
    return [url for generation,url in generations if generation not in used]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('old generation still read', solve([(1,'old'),(2,'new')],2,{'preview':1}), [])
check('old unreferenced', solve([(1,'old'),(2,'new')],2,{}), ['old'])
check('active no reader', solve([(1,'active')],1,{}), [])
check('multiple stale generations', solve([(1,'a'),(2,'b'),(3,'c')],3,{'save':2}), ['a'])
check('empty', solve([],0,{}), [])
check('parameterized generations', solve([(i,str(i)) for i in range(N+2)],N+1,{'preview':N}), [str(i) for i in range(N)])
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
old generation still read[][]Passed
old unreferenced['old']['old']Passed
active no reader[][]Passed
multiple stale generations['a']['a']Passed
empty[][]Passed
parameterized generations['0']['0']Passed

SHA-256 / 59a26322e17b997b6694173f932cb0eb548c451c81b83d00af5c1d4f59167ac2

Verification & scope

This models the stated application policy only; 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:41:00.699289+00:00.

Case digest / f9dee48c47a21ef0f1771b883b97a4f57be2202acaaf08dc79dbf0a37d0c3379