The library
Rendered from docs/handoffs/2026-09-26_post-draft-cpu-handoff.md; the markdown file is the record.
On this page
Handoff — post-draft CPU lane: the negative results, written up for the README (Sat Sep 26, 2026, ~17:25; revised after the Fable second opinion)
Purpose of this chat: turn tonight's measured negatives into one report the README chat can cite, docs/reports/2026-09-26_post-draft-negatives.md, by ~19:00. Optionally, only if that is done and the CPU is free, run the handcrafted noise-twin experiment (v6) as a candidate for the gate chat. CPU only; you never touch the GPU, fusion, the runner or the shipped bundle models/hc_selected.
What changed since the first version of this handoff: the noise twins were this lane's main job. Two independent opinions (docs/consults/2026-09-26_post-draft-review_RESPONSE.md, "What to do" and "Round 2") now put its test-set effect at zero: the channel lane's per-feature table shows the test set's noise-floor percentiles beyond the clean end, so additive noise is a measured weakness the test set does not exercise. It is worth a README paragraph, not a switch. The write-ups are worth more: 20 points of the grade are "what worked and what did not", and tonight produced five measured negatives nobody has written down.
Context
- NSA's draft review returned minDCF 0.0733, EER 3.534% on the shipped rule; one team is ahead at 0.0584. The consult records (
docs/consults/2026-09-26_post-draft-review_{CONSULTATION,RESPONSE,RESPONSE_fable}.md) hold every number below; cite them by file and section, and never invent a number. - The negatives to write up (each with the number and the mechanism, README voice: plain, short sentences, no marketing):
- More heads on the same backbone are dead on arrival. XLS-R layer probes on the M1b recipe (Fable memo, option 10): layer-7 baseline reproduces M1b (inner 0.2649, holdout 0.0717, In-the-Wild 0.342); mean of layers 5–9 gives holdout 0.052 but In-the-Wild 0.368 and doubles the In-the-Wild false-alarm rate (0.8% → 1.55%); concatenations of 6–8, 5/7/9 and 5–9 give In-the-Wild 0.353 / 0.430 / 0.399. Mechanism: of the shipped rule's 158 In-the-Wild misses, M1b alone would flag 1, handcrafted 2, M5 33, Spectra 107; a head on M1b's backbone inherits its blind spot.
- Fusion re-slicing has a measured ceiling. Cheating on purpose (weights chosen on In-the-Wild itself, (0.3, 0.2, 0.5)) reaches In-the-Wild 0.186, a 0.04 gain that costs the holdout two false alarms; a logistic stacker fit on In-the-Wild scores 0.257, worse than the shipped rank blend; the admissible non-negative stacker on inner non-LJ rows gives weights (0.66, −0.04, 0.37) and In-the-Wild 0.222 with holdout 0.029. The second M3 suppression tier is inert at the metric on every split (consult chat verification, Round 2 table). Calibration cannot move minDCF at all.
- The handcrafted column is the readable column, not a vote. Admissible stacker coefficient −0.04; test-set Spearman with M1b 0.21 against 0.79 on the holdout, so on the test set it reads the envelope shift. Tie this to the existing README text on the test-domain offset.
- The excluded detector could shrink the miss tail, and stays excluded. Promoting files with Spectra margin > 6.9 and base < 0.5 recovers 76 of 158 In-the-Wild misses at zero added false alarms (In-the-Wild 0.152), but the holdout shows two real files promoted [2, 11], the evidence is a set Spectra's authors evaluated on, and the suppression-only rule is a principle stated before any number. Loosening the threshold from −3 to −1.5 improves every proxy for the same reason and is skipped for the same reason.
- The cost convention is unknowable from the returned pair, and we hedge by requiring gains under both costs. The sponsor's scorer was edited from ASVspoof5's defaults to Pspoof 0.5, C_FA 4, and in that code the 4× multiplies accepted spoofs; the spoken rule puts it on false alarms. (0.0733, 3.53%) fits both: e.g. 3 false alarms + 25 misses, or 5 misses + 40 false alarms. The EER forces the two profiles to be mutually exclusive (at a single threshold both error rates cannot sit below the EER), so our own earlier decomposition (1.3% / 1.5%) was impossible.
- The proxies against the one measurement: the table in the CONSULTATION's second addendum (holdout optimistic 11× on minDCF and 17× on EER; In-the-Wild pessimistic 3× and 1.6×; the test sits further toward the wild end than λ̂ = 0.51 suggested).
- The M5 weight. A3 with M5 at 0.4 improves In-the-Wild by 0.028 under both costs with the holdout unchanged and inner slightly worse (0.135 → 0.137 brief, 0.300 → 0.337 sponsor-cost); post hoc, because the pre-declared sweep stopped at 0.2. Report it as measured; whether it ships is the gate chat's and Nathan's, and your paragraph must say so and be updated by 21:30 either way.
- The optional experiment (v6, noise twins) if and only if the report is committed and the CPU is free before 18:20: the shipped v5b recipe (
docs/reports/2026-09-26_handcrafted-v4.md, "v5: training-side augmentation") plus a 20 dB white-noise twin per class on fit-side rows via a new--noise-frac/--noise-snr-dboption inscripts/extract_handcrafted.py(same per-rowdefault_rng(seed + row)draw as laundering and tilt, recorded inhc_augment, applied before band match on both classes;hearsay.augment.add_noise(x, rng, snr_db)exists). Re-extract the training sample asnsa_train_sample_v6aug(~25 min at 4 workers), train exactly like v5b with--extra-rows-from, out-namehandcrafted_v6, score In-the-Wild withscripts/eval_bundle.pyon the seed-200 v4 features into_itw_handcrafted_v6.csv, and run the pre-declared diagnostic (the channel lane's 500-clip cohort under 20 dB noise throughscripts/m3_probes.py's perturbation path, handcrafted only; pass bar AUC ≥ 0.90 with clean AUC within 0.005 of 0.998). Numbers to sit beside, v5b clean rows: inner 0.469, LibriSpeech real 0.59, clean holdout 0.137, holdout LibriSpeech 0.16, ITW P_FA / P_miss 0.40% / 96%, ITW AUC 0.77. Do not re-pinmodels/hc_selected. If it is not exported by 18:50, report it as not run.
Working branch / worktree
main in ~/Projects/hearsay, shared. Your files: docs/reports/2026-09-26_post-draft-negatives.md; if the experiment runs, scripts/extract_handcrafted.py (the option only), one test, outputs/handcrafted/nsa_train_sample_v6aug.csv, models/hc_lgbm_<stamp>/, the two exports, and docs/reports/2026-09-26_post-draft-hc-noise.md. Stage only those; never git add -A; do not push; tell the README chat and the gate chat the commit hash.
Environment / setup
cd ~/Projects/hearsay && uv sync
What to do next
- Read the three consult records and the Round 2 table. Write
docs/reports/2026-09-26_post-draft-negatives.mdwith the seven items above, one short section each: what was tried, the number, the mechanism, the file it comes from. Mark item 7 "pending the 19:30 decision" and update it when the gate chat reports. - Message the README chat ("README" lane, address in
docs/handoffs/2026-09-26_docs-site-handoff.md) with the path so it can fold the items into "What did not work"; the README chat edits the README, you do not. - Run
uv run pytest -q tests/test_docs_consistency.py(52 passed at last count) after committing, because the README chat will cite you. - Only then, and only before 18:20: the optional v6 experiment above. Otherwise stop at 19:00.
IMPORTANT — tests & at-risk artifacts (make sure these survive)
- Test:
uv run pytest -q tests/test_docs_consistency.py→ 52 passed; fulluv run pytest -q→ all passing anduv run ruff check .clean if you touch a script. - Self-check for the optional experiment: with
--noise-frac 0the extraction is byte-identical to a v5-style run on the same rows. - At-risk: nothing for the write-up (tracked). For the optional experiment:
outputs/handcrafted/nsa_train_sample_v6aug.csv(gitignored, ~25 min to regenerate; NOT archived), the bundle (gitignored; NOT archived), the exports (regenerable); copy the bundle'smeta.jsonnumbers into its report. - LightGBM and torch must never be imported in one process (macOS OpenMP crash);
train_handcrafted.pyis the only LightGBM importer. - In flight: heads chat (GPU: WavLM), gate chat (manifest, sweep, packet 19:30, sleep-equals-ship copy), README and docs-site lanes.
Analytical notes
- Score direction 1.0 = synthetic everywhere. Augment both classes or neither; readouts on clean rows; the holdout never trained on; In-the-Wild eval-only.
- Every number in the report is cited to a file; where a number exists only in the Fable memo, cite that memo and say the consult chat verified the M5-weight and second-tier rows from the exports and did not re-run the layer probes.
- Tone: the README's voice. A negative result with its mechanism is graded content; a negative result without the mechanism is not.
Pointers
docs/consults/2026-09-26_post-draft-review_RESPONSE.md,…_RESPONSE_fable.md,…_CONSULTATION.md;docs/reports/2026-09-26_channel-robustness.md(§A per-feature positions, §E the noise finding);docs/reports/2026-09-26_handcrafted-v4.md;README.md"What did not work" (the section your items extend);src/hearsay/augment.py,scripts/{extract_handcrafted,train_handcrafted,eval_bundle,m3_probes}.py.