DashboardThree-Axis ProbesCrypto Shared Data PoolThe S1 pin-invariant spec (GCM + O-information)

finding · findings/evolution/shared_data/S1_GCM_OINFO_PIN_SPEC.md

The S1 pin-invariant spec: a "tamper test" for the research code's decision-making

A detailed blueprint for a self-test that deliberately breaks the analysis code in hundreds of tiny ways, then checks that each break gets caught. If even one break that matters slips through unnoticed, the whole gate is rejected. It exists to guarantee the code's most important yes/no decisions are genuinely protected.

In plain English. Imagine you've installed a burglar alarm. Before trusting it, you'd want to walk through every door and window and confirm the alarm goes off each time — and if any entry point is silent, you don't trust the alarm at all. This spec is exactly that walkthrough, but for a piece of statistics code. It introduces hundreds of small "burglars" (one-character bugs) into the code and demands that the test suite trip on at least 80% of them — and on 100% of the ones near a real decision line. A single silent door anywhere near a decision = the alarm fails inspection.

What is this?

This document is the single source of truth (the one authoritative blueprint) for building two small programs that guard a research script called ivs_loop_s3b.py:

The whole thing is called S1 — it's the first hard quality gate in a research pipeline. It copies, line-for-line, a proven earlier gate (the cascade_pins.py / mutation_oracle.py pair, internally "#514"), so the pattern is battle-tested rather than invented from scratch.

The code it guards makes statistical decisions about whether crypto-market features are genuinely related or just coincidentally correlated. The two headline techniques it protects:

Why it matters

Earlier in this research program, a serious bug — a data leakage (where information from the "future" or the test set sneaks into training, producing fake-good results) — was caught only at the very last minute, at pull-request time. A whole walk-forward analysis looked brilliant (a near-perfect 0.926 score, passing 333 of 333 checks) precisely because it was secretly cheating.

The lesson baked into this spec: don't trust a measurement just because it looks good — try to break the thing that produced it first. A pin suite that doesn't actually trip on broken code gives false confidence, which is worse than no test at all. So this spec is unusually paranoid: every claim about what the tests catch was empirically verified on real frozen market data, and several "obvious" tests were thrown out because they would have wrongly flagged correct code or quietly missed real bugs.

How it works

The frozen real-data fixture

The tests don't touch the live database or the network. Everything runs against a frozen fixture — a snapshot of real crypto data saved once to disk so every run is identical and reproducible. The primary snapshot is Bitcoin at a 100-dbps bar threshold (dbps = decimal basis points, the bar-size setting; 100 dbps = 0.1%), holding roughly 8,000 rows and 17 columns of real market features. A second Bitcoin snapshot (500 dbps, ~7,624 rows) is kept as a cross-check.

The build refuses to run on weak data (fail-closed)

Before any testing, the oracle checks that the snapshot is rich enough to make the tests meaningful — and if it isn't, it refuses outright rather than quietly passing. "Fail-closed" is the recurring safety principle here: when in doubt, stop and reject, never wave it through. The snapshot must contain specific named columns (e.g. the arithmetic identity volume = buy_volume + sell_volume, plus a cluster of known-unrelated features), at least 5,000 rows, and at least 12 columns.

The 80% / zero-boundary pass rule

The core verdict is simple and strict. Over all the meaningful mutants (the genuinely-broken versions, excluding ones that are mathematically identical to the original):

The "is it real, or just identical?" check (the signature)

Some code rewrites change nothing observable — e.g. a setting like "max 60 iterations" nudged to 59 — and shouldn't be counted against the pins. A signature function takes a behavioural fingerprint of the code; if a surviving mutant has the same fingerprint as the original, it's declared EQUIVALENT and excluded from the scoring. The spec is careful that this fingerprint is a superset of what the pins look at, so a genuine behaviour change can never disguise itself as "equivalent" and escape.

Built-in proof the test has teeth

Before scoring anything real, the oracle runs two sanity checks on itself:

Key numbers

≥ 80%
Mutants the pins must catch ("kill rate")
0
Surviving decision-boundary mutants allowed
~8,000
Rows in the frozen BTC@100 fixture
~17
Real market-feature columns
11
Decision functions under guard
≥ 12
Columns required, or build rejects
≥ 5,000
Rows required, or build rejects
5
Fail-closed safety preconditions

Threshold values the spec defends (and what they mean)

ConstantValuePlain meaning
ALPHA0.05The significance cutoff — a relationship counts as "real" only if its p-value is below this.
TAU0.30Correlation gate — feature pairs more correlated than this are too similar to both keep.
XI_FLAG0.80A second redundancy gate (the "ξ" / xi sieve) catching duplicates that ordinary correlation misses.
OMEGA_STRICT0.70The synergy floor — a triplet counts as synergistic only if its Ω is below −0.70.
COND_CAP(cap)Max number of "control" variables used when testing a relationship; here the conditioning list comes out to 10 items.
TRAIN / TEST / PURGE3000 / 1500 / 200The walk-forward windows: 3,000 training rows, 1,500 test rows, and a 200-row purge gap in between to stop the future leaking into the past. (Walk-forward = train on the past, test on the next unseen slice, repeat.)

The 11 decision functions under guard

FunctionWhat it decides
bh_rejectWhich p-values pass the multiple-testing correction (Benjamini–Hochberg FDR). The literal yes/no line.
foldsThe walk-forward window geometry — the train/test/purge boundaries that prevent leakage.
_hac_seA noise-robust error bar (Newey–West HAC standard error) that feeds the GCM test.
_resid + gcm_pStrips out everything explainable, then computes the GCM p-value for "are these still related?"
copnorm + oinfo_gcComputes O-information (the Ω synergy/redundancy number).
select_trainThe orthogonality gate — picks feature pairs that are genuinely different from each other.
cond_idxBuilds the list of control variables for each conditional test.
gcm_flagsetThe final list of relationships that survive multiple-testing correction.
syn_setThe final list of synergistic triplets (the Ω verdict).

The rules / what must hold

The verdict is PASS only if all of these are true at once — otherwise REJECT:

Six hard hygiene rules (lessons paid for in bugs)

RuleWhat it forbids / requires, and why
H1 — no self-referenceEvery threshold test compares against a hard-coded number (0.30, 0.70, 0.05…), never the code's own variable. Otherwise the test would move along with the bug it's meant to catch and protect nothing.
H2 — independent referenceThe O-information check is re-derived from scratch using a separate library, never by calling the very function it's testing.
H3 — banned clauseA tempting "correlation > 0.99" check is forbidden: the underlying model is intentionally lossy, so correct code only reaches ~0.97–0.99 and the check would wrongly fail honest code.
H4 — self-identity anchorThe "definitely related" test case compares a column against an exact copy of itself (guaranteed p≈0). An earlier buy/sell-volume anchor was empirically only p≈0.46 — not significant — so it was replaced.
H5 — fail-closed witnessesIf a boundary test case can't be constructed from real data, the build stops and rejects, rather than silently skipping the test.
H6 — explicit equivalent setOnly a short, documented list of rewrites may be excused as "equivalent". Everything else that survives counts as a real survivor.

Hard-won facts that shaped the design

These came from actually measuring the real data, and each one killed a naïve test idea:

One open escalation. If no real-data triplet can be placed within 0.01 of the −0.70 synergy floor, S1 does not quietly pass — it rejects and flags OMEGA_STRICT as a calibration defect to be fixed in the next stage (S2), so the synergy test regains a valid positive control. The threshold is never silently accepted as "equivalent".

The verdict the oracle writes

At the end, the oracle emits a small machine-readable report: which fixture cell was used, how many mutants were generated, how many were equivalent vs killed vs survived, the final kill rate, whether the clean and lethal self-checks passed, the list of any boundary survivors, and the single PASS / REJECT verdict. The rule, stated once: kill rate ≥ 0.80 AND zero decision-boundary survivors AND all preconditions pass.

Bottom line. This spec turns "we hope the code is correct" into "we proved the tests catch real bugs": it deliberately breaks the analysis code thousands of ways and only lets the research proceed if at least 80% of the breaks are caught and every break near a real decision is caught — a hard, fail-closed barrier against the kind of silent data-leakage that once produced a fake-perfect result.