What's New
v0.57.0 — soup adapters: git for LoRA. Three years of lora_v3_final_final2/ ends here. v0.57 ships git-shaped UX on top of the v0.22 adapter surface — diff, weighted merge, attribution-by-ablation, and snapshot pointers — in pure numpy with TOCTOU defence on every path and atomic writes throughout.
4 new top-level commands (6 new CLI surfaces)
soup adapters diff <a> <b>— per-layer ΔW Frobenius norm + relative drift, effective-rank delta via SVD entropy, top-K changed projections. JSON / Markdown / table output via--formatfor CI/PR-comment use.soup adapters merge <a> <b> [c...] -o <out> --strategy {linear|ties|dare|svd}— 4 pure-numpy merge strategies: weighted linear, TIES (Yadav et al. — trim / elect majority sign / disjoint avg), DARE (Yu et al. — drop+rescale, deterministic via--seed), and SVD low-rank reconstruction (--rank).soup adapters blame <adapter> --dataset <d> --layer <l> --budget <t>— leave-one-out ablation plan emitter. Splits dataset into N shards, estimates per-shard runtime against your wall-clock budget, emits a feasibility check.soup adapters branch <name> -c <cfg> --base <model>+soup adapters checkout <name>+soup adapters branches— SHA-256 snapshot pointers under~/.soup/branches/(orSOUP_BRANCHES_DIR-override, $HOME/$CWD/$TMPDIR-bounded). Drift detection refuses restore when source SHA != snapshot SHA.
Install / Upgrade
pip install --upgrade soup-cliSecurity
5-agent review-fix wave (1 CRITICAL + 9 HIGH + 11 MEDIUM + 4 LOW):
- TIES tied-sign defaults to +1 (paper convention). The first-cut
np.sign(0) == 0would have silently zeroed every parameter with evenly-split votes — fixed before ship. load_branch/delete_branchreject pre-placed symlinks viaos.lstat + S_ISLNKbefore read/unlink (TOCTOU defence; defends against~/.soup/branches/<name>.json -> /etc/passwdcontent leakage on read AND against silent deletion of victim files on unlink).- Merge output safetensors +
adapter_config.jsonwrites are atomic via tempfile +os.replace; output path symlink-rejected; source config size-capped at 256 KB before read. compute_adapter_diffrejects symlinks at theadapter_model.safetensorsleaf BEFOREis_file()— defends againstsafetensors -> /etc/passwdescape from the directory-level containment check._count_dataset_rowsopens via the realpath captured at containment check (closes TOCTOU window betweenenforce_under_cwd_and_no_symlinkandopen).--outputdiff write is atomic via tempfile + os.replace.SOUP_BRANCHES_DIRenv override rejects every C0 control char (CRLF/tab/null/etc.), mirroring v0.51.0 hub-endpoint policy.
Plus tighter test invariants throughout: 5× pytest.raises(Exception) → FrozenInstanceError; +12 new POSIX symlink-rejection tests; bool-rejection extended to every numeric public input (base_model, budget_seconds, top_k boundaries, num_shards=False); source-grep regression guards for the lazy-import policy.
Known limitations (tracked for v0.57.1)
- Live blame ablation runner —
run_blameraisesNotImplementedErrorwith explicit v0.57.1 marker.soup adapters blameemits the plan + per-shard table + budget check and exits clean. Same stub-then-live cadence as v0.27.0 MII / v0.37.0 multipack / v0.50.0 GRPO Plus / v0.56.0 diagnose. - Merge canary verdict —
MergeReport.verdictis'UNKNOWN'stub; live canary-eval via v0.55 eval gate ships in v0.57.1. CLI panel prints "Verdict: UNKNOWN (live eval in v0.57.1)" so the deferral is visible. - Branch pointers are local-only — not yet wired into v0.26 Registry lineage DAG. Cross-machine branch sharing requires copying the JSON pointer + source config + dataset manually.
.binadapter format unsupported —compute_adapter_diffrejects with friendly "re-save as safetensors" message._MAX_ADAPTERS=16per merge — matches mergekit's practical limit; 17+ adapters require chained merges.- Rich-markup escape in legacy
soup adapters list/info/compare— pre-existing v0.22.0 surface still embeds adapter_config values directly into Rich markup. v0.57.0's new commands all userich.markup.escape; backfilling the legacy commands is tracked for v0.57.1.
Tests
8849 → 8998 (+149 net across 4 new test files). Full suite green on Linux / macOS / Windows × Python 3.9 / 3.11 / 3.12. 4 POSIX-only symlink tests skipped on Windows.