FA-44896 / Data systems / Open access
Pivot drops null fact values inside a cell · case 01
Pivot drops null fact values inside a cell.
ROOT CAUSE
categorical-pivot-lists: Pivot drops null fact values inside a cell.
VERIFIED REPAIR
Preserve the stated physical representation and operation order: Pivot [row-id,category,value] into [row-id,list-for-category...] using the caller category order. Each cell is an ordered bag list. Unknown categories do not populate cells but retain their row identity; absent cells are empty lists and null values remain elements.
Unsuccessful approach: Zero imputation changes null-valued facts.
Case contract
Pivot [row-id,category,value] into [row-id,list-for-category...] using the caller category order. Each cell is an ordered bag list. Unknown categories do not populate cells but retain their row identity; absent cells are empty lists and null values remain elements.
Why this case matters
A bounded deterministic data engine model makes representation and changelog faults reproducible.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(d):
try:
rows,categories=d
ids=list(dict.fromkeys(row[0] for row in rows))
out=[]
for ident in ids:
record=[ident]
for category in categories:
cell=[value for i,c,value in rows if i==ident and c==category]
record.append([v for v in cell if v is not None])
out.append(record)
return out
except (IndexError, KeyError, ValueError, StopIteration) as exc:
return {"representation_error": type(exc).__name__}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
if N == 1:
check('column order', solve([[[1, 'a', 1], [1, 'b', 2]], ['b', 'a']]), [[1, [2], [1]]])
check('unknown-only row', solve([[[1, 'z', 1]], ['a']]), [[1, []]])
check('two row groups', solve([[[1, 'a', 1], [2, 'a', 2]], ['a']]), [[1, [1]], [2, [2]]])
check('null fact', solve([[[1, 'a', None]], ['a']]), [[1, [None]]])
check('duplicate fact', solve([[[1, 'a', 1], [1, 'a', 1]], ['a']]), [[1, [1, 1]]])
check('no categories', solve([[[1, 'a', 1]], []]), [[1]])
check('no facts', solve([[], ['a']]), [])
elif N == 2:
check('column order', solve([[[1, 'a', 2], [1, 'b', 3]], ['b', 'a']]), [[1, [3], [2]]])
check('unknown-only row', solve([[[1, 'z', 2]], ['a']]), [[1, []]])
check('two row groups', solve([[[1, 'a', 2], [2, 'a', 3]], ['a']]), [[1, [2]], [2, [3]]])
check('null fact', solve([[[1, 'a', None]], ['a']]), [[1, [None]]])
check('duplicate fact', solve([[[1, 'a', 2], [1, 'a', 2]], ['a']]), [[1, [2, 2]]])
check('no categories', solve([[[1, 'a', 2]], []]), [[1]])
check('no facts', solve([[], ['a']]), [])
elif N == 3:
check('column order', solve([[[1, 'a', 3], [1, 'b', 4]], ['b', 'a']]), [[1, [4], [3]]])
check('unknown-only row', solve([[[1, 'z', 3]], ['a']]), [[1, []]])
check('two row groups', solve([[[1, 'a', 3], [2, 'a', 4]], ['a']]), [[1, [3]], [2, [4]]])
check('null fact', solve([[[1, 'a', None]], ['a']]), [[1, [None]]])
check('duplicate fact', solve([[[1, 'a', 3], [1, 'a', 3]], ['a']]), [[1, [3, 3]]])
check('no categories', solve([[[1, 'a', 3]], []]), [[1]])
check('no facts', solve([[], ['a']]), [])
elif N == 4:
check('column order', solve([[[1, 'a', 4], [1, 'b', 5]], ['b', 'a']]), [[1, [5], [4]]])
check('unknown-only row', solve([[[1, 'z', 4]], ['a']]), [[1, []]])
check('two row groups', solve([[[1, 'a', 4], [2, 'a', 5]], ['a']]), [[1, [4]], [2, [5]]])
check('null fact', solve([[[1, 'a', None]], ['a']]), [[1, [None]]])
check('duplicate fact', solve([[[1, 'a', 4], [1, 'a', 4]], ['a']]), [[1, [4, 4]]])
check('no categories', solve([[[1, 'a', 4]], []]), [[1]])
check('no facts', solve([[], ['a']]), [])
elif N == 5:
check('column order', solve([[[1, 'a', 5], [1, 'b', 6]], ['b', 'a']]), [[1, [6], [5]]])
check('unknown-only row', solve([[[1, 'z', 5]], ['a']]), [[1, []]])
check('two row groups', solve([[[1, 'a', 5], [2, 'a', 6]], ['a']]), [[1, [5]], [2, [6]]])
check('null fact', solve([[[1, 'a', None]], ['a']]), [[1, [None]]])
check('duplicate fact', solve([[[1, 'a', 5], [1, 'a', 5]], ['a']]), [[1, [5, 5]]])
check('no categories', solve([[[1, 'a', 5]], []]), [[1]])
check('no facts', solve([[], ['a']]), [])
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 |
|---|---|---|---|
| column order | [[1, [2], [1]]] | [[1, [2], [1]]] | Passed |
| unknown-only row | [[1, []]] | [[1, []]] | Passed |
| two row groups | [[1, [1]], [2, [2]]] | [[1, [1]], [2, [2]]] | Passed |
| null fact | [[1, []]] | [[1, [None]]] | Failed |
| duplicate fact | [[1, [1, 1]]] | [[1, [1, 1]]] | Passed |
| no categories | [[1]] | [[1]] | Passed |
| no facts | [] | [] | Passed |
SHA-256 / 2b40e693131466ce716cc3c362c3658b3edd4bb8b81232be1127e90af8011fb6
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(d):
try:
rows,categories=d
ids=list(dict.fromkeys(row[0] for row in rows))
out=[]
for ident in ids:
record=[ident]
for category in categories:
cell=[value for i,c,value in rows if i==ident and c==category]
record.append([0 if v is None else v for v in cell])
out.append(record)
return out
except (IndexError, KeyError, ValueError, StopIteration) as exc:
return {"representation_error": type(exc).__name__}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
if N == 1:
check('column order', solve([[[1, 'a', 1], [1, 'b', 2]], ['b', 'a']]), [[1, [2], [1]]])
check('unknown-only row', solve([[[1, 'z', 1]], ['a']]), [[1, []]])
check('two row groups', solve([[[1, 'a', 1], [2, 'a', 2]], ['a']]), [[1, [1]], [2, [2]]])
check('null fact', solve([[[1, 'a', None]], ['a']]), [[1, [None]]])
check('duplicate fact', solve([[[1, 'a', 1], [1, 'a', 1]], ['a']]), [[1, [1, 1]]])
check('no categories', solve([[[1, 'a', 1]], []]), [[1]])
check('no facts', solve([[], ['a']]), [])
elif N == 2:
check('column order', solve([[[1, 'a', 2], [1, 'b', 3]], ['b', 'a']]), [[1, [3], [2]]])
check('unknown-only row', solve([[[1, 'z', 2]], ['a']]), [[1, []]])
check('two row groups', solve([[[1, 'a', 2], [2, 'a', 3]], ['a']]), [[1, [2]], [2, [3]]])
check('null fact', solve([[[1, 'a', None]], ['a']]), [[1, [None]]])
check('duplicate fact', solve([[[1, 'a', 2], [1, 'a', 2]], ['a']]), [[1, [2, 2]]])
check('no categories', solve([[[1, 'a', 2]], []]), [[1]])
check('no facts', solve([[], ['a']]), [])
elif N == 3:
check('column order', solve([[[1, 'a', 3], [1, 'b', 4]], ['b', 'a']]), [[1, [4], [3]]])
check('unknown-only row', solve([[[1, 'z', 3]], ['a']]), [[1, []]])
check('two row groups', solve([[[1, 'a', 3], [2, 'a', 4]], ['a']]), [[1, [3]], [2, [4]]])
check('null fact', solve([[[1, 'a', None]], ['a']]), [[1, [None]]])
check('duplicate fact', solve([[[1, 'a', 3], [1, 'a', 3]], ['a']]), [[1, [3, 3]]])
check('no categories', solve([[[1, 'a', 3]], []]), [[1]])
check('no facts', solve([[], ['a']]), [])
elif N == 4:
check('column order', solve([[[1, 'a', 4], [1, 'b', 5]], ['b', 'a']]), [[1, [5], [4]]])
check('unknown-only row', solve([[[1, 'z', 4]], ['a']]), [[1, []]])
check('two row groups', solve([[[1, 'a', 4], [2, 'a', 5]], ['a']]), [[1, [4]], [2, [5]]])
check('null fact', solve([[[1, 'a', None]], ['a']]), [[1, [None]]])
check('duplicate fact', solve([[[1, 'a', 4], [1, 'a', 4]], ['a']]), [[1, [4, 4]]])
check('no categories', solve([[[1, 'a', 4]], []]), [[1]])
check('no facts', solve([[], ['a']]), [])
elif N == 5:
check('column order', solve([[[1, 'a', 5], [1, 'b', 6]], ['b', 'a']]), [[1, [6], [5]]])
check('unknown-only row', solve([[[1, 'z', 5]], ['a']]), [[1, []]])
check('two row groups', solve([[[1, 'a', 5], [2, 'a', 6]], ['a']]), [[1, [5]], [2, [6]]])
check('null fact', solve([[[1, 'a', None]], ['a']]), [[1, [None]]])
check('duplicate fact', solve([[[1, 'a', 5], [1, 'a', 5]], ['a']]), [[1, [5, 5]]])
check('no categories', solve([[[1, 'a', 5]], []]), [[1]])
check('no facts', solve([[], ['a']]), [])
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 |
|---|---|---|---|
| column order | [[1, [2], [1]]] | [[1, [2], [1]]] | Passed |
| unknown-only row | [[1, []]] | [[1, []]] | Passed |
| two row groups | [[1, [1]], [2, [2]]] | [[1, [1]], [2, [2]]] | Passed |
| null fact | [[1, [0]]] | [[1, [None]]] | Failed |
| duplicate fact | [[1, [1, 1]]] | [[1, [1, 1]]] | Passed |
| no categories | [[1]] | [[1]] | Passed |
| no facts | [] | [] | Passed |
SHA-256 / bf561b0aed9229505b660adadd8b20eec84db57b631e969263b6a3488310168d
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(d):
try:
rows,categories=d
ids=list(dict.fromkeys(row[0] for row in rows))
out=[]
for ident in ids:
record=[ident]
for category in categories:
cell=[value for i,c,value in rows if i==ident and c==category]
record.append(cell)
out.append(record)
return out
except (IndexError, KeyError, ValueError, StopIteration) as exc:
return {"representation_error": type(exc).__name__}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
if N == 1:
check('column order', solve([[[1, 'a', 1], [1, 'b', 2]], ['b', 'a']]), [[1, [2], [1]]])
check('unknown-only row', solve([[[1, 'z', 1]], ['a']]), [[1, []]])
check('two row groups', solve([[[1, 'a', 1], [2, 'a', 2]], ['a']]), [[1, [1]], [2, [2]]])
check('null fact', solve([[[1, 'a', None]], ['a']]), [[1, [None]]])
check('duplicate fact', solve([[[1, 'a', 1], [1, 'a', 1]], ['a']]), [[1, [1, 1]]])
check('no categories', solve([[[1, 'a', 1]], []]), [[1]])
check('no facts', solve([[], ['a']]), [])
elif N == 2:
check('column order', solve([[[1, 'a', 2], [1, 'b', 3]], ['b', 'a']]), [[1, [3], [2]]])
check('unknown-only row', solve([[[1, 'z', 2]], ['a']]), [[1, []]])
check('two row groups', solve([[[1, 'a', 2], [2, 'a', 3]], ['a']]), [[1, [2]], [2, [3]]])
check('null fact', solve([[[1, 'a', None]], ['a']]), [[1, [None]]])
check('duplicate fact', solve([[[1, 'a', 2], [1, 'a', 2]], ['a']]), [[1, [2, 2]]])
check('no categories', solve([[[1, 'a', 2]], []]), [[1]])
check('no facts', solve([[], ['a']]), [])
elif N == 3:
check('column order', solve([[[1, 'a', 3], [1, 'b', 4]], ['b', 'a']]), [[1, [4], [3]]])
check('unknown-only row', solve([[[1, 'z', 3]], ['a']]), [[1, []]])
check('two row groups', solve([[[1, 'a', 3], [2, 'a', 4]], ['a']]), [[1, [3]], [2, [4]]])
check('null fact', solve([[[1, 'a', None]], ['a']]), [[1, [None]]])
check('duplicate fact', solve([[[1, 'a', 3], [1, 'a', 3]], ['a']]), [[1, [3, 3]]])
check('no categories', solve([[[1, 'a', 3]], []]), [[1]])
check('no facts', solve([[], ['a']]), [])
elif N == 4:
check('column order', solve([[[1, 'a', 4], [1, 'b', 5]], ['b', 'a']]), [[1, [5], [4]]])
check('unknown-only row', solve([[[1, 'z', 4]], ['a']]), [[1, []]])
check('two row groups', solve([[[1, 'a', 4], [2, 'a', 5]], ['a']]), [[1, [4]], [2, [5]]])
check('null fact', solve([[[1, 'a', None]], ['a']]), [[1, [None]]])
check('duplicate fact', solve([[[1, 'a', 4], [1, 'a', 4]], ['a']]), [[1, [4, 4]]])
check('no categories', solve([[[1, 'a', 4]], []]), [[1]])
check('no facts', solve([[], ['a']]), [])
elif N == 5:
check('column order', solve([[[1, 'a', 5], [1, 'b', 6]], ['b', 'a']]), [[1, [6], [5]]])
check('unknown-only row', solve([[[1, 'z', 5]], ['a']]), [[1, []]])
check('two row groups', solve([[[1, 'a', 5], [2, 'a', 6]], ['a']]), [[1, [5]], [2, [6]]])
check('null fact', solve([[[1, 'a', None]], ['a']]), [[1, [None]]])
check('duplicate fact', solve([[[1, 'a', 5], [1, 'a', 5]], ['a']]), [[1, [5, 5]]])
check('no categories', solve([[[1, 'a', 5]], []]), [[1]])
check('no facts', solve([[], ['a']]), [])
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 |
|---|---|---|---|
| column order | [[1, [2], [1]]] | [[1, [2], [1]]] | Passed |
| unknown-only row | [[1, []]] | [[1, []]] | Passed |
| two row groups | [[1, [1]], [2, [2]]] | [[1, [1]], [2, [2]]] | Passed |
| null fact | [[1, [None]]] | [[1, [None]]] | Passed |
| duplicate fact | [[1, [1, 1]]] | [[1, [1, 1]]] | Passed |
| no categories | [[1]] | [[1]] | Passed |
| no facts | [] | [] | Passed |
SHA-256 / 2321267ab165b73e3dfda40a3391dbb8b81872432dbbb2c0dec96f9a9147cab9
Verification & scope
Offline stipulated semantics over valid small inputs; no performance, concurrency, or production-engine conformance claim. 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:16.654275+00:00.
Case digest / b3fc8e39102aa8d99ac1f0843666ca55d59fb95e15a68724ac1e90741a2b9fe9