FAILURE MAP
← Case archive

FA-11581 / Filesystem semantics / Open access

Truncation rewinds an open file position · case 01

Truncation rewinds an open file position.

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

ROOT CAUSE

Changing file length is incorrectly coupled to changing the descriptor offset.

VERIFIED REPAIR

Resize contents while retaining the descriptor position even beyond new EOF.

Unsuccessful approach: Clamping the position to new EOF still changes a valid beyond-EOF offset.

Case contract

Deterministic in-memory filesystem model. Resize text to nonnegative size, filling growth with null characters, and return [new text, unchanged nonnegative offset].

Why this case matters

An offline semantic experiment for file API clients; it models only the stated operations, not a complete operating system.

1 / The failure

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

N = 1
observations = []
def solve(text, offset, size):
    return [text[:size]+'\0'*max(0,size-len(text)),0]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('shrink below current offset',solve('abcdef',N+6,2),['ab',N+6])
check('truncate to zero retains position',solve('abc',N,0),['',N])
check('growth retains position',solve('a',1,3),['a\0\0',1])
check('same size retains position',solve('abc',2,3),['abc',2])
check('position zero',solve('abc',0,1),['a',0])
check('empty growing file',solve('',N,1),['\0',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
shrink below current offset['ab', 0]['ab', 7]Failed
truncate to zero retains position['', 0]['', 1]Failed
growth retains position['a\x00\x00', 0]['a\x00\x00', 1]Failed
same size retains position['abc', 0]['abc', 2]Failed
position zero['a', 0]['a', 0]Passed
empty growing file['\x00', 0]['\x00', 1]Failed

SHA-256 / e90aaf101be6f410497802bf38597dc703b155b380a23d6b2f22524201c312c2

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(text, offset, size):
    return [text[:size]+'\0'*max(0,size-len(text)),min(offset,size)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('shrink below current offset',solve('abcdef',N+6,2),['ab',N+6])
check('truncate to zero retains position',solve('abc',N,0),['',N])
check('growth retains position',solve('a',1,3),['a\0\0',1])
check('same size retains position',solve('abc',2,3),['abc',2])
check('position zero',solve('abc',0,1),['a',0])
check('empty growing file',solve('',N,1),['\0',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
shrink below current offset['ab', 2]['ab', 7]Failed
truncate to zero retains position['', 0]['', 1]Failed
growth retains position['a\x00\x00', 1]['a\x00\x00', 1]Passed
same size retains position['abc', 2]['abc', 2]Passed
position zero['a', 0]['a', 0]Passed
empty growing file['\x00', 1]['\x00', 1]Passed

SHA-256 / 154b338e6572d53551defab5fa11e949a0f53e65fae398df96bcc8cab5f45de7

3 / The verified repair

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

N = 1
observations = []
def solve(text, offset, size):
    return [text[:size]+'\0'*max(0,size-len(text)),offset]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('shrink below current offset',solve('abcdef',N+6,2),['ab',N+6])
check('truncate to zero retains position',solve('abc',N,0),['',N])
check('growth retains position',solve('a',1,3),['a\0\0',1])
check('same size retains position',solve('abc',2,3),['abc',2])
check('position zero',solve('abc',0,1),['a',0])
check('empty growing file',solve('',N,1),['\0',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
shrink below current offset['ab', 7]['ab', 7]Passed
truncate to zero retains position['', 1]['', 1]Passed
growth retains position['a\x00\x00', 1]['a\x00\x00', 1]Passed
same size retains position['abc', 2]['abc', 2]Passed
position zero['a', 0]['a', 0]Passed
empty growing file['\x00', 1]['\x00', 1]Passed

SHA-256 / d23109b2abc7dfffe357c30cdea3a6239a078d32ed22019e0603a6550ff06fb9

Verification & scope

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

Case digest / 2401341bb79e1fd9a6e1d722e4ad862825b90d6831966267bc10c7d87ecbf46a