docs(plan): add Phase Q pre-restructure functional+DSP audit wave (Q-W0)
This commit is contained in:
+76
-2
@@ -3204,6 +3204,13 @@ compat event.
|
|||||||
> bar), the reorg being the means. Product framing, the Vital-grounded target shape, the
|
> bar), the reorg being the means. Product framing, the Vital-grounded target shape, the
|
||||||
> grep-verified SOLID audit (the evidence base), and the fork record (Q-1..Q-6):
|
> grep-verified SOLID audit (the evidence base), and the fork record (Q-1..Q-6):
|
||||||
> `docs/product/code-organization.md`. When a point lands, doc-keeper moves it to `COMPLETED.md`.
|
> `docs/product/code-organization.md`. When a point lands, doc-keeper moves it to `COMPLETED.md`.
|
||||||
|
>
|
||||||
|
> **Phase Q opens with a pre-restructure audit (Q-W0 — added 2026-07-27).** Before any structural
|
||||||
|
> point (Q-W1+), Phase Q runs a **functional + DSP quality audit** that produces a written, triaged
|
||||||
|
> 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.
|
||||||
|
|
||||||
## What it is
|
## What it is
|
||||||
|
|
||||||
@@ -3219,6 +3226,66 @@ architecture *changes*; it becomes *visible*. This is why the phase can be zero-
|
|||||||
CTest-green throughout: the seams already exist in the link graph; Phase Q draws them where a
|
CTest-green throughout: the seams already exist in the link graph; Phase Q draws them where a
|
||||||
reader sees them.
|
reader sees them.
|
||||||
|
|
||||||
|
## The pre-restructure audit wave (Q-W0)
|
||||||
|
|
||||||
|
Phase Q **opens** with `Q-W0` — a thorough **static/functional audit** that runs before any
|
||||||
|
structural point (Q-W1+) moves a single file. It is the *functional-correctness and
|
||||||
|
algorithm-quality* complement to the grep-verified SOLID audit (§"The evidence base" in
|
||||||
|
`docs/product/code-organization.md` §2) and naming audit (§2b): those ground *where responsibilities
|
||||||
|
live* and *what things are called*; Q-W0 grounds *does the code do the right thing, and does it do it
|
||||||
|
well.* It exists because the structural reorg is the wrong moment to discover a bad algorithm — a
|
||||||
|
reinvented wheel or a numerically-fragile DSP path should be eliminated or consciously documented
|
||||||
|
**before** it is relocated, re-namespaced, and split, not carried forward untouched into a tidier
|
||||||
|
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*.
|
||||||
|
|
||||||
|
**Audit scope — the named surfaces:**
|
||||||
|
|
||||||
|
1. **DSP / audio, close eye on pitch.** Assess *algorithm quality* — correctness, artifacts,
|
||||||
|
numerical robustness, interpolation quality, and reinvented-wheel-vs.-established-technique — on:
|
||||||
|
- `src/vst/pitch_shift` — the hand-rolled OLA pitch-preserve engine: window/overlap choice, phase
|
||||||
|
coherence, transient and formant behavior, buffer-edge handling. **The highest-priority DSP
|
||||||
|
surface** (Daniel: "a close eye on the Pitch stuff").
|
||||||
|
- `sampler_core` — repitch ratio math, interpolation order/quality, loop-point-aware sustain
|
||||||
|
crossfade, and voice-stealing correctness (clicks/discontinuities on steal).
|
||||||
|
- `peaks` — envelope min/max binning correctness.
|
||||||
|
- `wav_trim` — the realtime-tail decay-scan threshold + truncate plan.
|
||||||
|
- the capture / tail paths — any DSP-adjacent arithmetic in capture range/tail handling.
|
||||||
|
2. **Architecture smells.** Duplicate code, reinvented wheels, poor abstractions, and leaky
|
||||||
|
pure/shell boundaries (a `core/` file reaching a REAPER/host type; geometry or algorithm math
|
||||||
|
sitting untestable in a shell instead of a pure module). This overlaps the SOLID audit's territory
|
||||||
|
but targets the *functional* smell, not the responsibility-placement smell — Q-W0 reports what
|
||||||
|
§2/§2b did not.
|
||||||
|
3. **Env-coupled-constant domain-modeling smells (explicit category).** ANY value stored in a
|
||||||
|
frame / rate / DPI / tick-coupled domain that should instead be stored **rate-free and resolved at
|
||||||
|
the point of use** is a domain-modeling smell — *store rate-free, resolve at use*, **not** "rescale
|
||||||
|
by the rate." This is grounded in the load-bearing invariant that wall-clock times are stored as
|
||||||
|
rate-free **SECONDS** resolved against the live project rate (`sample_map`), with **NO hardcoded
|
||||||
|
sample rates in `src/`** (Daniel's standing ruling). There was a prior incident on exactly this —
|
||||||
|
envelope times stored in the frame domain — which is why it is a first-class audit category, not a
|
||||||
|
footnote. Sweep at least: envelope times, loop points, fade lengths, tail lengths, and any UI
|
||||||
|
geometry constant that silently bakes in a DPI or rate.
|
||||||
|
|
||||||
|
**Deliverable + acceptance:** a **written findings report** exists covering the named surfaces;
|
||||||
|
**every finding is triaged** into *eliminate-before-restructure* (fix-now) or *document-and-defer*
|
||||||
|
(with a one-line rationale so the deferral is a decision, not an omission). Fix-now findings are
|
||||||
|
remediated **in Q-W0**, or folded into the downstream wave that already opens the file (recorded per
|
||||||
|
finding) — they are **not** silently deferred into the structural waves. Any behavior-changing
|
||||||
|
remediation lands with the module's CTest executable green, and where a DSP path changes audibly, a
|
||||||
|
stated before/after listening or null check. **The gate to begin Q-W1 is: triage complete and Daniel
|
||||||
|
signed off on every disposition.**
|
||||||
|
|
||||||
|
**Relationship to the structural waves:** Q-W0's findings may **add or reshape** downstream
|
||||||
|
Q-W1..Q-W6 points (e.g. an algorithm rewrite that changes a module's shape, or a domain-modeling fix
|
||||||
|
that changes a payload). Those reshapes are folded in before Q-W1 begins. Q-W0 is thus both the entry
|
||||||
|
point and a scoping input to the rest of the phase.
|
||||||
|
|
||||||
|
**Report home (fork — Daniel's call):** whether the findings report lives as a committed doc under
|
||||||
|
`docs/product/` (e.g. `code-quality-audit.md`, alongside the SOLID/naming audit that already lives in
|
||||||
|
`docs/product/code-organization.md`) or as a tracked issue list is Daniel's call — see the fork note
|
||||||
|
in `docs/product/code-organization.md` §2c. The recommendation is a committed doc: it sits beside the
|
||||||
|
existing audit, travels with the tree, and each finding's disposition is reviewable in one place.
|
||||||
|
|
||||||
## The quality bar — Vital (read from its actual `src/` tree)
|
## The quality bar — Vital (read from its actual `src/` tree)
|
||||||
|
|
||||||
Vital (`github.com/mtytel/vital`) groups its synth by **subsystem** — `common/` `synthesis/`
|
Vital (`github.com/mtytel/vital`) groups its synth by **subsystem** — `common/` `synthesis/`
|
||||||
@@ -3232,7 +3299,8 @@ below). Vital is GPLv3; the borrowed artifact is the **structural pattern**, not
|
|||||||
## Settled decisions (Q-1 settled; Q-2..Q-6 recommended — see `docs/product/code-organization.md` §6)
|
## Settled decisions (Q-1 settled; Q-2..Q-6 recommended — see `docs/product/code-organization.md` §6)
|
||||||
|
|
||||||
- **Q-1 — namespace letter. SETTLED: `Q` (Quality).** Point-id family `Q1..Qn`, wave prefixes
|
- **Q-1 — namespace letter. SETTLED: `Q` (Quality).** Point-id family `Q1..Qn`, wave prefixes
|
||||||
`Q-W1..Q-W6`. `O` (Organization) was set aside: the glyph reads ambiguously against zero in
|
`Q-W0` (the pre-restructure audit) then `Q-W1..Q-W6` (the structural reorg). `O` (Organization)
|
||||||
|
was set aside: the glyph reads ambiguously against zero in
|
||||||
point ids, and "Organization" undersells a phase measured against a *quality* bar.
|
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
|
- **Q-2 — JSON extraction in scope + first. REC: yes.** The 4× duplicated `Parser` is the largest
|
||||||
DRY+SRP violation and is entirely off the hot paths — the ideal safe, high-leverage opener
|
DRY+SRP violation and is entirely off the hot paths — the ideal safe, high-leverage opener
|
||||||
@@ -3412,6 +3480,11 @@ Big-bang is rejected — the CMake per-module static-lib + per-module test-execu
|
|||||||
file move + namespace change **mechanically verifiable** (`ctest --test-dir build` green or not, at
|
file move + namespace change **mechanically verifiable** (`ctest --test-dir build` green or not, at
|
||||||
every commit), a property only an *incremental* reorg uses. Risk-ordered:
|
every commit), a property only an *incremental* reorg uses. Risk-ordered:
|
||||||
|
|
||||||
|
- **Q-W0** — **pre-restructure functional + DSP quality audit** (entry point; see §"The
|
||||||
|
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/
|
- **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. **Carries the naming collision fixes + the model-class
|
All later waves assume this layout. **Carries the naming collision fixes + the model-class
|
||||||
@@ -3458,6 +3531,7 @@ every commit), a property only an *incremental* reorg uses. Risk-ordered:
|
|||||||
- **No big-bang commit.** Every wave is independently landable and CTest-green; reject a change set
|
- **No big-bang commit.** Every wave is independently landable and CTest-green; reject a change set
|
||||||
that cannot be verified at each step.
|
that cannot be verified at each step.
|
||||||
- **Do not begin before the GATE.** Re-confirm the tree is quiescent (Phase S + L + D2 merged/closed;
|
- **Do not begin before the GATE.** Re-confirm the tree is quiescent (Phase S + L + D2 merged/closed;
|
||||||
M9 abandoned) before any Q point.
|
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.
|
||||||
- **Verify** the CMake `src/` path updates and the SWELL/LICE surfaces still resolve after
|
- **Verify** the CMake `src/` path updates and the SWELL/LICE surfaces still resolve after
|
||||||
relocation, as the existing build already requires.
|
relocation, as the existing build already requires.
|
||||||
|
|||||||
@@ -454,13 +454,27 @@ L1, L2, L3, L4, L5, L6, and L7 have all landed. **Phase L is complete.**
|
|||||||
> changed) — a combinatorial re-resolution, not a linear one. Phase Q is *last* precisely
|
> 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
|
> because it reshapes the ground every other pillar stands on. Landing it early taxes every
|
||||||
> subsequent phase; landing it last taxes nothing. **The gate is now satisfied — Phase Q
|
> subsequent phase; landing it last taxes nothing. **The gate is now satisfied — Phase Q
|
||||||
> may begin.**
|
> may begin, entering at the Q-W0 audit wave** (the structural waves Q-W1+ do not begin until
|
||||||
|
> Q-W0's triage closes and Daniel signs off — see the Q-W0 sub-gate above).
|
||||||
>
|
>
|
||||||
> **M9 disposition — resolved (Daniel, 2026-07-27): abandoned.** M9 is out; it will not be
|
> **M9 disposition — resolved (Daniel, 2026-07-27): abandoned.** M9 is out; it will not be
|
||||||
> reactivated. The gate remains satisfied; no re-arm condition applies.
|
> reactivated. The gate remains satisfied; no re-arm condition applies.
|
||||||
>
|
>
|
||||||
|
> **PRE-RESTRUCTURE AUDIT WAVE (Q-W0 — added 2026-07-27, Daniel's ask; runs FIRST).** Before any
|
||||||
|
> structural point (Q-W1+) begins, Phase Q now opens with a **functional + DSP quality audit**
|
||||||
|
> (`Q-W0`) — a thorough static analysis of the code from a *functional-correctness* and
|
||||||
|
> *algorithm-quality* point of view, complementary to (not a repeat of) the grep-verified
|
||||||
|
> SOLID/naming audit that already grounds Q-W1..Q-W6. Q-W0 hunts DSP smells (close eye on the pitch
|
||||||
|
> engine), reinvented wheels, duplicate code, poor-quality algorithms, leaky pure/shell boundaries,
|
||||||
|
> and domain-modeling smells around env-coupled constants; it produces a written, triaged findings
|
||||||
|
> report. **The gate to begin Q-W1 is that Q-W0's triage is complete and Daniel has signed off on
|
||||||
|
> each finding's disposition** (fix-now vs. document-and-defer). Q-W0's findings may add or reshape
|
||||||
|
> downstream Q-W1..Q-W6 points; fixes that Q-W0 classifies fix-now are remediated in Q-W0 (or folded
|
||||||
|
> into the wave that already touches the file), **not** deferred silently into the structural waves.
|
||||||
|
>
|
||||||
> **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-9, see
|
> prefixes `Q-W0` (the pre-restructure audit) then `Q-W1..Q-W6` (the structural reorg).
|
||||||
|
> **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
|
||||||
@@ -500,6 +514,56 @@ L1, L2, L3, L4, L5, L6, and L7 have all landed. **Phase L is complete.**
|
|||||||
> or it isn't. **Green-CTest-at-every-point is an acceptance criterion.** Big-bang is rejected;
|
> or it isn't. **Green-CTest-at-every-point is an acceptance criterion.** Big-bang is rejected;
|
||||||
> the reorg is risk-ordered waves (W1 safe opener → W2–W5 god-module splits → W6 OCP finish).
|
> the reorg is risk-ordered waves (W1 safe opener → W2–W5 god-module splits → W6 OCP finish).
|
||||||
|
|
||||||
|
## Q-W0 — pre-restructure functional + DSP quality audit (runs FIRST; gates Q-W1)
|
||||||
|
**Goal:** Before a single structural point moves, perform a **thorough static/functional audit** of
|
||||||
|
the codebase and produce a **written, triaged findings report**. This is the *functional-correctness
|
||||||
|
and algorithm-quality* complement to the grep-verified SOLID/naming audit that already grounds
|
||||||
|
Q-W1..Q-W6 (§2/§2b of `docs/product/code-organization.md`) — it goes deeper on *does the code do the
|
||||||
|
right thing well*, not *where does the responsibility live*. It hunts, across the whole `src/` tree:
|
||||||
|
duplicate code, reinvented wheels, poor-quality algorithms (**close eye on the pitch engine**),
|
||||||
|
numerical-robustness and artifact hazards in the DSP paths, leaky pure/shell boundaries, and
|
||||||
|
**domain-modeling smells around env-coupled constants** (values stored in a frame/rate/DPI/tick-coupled
|
||||||
|
domain that should be stored rate-free and resolved at use). Every finding is **classified for
|
||||||
|
disposition**: *eliminate-before-restructure* (fix-now) vs. *document-and-defer* (with rationale).
|
||||||
|
Nothing structural (Q-W1+) begins until this wave closes and Daniel signs off on the disposition of
|
||||||
|
every finding. CONTEXT.md §Phase Q (Q-W0 audit scope + triage). See
|
||||||
|
`docs/product/code-organization.md` §2c.
|
||||||
|
**Verify:** A findings report exists and is complete over the named audit surfaces (DSP/audio incl.
|
||||||
|
pitch; architecture smells; env-coupled-constant domain-modeling smells). **Every finding is
|
||||||
|
triaged** (fix-now vs. documented-and-deferred, each with a one-line rationale). Fix-now findings are
|
||||||
|
either remediated in this wave or explicitly assigned to the downstream wave that already touches the
|
||||||
|
file (recorded per finding); no fix-now finding is left implicit. Any behavior-changing remediation
|
||||||
|
lands with its module's CTest executable green and (where a DSP path changes audibly) a stated
|
||||||
|
before/after listening or null check. **The gate to Q-W1 is: triage complete + Daniel signed off.**
|
||||||
|
**Depends on:** the GATE (tree quiescent). Precedes every other Q wave — Q-W1 depends on Q-W0.
|
||||||
|
|
||||||
|
- [ ] **DSP / audio audit — close eye on pitch.** Assess *algorithm quality* (correctness,
|
||||||
|
artifacts, numerical robustness, interpolation quality, reinvented-wheel vs. established DSP
|
||||||
|
technique) across: `src/vst/pitch_shift` (hand-rolled OLA pitch-preserve — window/overlap choice,
|
||||||
|
phase handling, transient/formant behavior, buffer edges), `sampler_core` (repitch ratio math,
|
||||||
|
interpolation order/quality, loop-point crossfade, voice-stealing correctness/click behavior),
|
||||||
|
`peaks` (envelope min/max binning), `wav_trim` (decay-scan threshold + truncate plan), and the
|
||||||
|
capture/tail paths.
|
||||||
|
- [ ] **Architecture-smell audit.** Duplicate code, reinvented wheels, poor abstractions, and any
|
||||||
|
leaky pure/shell boundary (a `core/` module reaching a REAPER/host type, or geometry/algorithm
|
||||||
|
math living untestable in a shell). Cross-check against — but do not merely restate — the §2/§2b
|
||||||
|
SOLID/naming findings; Q-W0's contribution is the *functional* smells those audits didn't target.
|
||||||
|
- [ ] **Env-coupled-constant domain-modeling audit (explicit smell category).** Flag ANY value
|
||||||
|
stored in a frame/rate/DPI/tick-coupled domain that should be stored **rate-free and resolved at
|
||||||
|
the point of use** — per the load-bearing invariant that wall-clock times are rate-free SECONDS
|
||||||
|
resolved against the live project rate (`sample_map`), with NO hardcoded sample rates in `src/`.
|
||||||
|
Treat this as **domain-modeling** (store rate-free, resolve at use), **not** "rescale by rate."
|
||||||
|
There was a prior incident here — envelope times stored in the frame domain — so this is a
|
||||||
|
first-class category, not a footnote. Sweep envelope times, loop points, fade lengths, tail
|
||||||
|
lengths, and any UI geometry constant that silently assumes a DPI/rate.
|
||||||
|
- [ ] **Triage + report.** Write the findings report; classify each finding fix-now vs.
|
||||||
|
document-and-defer with a one-line rationale; for each fix-now, note whether it is remediated in
|
||||||
|
Q-W0 or assigned to the downstream wave that already opens the file. Deferred findings carry a
|
||||||
|
documented rationale so they are a decision, not an omission.
|
||||||
|
- [ ] **Sign-off gate.** Daniel reviews the triage and signs off on each disposition. Q-W1 does not
|
||||||
|
begin until this is done; fold any new/reshaped downstream points the audit surfaces into
|
||||||
|
Q-W1..Q-W6 before starting them.
|
||||||
|
|
||||||
## Q-W1 — safe opener: extract `core/json` + impose the directory/namespace layout on clean modules
|
## Q-W1 — safe opener: extract `core/json` + impose the directory/namespace layout on clean modules
|
||||||
**Goal:** The zero-god-module-risk opener. Two moves: (1) extract a pure **`core/json`** module
|
**Goal:** The zero-god-module-risk opener. Two moves: (1) extract a pure **`core/json`** module
|
||||||
(parser + serializer) and **delete the four hand-rolled `Parser`s** in `bank_model` /
|
(parser + serializer) and **delete the four hand-rolled `Parser`s** in `bank_model` /
|
||||||
@@ -515,7 +579,8 @@ surgery. CONTEXT.md §Phase Q (json extraction; directory + namespace map).
|
|||||||
compiles and its test executable passes unmoved. `Sample` (model) vs `AudioSample` (audio) vs
|
compiles and its test executable passes unmoved. `Sample` (model) vs `AudioSample` (audio) vs
|
||||||
unified `Parser` (json) do not collide once sub-namespaced. No REAPER type crosses into any
|
unified `Parser` (json) do not collide once sub-namespaced. No REAPER type crosses into any
|
||||||
`core/` file; the CMake pure/shell enforcement still holds.
|
`core/` file; the CMake pure/shell enforcement still holds.
|
||||||
**Depends on:** the GATE (tree quiescent). Nothing else in Phase Q.
|
**Depends on:** the GATE (tree quiescent) **and Q-W0 closed** (audit triaged + Daniel signed off;
|
||||||
|
any fix-now findings the audit assigned to Q-W1 folded in). First structural wave.
|
||||||
|
|
||||||
- [ ] Extract `core/json` (pure parser + serializer: parseString/parseInt/parseKey/skipValue +
|
- [ ] Extract `core/json` (pure parser + serializer: parseString/parseInt/parseKey/skipValue +
|
||||||
escape, plus emit helpers); unify under `reasampler::json`; guard the `Parser` name against
|
escape, plus emit helpers); unify under `reasampler::json`; guard the `Parser` name against
|
||||||
@@ -663,17 +728,27 @@ GATE: Phase S + Phase L L3 merged to dev (D2 complete, M9 abandoned) — tree qu
|
|||||||
("when Phase S and L3 are finished" — L1/L2/L3/L4–L7 all landed — GATE SATISFIED)
|
("when Phase S and L3 are finished" — L1/L2/L3/L4–L7 all landed — GATE SATISFIED)
|
||||||
│
|
│
|
||||||
▼
|
▼
|
||||||
|
Q-W0 (pre-restructure functional + DSP quality audit — findings report + triage)
|
||||||
|
│ ── SUB-GATE: triage complete + Daniel signed off on every disposition ──
|
||||||
|
▼ (fix-now findings remediated/assigned; downstream Q-W1..W6 reshaped as needed)
|
||||||
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)
|
||||||
├─► Q-W2 (split bank_panel) ──► Q-W4 (split actions + dedupe bank verbs vs panel_bank_ops)
|
├─► Q-W2 (split bank_panel) ──► Q-W4 (split actions + dedupe bank verbs vs panel_bank_ops)
|
||||||
├─► Q-W3 (split main.cpp; hoist orchestration) ──► Q-W6 (OCP registration-table + I splits)
|
├─► Q-W3 (split main.cpp; hoist orchestration) ──► Q-W6 (OCP registration-table + I splits)
|
||||||
└─► Q-W5 (split persist; isolate prune_fs) [best after Q-W4]
|
└─► Q-W5 (split persist; isolate prune_fs) [best after Q-W4]
|
||||||
```
|
```
|
||||||
W1 is the safe, high-leverage opener (all later waves assume the layout it establishes). The four
|
Q-W0 is the **entry point** — the functional/DSP audit runs FIRST and gates Q-W1 (no structural
|
||||||
god-module splits (W2–W5) are risk-ordered and mostly parallel-safe; W4 depends on W2's
|
point begins until its triage closes and Daniel signs off). W1 is then the safe, high-leverage
|
||||||
`panel_bank_ops`, W6 depends on W3's isolated registration code. Big-bang is rejected — every wave
|
structural opener (all later waves assume the layout it establishes). The four god-module splits
|
||||||
is independently landable and CTest-green.
|
(W2–W5) are risk-ordered and mostly parallel-safe; W4 depends on W2's `panel_bank_ops`, W6 depends
|
||||||
|
on W3's isolated registration code. Big-bang is rejected — every wave is independently landable and
|
||||||
|
CTest-green.
|
||||||
|
|
||||||
## Phase Q — must-verify-before-build
|
## Phase Q — must-verify-before-build
|
||||||
|
- **Q-W0 closed before any structural point** — the functional/DSP audit's findings report exists,
|
||||||
|
every finding is triaged (fix-now vs. document-and-defer, each with rationale), fix-now findings
|
||||||
|
are remediated or assigned to the wave that opens their file, and **Daniel has signed off on every
|
||||||
|
disposition.** Q-W1 does not begin otherwise. (CONTEXT.md §Phase Q Q-W0; naming/DSP smell
|
||||||
|
categories §2c of `docs/product/code-organization.md`.)
|
||||||
- **Hot-path call/inline shape** — before landing each split, confirm no virtual dispatch and no
|
- **Hot-path call/inline shape** — before landing each split, confirm no virtual dispatch and no
|
||||||
header→TU indirection was added on `peaks` envelope compute, audition/preview, or the realtime
|
header→TU indirection was added on `peaks` envelope compute, audition/preview, or the realtime
|
||||||
tick. `computeEnvelope` stays a free function on `const std::vector<float>&`;
|
tick. `computeEnvelope` stays a free function on `const std::vector<float>&`;
|
||||||
|
|||||||
@@ -15,15 +15,24 @@ Its build roadmap lives in **PLAN.md §Phase Q** and its authoritative spec in
|
|||||||
reference, and the numbered fork decisions.
|
reference, and the numbered fork decisions.
|
||||||
|
|
||||||
**Status:** framed by product-designer (2026-07-26); gate reconciled + naming dimension added
|
**Status:** framed by product-designer (2026-07-26); gate reconciled + naming dimension added
|
||||||
(2026-07-27). Forks Q-1 … Q-9 below are the decision record; **Q-1 (namespace letter) is settled
|
(2026-07-27); **pre-restructure functional + DSP audit wave (Q-W0) added 2026-07-27** (Daniel's ask —
|
||||||
by this doc**; the remaining forks carry a leading recommendation and are Daniel's to call. Two
|
§2c, forks Q-10/Q-11). Forks Q-1 … Q-11 below are the decision record; **Q-1 (namespace letter) is
|
||||||
grep-verified audits ground every claim: a **SOLID audit** (§2) and a **naming/symbol-consistency
|
settled by this doc**; the remaining forks carry a leading recommendation and are Daniel's to call.
|
||||||
audit** (§2b) — both staff-engineer-rigor analyses of the actual `src/` tree.
|
Three audits ground the phase: the two structural, grep-verified ones — a **SOLID audit** (§2) and a
|
||||||
|
**naming/symbol-consistency audit** (§2b) — plus the **functional + DSP audit** defined as Q-W0 (§2c),
|
||||||
|
which runs *first* and is *executed* in-phase (this doc scopes it, staff-engineer performs it).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 0. TL;DR
|
## 0. TL;DR
|
||||||
|
|
||||||
|
- **Phase Q opens with a pre-restructure audit (Q-W0), then does the structural reorg.** Before a
|
||||||
|
single file moves, a **functional + DSP quality audit** (§2c) runs first — a close-eyed pass over
|
||||||
|
the DSP paths (**pitch especially**), duplicate code / reinvented wheels, and env-coupled-constant
|
||||||
|
domain-modeling smells — producing a triaged findings report. **Q-W1 (the first structural wave)
|
||||||
|
is gated on that triage being complete and Daniel signing off on each finding's disposition.**
|
||||||
|
Fixes classified fix-now are eliminated in Q-W0 (or folded into the wave that opens the file), not
|
||||||
|
carried untouched into the reorg. Everything below §2c is the structural reorg that follows.
|
||||||
- **This is not a feature phase — it is a quality phase.** The code works. The pure-core /
|
- **This is not a feature phase — it is a quality phase.** The code works. The pure-core /
|
||||||
shell split is real and healthy (30 pure static libs, each with its own CTest executable,
|
shell split is real and healthy (30 pure static libs, each with its own CTest executable,
|
||||||
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
|
||||||
@@ -298,6 +307,95 @@ is the same guardrail §7 states for the reorg, restated for the naming dimensio
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 2c. The pre-restructure functional + DSP quality audit (Q-W0 — runs FIRST)
|
||||||
|
|
||||||
|
The §2 SOLID audit and §2b naming audit are **structural** analyses — they ground *where
|
||||||
|
responsibilities live* and *what things are called*. Daniel asked (2026-07-27) for a **third audit
|
||||||
|
that runs before the reorg begins**, on a different axis: *does the code do the right thing, and does
|
||||||
|
it do it well.* That is **Q-W0** — a thorough functional + DSP static analysis producing a written,
|
||||||
|
triaged findings report, complementary to (not a repeat of) §2/§2b. Its rationale: the structural
|
||||||
|
reorg is the wrong moment to discover a bad algorithm. A reinvented wheel or a numerically-fragile
|
||||||
|
DSP path should be eliminated — or consciously documented — **before** it is relocated,
|
||||||
|
re-namespaced, and split, not carried forward untouched into a tidier tree. "Something I can stand to
|
||||||
|
look at" is partly shape (§2/§2b) and partly *functional soundness* (§2c).
|
||||||
|
|
||||||
|
Q-W0 is **not executed by product-designer** — this doc *defines the wave and its scope*; the audit
|
||||||
|
itself is staff-engineer/DSP work. The authoritative wave definition lives in **PLAN.md §Q-W0** and
|
||||||
|
its spec framing in **CONTEXT.md §"The pre-restructure audit wave (Q-W0)"**; this section is the
|
||||||
|
evidence-doc framing (the *why* and the smell taxonomy), matching how §2/§2b frame the structural
|
||||||
|
audits.
|
||||||
|
|
||||||
|
### 2c.1 Audit surfaces (the named targets)
|
||||||
|
|
||||||
|
1. **DSP / audio — a close eye on pitch** (Daniel's verbatim emphasis). Assess *algorithm quality* —
|
||||||
|
correctness, artifacts, numerical robustness, interpolation quality, reinvented-wheel vs.
|
||||||
|
established DSP technique — across:
|
||||||
|
- **`src/vst/pitch_shift`** — the **hand-rolled OLA pitch-preserve** engine. Highest priority.
|
||||||
|
Look at window function + overlap factor choice, phase coherence between frames, transient
|
||||||
|
smearing and formant behavior, and buffer-edge handling. A hand-rolled OLA shifter is exactly
|
||||||
|
the class of "reinvented wheel / poor-quality algorithm" Daniel wants scrutinized: is the
|
||||||
|
technique sound, are the artifacts acceptable, is a better-established method (e.g. a
|
||||||
|
phase-vocoder or WSOLA variant) warranted — and if the current approach is kept, is that a
|
||||||
|
*documented* decision?
|
||||||
|
- **`sampler_core`** — repitch ratio math, interpolation order/quality (linear vs. higher-order),
|
||||||
|
loop-point-aware sustain crossfade behavior, and voice-stealing correctness (clicks or
|
||||||
|
discontinuities on steal).
|
||||||
|
- **`peaks`** — envelope min/max binning correctness.
|
||||||
|
- **`wav_trim`** — the realtime-tail decay-scan threshold + truncate plan (numerical edge cases).
|
||||||
|
- **capture / tail paths** — DSP-adjacent arithmetic in range/tail handling.
|
||||||
|
2. **Architecture smells (functional lens).** Duplicate code, reinvented wheels, poor abstractions,
|
||||||
|
and leaky pure/shell boundaries — overlapping §2/§2b's territory but reporting the *functional*
|
||||||
|
smell those audits did not target (a duplicated *algorithm*, not merely a duplicated
|
||||||
|
*responsibility*; a `core/` module reaching a host type; algorithm math stranded untestable in a
|
||||||
|
shell).
|
||||||
|
3. **Env-coupled-constant domain-modeling smells — a first-class category.** ANY value stored in a
|
||||||
|
**frame / rate / DPI / tick-coupled** domain that should instead be stored **rate-free and
|
||||||
|
resolved at the point of use** is a domain-modeling smell. The correct framing is *store rate-free,
|
||||||
|
resolve at use* — **not** "rescale by the rate at the boundary." This is grounded in the
|
||||||
|
load-bearing invariant that wall-clock times are stored as **rate-free SECONDS** resolved against
|
||||||
|
the live project rate (`sample_map`), with **NO hardcoded sample rates in `src/`** (Daniel's
|
||||||
|
standing ruling). **There was a prior incident on exactly this** — envelope times stored in the
|
||||||
|
frame domain — which is why it is called out as its own smell category and not folded into
|
||||||
|
"architecture smells." Sweep at least: envelope times, loop points, fade lengths, tail lengths,
|
||||||
|
and any UI geometry constant that silently bakes in a DPI or a rate.
|
||||||
|
|
||||||
|
### 2c.2 Deliverable, triage, and the sub-gate
|
||||||
|
|
||||||
|
- **Deliverable:** a **written findings report** over the surfaces above.
|
||||||
|
- **Triage:** every finding is classified **eliminate-before-restructure** (fix-now) or
|
||||||
|
**document-and-defer** (with a one-line rationale, so a deferral is a recorded decision, never a
|
||||||
|
silent omission).
|
||||||
|
- **Where fixes land:** fix-now findings are remediated **in Q-W0**, or folded into the downstream
|
||||||
|
wave that already opens the file (recorded per finding). They are **not** silently deferred into the
|
||||||
|
structural waves — eliminations happen here or as folded-in remediation, so Q-W1+ inherits a
|
||||||
|
functionally-sound tree.
|
||||||
|
- **Reshaping downstream:** Q-W0's findings may **add or reshape** Q-W1..Q-W6 points (an algorithm
|
||||||
|
rewrite that changes a module's shape; a domain-modeling fix that changes a payload). Those reshapes
|
||||||
|
are folded in before Q-W1 begins.
|
||||||
|
- **The sub-gate:** Q-W1 does not begin until Q-W0's **triage is complete and Daniel has signed off**
|
||||||
|
on every finding's disposition. This is the entry gate to the whole structural reorg.
|
||||||
|
|
||||||
|
### 2c.3 Fork — Q-10: where does the findings report live? (Daniel's call)
|
||||||
|
|
||||||
|
- **Recommendation:** a **committed doc under `docs/product/`** (e.g. `code-quality-audit.md`),
|
||||||
|
beside the SOLID/naming audit this doc already holds. Reasons: it travels with the tree, each
|
||||||
|
finding's disposition is reviewable in one place, and it matches the precedent set by §2/§2b living
|
||||||
|
as committed framing.
|
||||||
|
- **Alternative:** a tracked **issue list** (one issue per finding). Better if Daniel wants each
|
||||||
|
finding to carry independent lifecycle state (assignee, open/closed) and to drive work item by item.
|
||||||
|
Reasonable; rejected as the lead only because the audit is a one-shot pre-reorg sweep, not an ongoing
|
||||||
|
backlog, and a single reviewable doc reads better against the "stand to look at" bar.
|
||||||
|
- **Fork — Q-11: how deep does pitch remediation go, if the audit finds the OLA shifter wanting?**
|
||||||
|
Three shapes, Daniel's call at triage time: **(a) document-and-defer** — record the artifacts/limits
|
||||||
|
as a known trade-off, change nothing now (lowest risk; keeps Phase Q a reorg); **(b) bounded fix** —
|
||||||
|
tune window/overlap/edge handling within the existing OLA approach (medium; no new dependency, no
|
||||||
|
new module shape); **(c) replace the technique** — swap in a stronger method (phase-vocoder / WSOLA),
|
||||||
|
a real DSP change that reshapes `pitch_shift` and likely spills a downstream Q-wave point. The
|
||||||
|
recommendation is to **defer this decision to the audit's findings** rather than pre-commit: pick (a)
|
||||||
|
unless the audit shows audible artifacts that matter for the tool's use, then weigh (b) before (c).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 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
|
||||||
|
|||||||
Reference in New Issue
Block a user