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.
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| 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