Leakage review of the E3 code (conformal layer, selectors, E3 runner)¶
Reviewer: leakage-reviewer subagent, read-only, 16 Oct 2026, on branch phase-08-conformal-e3 (code version of the E3 runs: f38858e). A first pass on the same code was lost with a context reset; this is the second pass, and it confirmed the two issues that the first pass had raised. Dispositions are Claude Code’s proposals; the researcher decides the open items.
Verdict¶
No temporal leakage, no label-delay violation and no calibration contamination in the non-trap arms. Selectors receive only the opaque slot and label-free scores; the true labels leave the sealed slot only through the queue release and the metric code; delay is computed only in sim/queue.py; the Mondrian p-value (1 + #{s_i >= s}) / (n_c + 1) and the credibility p[pred] are correct; centroids and scalers are fitted on the current pool, which excludes hold-out and calibration rows. One design defect (finding 1) and one ADR deviation (finding 2) affect how registered secondary results are read.
Findings and dispositions¶
# |
Severity |
Finding |
Disposition |
|---|---|---|---|
1 |
major (a confound, not a leak) |
The trap arm never retrains. With reserved share 0 every released row is routed to the calibration buffer and, with |
Open, researcher’s decision. The trap cells ran as registered and are kept. Report: the A-AUT of the trap arm is not read as the cost of contamination (CLAIMS E-45, chapter 7 section 7.5); only its coverage and credibility diagnostics are read. Options: (a) an addendum v3 that lets trap rows also enter the pool, then rerun the two trap cells (one per dataset; comparable cells took about 1,200 s on LAMDA); (b) add a matched |
2 |
minor (possible major reading) |
The initial hold-out is cut by timestamp inside the window, not at a slot boundary ( |
Recorded as a deviation. ADR-0009 rule 1 (“newest 20% of rows”) was written without reconciling ADR-0004 item 8. The runs are kept; chapter 8 lists it as a threat to validity for the initial calibration counts. A fix (split at a slot boundary chosen to hold out about 20%) would change every E3 cell, so it needs an ADR and a rerun; not proposed unless the researcher wants it. |
3 |
minor |
Equal-labels coverage was thin: the table check compared per-condition means, hard-coded seeds 0 to 4, skipped share 0 and the centroid score, and overwrote the keys of the three reserved shares. |
Fixed in |
4 |
minor |
The E3 contamination, delay and spy tests are all |
Mitigated: the phase closeout runs |
5 |
minor |
Duplicate feature vectors between calibration rows and the training pool are not counted (only evaluation slot against pool is). An identical calibration and pool row scores too low and inflates p-values. |
Open, listed in chapter 8 as a threat to validity; logging the overlap of buffer and pool hashes is future hardening. |
What was checked and found sound¶
Sealed labels (selectors see OpaqueSlot, proba, cred only); delay (t+1+d and the drop after the window end only in queue.py; slot scored before its query); calibration routing in non-trap arms (origin check in the buffer, test patches the router and fails); reserved slice and selection are disjoint and sum to the budget; fit scope; Mondrian and credibility formulas.