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:
+65
-10
@@ -1976,6 +1976,15 @@ below). Vital is GPLv3; the borrowed artifact is the **structural pattern**, not
|
|||||||
- **Q-5 — god-module split granularity. REC: to the audit's named seams, no finer.** Well-factored,
|
- **Q-5 — god-module split granularity. REC: to the audit's named seams, no finer.** Well-factored,
|
||||||
not atomized.
|
not atomized.
|
||||||
- **Q-6 — OCP registration-table. REC: in scope, last (most droppable if narrowing).**
|
- **Q-6 — OCP registration-table. REC: in scope, last (most droppable if narrowing).**
|
||||||
|
- **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.
|
||||||
|
- **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).
|
||||||
|
|
||||||
## The directory + namespace map (Q-3 / Q-4)
|
## The directory + namespace map (Q-3 / Q-4)
|
||||||
|
|
||||||
@@ -2052,6 +2061,35 @@ mirror-unregisters from the same table. Command-id + display strings stay **byte
|
|||||||
(FOREVER-STABLE, per-channel — the Phase V V4 contract). Also split residual fat headers
|
(FOREVER-STABLE, per-channel — the Phase V V4 contract). Also split residual fat headers
|
||||||
(`capture.h`/`persist.h`) alongside their TU splits (I).
|
(`capture.h`/`persist.h`) alongside their TU splits (I).
|
||||||
|
|
||||||
|
## The naming dimension (Q-7 / Q-8 / Q-9 — grep-verified audit in `docs/product/code-organization.md` §2b)
|
||||||
|
|
||||||
|
Alongside giving symbols a directory + namespace *home* (Q-3/Q-4), Phase Q gives
|
||||||
|
inconsistently/poorly-named symbols a consistent *name* — same Vital bar, orthogonal to the SOLID
|
||||||
|
focus. The audit (2026-07-27) is grep-verified; the load-bearing findings:
|
||||||
|
|
||||||
|
- **Already consistent — preserve verbatim:** the geometry-mirror verb vocabulary
|
||||||
|
(`compute<Thing>Rects`/`compute<Thing>` + `hitTest<Thing>`, verified across `bank_grid` /
|
||||||
|
`mode_switch` / `action_buttons` / `action_bar` / `tab_strip` / `prune_button` / `overflow_menu` /
|
||||||
|
`footer_bar` / `card_drag` / `component_geometry`) and the uniform `<module>_tests` CTest suffix.
|
||||||
|
- **Collisions — resolved by the Q-4 sub-namespaces for free:** four `class Parser`
|
||||||
|
(`bank_model.cpp` / `bank_book.cpp` / `owned_manifest.cpp` / `view_mode_model.cpp`) collapse to
|
||||||
|
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`
|
||||||
|
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
|
||||||
|
shell↔core convention (`drag_out`↔`drag_out_win` is the model) during Q-W3.
|
||||||
|
- **Sequencing (Q-7):** renames ride the wave that already relocates/splits the file — **no
|
||||||
|
dedicated naming wave.** Rule: *no rename lands on a file the wave isn't otherwise touching.* W1
|
||||||
|
carries the collision + model-class renames; W2 the `panel_*` names; W3 the realtime word-order
|
||||||
|
fix. Zero-behavior-change like the rest of Phase Q; verified by the module's own test executable.
|
||||||
|
- **Out of scope (never renamed):** the FOREVER-STABLE contract strings are not C++ symbols —
|
||||||
|
`command_id` strings, action display names, ext-state namespace (`"reasampler"`/`"reasampler_beta"`)
|
||||||
|
and keys, the `reasampler:` lane prefix, the VST3 class UID. Renaming a C++ class is orthogonal
|
||||||
|
to these literals (audit §2b.5).
|
||||||
|
|
||||||
## Performance guardrails (HARD CONSTRAINT — Daniel's non-negotiable)
|
## Performance guardrails (HARD CONSTRAINT — Daniel's non-negotiable)
|
||||||
|
|
||||||
The reorg must cost **zero runtime.** The two hot paths must keep their exact call/inline shape;
|
The reorg must cost **zero runtime.** The two hot paths must keep their exact call/inline shape;
|
||||||
@@ -2075,15 +2113,27 @@ hot ones. *A split that would add a hot-path indirection is out of scope — rew
|
|||||||
|
|
||||||
## The GATE (load-bearing — Phase Q is last)
|
## The GATE (load-bearing — Phase Q is last)
|
||||||
|
|
||||||
Phase Q is **gated on the tree being otherwise quiescent.** It does not begin until **Phase S has
|
Phase Q is **gated on the tree being otherwise quiescent.** Daniel's plain readiness target:
|
||||||
merged to dev**, **Phase L (L2 + L3) has merged to dev**, any **D2 residuals** are closed, and
|
**"when Phase S and L3 are finished."** As of 2026-07-27 the outstanding work is precisely
|
||||||
**M9** is landed-or-abandoned. *Why:* Phase Q touches **nearly every file in `src/`** (relocate,
|
**(1) Phase S** merged to dev (the large second-artifact branch, currently on the phase-s worktree)
|
||||||
re-namespace, split the four largest TUs); every large in-flight branch (Phase S on its worktree,
|
and **(2) Phase L L3** merged to dev (the VST restyle, itself gated on Phase S). **L1/L2/L4/L5/L6/L7
|
||||||
Phase L's `bank_panel`-touching L2/L3) is diffed against the *current flat layout*, so landing a
|
have already landed** (see `COMPLETED.md`) — the earlier "L2 + L3" wording was stale and is
|
||||||
rename-and-relocate-everything reorg mid-flight forces every open branch through the worst conflict
|
corrected to **L3 only**. **D2** is functionally complete (D2-W1..W3-B landed; its lone open item,
|
||||||
class — a combinatorial re-resolution, not a linear one. Phase Q is *last* precisely because it
|
a per-track lane-split panel indicator, is *explicitly deferred*, not a blocking residual). **M9**
|
||||||
reshapes the ground every other pillar stands on: landing it early taxes every subsequent phase;
|
(slots) is *explicitly deferred* (Daniel, 2026-07-26), not scheduled work. D2 and M9 are named here
|
||||||
landing it last taxes nothing. Re-confirm quiescence against dev before Q-W1.
|
only so that *reactivating* either re-arms the quiescence condition; neither blocks the gate today.
|
||||||
|
*Why:* Phase Q touches **nearly every file in `src/`** (relocate, re-namespace, split the four
|
||||||
|
largest TUs, plus the §2b renames); every large in-flight branch (Phase S on its worktree, L3 once
|
||||||
|
it lands) is diffed against the *current flat layout*, so landing a rename-and-relocate-everything
|
||||||
|
reorg mid-flight forces every open branch through the worst conflict class — 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. Re-confirm quiescence against dev before Q-W1.
|
||||||
|
|
||||||
|
> **M9 disposition (Daniel-decision note).** "Deferred indefinitely" ≠ "abandoned." Immaterial to
|
||||||
|
> the gate (both clear it); matters only if M9 is reactivated — *before* Phase Q it lands cheaply on
|
||||||
|
> the flat layout, *after* it is authored against the reorganized tree. Surfaced, not silently
|
||||||
|
> resolved (full note: `docs/product/code-organization.md` §4).
|
||||||
|
|
||||||
## Wave sequencing (each independently landable, CTest-green at every step)
|
## Wave sequencing (each independently landable, CTest-green at every step)
|
||||||
|
|
||||||
@@ -2093,12 +2143,17 @@ every commit), a property only an *incremental* reorg uses. Risk-ordered:
|
|||||||
|
|
||||||
- **Q-W1** — safe opener: `core/json` extract (delete 4 `Parser`s) + impose the directory/
|
- **Q-W1** — safe opener: `core/json` extract (delete 4 `Parser`s) + impose the directory/
|
||||||
namespace layout on the 30 clean pure libs + clean shells (pure relocation, no logic change).
|
namespace layout on the 30 clean pure libs + clean shells (pure relocation, no logic change).
|
||||||
All later waves assume this layout.
|
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` →
|
- **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
|
`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.
|
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).**
|
||||||
- **Q-W6** — OCP registration-table + residual fat-header (I) splits. Depends on Q-W3 (registration
|
- **Q-W6** — OCP registration-table + residual fat-header (I) splits. Depends on Q-W3 (registration
|
||||||
code isolated first). Sequenced last; most droppable if narrowing.
|
code isolated first). Sequenced last; most droppable if narrowing.
|
||||||
|
- **Naming (Q-7): no dedicated wave** — every rename rides the wave already relocating/splitting
|
||||||
|
its file; a rename that would touch an otherwise-untouched file is deferred.
|
||||||
|
|
||||||
## Precision / invariant implications (what Phase Q does NOT change)
|
## Precision / invariant implications (what Phase Q does NOT change)
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
> `docs/product/code-organization.md`. When a point lands, doc-keeper moves it to
|
||||||
> `COMPLETED.md`.
|
> `COMPLETED.md`.
|
||||||
>
|
>
|
||||||
> **THE GATE (load-bearing — state first).** Phase Q is **gated on the tree being otherwise
|
> **THE GATE (load-bearing — state first; reconciled to reality 2026-07-27).** Phase Q is
|
||||||
> quiescent.** It does not begin until **Phase S has merged to dev**, **Phase L (L2 + L3) has
|
> **gated on the tree being otherwise quiescent.** Daniel's plain readiness target: **"when
|
||||||
> merged to dev**, any **D2 residuals** are closed, and **M9** is landed-or-abandoned. *Why:*
|
> Phase S and L3 are finished."** As of 2026-07-27 the outstanding work is precisely: **(1)
|
||||||
> Phase Q touches **nearly every file in `src/`** (relocate into subdirectories, re-namespace
|
> Phase S** merged to dev (the large second-artifact branch, currently on the phase-s worktree —
|
||||||
> every header, split the four largest TUs). Every large in-flight branch (Phase S on its
|
> the dominant gate item); **(2) Phase L L3** merged to dev (the VST restyle, itself gated on
|
||||||
> worktree, Phase L's `bank_panel`-touching L2/L3) is diffed against the *current flat layout*;
|
> Phase S landing on dev). **L1/L2/L4/L5/L6/L7 have already landed** (see `COMPLETED.md`) — the
|
||||||
> landing a rename-and-relocate-everything reorg mid-flight forces every open branch through the
|
> earlier "L2 + L3" wording was stale and is corrected here to **L3 only**. **D2** is functionally
|
||||||
> worst conflict class (every hunk moved, every qualified reference changed) — a combinatorial
|
> complete (D2-W1..W3-B landed; the lone open item, a per-track lane-split panel indicator, is
|
||||||
> re-resolution, not a linear one. Phase Q is *last* precisely because it reshapes the ground
|
> *explicitly deferred*, not a blocking residual). **M9** (slots) is *explicitly deferred*
|
||||||
> every other pillar stands on. Landing it early taxes every subsequent phase; landing it last
|
> (Daniel, 2026-07-26), not scheduled work. D2 and M9 are named in the gate only so that
|
||||||
> taxes nothing. **Do not begin any Q point until the gate is satisfied.**
|
> *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
|
> **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);
|
> `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
|
> 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
|
> 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
|
> 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`
|
> **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
|
> §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
|
> an acceptance criterion on every point: *a split that would add a hot-path indirection is out
|
||||||
> of scope — rework it or drop it.*
|
> 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
|
> **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;
|
> 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
|
> 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).
|
`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
|
- [ ] Apply sub-namespaces matching the directories on every relocated *clean* module (the
|
||||||
god-modules re-namespace their own new TUs as they split, W2–W5). Resolve `Sample`/
|
god-modules re-namespace their own new TUs as they split, W2–W5). 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
|
- [ ] 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).
|
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
|
- [ ] Hoist the realtime-capture lifecycle state machine + globals + the two RAII selection
|
||||||
guards → `realtime_lifecycle`; **idle tick stays a single pointer test.**
|
guards → `realtime_lifecycle`; **idle tick stays a single pointer test.**
|
||||||
- [ ] Leave `main.cpp` = API-pointer ownership + `ReaperPluginEntry` + dispatch; move to `app/`.
|
- [ ] 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;
|
- [ ] Verify in DAW: null test nulls, bit-identical repeats match, capture≠placement holds;
|
||||||
CTest green; no realtime-tick branch-shape change.
|
CTest green; no realtime-tick branch-shape change.
|
||||||
|
|
||||||
@@ -657,7 +699,8 @@ droppable point if the phase needs narrowing (Q-6).
|
|||||||
|
|
||||||
## Phase Q — sequencing
|
## 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/L4–L7 already landed)
|
||||||
│
|
│
|
||||||
▼
|
▼
|
||||||
Q-W1 (safe opener: core/json extract + directory/namespace layout on clean modules)
|
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
|
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.)
|
(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
|
- **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
|
unified `Parser` (json), plus the shared pure-UI rect types `FooterRect`/`ButtonRect` (already
|
||||||
granular namespaces. Resolve by each symbol's new subsystem home before landing W1. (audit §2.4;
|
hand-collision-checked in `footer_bar.h`), and any other cross-lib name that collides once
|
||||||
`docs/product/code-organization.md` §6 Q-4.)
|
flattened into granular namespaces. Resolve by each symbol's new subsystem home before landing
|
||||||
- **The GATE** — do not begin any Q point until Phase S + Phase L (L2/L3) + D2 residuals + M9 are
|
W1. (naming audit §2b.2; `docs/product/code-organization.md` §6 Q-4/Q-8.)
|
||||||
merged/closed and the tree is quiescent. Re-confirm quiescence against dev before W1.
|
- **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.
|
||||||
|
|||||||
@@ -14,10 +14,11 @@ Its build roadmap lives in **PLAN.md §Phase Q** and its authoritative spec in
|
|||||||
(a grep-verified SOLID audit), the target directory/namespace shape grounded in the Vital
|
(a grep-verified SOLID audit), the target directory/namespace shape grounded in the Vital
|
||||||
reference, and the numbered fork decisions.
|
reference, and the numbered fork decisions.
|
||||||
|
|
||||||
**Status:** framed by product-designer (2026-07-26). Forks Q-1 … Q-6 below are the decision
|
**Status:** framed by product-designer (2026-07-26); gate reconciled + naming dimension added
|
||||||
record; **Q-1 (namespace letter) is settled by this doc**; the remaining forks carry a
|
(2026-07-27). Forks Q-1 … Q-9 below are the decision record; **Q-1 (namespace letter) is settled
|
||||||
leading recommendation and are Daniel's to call. The SOLID audit that grounds every claim
|
by this doc**; the remaining forks carry a leading recommendation and are Daniel's to call. Two
|
||||||
is a **grep-verified** staff-engineer analysis of the actual `src/` tree, reproduced in §2.
|
grep-verified audits ground every claim: a **SOLID audit** (§2) and a **naming/symbol-consistency
|
||||||
|
audit** (§2b) — both staff-engineer-rigor analyses of the actual `src/` tree.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -28,7 +29,10 @@ is a **grep-verified** staff-engineer analysis of the actual `src/` tree, reprod
|
|||||||
the discipline CMake-enforces). What Phase Q fixes is that the *shape* of the code doesn't
|
the discipline CMake-enforces). What Phase Q fixes is that the *shape* of the code doesn't
|
||||||
yet read the way the architecture actually is: `src/` is one flat 45-file directory, all
|
yet read the way the architecture actually is: `src/` is one flat 45-file directory, all
|
||||||
37 headers sit in one flat `reasampler` namespace, four modules have grown into
|
37 headers sit in one flat `reasampler` namespace, four modules have grown into
|
||||||
god-modules, and one utility (JSON parsing) is copy-pasted across four models.
|
god-modules, one utility (JSON parsing) is copy-pasted across four models, and a set of
|
||||||
|
symbols are named inconsistently or collision-prone (§2b). Phase Q addresses four dimensions:
|
||||||
|
**structure** (directories), **encapsulation** (namespaces + JSON dedupe), **factoring**
|
||||||
|
(god-module splits), and **naming** (a consistent component-naming scheme, §2b + Q-7…Q-9).
|
||||||
- **The quality bar is Vital** (§1). Vital groups its ~1,000-file synth by *subsystem*
|
- **The quality bar is Vital** (§1). Vital groups its ~1,000-file synth by *subsystem*
|
||||||
(`common/` `synthesis/` `interface/` `plugin/`) with nested functional sub-dirs. That is
|
(`common/` `synthesis/` `interface/` `plugin/`) with nested functional sub-dirs. That is
|
||||||
the aspirational shape: the directory tree *is* the architecture diagram. ReaSampler's
|
the aspirational shape: the directory tree *is* the architecture diagram. ReaSampler's
|
||||||
@@ -40,11 +44,19 @@ is a **grep-verified** staff-engineer analysis of the actual `src/` tree, reprod
|
|||||||
added virtual dispatch, no header→TU indirection on a hot path.** This is an explicit
|
added virtual dispatch, no header→TU indirection on a hot path.** This is an explicit
|
||||||
acceptance criterion on every point, not a footnote (§3).
|
acceptance criterion on every point, not a footnote (§3).
|
||||||
- **This phase is GATED on the tree being otherwise quiescent** (§4). A structural reorg that
|
- **This phase is GATED on the tree being otherwise quiescent** (§4). A structural reorg that
|
||||||
lands while Phase S (on the phase-s worktree) and Phase L (L2/L3) are mid-flight would
|
lands while Phase S (on the phase-s worktree) is mid-flight would create catastrophic merge
|
||||||
create catastrophic merge conflicts — the reorg touches nearly every file, and every
|
conflicts — the reorg touches nearly every file, and every in-flight branch is diffed against
|
||||||
in-flight branch is diffed against the *old* layout. Phase Q starts only when Phase S,
|
the *old* layout. As of 2026-07-27 the outstanding work is **Phase S** (merged to dev) and
|
||||||
Phase L, and any D2/M9 residuals have merged to dev and the tree is quiet. Stated
|
**Phase L L3** (the VST restyle, itself gated on Phase S) — Daniel's plain target: *"when
|
||||||
prominently because getting the gate wrong is the one way this phase does real damage.
|
Phase S and L3 are finished."* (L1/L2/L4–L7 have already landed; D2 is functionally complete;
|
||||||
|
M9 is deferred.) Stated prominently because getting the gate wrong is the one way this phase
|
||||||
|
does real damage.
|
||||||
|
- **Beyond SOLID, Phase Q also fixes naming.** The reorg gives every symbol a *directory +
|
||||||
|
namespace home* (Q-3/Q-4); §2b's grep-verified naming audit adds the orthogonal dimension of
|
||||||
|
giving poorly/inconsistently-named symbols a *consistent name*, measured against the same
|
||||||
|
Vital "something I can stand to look at" bar. Renames ride the waves that already relocate the
|
||||||
|
file (a rename is nearly free when a file is already moving); the scheme + new forks (Q-7…Q-9)
|
||||||
|
are in §6.
|
||||||
- **Every point is independently landable and CTest-green at every step** (§5). The CMake
|
- **Every point is independently landable and CTest-green at every step** (§5). The CMake
|
||||||
targets already draw the module seams; a file move + namespace change keeps
|
targets already draw the module seams; a file move + namespace change keeps
|
||||||
`ctest --test-dir build` green at each point. Green-CTest-at-every-point is an acceptance
|
`ctest --test-dir build` green at each point. Green-CTest-at-every-point is an acceptance
|
||||||
@@ -170,6 +182,122 @@ decision-grade evidence; the PLAN points and CONTEXT spec cite back to it.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 2b. The naming audit — grep-verified symbol/module-naming inconsistencies
|
||||||
|
|
||||||
|
The SOLID audit (§2) grounds *where responsibilities live*; this section grounds *what things are
|
||||||
|
called*. Same rigor: **every claim below cites a symbol or file verified by grep/read of the
|
||||||
|
actual `src/` tree (2026-07-27), not taste asserted in the abstract.** The reorg is the moment to
|
||||||
|
fix naming because a rename is nearly free when the file is already being relocated or split
|
||||||
|
(Q-W1–Q-W6). Measured against the same bar: *"something I can stand to look at"* means a newcomer
|
||||||
|
can predict a symbol's name from its role and never meets two unrelated things sharing one name.
|
||||||
|
|
||||||
|
### 2b.1 The good news — what is already consistent (leave alone)
|
||||||
|
|
||||||
|
Two families are already named on a legible principle; the audit's job there is only to *protect*
|
||||||
|
them through the reorg, not to change them:
|
||||||
|
|
||||||
|
- **The geometry-mirror *verb* vocabulary is consistent.** Every pure layout/hit-test module uses
|
||||||
|
the same two verbs: `compute<Thing>Rects` / `compute<Thing>` for layout and `hitTest<Thing>` for
|
||||||
|
hit-testing — verified across `bank_grid` (`computeCellRects`/`hitTestCell`), `mode_switch`
|
||||||
|
(`computeSegmentRects`/`hitTestSegment`), `action_buttons` (`computeButtonRects`/`hitTestButton`),
|
||||||
|
`action_bar` (`computeBarSlots`/`hitTestActionBar`), `tab_strip`
|
||||||
|
(`computeTabRects`/`hitTestTabStrip`), `prune_button` (`computePruneButton`/`hitTestPruneButton`),
|
||||||
|
`overflow_menu` (`computeMenuButton`/`hitTestMenuButton`), `footer_bar`
|
||||||
|
(`computeFooterBar`/`hitTestFooterBar`), `card_drag` (`computeSlotRects`/`hitTestSlot`),
|
||||||
|
`component_geometry` (`computeButtonBox`/`hitTestBox`). This is a real, followed convention —
|
||||||
|
preserve it verbatim.
|
||||||
|
- **The `_tests` suffix is uniform.** Every pure module's CTest executable is `<module>_tests`
|
||||||
|
(30 targets in CLAUDE.md's table, no exceptions). No action.
|
||||||
|
|
||||||
|
### 2b.2 Ambiguous / collision-prone symbols (the highest-priority fixes)
|
||||||
|
|
||||||
|
These are the naming equivalent of the JSON-`Parser` DRY violation — concrete hazards, not taste:
|
||||||
|
|
||||||
|
1. **Four hand-rolled `Parser` classes, one name.** `class Parser` is defined **four times** —
|
||||||
|
`bank_model.cpp:306`, `bank_book.cpp:663`, `owned_manifest.cpp:107`, `view_mode_model.cpp:654`.
|
||||||
|
Q-W1 already deletes three of them by extracting `core/json`; the naming rule is that the
|
||||||
|
survivor is **`json::Parser`** (or a more specific `json::Reader`/`json::Writer` pair — see
|
||||||
|
Q-8), never a bare `Parser` in flat scope.
|
||||||
|
2. **`FooterRect` and `ButtonRect` are shared across pure UI modules — and the codebase already
|
||||||
|
*knows* it.** `struct FooterRect` and `struct ButtonRect` are defined in `prune_button.h`
|
||||||
|
(lines 32, 46) and **reused** by `footer_bar.h`, which carries an explicit in-file "NAME NOTE"
|
||||||
|
(`footer_bar.h:27–34`) documenting that `ButtonRect / FooterRect / SegmentRect / ActionBarRect /
|
||||||
|
KitBox / KitButtonBox` are "already owned in this namespace" and that new types must carry a
|
||||||
|
`FooterBar*` prefix to avoid collision. That comment is a smell made visible: the flat
|
||||||
|
`reasampler::` namespace forces every pure-UI author to hand-check for name collisions before
|
||||||
|
minting a type. This is the single strongest in-codebase argument for the Q-4 sub-namespaces —
|
||||||
|
under `reasampler::ui` these shared rect types get one clear owner and the hand-checking stops.
|
||||||
|
3. **`Sample` (`bank_model.h:69`, the bank metadata struct) vs `AudioSample` (the `peaks` float
|
||||||
|
alias).** Already flagged in §2.4/Q-4; verified — `Sample` is the model record, `AudioSample`
|
||||||
|
is a raw PCM float. Under `model::Sample` vs `audio::AudioSample` the collision risk is gone,
|
||||||
|
but the *names* still read oddly side by side (a `Sample` that is metadata, an `AudioSample`
|
||||||
|
that is one float). Noted; the namespace split is the required fix, a rename is optional (Q-8).
|
||||||
|
4. **`Selection` (`bank_grid.h:112`) and `CellRect` (`bank_grid.h:23`) are generic names in a
|
||||||
|
flat namespace.** `Selection` in particular is the kind of name a newcomer cannot place without
|
||||||
|
opening the file. `ui::Selection` / `ui::CellRect` resolve it structurally; no rename needed
|
||||||
|
beyond the namespace.
|
||||||
|
|
||||||
|
### 2b.3 Inconsistent module/type *naming families* (the taste-but-grounded tier)
|
||||||
|
|
||||||
|
Here the names are legal and non-colliding but do not read on one principle — the "stand to look
|
||||||
|
at" gap:
|
||||||
|
|
||||||
|
1. **The model-family suffixes disagree: `_model` vs `_book` vs `Index`.** Verified: the pure model
|
||||||
|
modules are `bank_model.{h,cpp}` (owning `class BankIndex`, `bank_model.h:132`), `bank_book.{h,cpp}`
|
||||||
|
(owning `class BankBook`, `bank_book.h:208`), `view_mode_model.{h,cpp}` (owning `class ViewModeModel`,
|
||||||
|
`view_mode_model.h:376`), `owned_manifest.{h,cpp}` (owning `class OwnedFileManifest`,
|
||||||
|
`owned_manifest.h:52`). Four modules, four different file↔class naming relationships:
|
||||||
|
`bank_model`→`BankIndex` (file says "model," class says "index"), `bank_book`→`BankBook`
|
||||||
|
(file = class), `view_mode_model`→`ViewModeModel` (file = class), `owned_manifest`→`OwnedFileManifest`
|
||||||
|
(file ≈ class, but the class adds "File"). The `bank_model`/`BankIndex` mismatch is the worst:
|
||||||
|
the file name and its primary class name share no word. This is a genuine legibility wart — the
|
||||||
|
fix is a *rename decision* (Q-8), not something the directory move alone resolves.
|
||||||
|
2. **The `bank_book` "wraps `bank_model`" relationship is invisible in the names.** `BankBook`
|
||||||
|
(`bank_book.h:208`) is a registry of `Bank` (`bank_book.h:147`), each wrapping a `BankIndex`
|
||||||
|
(`bank_model.h:132`). The names `Book` → `Bank` → `Index` do not read as a containment hierarchy;
|
||||||
|
a reader has to learn it. (Not necessarily worth a rename — "book of banks" is evocative — but
|
||||||
|
it is the kind of call Q-8 should make deliberately, not by accident.)
|
||||||
|
3. **`realtime_record.h` (pure) vs `capture_realtime.cpp` (shell) — the word order flips.** Verified:
|
||||||
|
the pure realtime module is `realtime_record.{h}` (owning `RecordModePlan`/`RecordPhase`/
|
||||||
|
`RecordTickInputs`, `realtime_record.h:57–173`) while its shell is `capture_realtime.cpp`. So the
|
||||||
|
pure core is `realtime_record` but the shell is `capture_realtime` — the two halves of one feature
|
||||||
|
are named on inverted word order (`realtime_record` vs `capture_realtime`). Compare the *clean*
|
||||||
|
shell-pair convention elsewhere: `drag_out` (pure) ↔ `drag_out_win` (shell) — same stem, suffix
|
||||||
|
marks the platform shell. The realtime pair breaks that pattern. This is the clearest shell↔core
|
||||||
|
naming-drift instance in the tree (Q-9).
|
||||||
|
4. **`capture.{h,cpp}` is the *offline* backend shell, but the name claims all of capture.**
|
||||||
|
Verified: `capture.h` declares `ICaptureBackend`, `OfflineRenderBackend`, **and**
|
||||||
|
`RealtimeRecordBackend` (`capture.h:112,124,201`), while the realtime *implementation* lives in
|
||||||
|
`capture_realtime.cpp` and its pure planner in `realtime_record.h`. So `capture` is really
|
||||||
|
"capture interface + offline backend," a fat header (the §2.3 Interface-Segregation concern) whose
|
||||||
|
name oversells its scope. Its Q-W3 hoist (`capture_orchestrator`/`scope_resolve`) is the moment
|
||||||
|
to right-size the name.
|
||||||
|
|
||||||
|
### 2b.4 Abbreviations / opacity (low-severity, opportunistic)
|
||||||
|
|
||||||
|
Swept for names a newcomer couldn't decode; the tree is mostly clean here (a credit to it). Two
|
||||||
|
minor notes:
|
||||||
|
|
||||||
|
- **`guid_diff` / `GuidBaseline` (`guid_diff.h:40`)** — "GUID diff" is decodable in context (it
|
||||||
|
diffs the live track/item GUID set between polls) but `GuidBaseline` reads more clearly as "the
|
||||||
|
previous-poll snapshot" than the module name suggests. Low priority; leave unless its `core/view`
|
||||||
|
relocation invites it.
|
||||||
|
- **`MinMax` (`peaks.h:30`), `KitBox` (`component_geometry.h:28`)** — terse but correct and local;
|
||||||
|
no change. Named here only to record they were swept and cleared.
|
||||||
|
|
||||||
|
### 2b.5 What the naming audit does NOT touch (hard boundary)
|
||||||
|
|
||||||
|
The FOREVER-STABLE on-the-wire/on-disk contracts are **not** C++ symbol names and are **out of
|
||||||
|
scope for every rename**: `command_id` strings (`CEREBELLUM_REASAMPLER_*` / `_BETA_`), action
|
||||||
|
display names (`"ReaSampler: …"`), ext-state namespace (`"reasampler"` / `"reasampler_beta"`) and
|
||||||
|
its keys (`"banks"`, `"view_state"`, `"tail_setting"`, `"owned_files"`, `"version"`), the
|
||||||
|
`reasampler:` lane-name prefix, and the Phase S VST3 class UID. Renaming a C++ class is orthogonal
|
||||||
|
to these strings; the audit's renames touch symbols only, never a shipped contract literal. This
|
||||||
|
is the same guardrail §7 states for the reorg, restated for the naming dimension because a careless
|
||||||
|
"tidy the names" pass is exactly how a shipped id gets broken.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 3. Performance is a hard constraint (the guardrail, carried verbatim-in-spirit)
|
## 3. Performance is a hard constraint (the guardrail, carried verbatim-in-spirit)
|
||||||
|
|
||||||
Daniel's stated non-negotiable: reorganize **without sacrificing actual performance.** The
|
Daniel's stated non-negotiable: reorganize **without sacrificing actual performance.** The
|
||||||
@@ -210,22 +338,49 @@ namespace of every header, splitting the four largest TUs). Meanwhile:
|
|||||||
- **Phase S** lives on the **phase-s worktree**, is **not on dev**, and is a large body of
|
- **Phase S** lives on the **phase-s worktree**, is **not on dev**, and is a large body of
|
||||||
work (a whole second VST3 build artifact + pure sampler core). Its branch is diffed against
|
work (a whole second VST3 build artifact + pure sampler core). Its branch is diffed against
|
||||||
the *current* flat layout.
|
the *current* flat layout.
|
||||||
- **Phase L** has **L2** (dock-panel layout redesign, itself gated after M11) and **L3** (VST
|
- **Phase L** has **L3** (VST editor + embed-strip restyle, gated on Phase S landing on dev)
|
||||||
restyle, gated on Phase S) still to land — both touching `bank_panel` and the draw/UI
|
still to land — it touches the Phase S draw shells (`reasampler_editor` / `reasampler_embed`),
|
||||||
layer, exactly the files Phase Q's god-module split rewrites.
|
which arrive on dev with Phase S. (L1/L2/L4/L5/L6/L7 have **already landed** — see
|
||||||
- **D2 residuals / M9** (deferred) could reactivate.
|
`COMPLETED.md`; the once-listed "L2 pending" is stale and has been corrected here.)
|
||||||
|
- **D2** is **functionally complete** (D2-W1..W3-B landed; the only 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. Neither blocks the gate on
|
||||||
|
its own; both are named in the gate only so a future reactivation of either re-arms the "tree
|
||||||
|
must be quiescent" condition.
|
||||||
|
|
||||||
A structural reorg landing while any of these is mid-flight would force every in-flight
|
A structural reorg landing while any of these is mid-flight would force every in-flight
|
||||||
branch through a **rename-and-relocate-everything** merge — the worst possible conflict
|
branch through a **rename-and-relocate-everything** merge — the worst possible conflict
|
||||||
class (every hunk moved, every namespace-qualified reference changed). The cost is not linear;
|
class (every hunk moved, every namespace-qualified reference changed). The cost is not linear;
|
||||||
it is a combinatorial re-resolution of every open branch against a moved tree.
|
it is a combinatorial re-resolution of every open branch against a moved tree.
|
||||||
|
|
||||||
**The gate, stated as a rule:** Phase Q does not begin until **Phase S has merged to dev**,
|
**The gate, stated as a rule (reconciled to reality, product-designer 2026-07-27):** Phase Q
|
||||||
**Phase L (L2 + L3) has merged to dev**, any **D2 residuals** are closed, and **M9** is either
|
does not begin until the tree is **quiescent**, with no large branch outstanding. As of
|
||||||
landed or confirmed-abandoned — i.e. the tree is **quiescent**, with no large branch
|
2026-07-27 the outstanding work is precisely:
|
||||||
outstanding. Phase Q is the *last* structural pillar precisely because it reshapes the ground
|
|
||||||
every other pillar stands on. Landing it early would tax every subsequent phase; landing it
|
1. **Phase S** — merged to dev (currently on the phase-s worktree; the large second-artifact
|
||||||
last taxes nothing.
|
branch, the dominant gate item).
|
||||||
|
2. **Phase L L3** — merged to dev (the VST restyle; itself gated on Phase S, so it lands after
|
||||||
|
Phase S reaches dev). **L2 is already landed** — the earlier "L2 + L3" wording was stale.
|
||||||
|
3. **D2** — confirmed complete or its deferred indicator explicitly re-deferred. It is
|
||||||
|
functionally complete today; this line stays only so that if the deferred panel indicator is
|
||||||
|
picked up as active work, it re-arms the quiescence condition.
|
||||||
|
4. **M9** — landed **or** confirmed-abandoned. It is *deferred* today (Daniel, 2026-07-26); the
|
||||||
|
distinction between "deferred" and "abandoned" is a Daniel call (see the disposition note
|
||||||
|
below), but either disposition satisfies the gate as long as M9 is not *active in-flight work*
|
||||||
|
when Q-W1 opens.
|
||||||
|
|
||||||
|
Restated as the plain readiness target Daniel named: **"when Phase S and L3 are finished."**
|
||||||
|
Phase Q is the *last* structural pillar precisely because it reshapes the ground every other
|
||||||
|
pillar stands on. Landing it early would tax every subsequent phase; landing it last taxes
|
||||||
|
nothing.
|
||||||
|
|
||||||
|
> **Daniel-decision note (M9 disposition).** M9 (MPC-style slots) is recorded as "deferred
|
||||||
|
> indefinitely / can be picked up later" — which is *not* the same as "abandoned." For the gate
|
||||||
|
> this is immaterial (deferred and abandoned both clear it). It matters only if M9 is ever
|
||||||
|
> reactivated as scheduled work: doing so *before* Phase Q means M9 lands on the flat layout and
|
||||||
|
> is cheap; doing so *after* means M9 is authored against the reorganized `core/`/`shell/` tree.
|
||||||
|
> No action needed unless Daniel wants M9 scheduled — flagged so the "deferred vs abandoned"
|
||||||
|
> ambiguity is surfaced, not silently resolved.
|
||||||
|
|
||||||
*(Sequencing corollary: because the gate is "everything else first," Phase Q's own internal
|
*(Sequencing corollary: because the gate is "everything else first," Phase Q's own internal
|
||||||
sequencing —§5— is about risk-ordering the reorg, not about racing other phases.)*
|
sequencing —§5— is about risk-ordering the reorg, not about racing other phases.)*
|
||||||
@@ -255,6 +410,28 @@ individually-revertible step:
|
|||||||
and any fat-header (I) splits not already resolved. Sequenced last because it depends on
|
and any fat-header (I) splits not already resolved. Sequenced last because it depends on
|
||||||
the `main.cpp` split (W3) having already isolated the registration code.
|
the `main.cpp` split (W3) having already isolated the registration code.
|
||||||
|
|
||||||
|
**Where the naming work (§2b) rides — renames follow relocations, no dedicated wave (Q-7).**
|
||||||
|
A rename is cheapest when the file is already moving or splitting, so naming does **not** get its
|
||||||
|
own wave; each fix rides the wave that already touches its file:
|
||||||
|
|
||||||
|
- **W1 absorbs** the collision fixes (§2b.2): the survivor `Parser` becomes `json::Parser` (or the
|
||||||
|
Q-8 `Reader`/`Writer` pair) as the four copies collapse; and every clean pure-UI type
|
||||||
|
(`FooterRect`/`ButtonRect`/`Selection`/`CellRect`) gets its `ui::` (etc.) home as the modules
|
||||||
|
relocate — retiring the `footer_bar.h` hand-collision "NAME NOTE." W1 already re-namespaces the
|
||||||
|
clean modules, so the sub-namespace half of every §2b fix lands here for free.
|
||||||
|
- **W1 also carries** any *pure-model* class rename Q-8 settles (e.g. `BankIndex`→a name matching
|
||||||
|
`bank_model`), because those modules relocate in W1 and a class rename is a mechanical
|
||||||
|
find-replace verified by the module's own test executable.
|
||||||
|
- **W2 absorbs** the `bank_panel`-side names as the god-module splits into `panel_*`.
|
||||||
|
- **W3 absorbs** the `capture`/`realtime` shell↔core word-order fix (Q-9) — the realtime lifecycle
|
||||||
|
is *already* being hoisted in W3, so aligning `capture_realtime`/`realtime_record` naming is a
|
||||||
|
rider on a move that is happening regardless.
|
||||||
|
|
||||||
|
The rule (Q-7): **no rename lands on a file that is not otherwise being touched by its wave.** A
|
||||||
|
rename that would force a file to move *only* to be renamed is deferred — the churn/legibility
|
||||||
|
trade isn't worth a standalone edit. This keeps the naming dimension inside the same
|
||||||
|
"green-CTest-at-every-point, minimal-diff-per-wave" discipline as the rest of Phase Q.
|
||||||
|
|
||||||
**Why incremental beats big-bang here, concretely:** the CMake per-module static-lib + per-
|
**Why incremental beats big-bang here, concretely:** the CMake per-module static-lib + per-
|
||||||
module test-executable structure means a file move + namespace change is *mechanically*
|
module test-executable structure means a file move + namespace change is *mechanically*
|
||||||
verifiable — `ctest` is green or it isn't, at every point. That property only pays off if the
|
verifiable — `ctest` is green or it isn't, at every point. That property only pays off if the
|
||||||
@@ -366,6 +543,69 @@ no finer.**
|
|||||||
because, once W3 has hoisted the registration code, tabling it is a small, high-legibility
|
because, once W3 has hoisted the registration code, tabling it is a small, high-legibility
|
||||||
finish — but it is the most droppable point if the phase needs narrowing.
|
finish — but it is the most droppable point if the phase needs narrowing.
|
||||||
|
|
||||||
|
**Fork Q-7 — is naming its own wave, or does it ride the relocation waves? RECOMMEND: rides the
|
||||||
|
waves; no dedicated naming wave.** SETTLED-by-structure once Q-3/Q-4 are settled.
|
||||||
|
|
||||||
|
- **Recommendation:** naming fixes ride the wave that already relocates or splits the file (§5),
|
||||||
|
under the rule *no rename lands on a file the wave isn't otherwise touching.* A rename is nearly
|
||||||
|
free during a relocation (the file is open, the diff is already large, the module's own test
|
||||||
|
executable verifies it) and near-pure-churn as a standalone edit. Because Q-3 (directories) and
|
||||||
|
Q-4 (sub-namespaces) already move and re-namespace every file, the *collision* half of the
|
||||||
|
naming audit (§2b.2) is resolved by the namespace split with zero extra renames — the sub-
|
||||||
|
namespace *is* the fix. Only the genuine *class/module renames* (Q-8/Q-9) add symbol churn, and
|
||||||
|
those are scoped to files already in motion.
|
||||||
|
- **Alternative considered:** a dedicated final "naming pass" wave (Q-W7). Rejected: it would
|
||||||
|
re-open files W1–W6 just closed, producing exactly the churn-without-relocation the rule forbids,
|
||||||
|
and a diff that touches everything again defeats the per-wave reviewability property.
|
||||||
|
- **This makes Q-7 not really a judgment call once Q-3/Q-4 are settled** — it is the forced
|
||||||
|
consequence of "renames are cheapest during relocation." Recorded as a fork only because Daniel
|
||||||
|
might still want naming called out as a first-class deliverable rather than folded silently into
|
||||||
|
the reorg waves; if so, the plan *names* the riders per wave (it does, §5) without adding a wave.
|
||||||
|
|
||||||
|
**Fork Q-8 — how far to push *class/module* renames (beyond the free namespace fix)? RECOMMEND:
|
||||||
|
fix the two that actively mislead; leave the merely-quirky.** Daniel's to call.
|
||||||
|
|
||||||
|
- **Recommendation (leading):** rename only where a name *actively misleads* a reader, and stop:
|
||||||
|
- **`BankIndex` → a name matching `bank_model`** (§2b.3.1) — the file/class word-mismatch is the
|
||||||
|
worst offender (`bank_model.h` owns `class BankIndex`; the two share no word). Two shapes:
|
||||||
|
(a) rename the class to `BankModel` (file = class, matches `ViewModeModel`/`BankBook`); or
|
||||||
|
(b) rename the *file* to `bank_index.{h,cpp}` (class stays `BankIndex`). **Prefer (a)** — it
|
||||||
|
makes the model family read on one principle (`BankModel`/`BankBook`/`ViewModeModel`, all
|
||||||
|
`<noun>Model`/`<noun>Book`), and it is a class rename W1 verifies via `bank_model_tests`.
|
||||||
|
- **The unified JSON `Parser`** (§2b.2.1) — make it a `json::Reader` + `json::Writer` pair (or
|
||||||
|
keep `json::Parser` if extraction stays parse-only). This is a *new* module's naming, decided
|
||||||
|
at W1 mint time, so it costs nothing to get right.
|
||||||
|
- **Leave quirky-but-harmless:** `Book`→`Bank`→`Index` containment (§2b.3.2 — evocative, learnable),
|
||||||
|
`Sample`/`AudioSample` (§2b.2.3 — the namespace split already de-collides them; renaming
|
||||||
|
`AudioSample`→`Pcm`/`PcmSample` is optional polish), `guid_diff`/`GuidBaseline`, `MinMax`,
|
||||||
|
`KitBox`. Renaming these is pure taste with no misleading-a-reader payoff — the "stand to look
|
||||||
|
at" bar is met by the namespace homes alone.
|
||||||
|
- **Alternative (more aggressive):** normalize the *entire* model family to one suffix
|
||||||
|
(`BankModel`/`BankBookModel`/`ViewModeModel`/`OwnedManifestModel`) and rename `AudioSample`→
|
||||||
|
`PcmSample`. Rejected as the lead because it renames things that already read fine, adding symbol
|
||||||
|
churn (every call site, every test) for marginal legibility — but it is a coherent option if
|
||||||
|
Daniel wants the model family *rigidly* uniform. Kept on the table as Daniel's call.
|
||||||
|
- **Alternative (minimal):** do zero class renames; let the sub-namespaces (Q-4) carry the whole
|
||||||
|
naming win. Defensible — it is the lowest-churn, lowest-risk reading, and the namespace split
|
||||||
|
genuinely resolves every *collision*. Rejected as the lead only because `bank_model`/`BankIndex`
|
||||||
|
is a standing "what is this file" cost the reorg is uniquely cheap to fix.
|
||||||
|
|
||||||
|
**Fork Q-9 — align the `capture_realtime` / `realtime_record` shell↔core word order? RECOMMEND:
|
||||||
|
yes, during W3.** Daniel's to call.
|
||||||
|
|
||||||
|
- **Recommendation:** align the pair to the house shell↔core convention (`drag_out` ↔
|
||||||
|
`drag_out_win`: shared stem, suffix marks the shell). The pure planner `realtime_record` and its
|
||||||
|
shell `capture_realtime` invert word order for one feature — the tree's clearest shell/core drift
|
||||||
|
(§2b.3.3). W3 is *already* hoisting the realtime lifecycle, so aligning the names is a rider on a
|
||||||
|
move that happens anyway. Two shapes: (a) core `capture_realtime` / shell `capture_realtime_shell`
|
||||||
|
(stem = `capture_realtime`, matches the `capture` offline pair); (b) core `realtime_record` /
|
||||||
|
shell `realtime_record_shell`. **Prefer (a)** — it nests the realtime naming under `capture_*`
|
||||||
|
alongside the offline path, so the whole capture subsystem reads on one stem.
|
||||||
|
- **Alternative:** leave it — the inversion is cosmetic and both names are individually clear.
|
||||||
|
Reasonable if Daniel wants W3 kept strictly to the god-module split with no adjacent renames. The
|
||||||
|
fix is cheap enough (W3 touches these files regardless) that the lead is to take it, but it is
|
||||||
|
the most droppable of the three naming forks.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 7. What Phase Q does NOT change (guardrails)
|
## 7. What Phase Q does NOT change (guardrails)
|
||||||
|
|||||||
Reference in New Issue
Block a user