Systems and subsystems

The fusion rule

Three detectors are turned into ranks against their own training distributions, blended with fixed weights, checked once by Spectra-AASIST, which may only halve a high rank, and mapped through a Platt map into a probability. Everything it needs is in one constants file that the runner never refits.

In plain words

The metric only sees the order of our scores, so the fusion is a rank blendEach detector's raw score is replaced by its rank among that detector's own out-of-fold training scores (the share of training rows scoring below it), and the ranks are combined with fixed weights. Ranking is all the metric sees, so fusing ranks avoids letting one detector's scale dominate.: each detector's raw score becomes "what share of my training rows scored below this", and those shares are averaged with weights. That stops one detector's scale from dominating and makes the rule easy to read. The weights were not fitted; they were chosen by a selection rule written down before any result (see the sweeps). The worked file shows the arithmetic on a real test file.

What goes in and comes out

In: the logits of m1b_v3, handcrafted_v5, m5_xlsr_ft and spectra_aasist for a file. Out: the base rank, whether the Spectra step fired, the Platt probability, and, after the policy, the final score.

Where it lives

FusionConstants in pipeline.py, lines 132–328 (parsing, validation, the arithmetic); the writer of the shipped file, fuse_sweep_m5.py; the previous rule's writer, fuse_sweep.py. The shipped constants are models/fusion_v2/constants.json (not in the repository), the previous rule's models/fusion_v1/constants.json.

The rule and where each piece is set

  1. Rank. Each logit's position among that detector's sorted inner out-of-fold logits, left-sided, as a fraction (pipeline.py, lines 285–288). The references are stored in the constants file and validated as sorted, finite and non-empty.
  2. Blend. 0.6 × rank(M1b) + 0.2 × rank(handcrafted) + 0.2 × rank(M5); the file's weights must be finite, positive, name fused columns other than Spectra, and sum to one (pipeline.py, lines 167–185). The previous rule was a two-way blend with α = 0.2source: README.md, section the-fusion-rule on the handcrafted column.
  3. The Spectra step. If Spectra's margin is below −3.0source: scripts/fuse_sweep.py line 172 (GitHub; assumes main is public) and the base rank is above 0.5source: scripts/fuse_sweep.py line 172 (GitHub; assumes main is public), the base is multiplied by 0.5source: scripts/fuse_sweep.py line 172 (GitHub; assumes main is public); strict inequalities; a missing Spectra means no suppression; nothing is ever fitted on Spectra (pipeline.py, lines 307–316).
  4. Platt map at the 0.3source: docs/reports/2026-09-26_worked-examples.md prior: a class-balanced logistic regression fit on the inner out-of-fold base scores, applied as sigmoid(a·base + b + the log prior odds) (pipeline.py, line 327).
  5. The determinate map into [0.001source: scripts/fuse_sweep.py line 159 (GitHub; assumes main is public), 1], applied exactly once by the policy; gated files go below it.
  6. Imputation. A missing fused column is imputed at rank 0.5source: src/hearsay/pipeline.py line 300 (GitHub; assumes main is public), the inner-fold median, and the fusion line names it (pipeline.py, lines 299–300).

A constants file that weights M5 must also record the M5 checkpoint's directory and hashes, and the runner refuses a checkpoint that does not match (pipeline.py, lines 197–202).

Status

The shipped rule is A3_w0.2_E, ratified at 12:03 on Saturday and the runner's default since 12:35; the previous rule E_on_A_alpha0.2 is loadable as the fallback. The two files fuse identically on their shared inputs (a test pins it), so the previous rule is exactly the shipped one with the M5 weight moved back to the probe.

Numbers

Shipped: inner 0.135source: README.md, section results-at-a-glance, holdout 0.0065source: README.md, section results-at-a-glance, In-the-Wild 0.228source: README.md, section results-at-a-glance / 0.239source: README.md, section numbers. Previous: 0.140source: README.md, section results-at-a-glance / 0.014source: README.md, section results-at-a-glance / 0.260source: README.md, section results-at-a-glance / 0.267source: README.md, section numbers. Between the two, Spearman 0.974source: README.md, section the-fusion-rule on the test set and 3 of 1,671source: README.md, section the-fusion-rule files cross 0.5source: README.md, section the-fusion-rule. From exported logits the runner reproduces the submitted TSV to 6.7e-16source: README.md, section score-a-directory-on-the-mac.

Known limits

Not noise-robust: at 20 dB white noise the handcrafted column collapses and the rule's holdout cost rises from 0.012source: README.md, section what-did-not-work to 0.269source: README.md, section what-did-not-work, while the Spectra step never fires. Giving Spectra a full vote scores better on every labeled readout and was ruled out beforehand.

Tests that pin it

tests/test_pipeline.py: constants parse and validate, a file with mismatched weights is rejected, the rank rule is the sweep script's arithmetic including the left-sided boundary, the three-way blend is the M5 sweep's arithmetic, the Spectra step's boundaries are strict, the step can be off in the file, imputation, the previous file and its shipped twin fuse identically, the v2 file loads weights, references and the checkpoint identity and rejects bad files, the flip reverses determinate rows and keeps the block, the fusion line lists every weighted term; data-gated parity against the 09:14 candidate TSV.

Sources

README, "The fusion rule"; the sweep report; the fusion consult; the M5-scorer run spec.