Skip to content

v3.20.1 — guard the bound, cut two spellings of one knob

Choose a tag to compare

@mikessh mikessh released this 26 Sep 20:18
· 89 commits to master since this release

Added — tests/test_knob_audit.py. The "never silently" claim as an equality rather than a slogan: the cells that move between clip=2 and clip=8 must be a subset of the cells saturation() names. If a knob can move a cell no report mentions, the report is decoration. Seven loci at a realistic clonotype spread, because the blast radius of a knob is a property of a cohort, not of a fixture.

Mutation-checked: reverting the soft squash to a hard clip fails 3 tests, dropping saturation()'s worst column fails 1, holing a scaled column under on_unscaled="hole" fails 1.

At cohort scale on 40 seven-locus samples, 528 rsig columns, clip=8.0: 294 of 5,882 finite scaled entries (5.00%) sit beyond the bound, and the soft and hard maps differ in exactly those 294 cells across 57 columns. Sample ordering survives in 521/521 columns under the soft squash and 490/521 under the hard clip — 31 columns whose ranking a clip destroys on a cohort where only one entry in twenty is out of bound. unapply round-trips to 1.32e-12; n_jobs moves 0 cells.

Removed. squash="none" was a second way to say clip=None, and unapply's squash selected between two identical behaviours — a hard clip cannot produce a value outside the bound, and below it the two maps are the same function. squash is "soft" or "hard".

SOURCES.md is no longer tracked: cluster project paths, private dataset names, local checkouts and cohort composition. Gitignored and excluded from the sdist; the README, docs, SKILL.md and prototypes.py point at the per-artifact manifest.json or the public HF dataset card.