Systems and subsystems
The speech gate and the default-answer policy
Five cheap cues decide whether a file contains speech to judge. A file that fails skips fusion and is placed in a block strictly below every judged file, at the real end of the ranking, where an uncertain file belongs under the sponsor's cost.
In plain words
Our first deep probe scored pure silence at 0.99source: README.md, section orchestration-what-routing-changes synthetic. Under a cost where a false alarm counts 9.33source: README.md, section how-it-decides misses, a handful of silent or musical files at the top of the ranking would cost more than the entire fusion decision. The gate catches such files; the policy puts them where a "we don't know" belongs. The thresholds were set beyond the extreme value of every cue in the full test set, so the gate touches 0 of 1,671source: README.md, section the-eight-forensic-techniques test files and only ever catches silence, tones, static and noise.
What goes in and comes out
In: the prepared clip. Out: a speech_gate result whose score is always the neutral value (fusion never sees it), with features for the five cues, the reasons that fired and is_speech; and, from the policy, the final placement of every file's probability.
Where it lives
src/hearsay/detectors/speech_gate.py: analyze, the detector, and apply_default_answer. The runner applies the policy exactly once in final_score (pipeline.py, lines 656–668).
The five cues and where each is set
- Silence: RMS below −70.0source: src/hearsay/detectors/speech_gate.py line 47 (GitHub; assumes main is public) dBFS.
- Unvoiced: fewer than 0.05source: src/hearsay/detectors/speech_gate.py line 48 (GitHub; assumes main is public) of frames voiced (a frame is voiced when it is loud enough and its pitch is in the speech range).
- Tone: voiced, but the spread of log pitch is below 0.02source: src/hearsay/detectors/speech_gate.py line 49 (GitHub; assumes main is public).
- Static: loudness standard deviation below 3.0source: src/hearsay/detectors/speech_gate.py line 50 (GitHub; assumes main is public) dB.
- Noise: long-term spectral flatness at or above 0.5source: src/hearsay/detectors/speech_gate.py line 51 (GitHub; assumes main is public).
Any one cue firing gates the file. The test set's extremes that sit behind the thresholds: quietest file −34.6source: src/hearsay/detectors/speech_gate.py line 15 (GitHub; assumes main is public) dBFS, lowest voiced fraction 0.099source: src/hearsay/detectors/speech_gate.py line 15 (GitHub; assumes main is public), lowest loudness spread 6.0source: src/hearsay/detectors/speech_gate.py line 15 (GitHub; assumes main is public) dB, highest flatness 0.39source: src/hearsay/detectors/speech_gate.py line 15 (GitHub; assumes main is public) (speech_gate.py, lines 14–16). Clips shorter than half a second are zero-padded; pitch comes from YIN between 60 and 400source: src/hearsay/detectors/speech_gate.py line 76 (GitHub; assumes main is public) Hz.
The default-answer policy
- Judged files are mapped into [0.001source: src/hearsay/detectors/speech_gate.py line 52 (GitHub; assumes main is public), 1] (the determinate map, applied once).
- Gated files that decoded land below 0.001source: src/hearsay/detectors/speech_gate.py line 52 (GitHub; assumes main is public) (
BLOCK_TOP) and at or above a tenth of it (FAILURE_TOP): ordered by a weak signal (the probe's own probability when it exists), with a 0.01source: src/hearsay/detectors/speech_gate.py line 54 (GitHub; assumes main is public) share of hash jitter from the filename so no two files tie. - Files that failed to decode, or are missing, land below
FAILURE_TOP, at the very bottom (speech_gate.py, lines 132–162). - Only the gate's own flag gates a file; a gate error does not.
Status
Built about 06:10 on Saturday; the block's formula was corrected at 08:30 when the pipeline turned out to score some real files as low as 0.0009source: docs/reports/2026-09-26_gate-and-drift.md, which the first version would have overlapped. The architecture document still shows the first formula.
Numbers
Gated: 0 of 1,671source: README.md, section the-eight-forensic-techniques test files; 31 holdout rows and 9 In-the-Wild rows in the ablation, costing 0.001source: README.md, section orchestration-what-routing-changes under the brief's cost on In-the-Wild. Placement is optimal under the brief's cost when the block's fake rate is below 80%source: README.md, section orchestration-what-routing-changes and under the sponsor code's reading when it is above 9.7%source: README.md, section orchestration-what-routing-changes; see the metric page.
Known limits
Rhythmic polyphonic music can pass the cues; the preflight and the high-score flag remain the backstop. The module's docstring says "a tenth" of frames voiced where the constant is five percent.
Tests that pin it
tests/test_speech_gate.py: silence, a chord, a tone and white noise are gated with the right reason; speech-like input passes; quiet real-level speech is not silence; contract and determinism; the policy pins gated files strictly below every scored file; ordering uses the weak signal and keys and puts failures at the bottom; only the gate flag gates; a data-gated test that real test clips pass. tests/test_pipeline.py pins that the map is applied once and that a decode failure sits below the block.
Sources
The gate and drift report; README, "The abstention path"; consult item 5.