docs: give Phase Gamma's DAW obligations a home in VERIFICATION.md

This commit is contained in:
2026-08-02 23:12:51 -04:00
parent 27712b7573
commit cbc4a4c53e
2 changed files with 27 additions and 19 deletions
-18
View File
@@ -847,24 +847,6 @@ doc-keeper edit.
**Done looks like.** The enumeration distinguishes "in the project's state" from "on disk
in the `.rpp`", and does not gain a second home for the distinction.
## The VST3 parameter surface's DAW-verifiable claims
**Context (what shipped — Γ-W4-T1).** The instrument reports 44 automatable parameters under the frozen id table, services both delivery channels (the controller's `setParamNormalized` and the audio thread's `IParameterChanges` drain), and folds automated values back into the blob on the UI thread.
**What is settled without a DAW.** The channel question itself is answered by the vendored SDK, not by observation: `ivsteditcontroller.h` documents `setParamNormalized` as the GUI-update channel ("should update the according GUI element(s) only"), and the SDK's own `SingleComponentEffect` sample (`public.sdk/samples/vst/again/source/againsimple.cpp`) drains `ProcessData::inputParameterChanges` in `process()` while also implementing `setParamNormalized`. Servicing both is what the SDK's own precedent does; it needs no verification, only exercise.
**What genuinely needs a running REAPER, and why none of it can change the design.** Each item below is a host BEHAVIOUR, not a contract — the plug-in is correct under either answer, so discovering the answer costs a display fix at worst:
1. **Whether REAPER renders `ParameterInfo::units` beside the string `getParamStringByValue` returns, or shows the string alone.** We ship the SDK's own convention (digits in the string, unit carried separately). If REAPER shows no unit at all, the fallback is to append the unit inside the one formatter — one line in one place, touching neither the frozen id table nor the editor, because display strings are explicitly not frozen.
2. **Whether REAPER's own per-parameter MIDI learn covers what a shipped `IMidiMapping` CC table would have.** The decision to ship no default map rests on it; if learn does not reach these parameters, a CC table is additive and frozen by nothing.
3. **That the three migration round trips hold**: a pre-parameter project opens with every parameter reading the blob's value and sounds identical; a project saved by this build restores fully in an older binary; a project with automation drawn, saved and reopened, replays against the same plain values.
4. **That an offline render replays automation** — the sharpest case for the audio-side drain, because the host drives `process()` and may never touch the controller.
5. **That REAPER restores instance state through `setState`, not `setComponentState`.** This is the ENTRY-POINT half of the original bundled `[verify, FIRST]`; the pass that closed that item closed only its delivery-channel half, which is a different question. The evidence short of a DAW is strong but is inference: `vstsinglecomponenteffect.h:41-47` collapses the two names on a single-component plug-in, our `setState`/`getState` overrides land on the `IComponent` pair with `setEditorState`/`getEditorState` left at the base's `kNotImplemented`, and the blob has round-tripped through payload v1…v16 in real projects. Exercising it costs one save/reopen.
**Priority / risk.** Low. Nothing here is load-bearing on the frozen contract: the id table, the plain ranges and the norm↔plain laws are all decided and tested without a host.
**Done looks like.** Each of the four exercised once in REAPER, with the unit-rendering answer recorded and, if it went the other way, the one-line formatter change made.
## `view_mode_model.cpp` is over the ~600-line structural bar, and `view.cpp` is close behind
**Context (surfaced by the FX-GUID keying track).** Root `CLAUDE.md`'s structural
+27 -1
View File
@@ -1,6 +1,6 @@
# DAW verification — post-1.0 work on `dev`
Checks for Θ, Ξ, Ψ, Ε, and Ρ work that no unit test can close. Build **Release**, install into
Checks for Θ, Ξ, Ψ, Ε, Ρ, and Γ work that no unit test can close. Build **Release**, install into
`UserPlugins/`, restart REAPER. Panel tail toggle = **None**, project rate 48000, unless a check says otherwise.
## Precision invariants
@@ -174,3 +174,29 @@ Checks for Θ, Ξ, Ψ, Ε, and Ρ work that no unit test can close. Build **Rele
- [ ] Piano strip at the 840 px default — keys tile uniformly, the 37 px end gutters read as acceptable (`docs/COMPLETED.md` §"Θ-W2-T3")
- [ ] Resize the editor across several widths — gutters stay symmetric, no key width jumps (`docs/COMPLETED.md` §"Θ-W2-T3")
- [ ] Set host/OS scaling to 150% then 200% — record how the strip and the AA strokes actually look (`docs/TODO.md` §"High-DPI host scaling is unverified (distinct from the antialiasing audit)", `docs/COMPLETED.md` §"Θ-W2-T3" — "Width uniformity is guaranteed in client pixels only")
## The VST3 parameter surface
- [ ] `[verify — DAW]` Whether REAPER renders `ParameterInfo::units` beside the string
`getParamStringByValue` returns, or shows the string alone. We ship the SDK's own
convention (digits in the string, unit carried separately); if REAPER shows no unit at
all, the fallback is a one-line change to the single formatter, touching neither the
frozen id table nor the editor (`docs/COMPLETED.md` §"Γ-W4-T1")
- [ ] Whether REAPER's own per-parameter MIDI learn covers what a shipped `IMidiMapping`
CC table would have — the decision to ship no default map rests on it; if learn does not
reach these parameters, a CC table is additive and frozen by nothing (`docs/COMPLETED.md`
§"Γ-W4-T1")
- [ ] The three migration round trips: a pre-parameter project opens with every parameter
reading the blob's value and sounds identical; a project saved by this build restores
fully in an older binary; a project with automation drawn, saved and reopened, replays
against the same plain values (`docs/COMPLETED.md` §"Γ-W4-T1")
- [ ] `[verify — DAW]` **Whether an offline render replays automation at all** — the
sharpest case for the audio-side drain, because the host drives `process()` and may
never touch the controller (`docs/COMPLETED.md` §"Γ-W4-T1")
- [ ] `[verify — DAW]` **Whether REAPER restores instance state through `setState`, not
`setComponentState`** — the entry-point half of the original bundled `[verify, FIRST]`
that an earlier pass closed only the delivery-channel half of. The evidence short of a
DAW is strong but is inference: `vstsinglecomponenteffect.h:41-47` collapses the two
names on a single-component plug-in, and the blob has round-tripped through payload
v1…v16 in real projects. Exercising it costs one save/reopen (`docs/COMPLETED.md`
§"Γ-W4-T1")