docs(phase-q): fold Q-W0 sign-off into PLAN/CONTEXT — all 59 dispositions settled; Q-W2v wave, T4-18 VST placement, ~600 ceiling + structural heuristics, W3 riders (wav_codec, ICaptureBackend, Q-9)

This commit is contained in:
2026-07-28 18:44:48 -04:00
parent a4571cc074
commit 78a214b247
2 changed files with 431 additions and 105 deletions
+183 -40
View File
@@ -2301,7 +2301,10 @@ shell maps that pure result to a cursor. No cue logic in the shell; the shell on
> findings report — a functional-correctness/algorithm-quality complement to the SOLID/naming audit
> below. **Q-W1 is gated on Q-W0's triage being complete and Daniel signing off on each finding's
> disposition** (fix-now vs. document-and-defer). Spec: §"The pre-restructure audit wave (Q-W0)"
> below.
> below. **STATUS (2026-07-28): Q-W0 COMPLETE and SIGNED OFF — all 59 dispositions approved; the
> Q-W1 sub-gate is satisfied once the six approved fix-now remediations land (in flight on
> `pq-w0-fixes`). The audit's plan reshape is folded into this spec: Q-W2 6→8 seams, NEW wave
> Q-W2v (parallel with Q-W2), Q-W3 3→4 hoists + riders, Q-W5 + the ext-state-loop dedupe.**
## What it is
@@ -2330,6 +2333,21 @@ reinvented wheel or a numerically-fragile DSP path should be eliminated or consc
tree. Bringing the code "into the realm of something I can stand to look at" is not only a matter of
shape; it is also a matter of the code being *functionally sound*.
**STATUS (2026-07-28): Q-W0 is COMPLETE — audit run, triage done, sign-off given.** Four parallel
tracks (T1 DSP, T2 architecture, T3 env-coupled constants, T4 sizing + placement), **59
findings**; report: `docs/product/code-quality-audit.md`, appendices:
`docs/product/audit-notes/q-w0-t{1..4}-*.md`. Daniel approved **every disposition as proposed** on
2026-07-28. Six findings are fix-now *in Q-W0***T1-01** (linked-lag stereo splice alignment),
**T1-03** (Preserve prime bound + immediate `freezeTail()`), **T1-09** (`declickR_` dead-state
removal, riding the `sampler_core` edits), **T2-01(a)** (provenance wire-cursor hardening
backport), **T3-01** (gain-ramp seconds), **T3-03** (fade-ceiling seconds) — in flight on branch
`pq-w0-fixes`; **the Q-W1 sub-gate is satisfied once they land** (each with its module's CTest
target green; the audible DSP fixes with a stated before/after listening check). All other
fix-nows are assigned to the wave that already opens their file and are recorded in the wave specs
below. **The Q-11 question is answered:** the correlation-aligned SOLA pitch engine is **sound —
no technique replacement (phase-vocoder / WSOLA) warranted**; every pitch finding is a bounded
in-technique fix or a documented operating limit.
**Audit scope — the named surfaces:**
1. **DSP / audio, close eye on pitch.** Assess *algorithm quality* — correctness, artifacts,
@@ -2395,10 +2413,11 @@ the subsystem map off the folders. ReaSampler adopts the *pattern* (directory =
adapted to its own most load-bearing invariant — the pure/shell split — as the top level (see
below). Vital is GPLv3; the borrowed artifact is the **structural pattern**, not code.
## Settled decisions (Q-1 settled; Q-2..Q-6 recommended — see `docs/product/code-organization.md` §6)
## Settled decisions (Q-1/Q-10/Q-11 settled 2026-07-27; Q-5/Q-6/Q-8/Q-9 + the audit's §4 forks settled 2026-07-28 — REC history kept; see `docs/product/code-organization.md` §6 and `docs/product/code-quality-audit.md` §4)
- **Q-1 — namespace letter. SETTLED: `Q` (Quality).** Point-id family `Q1..Qn`, wave prefixes
`Q-W0` (the pre-restructure audit) then `Q-W1..Q-W6` (the structural reorg). `O` (Organization)
`Q-W0` (the pre-restructure audit) then `Q-W1..Q-W6` (the structural reorg; + **`Q-W2v`**, the
VST god-module wave added at the Q-W0 sign-off, 2026-07-28). `O` (Organization)
was set aside: the glyph reads ambiguously against zero in
point ids, and "Organization" undersells a phase measured against a *quality* bar.
- **Q-2 — JSON extraction in scope + first. REC: yes.** The 4× duplicated `Parser` is the largest
@@ -2413,17 +2432,43 @@ below). Vital is GPLv3; the borrowed artifact is the **structural pattern**, not
`audio`/`ui`/`reclaim`/`version`/`json`. Directory and namespace agree; a symbol's home is
unambiguous from either.
- **Q-5 — god-module split granularity. REC: to the audit's named seams, no finer.** Well-factored,
not atomized.
- **Q-6 — OCP registration-table. REC: in scope, last (most droppable if narrowing).**
not atomized. **SETTLED (Daniel, 2026-07-28): seams-by-responsibility with the Q-W0 T4 seam
lists adopted** — `bank_panel` 6→8 seams (+ `panel_layout`, `panel_drag`; T4-01),
`capture_orchestrator` further split with `capture_batch` (T4-02) — **and the ~600-line file
ceiling is an acceptance criterion on every split wave**: seams are the method, the ceiling is
the bar; arbitrary bisection to hit the number is rejected. One documented exception:
`sampler_core.cpp` stays whole (T4-14/T4-27).
- **Q-6 — OCP registration-table. REC: in scope, last (most droppable if narrowing).** **SETTLED
(Daniel, 2026-07-28): in scope, last wave, as planned.**
- **Q-7 — naming rides the relocation waves, no dedicated naming wave. REC: yes** (forced once
Q-3/Q-4 settle — a rename is near-free during relocation, near-pure-churn standalone).
- **Q-8 — class/module renames beyond the free namespace fix. REC: fix the two that actively
mislead** — `BankIndex``BankModel` (the `bank_model.h`/`BankIndex` file↔class word-mismatch)
and the unified JSON parser → `json::Reader`/`json::Writer` (or `json::Parser`) — **leave the
merely-quirky** (`Book`/`Bank`/`Index`, `Sample`/`AudioSample`, `MinMax`, `KitBox`). Daniel's
to call.
to call. **SETTLED (Daniel, 2026-07-28): both renames**`BankIndex``BankModel` (W1) and the
JSON parser minted as `json::Reader`/`json::Writer` (W1). From the audit, additionally:
**`ICaptureBackend` is deleted in Q-W3** (T4-26 — one deriver, zero polymorphic call sites; the
CLAUDE.md/CONTEXT "two backends behind one interface" correction **rides Q-W3's own commit**,
not earlier).
- **Q-9 — align the `capture_realtime` (shell) / `realtime_record` (pure) word-order inversion.
REC: yes, during Q-W3** (a free rider — W3 already hoists the realtime lifecycle).
REC: yes, during Q-W3** (a free rider — W3 already hoists the realtime lifecycle). **SETTLED
(Daniel, 2026-07-28): yes** — the pure module takes the stem `capture_realtime`, the shell
takes the suffix (the `drag_out``drag_out_win` model), during W3.
- **Audit §4a — VST placement. SETTLED (Daniel, 2026-07-28): T4-18** — `src/vst/` integrates into
the single `core/`/`shell/` top split as `core/instrument/{engine,map,ui}` +
`shell/instrument/`. One rule, no special case: a file's directory says whether it may touch a
*host* type (REAPER **or** VST3 SDK); the artifact boundary is a link-graph fact the sources
already straddle. The T4-19 artifact-first subtree was set aside. Directory map below updated.
- **Audit §4e — WAV/RIFF consolidation moment. SETTLED (Daniel, 2026-07-28): a named rider on
Q-W3** — one pure **`wav_codec`** owner (chunk walker + layout + build + patch), absorbing the
T4-10 ingest extraction (T2-08 / T4-23 / T4-10). The dedup-by-hash / null-test maintenance
surface gets exactly one implementation.
- **Audit §4f — Q-W2v scheduling. SETTLED (Daniel, 2026-07-28): parallel with Q-W2** (different
artifact, zero file overlap); the serial "Q-W7" alternative was set aside.
- **Audit §4b/§4c/§4d — the Q-W0 fix-now set. SETTLED (Daniel, 2026-07-28): all approved
fix-now** — T1-01 + T1-03 (with T1-09 riding), T2-01(a), T3-01 + T3-03; in flight on
`pq-w0-fixes`; landing them closes Q-W0 and opens Q-W1.
## The directory + namespace map (Q-3 / Q-4)
@@ -2434,24 +2479,42 @@ directories.
- `core/model/` (`::model`) — `bank_model`, `bank_book`, `owned_manifest`, `provenance`
- `core/view/` (`::view`) — `view_mode_model`, `view_tree`, `lane_keys`, `mode_switch`
- `core/capture/` (`::capture`) — `render_settings`, `batch_capture`, `tail_control`,
`capture_paths`, `wav_trim`, `insert_plan`
`capture_paths`, `wav_trim`, `insert_plan`; **post-Q-W3** `wav_codec` (the one pure WAV/RIFF
owner — audit §4e rider)
- `core/audio/` (`::audio`) — `peaks`
- `core/ui/` (`::ui`) — `theme`, `component_geometry`, `bank_grid`, `tab_strip`, `action_buttons`,
`prune_button`
- `core/reclaim/` (`::reclaim`) — `prune_reconcile`
- `core/version/` (`::version`) — `app_version`
- `core/json/` (`::json`) — **NEW** — extracted parser/serializer (replaces the 4 duplicate
`Parser`s)
- `core/json/` (`::json`) — **NEW** — extracted parser/serializer, minted as
`json::Reader`/`json::Writer` (replaces the 5 duplicate hand-rolled decoders — the four
`Parser`s + `tail_control`'s, T2-02)
- `core/instrument/`**T4-18 SETTLED (Daniel, 2026-07-28)** — the VST artifact's pure side
joins the one top split (directory = "may it touch a host type", REAPER *or* VST3 SDK):
- `core/instrument/engine/``sampler_core`, `pitch_shift`, `velocity_curve`, `master_gain`
- `core/instrument/map/``sample_map` (+ `component_state_io` post-Q-W2v), `bank_sync`,
`bridge_marshal`, `note_entry`, `trigger_seam`
- `core/instrument/ui/``editor_geometry`, `keyboard_strip`, `waveform_view`,
`capture_browser`, `browser_scroll`, `param_slider`, `knob_deck`, `curve_popup`,
`envelope_overlay`, `envelope_edit`, `embed_strip`
**`shell/` (REAPER-facing — subdir by subsystem, namespace as house style prefers):**
- `shell/capture/``capture`, `capture_realtime`, `provenance_shell`, `track_guid`, `item_read`;
**post-Q-W3** `capture_orchestrator`, `scope_resolve`, `realtime_lifecycle`
**post-Q-W3** `capture_orchestrator`, `capture_batch`, `scope_resolve`, `realtime_lifecycle`,
`capture_realtime_finalize` (with the Q-9 stem/suffix rename)
- `shell/panel/``draw_kit`; **post-Q-W2** `panel_render`, `panel_thumbnails`,
`panel_audition`, `panel_input`, `panel_bank_ops`, `panel_window` (from `bank_panel`)
`panel_audition`, `panel_input`, `panel_layout`, `panel_drag`, `panel_bank_ops`,
`panel_window` (from `bank_panel` — eight seams, T4-01)
- `shell/view/``view`
- `shell/persist/`**post-Q-W5** `session`, `ext_state_io`, `prune_fs` (from `persist`)
- `shell/actions/``drag_out_win`; **post-Q-W4** `design_view_actions`, `bank_actions`,
`prune_action` (from `actions`)
- `shell/instrument/``reaper_bridge`, `reasampler_embed`, `vst_entry`, `reasampler_vst.h` /
`reasampler_uid.h`; **post-Q-W2v** the editor TUs (`editor_session` / `editor_controls` /
`editor_paint_sample` / `editor_paint_browse_zone` / `editor_input_sample` /
`editor_input_browse_zone` / `editor_platform``editor_layout` hoists *pure*
`core/instrument/ui/`, discharging T2-06) and the processor TUs (`processor_state` /
`processor_reload` / lifecycle+`process()`)
**`app/`:** `main.cpp` (post-Q-W3: API-pointer ownership + `ReaperPluginEntry` + dispatch only).
@@ -2459,37 +2522,83 @@ directories.
unified `Parser` (`::json`) must not collide once flattened into granular namespaces; resolve by
subsystem home.
## The god-module split seams (Q-5)
## The god-module split seams (Q-5 — SETTLED 2026-07-28: T4 seam lists adopted; ~600 ceiling is the bar)
Split each to the audit-validated seams, no finer:
Split each to the audit-validated seams, no finer — **and every shipped TU lands under the
~600-line ceiling** (the Q-5 settlement: seams are the method, the ceiling is the bar; arbitrary
bisection to hit the number is rejected; the one documented exception is `sampler_core.cpp`).
LOC figures updated to the Q-W0 T4 census (2026-07-28):
- **`bank_panel.cpp` (2424 LOC → `shell/panel/`, Q-W2):** `panel_render` (draw/paint) /
`panel_thumbnails` (compute+cache) / `panel_audition` (preview engine — **hot path, direct
call-through**) / `panel_input` (mouse/key/wheel + new-content detection) / `panel_bank_ops`
(bank CRUD — the single owner W4 dedupes against) / `panel_window` (lifecycle + OS
drag-out/drop-target). Split the fat `bank_panel.h` per seam (I).
- **`main.cpp` (1762 LOC → hoist to `shell/capture/`, Q-W3):** `capture_orchestrator`
(`RunCapture`/`captureAndIndexOne`/`renderOffline`/batch/recapture/realtime `Run*`) /
`scope_resolve` (range/razor/track resolution + provenance assembly inputs) /
`realtime_lifecycle` (state machine + globals + selection guards). `FxBypassGuard` moves out
but **stays stack RAII** (precision-critical). `main.cpp``app/`, reduced to pointers + entry
+ dispatch.
- **`actions.cpp` (981 LOC → `shell/actions/`, Q-W4):** `design_view_actions` /
- **`bank_panel.cpp` (3459 LOC → `shell/panel/`, Q-W2 — eight seams, T4-01):** `panel_render`
(draw/paint) / `panel_thumbnails` (compute+cache) / `panel_audition` (preview engine — **hot
path, direct call-through**) / `panel_input` (mouse/key/wheel + new-content detection) /
**`panel_layout`** (toolbar/footer/menu rects + row/cluster builders + region geometry — new
seam) / **`panel_drag`** (the card-drag/hover state machine, pure mirror `card_drag` — new
seam) / `panel_bank_ops` (bank CRUD — the single owner W4 dedupes against) / `panel_window`
(lifecycle + OS drag-out/drop-target). Without the two new seams, `panel_render` (~700) and
`panel_input` (~800) would ship over the ceiling. Split the fat `bank_panel.h` per seam (I).
- **`main.cpp` (1897 LOC → hoist to `shell/capture/`, Q-W3 — four hoists, T4-02):**
`capture_orchestrator` (`RunCapture`/`captureAndIndexOne`/`renderOffline`/single-capture +
realtime/insert action bodies — lands ~450) / **`capture_batch`** (batch family +
`RunRecaptureFromSource` + the two RAII selection guards — new hoist; recapture is
planner-driven like batch and shares the guard machinery) / `scope_resolve` (range/razor/track
resolution + provenance assembly inputs) / `realtime_lifecycle` (state machine + globals).
`FxBypassGuard` moves out but **stays stack RAII** (precision-critical). `main.cpp``app/`,
reduced to pointers + entry + dispatch. **Wave riders (SETTLED 2026-07-28):** delete
`ICaptureBackend` + correct the CLAUDE.md/CONTEXT description in the same commit (T4-26);
shared `stampCaptureSample` epilogue dedupe (T2-09); `capture_realtime_finalize` split with
the Q-9 rename (T4-08); `makeUniqueTag` per-session monotonic counter (T1-11); the pure
`wav_codec` consolidation (audit §4e).
- **`actions.cpp` (1016 LOC → `shell/actions/`, Q-W4 — T4-03: seams unchanged, still
sub-600):** `design_view_actions` /
`bank_actions` / `prune_action` (`doBankPruneFolder` — the single file-deletion action). Dedupe
`promptText`/`mintBankId` + bank verbs against `panel_bank_ops`.
- **`persist.cpp` (766 LOC → `shell/persist/`, Q-W5):** `session` (lifecycle/poll +
- **`persist.cpp` (852 LOC → `shell/persist/`, Q-W5 — T4-04: seams unchanged; the pS-usage
growth landed exactly where this wave isolates it):** `session` (lifecycle/poll +
`BeginLoadProjectState` reload hook) / `ext_state_io` (serialization bridge + GUID minting +
folder relocation) / **`prune_fs`** (prune scan + `deleteOrphanFile` via `SHFileOperationW`
the isolated single file-deletion authority).
the isolated single file-deletion authority). **Wave rider (T2-04):** the `GetProjExtState`
grow-loop ×3 dedupes onto `bridge_marshal`'s generalized retry policy — `usage_scan`'s
prune-safety-adjacent copy included.
- **`reasampler_editor.cpp` (3065 LOC — the largest file in the repo → `shell/instrument/`,
Q-W2v — eight TUs, T4-11; split axis = the Sample/Browse/Zone face structure):**
`editor_session` / `editor_controls` / `editor_layout` (**pure-candidate hoist** →
`core/instrument/ui/`, `editor_geometry` the named owner — discharges T2-06's
stranded-layout-math finding) / `editor_paint_sample` / `editor_paint_browse_zone` /
`editor_input_sample` / `editor_input_browse_zone` / `editor_platform`. Rider: adopt the pure
`ThumbnailKey` on the VST side while the editor is open (T2-10).
- **`reasampler_processor.cpp` (1164 LOC → `shell/instrument/`, Q-W2v — three TUs, T4-12):**
`processor_state` / `processor_reload` / lifecycle+`process()` kept whole. **No virtual seam
on the atomic-pointer-swap reload pattern (T4-29).**
- **`sample_map` (970 LOC + 708-line header → Q-W2v, T4-13 ≡ T2-07):** resolution core vs the
**`component_state_io`** binary ComponentState codec (+ matching header split) — the codec
grows every envelope bump (v6→v11 in one quarter); the extension stops linking the whole voice
engine to serialize one preset blob. The `core/wire` LE byte-codec template
(`putLE`/`readLE`, T4-20) lands with it.
- **`sampler_core.cpp` (968 LOC + 762-line header — Q-W2v, T4-14/T4-27): the TU stays WHOLE —
the documented hot-path exception to the ~600 ceiling.** Envelope `tick()`s run
per-voice-per-sample; same-TU definition is what lets the compiler inline the stack (no LTO in
the build); a by-class split is the exact heuristic-(3) dispatch blowout. The header splits
into `zone_params.h` + `sampler_core.h`. Recorded here so nobody "fixes" it later.
## The JSON extraction (Q-2 / Q-W1)
Extract one pure **`core/json`** (`::json`): parser (`parseString`/`parseInt`/`parseKey`/
Extract one pure **`core/json`** (`::json` — minted as **`json::Reader`/`json::Writer`**, Q-8
SETTLED 2026-07-28): parser (`parseString`/`parseInt`/`parseKey`/
`skipValue` + escape) + serialize/emit helpers. Rewire `bank_model`, `bank_book`,
`view_mode_model`, `owned_manifest` onto it and **delete their four hand-rolled `Parser`s**.
`view_mode_model`, `owned_manifest`, **and `tail_control` (T2-02 — the fifth hand-rolled decoder
the §2 audit undercounted)** onto it and **delete all five hand-rolled decoders**.
Round-trip output must be **byte-identical** to before — this is a structural dedupe, not a format
change. Off all hot paths (serialization runs at save/load, never per frame) — safe to abstract
freely.
freely. **W1 siblings (from the Q-W0 sign-off):** the shared `readFileBytes` pure helper
(T2-03); the length-prefixed wire-`Cursor` collapse into one shared wire codec beside
`core/json`, consumed by `provenance` / `assignment_request` / `sample_usage` /
`parseBankGeneration` (T2-01(b) — the structural half; the hardening backport lands in Q-W0);
the **concrete** `ui::Rect` unification + `contains()` + per-role aliases, retiring the
XYWH-vs-LTRB fork — NOT a template (T2-05 ≡ T4-21), with the `clamp01` rider (T4-24) and the
`hitIndex` template only as an opportunistic follow-on (T4-22); the `slot_map` extraction
(T4-05) and optional `view_mode_model` planner split (T4-06) riding files W1 already opens; the
relocation scope grows to the ~20 clean VST pure libs under `core/instrument/` (T4-18).
## The OCP registration-table (Q-6 / Q-W6)
@@ -2515,7 +2624,7 @@ focus. The audit (2026-07-27) is grep-verified; the load-bearing findings:
one `json::Parser` in Q-W1; the shared pure-UI rect types `FooterRect` / `ButtonRect` (defined in
`prune_button.h`, reused by `footer_bar.h` under an explicit hand-collision "NAME NOTE") get one
`ui::` owner; `Sample` (`model::`) vs `AudioSample` (`audio::`) de-collide by home.
- **Genuine renames (Q-8/Q-9 — Daniel's call):** `BankIndex``BankModel` (the `bank_model.h`
- **Genuine renames (Q-8/Q-9 — SETTLED, Daniel 2026-07-28: all land):** `BankIndex``BankModel` (the `bank_model.h`
file↔class word-mismatch — the worst legibility wart, rec: rename the class so the model family
reads `BankModel`/`BankBook`/`ViewModeModel`); the unified JSON parser named `json::Reader`/
`json::Writer` at W1 mint; align `capture_realtime`(shell)/`realtime_record`(pure) to the house
@@ -2550,6 +2659,25 @@ the following are acceptance criteria on every point:
**Net:** every recommended split falls on a cold path or preserves call/inline shape on the two
hot ones. *A split that would add a hot-path indirection is out of scope — rework it or drop it.*
## Structural heuristics (Daniel, 2026-07-28 — acceptance criteria phase-wide)
Three heuristics postdate the original framing and bind every wave. They **generalize** the
three-hot-path performance guardrail above — they do not replace it:
1. **More directories is a must; more files is good; ~600-line file ceiling.** SRP applies to
namespaces, encapsulation, and file organization alike. The ceiling is the *bar*, the audit's
named seams are the *method*: a file landing over ~600 needs a responsibility seam, not an
arbitrary bisection (bisection-to-hit-the-number is rejected). A documented hot-path
exception (`sampler_core.cpp`, T4-14/T4-27) is legitimate; silent overshoot is not.
2. **Templates are the right tool for compile-time dedup — use them where earned.** The LE
byte-codec `putLE`/`readLE` (T4-20) is earned: compile-time dispatch, zero runtime cost, off
the hot paths. The rect family is NOT (T4-21): the types differ in name only, so one
**concrete** `ui::Rect` — a template there would model nothing.
3. **SOLID is great, but saved CPU is better.** No dispatch-stack blowouts *anywhere* — not just
the three named hot paths; prefer static polymorphism where the types are compile-time-known.
The T4-27 warning is the canonical case: a by-class `sampler_core` split would put virtual
envelope `tick()`s on the per-voice-per-sample path — exactly the blowout this forbids.
## The GATE (load-bearing — Phase Q is last)
Phase Q is **gated on the tree being otherwise quiescent.** Daniel's plain readiness target:
@@ -2583,16 +2711,27 @@ every commit), a property only an *incremental* reorg uses. Risk-ordered:
pre-restructure audit wave (Q-W0)"). Produces a written, triaged findings report; runs **first**
and **gates Q-W1** — no structural point begins until the triage closes and Daniel signs off on
every disposition. Fix-now findings are remediated here or folded into the wave that opens the
file; the report may add/reshape downstream Q-W1..Q-W6 points before they start.
- **Q-W1** — safe opener: `core/json` extract (delete 4 `Parser`s) + impose the directory/
file; the report may add/reshape downstream Q-W1..Q-W6 points before they start. **COMPLETE
and signed off 2026-07-28; the sub-gate closes when the six fix-now remediations land
(`pq-w0-fixes`).**
- **Q-W1** — safe opener: `core/json` extract (delete the 5 hand-rolled decoders — T2-02 adds
`tail_control`) + impose the directory/
namespace layout on the 30 clean pure libs + clean shells (pure relocation, no logic change).
All later waves assume this layout. **Carries the naming collision fixes + the model-class
renames (Q-8), which are free during this relocation.**
- **Q-W2..Q-W5** — the four god-module splits, one per wave, risk-ordered (`bank_panel`
`main.cpp``actions.cpp``persist.cpp`). Q-W4 depends on Q-W2 (`panel_bank_ops` dedupe
target); Q-W5 best after Q-W4 (`prune_action``prune_fs` routing); otherwise parallel-safe.
renames (Q-8), which are free during this relocation.** **Scope grown by Q-W0 (2026-07-28):**
+ `readFileBytes` (T2-03), the wire-`Cursor` codec (T2-01(b)), the concrete `ui::Rect`
unification (T2-05 ≡ T4-21) + `clamp01` (T4-24), the `slot_map`/planner riders (T4-05/T4-06),
and the ~20 clean VST pure libs under `core/instrument/` (T4-18).
- **Q-W2..Q-W5 (+ Q-W2v)** — the god-module splits, risk-ordered (`bank_panel`
`main.cpp``actions.cpp``persist.cpp`), plus **Q-W2v** (NEW, added at the Q-W0 sign-off:
the VST god-modules — editor eight TUs / processor three TUs / `component_state_io`;
`sampler_core` TU whole, the documented exception), which **runs parallel with Q-W2**
(different artifact, zero file overlap — audit §4f SETTLED). Q-W4 depends on Q-W2
(`panel_bank_ops` dedupe target); Q-W5 best after Q-W4 (`prune_action``prune_fs` routing);
otherwise parallel-safe.
**Q-W2 carries the `panel_*` names; Q-W3 carries the `capture_realtime`/`realtime_record`
word-order fix (Q-9).**
word-order fix (Q-9) + the settled riders (`ICaptureBackend` deletion + doc correction,
`wav_codec`, `stampCaptureSample` dedupe, T1-11, `capture_realtime_finalize`).**
- **Q-W6** — OCP registration-table + residual fat-header (I) splits. Depends on Q-W3 (registration
code isolated first). Sequenced last; most droppable if narrowing.
- **Naming (Q-7): no dedicated wave** — every rename rides the wave already relocating/splitting
@@ -2624,7 +2763,9 @@ every commit), a property only an *incremental* reorg uses. Risk-ordered:
realtime-tick — ever (a hard acceptance bar, not advice).
- **No design-level (D-letter SOLID) rework.** `main`/`bank_panel` depending on concrete capture
backends is a low-priority Dependency-Inversion concern — **out of scope** (a design change, not
a reorg). Phase Q reorganizes; it does not re-architect interfaces.
a reorg). Phase Q reorganizes; it does not re-architect interfaces. (Deleting the *dead*
`ICaptureBackend` abstraction in Q-W3 is the opposite move — removing a false interface with
one deriver and zero polymorphic call sites, T4-26 — and is in scope.)
- **No `peaks` data-ownership change.** `peaks` forcing a whole-file `std::vector<float>` copy on
the thumbnail path is noted but **not touched** — reworking it risks the hot path.
- **No big-bang commit.** Every wave is independently landable and CTest-green; reject a change set
@@ -2632,5 +2773,7 @@ every commit), a property only an *incremental* reorg uses. Risk-ordered:
- **Do not begin before the GATE.** Re-confirm the tree is quiescent (Phase S + L + D2 merged/closed;
M9 abandoned) before any Q point. **And do not begin any structural point (Q-W1+) before the Q-W0
sub-gate:** the audit's triage is complete and Daniel has signed off on every finding's disposition.
(Sign-off given 2026-07-28; the sub-gate now closes when the six fix-now remediations land on
`pq-w0-fixes`.)
- **Verify** the CMake `src/` path updates and the SWELL/LICE surfaces still resolve after
relocation, as the existing build already requires.