Merge dev into phase-g: Phase Ε/Ρ and the 1.5.0 bump meet Phase Gamma's instrument work; 120/120 green

The per-directory CLAUDE.md count is re-derived at twenty-seven rather than
carried from either side. The "Decouple the instrument reload from VST3
activation" TODO entry does not survive: Γ-W3-T1 landed it, and COMPLETED.md
carries the discharge.
This commit is contained in:
2026-08-02 21:57:47 -04:00
139 changed files with 10870 additions and 1993 deletions
+7 -4
View File
@@ -6,7 +6,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
**ReaSampler** is a per-project audio sample-bank capture tool that builds two artifacts: the REAPER extension (`reaper_reasampler`) and **ReaSampler 9000**, a Windows-only VST3 sampler instrument (`reasampler_9000.vst3`, `core/instrument/` + `shell/instrument/`, second CMake target `reasampler_vst`, gated on the vendored `vendor/vst3sdk` submodule slice). The pure-testable-core / REAPER-facing-shell discipline is preserved throughout: `core/` never includes REAPER or VST3 SDK types, `shell/` is where those hosts are actually touched, `app/` is the extension entry point. Every REAPER API name cited in project docs is correct-by-intent; verify argument order, types, and flag values against `vendor/reaper-sdk/sdk/reaper_plugin_functions.h` before use.
Per-module detail — what each file owns, its invariants — lives in the twenty-four per-directory `src/**/CLAUDE.md` files; see the compact map in "Architecture: the load-bearing split" below to find the right one. Landed-phase history lives in `docs/ARCHIVE.md`; current work lives in `docs/COMPLETED.md`, `docs/TODO.md`, and `docs/TODO-1.0.md` — see "Project docs" below.
Per-module detail — what each file owns, its invariants — lives in the twenty-seven per-directory `src/**/CLAUDE.md` files; see the compact map in "Architecture: the load-bearing split" below to find the right one. Landed-phase history lives in `docs/ARCHIVE.md`; current work lives in `docs/COMPLETED.md`, `docs/TODO.md`, and `docs/TODO-1.0.md` — see "Project docs" below.
## Settled decisions
@@ -84,7 +84,7 @@ There is no hot-reload. Copy the **Release** build's binary (`build/Release/` on
## Architecture: the load-bearing split
`core/` holds pure, unit-testable logic — no REAPER or VST3 SDK types, each with a corresponding `<module>_tests` target that runs without a DAW. `shell/` holds the REAPER/host-facing shells — where those SDK types are actually touched. `app/` is the extension entry point. Each of the twenty-four directories below carries its own `CLAUDE.md` with the full module list and that area's invariants — open the relevant one for detail; this file states only repo-wide truth.
`core/` holds pure, unit-testable logic — no REAPER or VST3 SDK types, each with a corresponding `<module>_tests` target that runs without a DAW. `shell/` holds the REAPER/host-facing shells — where those SDK types are actually touched. `app/` is the extension entry point. Each of the twenty-seven directories below carries its own `CLAUDE.md` with the full module list and that area's invariants — open the relevant one for detail; this file states only repo-wide truth.
| Directory | Scope |
|---|---|
@@ -94,10 +94,12 @@ There is no hot-reload. Copy the **Release** build's binary (`build/Release/` on
| `src/core/instrument/` | pure VST3-instrument core (bake / engine / map / note / param / ui) |
| `src/core/instrument/bake/` | the resample bake's pure half — the programmed note resolved to a frame window, the offline render over a bake-only voice engine, and the post-bake reset |
| `src/core/instrument/engine/filter/` | pure per-voice resonant TPT/SVF filter (HP→BP→LP / HP→notch→LP morph, drive stage), run by each `Voice` between the pitch and amp stages |
| `src/core/instrument/engine/loop/` | the sustain loop's ONE validity/clamp fold plus its pre-seam crossfade geometry and the editor's default handle span |
| `src/core/instrument/note/` | the programmed capture-signal model — musical divisions, tempo resolution, anchored offsets |
| `src/core/instrument/param/` | the VST3 parameter surface's pure half — the FOREVER-FROZEN id table, the exposed set derived from the commit predicate, the plain-value layer, and the one formatter per unit category |
| `src/core/json/` | the hand-rolled JSON lexical layer |
| `src/core/model/` | the pure bank/sample index and its multi-bank container |
| `src/core/package/` | the pure RSBK bank-package codec — format contract, version ladder, JSON manifest, framing/layout codec |
| `src/core/reclaim/` | pure prune orphan computation |
| `src/core/tracking/` | the consolidated file-tracking system — birth/lineage records and the one authority answering prune's protected set and the resample's replace-vs-add |
| `src/core/ui/` | pure UI geometry, palette, and interaction-decision modules |
@@ -109,6 +111,7 @@ There is no hot-reload. Copy the **Release** build's binary (`build/Release/` on
| `src/shell/bank_ops/` | promptless bank-mutation verbs |
| `src/shell/capture/` | REAPER-facing capture backends and action bodies |
| `src/shell/instrument/` | ReaSampler 9000 VST3 shells |
| `src/shell/package/` | package filesystem I/O (streaming atomic read/write, exclusive-create landing), the rollback journal, and the REAPER file pickers |
| `src/shell/panel/` | the docked bank-panel shell + the shared LICE draw kit |
| `src/shell/persist/` | project ext-state persistence, prune filesystem I/O, usage scan |
| `src/shell/view/` | Design View mode application shell |
@@ -190,7 +193,7 @@ Comments carry *why*, and context where non-obvious — never *what* the code al
`docs/product/` holds the product-design reasoning behind each phase — the "why we chose this" that predates the spec. They are large; **grep for the cited section rather than reading a file whole**. `docs/cmake-cheatsheet.md` is a standalone build-system reference.
Files: `capture-tail.md`, `code-organization.md`, `design-view.md`, `midi-playback.md`, `multi-bank.md`, `provenance.md`, `removal-and-prune.md`, `versioning-and-release.md`, `visual-design-language.md`.
Files: `bank-package.md`, `capture-tail.md`, `code-organization.md`, `code-quality-audit.md`, `design-view.md`, `instrument-control-surface.md`, `linux-readiness.md`, `midi-playback.md`, `multi-bank.md`, `parameter-automation.md`, `provenance.md`, `removal-and-prune.md`, `render-in-place.md`, `versioning-and-release.md`, `visual-design-language.md`. `audit-notes/` is a subdirectory of track-evidence appendices for `code-quality-audit.md`, not a peer doc — not enumerated above.
## Project docs
@@ -202,7 +205,7 @@ Plan-style docs live under `docs/`:
## The load-bearing principle
**Capture and placement are separate acts.** Capturing audio writes a file to the bank and adds an index entry. It **never** puts an item in the arrange view. Placement is a distinct, on-demand action (`insert` module / `InsertMedia`). Any code path that auto-inserts a capture into the timeline violates the purpose of the tool and **must be rejected in review**.
**Capture and placement are separate acts.** Capturing audio writes a file to the bank and adds an index entry. It **never** puts an item in the arrange view. Placement is a distinct, on-demand action (`insert` module / `InsertMedia`). Any code path that auto-inserts a capture into the timeline violates the purpose of the tool and **must be rejected in review**. A render that goes arrange → arrange, never entering the bank and never reading it (`shell/capture/render_in_place`), is a THIRD verb outside this rule rather than a softening of it — the rule binds anything that touches the bank on either side, so a bank sample may still only reach the timeline through an on-demand placement, and a capture may never grow a place step.
## Precision invariants — required before any feature ships