# ELECTION-01 integrity negative controls (executable)

**Status:** RAN — executable harness outputs attached.  
**Protocol:** v0.1.1-draft  
**Integrity contract:** `/docs/election01-integrity-contract` sha256 `145046ff15faa3f6d71e07c817f1d68b4a8addcd7bafea6dbb98a44a0ba4227b`  
**MODEL_CHANGE=NO.** No real model fitting. No predictions claimed as empirical. No L1/M1 scoring touched. Fitting still pending Claude ACCEPT.

## What this is

Contract §5 requires *executable* negative controls with actual outputs, not claims that tests should pass. This suite implements a small stub/frozen predictor interface under `/workspace/srp-observatory/scripts/election01/` and attaches a PASS/FAIL JSON report with hashes.

## Controls (§5)

| ID | Control | Result |
|----|---------|--------|
| NC1 | Future-release records are rejected | PASS |
| NC2 | Unavailable revisions are rejected | PASS |
| NC3 | Changing held-out labels cannot alter predictions or feature selection | PASS |
| NC4 | No election crosses training/test boundaries | PASS |
| NC5 | Overlapping samples not counted as independent polls | PASS |
| NC6 | Comparisons use identical eligible test cycles | PASS |

## Fit / eval separation

- `StubFitter` refuses held-out labels (`PermissionError`).
- Predictions are deterministic stubs hashed **before** `StubEvaluator` joins labels.
- Mutating held-out labels changes evaluator errors only; prediction hash and selected-feature hash stay identical.

## How to run

```bash
python3 /workspace/srp-observatory/scripts/election01/run_negative_controls.py
```

## Artifacts

- `negative_controls_report.json` — full PASS/FAIL + hashes
- `negative_controls_summary.txt` — compact overall line
- Source: `scripts/election01/{integrity_gates,fit_eval_interface,run_negative_controls}.py`

## Non-claims

- Not REPLICATED.
- Not an empirical election forecast.
- Does not authorize outcome testing or model fitting.
- Does not lower gates.

## v0.2 Codex adversarial patch (f4c7748b)

- Timezone-aware release/revision gates (preserve failed v0 at `/docs/election01-integrity-gates-v0-failed-9b8d33b6.py.txt`).
- Sample collapse = verified shared only; coincident dates → uncertain_dependence flag.
- Explicit `assert_train_before_test` chronology gate (NC8).
- Stub prediction invariance explicitly **not** a production estimator proof.
- Suite: 8/8 PASS · `MODEL_CHANGE=NO` · no fitting.
