Files
support-fins/prototype/sweep

Regression sweep — the pre-merge gate

Unit tests pin cases we already know about. This looks at all of them: it builds supports for every model × pose × coverage (31 models × 9 poses × 3 = 837 cases) with the base engine and the branch, and reports every case where the branch supports less.

prototype/sweep/vs-base.sh                 # vs origin/main, incl. check_stl.py
prototype/sweep/vs-base.sh <sha>           # vs any commit
NOCHECK=1 prototype/sweep/vs-base.sh       # skip the check_stl pass (sweep alone: ~1 min)
CHECK_TIMEOUT=300 prototype/sweep/vs-base.sh   # per-case check_stl limit (default 45s)
KEEP=/some/dir prototype/sweep/vs-base.sh  # keep base/head JSON for digging

Exit 1 on any blocking regression. Rule: don't merge with an unexplained blocking line. A deliberate trade (e.g. fewer walls on purpose) still shows up and gets explained in the PR.

Blocking (compare.js): new crash · an overhang region goes unserved · wall length lost (>5mm and >5%) · tines lost (>3 and >5%) · lowest tine rises >0.1mm (base grip). Then check_diff.py runs prototype/check_stl.py on every changed case of both builds and blocks on a case that was clean and now fails (fused wall, open mesh, tine that misses, off-spec standoff), now builds nothing, or loses >2 points of overhang coverage.

Info only: wall count, squat walls, gains, plastic.

Mesh identity: each case records a hash of its exact support mesh, and the report prints meshes N/837 byte-identical to base. A change that should alter nothing (moving code between modules) must show 837/837. A case whose metrics match but whose mesh moved is listed under info and still gets the check_stl pass.

Why it exists: on 2026-09-22 a fix that looked perfect on the 35° cube was found (by an ad-hoc version of this) to cost tines on most parts and drop walls on others — nothing the one-part check or the unit tests could see.

Files: sweep.js (run one engine, optionally export STLs) · compare.js (diff two runs) · check_diff.py (check_stl on both exports) · vs-base.sh (all of it against a git ref, in a throwaway worktree).

check_stl.py checks every solid, so its cost scales with tine count (40mm cube ~1s; bigplate at dense ~200s). check_diff runs cases in parallel, one process each, with a per-case limit; a case that overruns is listed as NOT checked — never counted as a pass.

Memory: each check loads the whole part into trimesh, so the pass runs 3 at a time (CHECK_WORKERS) and skips bigplate + both voron parts by default — 8 parallel checks on those got the machine OOM-killed. The sweep itself still covers them. CHECK_BIG=1 includes them; only do that on its own, not while you're working.