FA-47711 / Delimited text / Open access
Ditto expansion reads the first row forever · case 01
A structured table violates the declared record or column contract.
ROOT CAUSE
The previous-row snapshot is not advanced after a data row.
VERIFIED REPAIR
Preserve the named invariant at the faulty decision: previous = row
Unsuccessful approach: Reassigning from the first row explicitly retains stale source values.
Case contract
Read semicolon rows in a schema where bare ^ copies the previous value in that column, ^^ represents literal ^, and ^! resets that column to null. A copy in the first row rejects. Exactly two columns are required; an explicit empty string replaces the previous value.
Why this case matters
Delimited interchange needs explicit framing, schema and field semantics at ingestion and emission boundaries.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
def _vary(value):
if value == '@END': return 3 + 4*N
if isinstance(value, str): return value.replace('@', 'cell' * N)
if isinstance(value, list): return [_vary(x) for x in value]
if isinstance(value, dict): return {_vary(k): _vary(v) for k,v in value.items()}
return value
N = 1
observations = []
def solve(data):
rows, previous = [], None
for line in data:
cells = line.split(';')
if len(cells) != 2: return None
row = []
for i, cell in enumerate(cells):
if cell == '^':
if previous is None: return None
value = previous[i]
elif cell == '^^': value = '^'
elif cell == '^!': value = None
else: value = cell
row.append(value)
rows.append(row)
if previous is None: previous = row
return rows
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('copy columns', solve(_vary(['@;a', '^;b', 'c;^'])), _vary([['@', 'a'], ['@', 'b'], ['c', 'b']]))
check('first copy', solve(_vary(['^;x'])), _vary(None))
check('literal marker', solve(_vary(['^^;@'])), _vary([['^', '@']]))
check('null reset', solve(_vary(['@;a', '^!;^', '^;z'])), _vary([['@', 'a'], [None, 'a'], [None, 'z']]))
check('empty replaces', solve(_vary(['@;a', ';b', '^;^'])), _vary([['@', 'a'], ['', 'b'], ['', 'b']]))
check('wrong width', solve(_vary(['@'])), _vary(None))
check('zero', solve(_vary([])), _vary([]))
check('literal prefix', solve(_vary(['^x;@'])), _vary([['^x', '@']]))
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 |
|---|---|---|---|
| copy columns | [['cell', 'a'], ['cell', 'b'], ['c', 'a']] | [['cell', 'a'], ['cell', 'b'], ['c', 'b']] | Failed |
| first copy | None | None | Passed |
| literal marker | [['^', 'cell']] | [['^', 'cell']] | Passed |
| null reset | [['cell', 'a'], [None, 'a'], ['cell', 'z']] | [['cell', 'a'], [None, 'a'], [None, 'z']] | Failed |
| empty replaces | [['cell', 'a'], ['', 'b'], ['cell', 'a']] | [['cell', 'a'], ['', 'b'], ['', 'b']] | Failed |
| wrong width | None | None | Passed |
| zero | [] | [] | Passed |
| literal prefix | [['^x', 'cell']] | [['^x', 'cell']] | Passed |
SHA-256 / c94199f29fa9434824a900c61bab46a60270b00e7841f6ff68ca9447666a8cf1
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
def _vary(value):
if value == '@END': return 3 + 4*N
if isinstance(value, str): return value.replace('@', 'cell' * N)
if isinstance(value, list): return [_vary(x) for x in value]
if isinstance(value, dict): return {_vary(k): _vary(v) for k,v in value.items()}
return value
N = 1
observations = []
def solve(data):
rows, previous = [], None
for line in data:
cells = line.split(';')
if len(cells) != 2: return None
row = []
for i, cell in enumerate(cells):
if cell == '^':
if previous is None: return None
value = previous[i]
elif cell == '^^': value = '^'
elif cell == '^!': value = None
else: value = cell
row.append(value)
rows.append(row)
previous = rows[0]
return rows
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('copy columns', solve(_vary(['@;a', '^;b', 'c;^'])), _vary([['@', 'a'], ['@', 'b'], ['c', 'b']]))
check('first copy', solve(_vary(['^;x'])), _vary(None))
check('literal marker', solve(_vary(['^^;@'])), _vary([['^', '@']]))
check('null reset', solve(_vary(['@;a', '^!;^', '^;z'])), _vary([['@', 'a'], [None, 'a'], [None, 'z']]))
check('empty replaces', solve(_vary(['@;a', ';b', '^;^'])), _vary([['@', 'a'], ['', 'b'], ['', 'b']]))
check('wrong width', solve(_vary(['@'])), _vary(None))
check('zero', solve(_vary([])), _vary([]))
check('literal prefix', solve(_vary(['^x;@'])), _vary([['^x', '@']]))
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 |
|---|---|---|---|
| copy columns | [['cell', 'a'], ['cell', 'b'], ['c', 'a']] | [['cell', 'a'], ['cell', 'b'], ['c', 'b']] | Failed |
| first copy | None | None | Passed |
| literal marker | [['^', 'cell']] | [['^', 'cell']] | Passed |
| null reset | [['cell', 'a'], [None, 'a'], ['cell', 'z']] | [['cell', 'a'], [None, 'a'], [None, 'z']] | Failed |
| empty replaces | [['cell', 'a'], ['', 'b'], ['cell', 'a']] | [['cell', 'a'], ['', 'b'], ['', 'b']] | Failed |
| wrong width | None | None | Passed |
| zero | [] | [] | Passed |
| literal prefix | [['^x', 'cell']] | [['^x', 'cell']] | Passed |
SHA-256 / 3bad05f6e9c8c9a0e0d1e133fe595744f9e89e0384dc51d21010e1d060d78fba
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
def _vary(value):
if value == '@END': return 3 + 4*N
if isinstance(value, str): return value.replace('@', 'cell' * N)
if isinstance(value, list): return [_vary(x) for x in value]
if isinstance(value, dict): return {_vary(k): _vary(v) for k,v in value.items()}
return value
N = 1
observations = []
def solve(data):
rows, previous = [], None
for line in data:
cells = line.split(';')
if len(cells) != 2: return None
row = []
for i, cell in enumerate(cells):
if cell == '^':
if previous is None: return None
value = previous[i]
elif cell == '^^': value = '^'
elif cell == '^!': value = None
else: value = cell
row.append(value)
rows.append(row)
previous = row
return rows
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('copy columns', solve(_vary(['@;a', '^;b', 'c;^'])), _vary([['@', 'a'], ['@', 'b'], ['c', 'b']]))
check('first copy', solve(_vary(['^;x'])), _vary(None))
check('literal marker', solve(_vary(['^^;@'])), _vary([['^', '@']]))
check('null reset', solve(_vary(['@;a', '^!;^', '^;z'])), _vary([['@', 'a'], [None, 'a'], [None, 'z']]))
check('empty replaces', solve(_vary(['@;a', ';b', '^;^'])), _vary([['@', 'a'], ['', 'b'], ['', 'b']]))
check('wrong width', solve(_vary(['@'])), _vary(None))
check('zero', solve(_vary([])), _vary([]))
check('literal prefix', solve(_vary(['^x;@'])), _vary([['^x', '@']]))
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 |
|---|---|---|---|
| copy columns | [['cell', 'a'], ['cell', 'b'], ['c', 'b']] | [['cell', 'a'], ['cell', 'b'], ['c', 'b']] | Passed |
| first copy | None | None | Passed |
| literal marker | [['^', 'cell']] | [['^', 'cell']] | Passed |
| null reset | [['cell', 'a'], [None, 'a'], [None, 'z']] | [['cell', 'a'], [None, 'a'], [None, 'z']] | Passed |
| empty replaces | [['cell', 'a'], ['', 'b'], ['', 'b']] | [['cell', 'a'], ['', 'b'], ['', 'b']] | Passed |
| wrong width | None | None | Passed |
| zero | [] | [] | Passed |
| literal prefix | [['^x', 'cell']] | [['^x', 'cell']] | Passed |
SHA-256 / 5bdf066eb089896c9cce3950f18f660992df873ed605f35e0d762fdffe98f609
Verification & scope
Deterministic bounded in-memory model. No claim of complete CSV or external format conformance. 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:44:44.083793+00:00.
Case digest / f18eb077a01b893afe5e44817e7557cfe7a4f610cfa64b35495b0707f5ae3283