_Two files, one idea. This doc explains what the tool is, why it exists, when to
reach for it, exactly how to call it, and — just as important — what it does
not do so nobody oversells it._
---
The leak-test answers a single, sharp question: **"Does signal Y carry
information that a candidate set X cannot reconstruct?"** If X can rebuild Y, Y is
_redundant / derived_ (safe to merge, or to compute from X). If a chunk of Y
survives every attempt to rebuild it, that chunk is a real hidden channel and
Y must stay separate. It measures this as a residual — the fraction of Y left
unexplained — using both a linear fit and a non-linear held-out model, so a
non-linear identity isn't mistaken for a hidden channel. That's the whole
instrument. Everything else is hardening so the number can be trusted.
---
leak_test_hardened.py | The canonical v3 instrument. Fixed thresholds, hand-driven. Battle-tested across 24 KAI modules. | You want the exact, reproducible number for a specific module decision. This stays the reference. |leak_universal.py | The adaptive sibling. Profiles the data, configures itself, runs the residual test several ways, hands the leftover to SRHT, logs a readable chain. Plug anything in. | You want to point it at an unknown signal and have it figure out the right settings and surface structure a single number would miss. |leak_universal imports leak_test_hardened for its non-linear engine, so
keep both files in the same folder. If leak_test_hardened (or scikit-learn) is
missing, leak_universal still runs — it drops to linear-only and says so in
the output. It never pretends it checked the non-linear channel when it didn't.
---
raphe → #11 serotonin got decided: 0.01% residual = duplicate.)
spotting a value that's just an EMA/lag of another (e.g. dopamine tonic).
consolidation_pressurebeing a renamed phase (0.4% non-linear residual).
proved BNST threat_context is genuinely tonic, not a lagged amygdala
(103% residual vs the amygdala) — so the phasic/tonic split is real, not a story.
(leak_universal only). It found the hidden sine in a test signal that a plain
R² reported only as "unexplained."
shows _where_ in an ordered candidate list the residual collapses.
Do not use it to prove two things are identical (it can only ever say
"redundant given THESE inputs"), and do not trust a merge verdict that rests
on hand-built synthetic data — the tool flags that and asks for real telemetry.
---
candidates you supplied_. Add a different candidate set, get a different answer.
measures whether leftover energy concentrates (structured) or spreads
(noise). "Emergence" here has a precise definition, not a mystical one.
you hand-built proves the _code path_, not the _live system_. Re-run on
kai.exe --probe telemetry before executing any irreversible merge.
which _structure_ is visible in which _framing_.
---
leak_universal.analyze() runs)
Y, X ─► 0 PROFILE measure variance, autocorrelation, saturation, trend
1 AUTO-CONFIG derive settings from the profile (add lags? trust ratio?)
2 MULTI-METHOD residual under levels / changes / cumulative / log
│ └► CARRY-OVER = the residual + stats (the "next equation's data")
3 GATE ◄── is the first pass already complete, or is there a carry-over
│ worth building the SRHT equation for?
│ ├─ SKIP → first answer stands (known-good / clean / low-var)
│ └─ RUN → hand the carry-over forward ↓
3b SRHT (only if the gate said RUN) is the leftover pattern or noise?
4 VERDICT one call, plus follow-up questions it spawns
└► CHAIN every stage logged as question → answer → next question
Stage 3b's input is stage 2's output (the residual vector). That is the
"the first answer builds the next equation" behaviour, made literal: the
unexplained part of the fit becomes the thing SRHT analyses — **but only when the
gate decides a carry-over exists.**
The pipeline is a cascade with an early exit, not a fixed straight line. The
first-pass answer (profile + multi-method residual) can be complete on its own.
The SRHT GATE decides whether to build the next equation at all:
known-good (known_good=True — the caller asserts it's already verified), or
the signal is low-var/saturated (its residual can't be embedded — judge by
RMSE). For a known-good thing the pipeline never builds the SRHT stage.
O(n log n) cheap, and (once calibrated, below) it does not false-positive on
noise, so running it costs almost nothing and its 3-tier reading decides whether
a carry-over really existed.
first_pass_complete is then true only when there is genuinely no carry-over: the
gate skipped for an honest reason, or SRHT ran and read the residual as
noise. It is *not* set just because levels looked redundant.
> Why not short-circuit on "redundant in levels"? An earlier version did, on the
> reasoning that if the candidates explain the signal the residual is a scale
> artifact. A calibrated adversarial sweep disproved that. With
> y = 2x + A·sin(t/7) (the sine an independent hidden channel), at A = 0.12 the
> levels residual is 0.4% — "redundant" — yet the residual is a real sine that
> SRHT catches as STRUCTURED. Even non-flipping cases at A = 0.05 (0.2% residual)
> hide it. A small residual can be a real deterministic signal, so the tool no
> longer skips there. This is the project's "verify the verification" rule applied
> to the tool itself.
The result always exposes first_pass_complete (bool) and carry_over (the
residual + stats). The chain records the gate's decision and _why_. Pass
known_good=True to force the short-circuit for things you already trust.
---
from leak_universal import analyze rep = analyze(Y, X, name="my_signal") print(rep["verdict"]) # ORTHOGONAL / REDUNDANT / BORDERLINE / INCONCLUSIVE print(rep["chain"].text()) # the readable question→answer chain
Y : 1-D array — the signal you want to explain.X : 1-D or 2-D array — the candidate explainer(s). Columns = candidates.verdict, profile, config, multi_method, srht, followups, and chain (a Chain object; call .text()).
rep = analyze(Y, X, name="my_signal", plot_path="my_signal.png") # writes a 2-panel PNG: residual-by-method bars + SRHT residual spectrum
from leak_universal import sequential_scan
steps = sequential_scan(Y, [c1, c2, c3, c4], names=["c1","c2","c3","c4"])
for s in steps:
print(s["added"], s["nonlinear"], s["verdict"])
# adds candidates ONE AT A TIME, in order; shows the residual after each
rep = analyze(Y, X, name="s", override={"use_lags": True, "merge_below": 8})
rep = analyze(Y, X, name="already_verified", known_good=True) print(rep["first_pass_complete"]) # True — SRHT never built print(rep["carry_over"]) # still exposed, in case a later stage wants it
from leak_test_hardened import leak, verdict
r = leak(Y, X) # {linear, nonlinear, rmse, var, flag}
print(verdict(r))
---
These live at the top of leak_universal.py. The tool chooses which to apply
from the data profile; it cannot violate them. This is what "adaptive but bound to
rules" means.
LOW_VAR | 1e-3 | Below this variance, the %-ratio is untrustworthy → judge by RMSE. |AR_STATEFUL | 0.60 | Lag-1 autocorrelation above this ⇒ signal is stateful ⇒ auto-add lags. |SAT_FRAC | 0.50 | Fraction pinned at an extreme above this ⇒ saturated ⇒ distrust ratio. |MERGE_BELOW | 6.0% | Non-linear residual below this ⇒ REDUNDANT / derived. |SEPARATE_ABOVE | 15.0% | Above this ⇒ ORTHOGONAL / keep separate. |EMERGE_STRUCT_PR | 0.22 | SRHT: pr_norm below this (with high conc) ⇒ structured. |EMERGE_STRUCT_CONC | 0.88 | Top-third energy share required for structured. |EMERGE_NOISE_CONC | 0.70 | conc below this ⇒ noise (guard, below lowest real conc). |EMERGE_NOISE_PR | 0.55 | pr_norm above this ⇒ noise (primary noise axis). |LAG_SET | (1,5,25) | Which lags get stacked for stateful signals. |Auto-config rules (derived, not guessed):
Every choice it makes is written into the chain under PROFILE + AUTO-CONFIG, so
you can always see _why_ it configured itself the way it did.
---
SRHT = Subsampled Randomized Hadamard Transform. It's the "old maths" the tool
leans on: Hadamard matrices (1893) and Walsh functions (1923), made into a fast
random projection by Ailon & Chazelle (2006). Mechanically:
P = sqrt(n/k) · S · H · D · M D = random ±1 sign flips (spreads energy so no sample dominates) H = normalised Hadamard (applied in O(n log n) via Fast Walsh–Hadamard) S = subsample k of n rows (the compression)
It projects a big matrix into a small one while preserving the geometry
(distances/angles) with low distortion — cheaply. That's all it is: a fast, honest
squeeze.
Why the leak-test uses it. After the fit, the leftover (residual) is turned
into a delay-embedding matrix (sliding windows of the residual — a Hankel matrix),
SRHT-projected, and its singular spectrum measured — reported as concentration
(share of energy in the top third of components) and pr_normalized (participation
ratio, 0 = one mode, 1 = flat/noise). It returns a three-tier reading:
pr_norm < 0.22 and conc ≥ 0.88 |pr_norm ≥ 0.55 or conc < 0.70 |Why three tiers, and why these numbers — the calibration. An earlier version
used one loose cutoff and called pure noise "structured." A labeled bank (below,
stable across seeds) fixed the thresholds. pr_norm is the clean separator: real
deterministic channels sit at ≤ 0.12, every noise type at ≥ 0.25.
The binary yes/no would have to lie about the last row; the third tier tells the
truth. That is the "see what a single R² misses" part — measurable, calibrated, not
vibes. In the demo, Y = x + sin(t/7) reported 34% "unexplained" — SRHT showed
that 34% is one clean mode (the sine), tier = structured. (Period 7 — a nod to
the 28/7 example.)
---
You framed this as: _there are many ways to work a problem, and different workings
give different answers._ Here is the straight version, because you asked me not to
nod along:
Anyone who tells you 28/7 = 13 is not doing division. I'm not going to encode a
claim that it does.
_represent_ the computation. 28 as 7+7+7+7, as 4×7, as (30−2)/7, in base-2,
as a running total, as a rate of change — same number, different structure
exposed. And **for a time-series, the framing you test in decides what patterns
are visible.** That part of your intuition is correct and useful.
So the tool operationalises the _true_ half of the idea. Stage 2 runs the residual
test under four legitimate framings of the same data:
When the verdict flips between framings, that _is_ the finding. Example from
the demo: x + hidden_sine is ORTHOGONAL in levels but REDUNDANT in
changes — which tells you the hidden channel lives in the values, not the
motion. A single method would have hidden that. This is the "multidimensional
sequential math shift" — not different answers to 28/7, but different windows
onto the same object, each valid, compared side by side.
---
Every run builds a Chain: the root question never disappears, and each stage
appends {question, method, answer, next_question}. Print it with
rep["chain"].text(). You read it top-to-bottom as a conversation the tool had
with the data:
ROOT QUESTION: Does the candidate set explain 'Y' — or does 'Y' carry
information the candidates cannot reconstruct?
[1] PROFILE + AUTO-CONFIG Q: what kind of signal is this? → A: stateful, lags on
[2] MULTI-METHOD RESIDUAL Q: how much is unexplained, and does it depend on framing?
[3] SRHT EMERGENCE Q: is the leftover a pattern or noise?
[4] VERDICT A: the call + the new questions it spawns
The next field of each link is the actual input to the next stage — so the chain
is not a summary written afterwards, it's the real path the computation took. The
follow-up questions in stage 4 are the tool handing you the next thing to ask.
---
numpy. Wants: scikit-learn (non-linear engine), matplotlib (plots). Missing either → it runs and tells you what it skipped.
leak_universal.py next to leak_test_hardened.py.---
The leak-test is a residual detector with guardrails. Its power is that it
refuses to be fooled — by non-linear identities (the boosting stage), by saturated
signals (the low-var guard), by trending data (shuffled folds), by single-framing
blindness (multi-method), and by "unexplained = noise" laziness (SRHT). Its limit
is equally firm: it only ever speaks about the candidates you gave it, and a
synthetic verdict is a hypothesis until real telemetry confirms it. Used that way,
it's the instrument that lets math decide instead of opinion — which is the
whole point.
Sources for the methods:
• Ailon & Chazelle (2006), "Approximate nearest neighbors and the fast
Johnson–Lindenstrauss transform" — the SRHT.
• Walsh (1923) / Hadamard (1893) — the transform's origins ("the old tool").
• Gradient-boosted held-out residual + shuffled K-fold — the non-linear channel.