docs(phase-q): reconcile gate to S+L3 and add naming-consistency dimension

Correct the Phase Q gate (L2 landed; outstanding is Phase S + Phase L L3;
D2 complete, M9 deferred). Add a grep-verified naming audit (code-organization
§2b) and forks Q-7/Q-8/Q-9; FOREVER-STABLE contract strings excluded.
This commit is contained in:
2026-07-27 03:50:20 -04:00
parent a434ef47f8
commit 8c65069fc3
3 changed files with 394 additions and 50 deletions
+69 -20
View File
@@ -473,25 +473,43 @@ feature work runs in parallel, ungated by Phase L.
> `docs/product/code-organization.md`. When a point lands, doc-keeper moves it to
> `COMPLETED.md`.
>
> **THE GATE (load-bearing — state first).** Phase Q is **gated on the tree being otherwise
> quiescent.** It does not begin until **Phase S has merged to dev**, **Phase L (L2 + L3) has
> merged to dev**, any **D2 residuals** are closed, and **M9** is landed-or-abandoned. *Why:*
> Phase Q touches **nearly every file in `src/`** (relocate into subdirectories, re-namespace
> every header, split the four largest TUs). Every large in-flight branch (Phase S on its
> worktree, Phase L's `bank_panel`-touching L2/L3) is diffed against the *current flat layout*;
> landing a rename-and-relocate-everything reorg mid-flight forces every open branch through the
> worst conflict class (every hunk moved, every qualified reference changed) — a combinatorial
> re-resolution, not a linear one. Phase Q is *last* precisely because it reshapes the ground
> every other pillar stands on. Landing it early taxes every subsequent phase; landing it last
> taxes nothing. **Do not begin any Q point until the gate is satisfied.**
> **THE GATE (load-bearing — state first; reconciled to reality 2026-07-27).** Phase Q is
> **gated on the tree being otherwise quiescent.** Daniel's plain readiness target: **"when
> Phase S and L3 are finished."** As of 2026-07-27 the outstanding work is precisely: **(1)
> Phase S** merged to dev (the large second-artifact branch, currently on the phase-s worktree —
> the dominant gate item); **(2) Phase L L3** merged to dev (the VST restyle, itself gated on
> Phase S landing on dev). **L1/L2/L4/L5/L6/L7 have already landed** (see `COMPLETED.md`) — the
> earlier "L2 + L3" wording was stale and is corrected here to **L3 only**. **D2** is functionally
> complete (D2-W1..W3-B landed; the lone open item, a per-track lane-split panel indicator, is
> *explicitly deferred*, not a blocking residual). **M9** (slots) is *explicitly deferred*
> (Daniel, 2026-07-26), not scheduled work. D2 and M9 are named in the gate only so that
> *reactivating* either re-arms the quiescence condition; neither blocks the gate today. *Why the
> gate:* Phase Q touches **nearly every file in `src/`** (relocate into subdirectories,
> re-namespace every header, split the four largest TUs, plus the §2b renames). Every large
> in-flight branch (Phase S on its worktree, and L3 once it lands) is diffed against the *current
> flat layout*; landing a rename-and-relocate-everything reorg mid-flight forces every open branch
> through the worst conflict class (every hunk moved, every qualified reference changed) — a
> combinatorial re-resolution, not a linear one. Phase Q is *last* precisely because it reshapes
> the ground every other pillar stands on. Landing it early taxes every subsequent phase; landing
> it last taxes nothing. **Do not begin any Q point until the gate is satisfied.**
>
> **M9 disposition (Daniel-decision note).** M9 is recorded "deferred indefinitely," which is not
> the same as "abandoned." Immaterial to the gate (both clear it). It matters only if M9 is ever
> reactivated: *before* Phase Q it lands cheaply on the flat layout; *after*, it is authored
> against the reorganized tree. Surfaced, not silently resolved — no action unless Daniel schedules
> M9. (Full note: `docs/product/code-organization.md` §4.)
>
> **Settled (Q-1, this-doc):** the phase is **`Q` (Quality)**; point-id family `Q1..Qn`, wave
> prefixes `Q-W1..Q-W6`. **Recommended, Daniel's to call (Q-2..Q-6, see
> prefixes `Q-W1..Q-W6`. **Recommended, Daniel's to call (Q-2..Q-9, see
> `docs/product/code-organization.md` §6):** Q-2 JSON extraction in scope + first (rec: yes);
> Q-3 directory shape `core/`/`shell/`/`app/` top-split with subsystem dirs beneath (rec: this
> over pure-Vital subsystem-first — it makes the pure/shell invariant *structural*); Q-4
> sub-namespace to match sub-directory (rec: both); Q-5 split god-modules to the audit's named
> seams, no finer (rec: yes); Q-6 OCP registration-table as the final wave (rec: in, last).
> seams, no finer (rec: yes); Q-6 OCP registration-table as the final wave (rec: in, last);
> **Q-7 naming rides the relocation waves, no dedicated naming wave (rec: yes — forced once
> Q-3/Q-4 settle); Q-8 class/module renames — fix the two that actively mislead (`BankIndex`→
> `BankModel`; the JSON `Parser`→`json::Reader`/`Writer`), leave the merely-quirky (rec);
> Q-9 align the `capture_realtime`/`realtime_record` shell↔core word order during W3 (rec: yes).**
>
> **HARD CONSTRAINT — performance (see CONTEXT.md §Phase Q, `docs/product/code-organization.md`
> §3).** The reorg must cost **zero runtime.** On the three hot paths — `peaks` envelope
@@ -502,6 +520,20 @@ feature work runs in parallel, ungated by Phase L.
> an acceptance criterion on every point: *a split that would add a hot-path indirection is out
> of scope — rework it or drop it.*
>
> **NAMING dimension (added 2026-07-27; grep-verified audit in `docs/product/code-organization.md`
> §2b).** Beyond giving symbols a directory + namespace *home* (Q-3/Q-4), Phase Q also gives
> poorly/inconsistently-named symbols a consistent *name*, against the same Vital bar. The audit
> found: four `class Parser` copies collapsing to one `json::Parser` (Q-W1); shared pure-UI rect
> types (`FooterRect`/`ButtonRect`) that the codebase already hand-checks for collision
> (`footer_bar.h`'s "NAME NOTE") — resolved by the Q-4 sub-namespaces for free; the
> `bank_model`/`BankIndex` file↔class word-mismatch (Q-8); and the `capture_realtime`/
> `realtime_record` shell↔core word-order inversion (Q-9). **Renames ride the wave that already
> relocates/splits the file — no dedicated naming wave (Q-7);** the geometry-mirror
> `compute*`/`hitTest*` verb vocabulary and the `_tests` suffix are already consistent and are
> preserved verbatim. Naming changes are zero-behavior-change like the rest of Phase Q, and the
> FOREVER-STABLE contract strings (command ids, action names, ext-state namespace/keys, VST3 UID)
> are **not** C++ symbols and are never renamed.
>
> **Every point is independently landable and CTest-green at EVERY step.** The CMake
> per-module static-lib + per-module test-executable seams already draw the module boundaries;
> a file move + namespace change is mechanically verifiable — `ctest --test-dir build` is green
@@ -536,7 +568,13 @@ unified `Parser` (json) do not collide once sub-namespaced. No REAPER type cross
`main.cpp` to `app/`. Update `CMakeLists.txt` `src/` paths only (no target-graph change).
- [ ] Apply sub-namespaces matching the directories on every relocated *clean* module (the
god-modules re-namespace their own new TUs as they split, W2W5). Resolve `Sample`/
`AudioSample`/`Parser` homes.
`AudioSample`/`Parser` homes. **This alone resolves the naming *collisions*** (§2b.2): the
shared pure-UI rect types (`FooterRect`/`ButtonRect`/`Selection`/`CellRect`) get one `ui::`
owner — retire the hand-collision "NAME NOTE" in `footer_bar.h`.
- [ ] **Naming riders (Q-8, if settled):** rename the survivor JSON parser to `json::Parser`
(or `json::Reader`/`json::Writer`); if Daniel takes the `BankIndex`→`BankModel` rename, land
it here (mechanical class rename, verified by `bank_model_tests`). No rename on a file this
wave isn't already relocating (Q-7).
- [ ] Confirm CTest green + no hot-path change: `peaks`/audition/realtime-tick untouched by this
wave (pure relocation of clean modules; `peaks` stays a free function).
@@ -588,6 +626,10 @@ path gains an `InsertMedia` call). The realtime idle fast-path is still a single
- [ ] Hoist the realtime-capture lifecycle state machine + globals + the two RAII selection
guards → `realtime_lifecycle`; **idle tick stays a single pointer test.**
- [ ] Leave `main.cpp` = API-pointer ownership + `ReaperPluginEntry` + dispatch; move to `app/`.
- [ ] **Naming rider (Q-9, if settled):** align the `capture_realtime` (shell) / `realtime_record`
(pure) word-order inversion to the house shell↔core convention (rec: stem `capture_realtime`,
shell suffixed) — a free rider since W3 already hoists the realtime lifecycle. No rename on a
file this wave isn't already touching (Q-7).
- [ ] Verify in DAW: null test nulls, bit-identical repeats match, capture≠placement holds;
CTest green; no realtime-tick branch-shape change.
@@ -657,7 +699,8 @@ droppable point if the phase needs narrowing (Q-6).
## Phase Q — sequencing
```
GATE: Phase S + Phase L (L2+L3) + D2 residuals + M9 all merged/closed to dev (tree quiescent)
GATE: Phase S + Phase L L3 merged to dev (D2 complete, M9 deferred) — tree quiescent
("when Phase S and L3 are finished" — L1/L2/L4L7 already landed)
Q-W1 (safe opener: core/json extract + directory/namespace layout on clean modules)
@@ -681,8 +724,14 @@ is independently landable and CTest-green.
C++ symbols is orthogonal to these on-the-wire/on-disk contract strings; keep them byte-identical
(per-channel, per the Phase V V4 contract). (CONTEXT.md §Phase Q.)
- **Name-collision sweep on sub-namespacing** — `Sample` (model) vs `AudioSample` (audio) vs the
unified `Parser` (json), and any other cross-lib name that collides once flattened into
granular namespaces. Resolve by each symbol's new subsystem home before landing W1. (audit §2.4;
`docs/product/code-organization.md` §6 Q-4.)
- **The GATE** — do not begin any Q point until Phase S + Phase L (L2/L3) + D2 residuals + M9 are
merged/closed and the tree is quiescent. Re-confirm quiescence against dev before W1.
unified `Parser` (json), plus the shared pure-UI rect types `FooterRect`/`ButtonRect` (already
hand-collision-checked in `footer_bar.h`), and any other cross-lib name that collides once
flattened into granular namespaces. Resolve by each symbol's new subsystem home before landing
W1. (naming audit §2b.2; `docs/product/code-organization.md` §6 Q-4/Q-8.)
- **Naming stays zero-behavior-change and off the wire** — the §2b renames touch C++ symbols only;
no `command_id` string, action display name, ext-state namespace/key, `reasampler:` lane prefix,
or VST3 class UID is renamed (naming audit §2b.5). A rename that would alter a shipped contract
literal is out of scope, full stop.
- **The GATE** — do not begin any Q point until **Phase S + Phase L L3** are merged to dev and the
tree is quiescent (D2 complete, M9 deferred; a reactivation of either re-arms the gate).
Re-confirm quiescence against dev before W1.