# The Foundry — TODO

Resume state for the URL→audio→stems→loops sampling tool. Snapshot **2026-06-29**.
Task IDs map to the session task board. Design: memory `project_foundry`.

## 🔵 In progress
- [ ] **#19 — Auto-tune loop** (create samples → grade → iterate sampling settings).
      PLN's closed-feedback main quest. **Harness BUILT & VALIDATED** (commit
      `6f85012`): `engine/autotune.py` (evaluate/search), `autotune.py` CLI,
      `loops.analyze_stem` `weights` override, 4 unit tests + a real run (baseline
      0.690 → best 0.763, **+10.5%** on 2 drum stems). Finder defaults (`loops.W`)
      deliberately UNCHANGED. **Exact next steps to resume cold:**
      1. Get real fuel: `cd tools/foundry && python3 foundry.py demos --all --sep`
         (fetches+separates the 10 sampling classics — SLOW, run as a durable bg
         job). Existing fuel: `~/Downloads/separated/htdemucs/*/{drums,bass,vocals,
         other}.wav` (27 tracks).
      2. Add the anti-gaming 2nd objective: recall-vs-provenance-GT (reuse
         `armada/tide-table/build_finder_eval.py` + `build_provenance.py`) so we
         don't just amplify the seam/zc confound. Make objective multi-objective
         (grade × recall) in `engine/autotune.py`.
      3. Per-stem-ROLE tuning: vocals want chop mode + different weights than drums
         (`--stems …/drums.wav` vs `…/vocals.wav`; analyze_chops path for vocals).
      4. Full campaign: more stems (`--max-stems`↑) + more configs (`--n`↑); factor
         window-feature extraction out of `analyze_stem` so weight sweeps are
         instant (extract-once/score-many — the scarcity-minded speedup).
      5. THEN adopt a VALIDATED profile as the new `loops.W` default, per role,
         with the lift numbers.
      Run: `python3 autotune.py --stems <glob> --n 24 --max-stems 4`.
      Objective so far = mean full-rubric grade × coverage.
      **VERIFY-RERANK now BUILT & validated end-to-end on the Super freak dub kit.**
      The finder scored the seam on the RAW window, but export zc-snaps (B1) — and the
      snap (plus the 3-dp start/end rounding export slices at) changes the wrap. Several
      proxy-seam≈1.0 windows CLICKED after the snap. Fix: `loops._verify_rerank` re-scores
      the ~3×top_n survivors' seam on the TRUE post-snap window (reusing `grade.seam_score`,
      DRY), swaps proxy→true seam in the composite, and hard-demotes true-seam <
      `VERIFY_SEAM_FLOOR`. New kwarg `analyze_stem(..., verify=True)` (default on; False
      reproduces the pre-#19 raw-proxy ranking for autotune baselines). Also fixed the
      sparse-material seam false-positive (`grade.seam_score`): the mean-|2nd-diff|
      denominator collapsed to ≈0 on sparse dub drums (129× click ratio on a clean loop);
      now 90th-percentile, amplitude-floored (2–3× on the same loop). Validation
      (drums+other, bars 1/2/4, BPM 132.5, export-faithful grades):
        drums top-3  BEFORE C/C/A  →  AFTER **S/S/A** (clicking @93.08 & @24.06 demoted)
        other top-3  BEFORE B/B/B  →  AFTER **S/S/S** (bad favorite @56.74 demoted out)
      +2 rerank regression tests + 1 sparse-percussion test; suite 57→60 green.

## 🔴 Open
- [ ] **#20 — Batch-explore many sources** (Foundry over the full corpus + merge).
      Workflow is one-catch-at-a-time; build batch exploration:
      - Batch driver: `find_takes` over MANY source stems (the ~30 in
        `~/Downloads/separated/htdemucs` + new fetches) → grade → surface the best
        loops/chops corpus-wide ("what's worth sampling across everything pulled").
      - **Stem-role-aware**: skip near-silent stems, mode per role (chops for
        vocals, loops for rhythmic), rank by grade. (e.g. Loituma has no drums —
        bass + high voice are the interesting stems; grid-from-drums already falls
        back drums→bass→first.)
      - Surface in the Hall of Fame / a "fresh catches" view: best ungraded-yet
        candidates corpus-wide, click to audition + forge.
      - Ties to #19: once settings are tuned per role, batch-explore applies them
        at scale. Relates #11 tierlist (showcase pattern), #9 merge.

> Note: the Foundry engines are also productized over HTTP by the **Fourier**
> audio API — `/separate` (#30) wraps `engine.separate`, `/loops /grade /correlate`
> (#31) wrap the rest. See `armada/api/TODO.md`.
