Skip to content

v5.1.0

Latest

Choose a tag to compare

@SAY-5 SAY-5 released this 27 Sep 00:27
86e32e4

The browser demo now runs on the package's own code path, and the README's figures are gated on committed runs. web/scripts/export.py scores its reference through spoofline.scoring.RunScorer and exports both graphs through spoofline.export.export_stream; it had kept a second copy of the ONNX wrapper and imported score_single_clip, which the v4 series removed, so the documented way to rebuild the page had been broken at HEAD. The page shows what the repository computes: the logistic fusion beside the weighted sum in the calibration table and in the clip lab, and the stream each fusion decision is attributed to, with the hero naming the corpus, the seed, the held out pair and the training commit, and saying that the catch strips replay exported logits rather than scoring in the tab.

docs/runs/ holds the JSON of the demo run and of the full profile sweep, and tests/test_readme_numbers.py re-renders every block and table the README quotes from them, so a stale figure fails the suite instead of drifting; the reduced profile variance table is the one block left without an artifact, and the README says so above it. CI runs the page as well: npm ci, npm run typecheck, npm run selfcheck and the production bundle, with ruff now linting web/scripts, and the self-check makes 374 assertions over 25 clips because both fusion probabilities, both decisions and the attribution have to match PyTorch.

spoofline sweep --pairs default restricts the sweep to the profile's held out pair, and three seeds of it at the full profile put the headline in context: fused unseen precision 0.972 (std 0.030, bootstrap interval 0.941 to 1.000), so the demo run's 0.941 sits at the bottom of the interval, while video alone holds precision 1.000 in all three runs. spoofline robustness takes its seed, held out families and split membership from the run's results.json and splits.json instead of recomputing them from the profile, so a run trained with another seed can be post-processed. Splits.counts() reports the clips dropped for carrying a held out family, so the four split sizes and the dropped count add up to the corpus, and the report orders its own rows so a run rendered from results.json prints what the run printed. The corpus cache compares the whole corpus shape rather than the seed and the clip count alone, so a corpus rendered with other frame or audio settings is refused instead of reused. On Linux torch and torchaudio resolve from the PyTorch CPU index, so a CPU only test run no longer installs the CUDA toolkit, and CI installs with uv sync --locked.

Accessibility and prose: one live region for the calibration table instead of one per cell, a plain text hero heading, the draggable target named in the chart label, larger small type, and a citation for the CNN-LSTM arrangement in the architecture note. Four new test modules cover the README figures against the committed runs, the browser demo's export path, reading a finished run's seed and splits back, and committed artifacts carrying no machine paths: 172 tests at this commit.