FA-12686 / Causal analysis data contracts / Open access
Ever-treated labeling allocates pre-initiation time to treatment · case 01
Ever-treated labeling allocates pre-initiation time to treatment.
ROOT CAUSE
Future initiation retrospectively labels earlier follow-up as exposed.
VERIFIED REPAIR
Split each unit follow-up at initiation, clamped to the observation interval.
Unsuccessful approach: Only detecting initiation inside follow-up forgets treatment already active at entry.
Case contract
Integer entry <= exit bounds half-open follow-up. start is treatment initiation or None; treatment persists. Return [unexposed duration, exposed duration].
Why this case matters
A deterministic synthetic study model isolates this data-contract defect; outputs alone establish no real-world causal identification.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(entry, exit, start):
return [exit-entry,0] if start is None else [0,exit-entry]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('initiates during', solve(N, N+10, N+4), [4,6])
check('already treated', solve(N, N+10, N-1), [0,10])
check('never treated', solve(N, N+10, None), [10,0])
check('future treatment', solve(N, N+10, N+11), [10,0])
check('at exit', solve(N, N+10, N+10), [10,0])
check('empty followup', solve(N, N, N), [0,0])
check('at entry', solve(N, N+10, N), [0,10])
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 |
|---|---|---|---|
| initiates during | [0, 10] | [4, 6] | Failed |
| already treated | [0, 10] | [0, 10] | Passed |
| never treated | [10, 0] | [10, 0] | Passed |
| future treatment | [0, 10] | [10, 0] | Failed |
| at exit | [0, 10] | [10, 0] | Failed |
| empty followup | [0, 0] | [0, 0] | Passed |
| at entry | [0, 10] | [0, 10] | Passed |
SHA-256 / 4753d014598e8a034c1ddafa784d9dc3833a2502a6389e2b8f73558617e02ec7
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(entry, exit, start):
if start is None or start < entry or start >= exit:
return [exit-entry,0]
return [start-entry,exit-start]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('initiates during', solve(N, N+10, N+4), [4,6])
check('already treated', solve(N, N+10, N-1), [0,10])
check('never treated', solve(N, N+10, None), [10,0])
check('future treatment', solve(N, N+10, N+11), [10,0])
check('at exit', solve(N, N+10, N+10), [10,0])
check('empty followup', solve(N, N, N), [0,0])
check('at entry', solve(N, N+10, N), [0,10])
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 |
|---|---|---|---|
| initiates during | [4, 6] | [4, 6] | Passed |
| already treated | [10, 0] | [0, 10] | Failed |
| never treated | [10, 0] | [10, 0] | Passed |
| future treatment | [10, 0] | [10, 0] | Passed |
| at exit | [10, 0] | [10, 0] | Passed |
| empty followup | [0, 0] | [0, 0] | Passed |
| at entry | [0, 10] | [0, 10] | Passed |
SHA-256 / 5c9ad2dd78747e7d62377beab29c0e661dcb813a1a3b8a0080db6352c701fea1
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(entry, exit, start):
cut = exit if start is None else max(entry,min(exit,start))
return [cut-entry,exit-cut]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('initiates during', solve(N, N+10, N+4), [4,6])
check('already treated', solve(N, N+10, N-1), [0,10])
check('never treated', solve(N, N+10, None), [10,0])
check('future treatment', solve(N, N+10, N+11), [10,0])
check('at exit', solve(N, N+10, N+10), [10,0])
check('empty followup', solve(N, N, N), [0,0])
check('at entry', solve(N, N+10, N), [0,10])
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 |
|---|---|---|---|
| initiates during | [4, 6] | [4, 6] | Passed |
| already treated | [0, 10] | [0, 10] | Passed |
| never treated | [10, 0] | [10, 0] | Passed |
| future treatment | [10, 0] | [10, 0] | Passed |
| at exit | [10, 0] | [10, 0] | Passed |
| empty followup | [0, 0] | [0, 0] | Passed |
| at entry | [0, 10] | [0, 10] | Passed |
SHA-256 / e569c954b2d68f86cb830f28d6fa00a3d520cf339bb3b8f25ea7724eb30d4ae3
Verification & scope
Finite, fully specified synthetic data only; identification assumptions are supplied by the fixture design, not inferred from observations. 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:59.221683+00:00.
Case digest / 6ae45043b0627169f6be425597d3b323233c0b9c0a745d365d67c0e1c66402f0