docs: archive Phase V (V1-V4) to COMPLETED; reconcile CLAUDE.md

Phase V landed: app_version module, ext-state version stamp, show-version
action, beta-in-isolation channel build. CLAUDE.md gains the module entry,
version key, test target, and beta-build note.
This commit is contained in:
2026-07-26 16:56:04 -04:00
parent 88e10c18c7
commit 6a6d305cf2
4 changed files with 113 additions and 56 deletions
+91
View File
@@ -657,6 +657,97 @@ items exempt; one undo block per action. ctest 14/14 green.
---
# Phase V — Versioning & release
> **New pillar, own lettered namespace.** Version scheme + beta side-channel.
> Namespaced **`V` (Versioning)** alongside `M`/`D`/`B`/`R` — a distinct concern
> (build identity + channel isolation) that touches CMake, `main.cpp`'s
> forever-stable command-id contract, and the `"reasampler"` ext-state. Product
> framing + full option analysis: `docs/product/versioning-and-release.md`.
> Deploy/CD wiring (two named artifacts per platform) hands off to dev-ops.
## V1/V3 — app_version module: version constant, ext-state stamp, show-version action
**Goal:** Pure `app_version` module — single-source semver from CMake
`REASAMPLER_VERSION "0.9.01"` via `configure_file` → `version_generated.h`;
ext-state writing-version stamp under key `"version"` riding
`saveToActiveProject()`; absent stamp = silent pre-versioning; on-demand
`"ReaSampler: show version"` action (no startup print). New CTest target
`app_version_tests`.
**Verify:** CTest green. Stamp written under `"version"` key on every
`saveToActiveProject()` call. Absent key classifies as `PreVersioning` (silent).
Show-version action fires on demand only.
- [x] `app_version` pure module (`src/app_version.{h,cpp}`): exports the CMake
version string constant (`appVersion()`), the ext-state stamp value
(`stampVersion()` — numeric triple only, no channel suffix), `parseVersion`,
`versionLess`, `classifyWritingVersion` (empty → `PreVersioning`; unparseable →
`Unknown`; well-formed → `Stamped`). No REAPER types; standard library only.
- [x] `configure_file` wires `REASAMPLER_VERSION` (the one CMake variable) +
`REASAMPLER_CHANNEL_IS_BETA` into `version_generated.h` in the build tree;
`app_version` reads from there — one edit re-threads the version string through
every consumer.
- [x] Writing-version stamp: `persist` calls `SetProjExtState` under
`kProjExtVersionKey` (`"version"`) with `stampVersion()` inside
`saveToActiveProject()` on every save. Absent key on load → `PreVersioning`
(silent; graceful for pre-versioning projects).
- [x] On-demand show-version action (`channelCommandId("SHOW_VERSION")` /
`channelActionName("show version")`): prints the CMake-sourced `appVersion()`
string to the console when fired. **No unconditional startup print** (no version
line added to the extension load message).
- [x] `app_version_tests` CTest target: version parse/compare/classify round-trip;
`PreVersioning` on empty; `Unknown` on malformed; `Stamped` on well-formed;
`versionLess` numeric ordering (10 > 9, not lexicographic).
## V4 — beta-in-isolation: fully isolated coexisting binary via compile-time channel flag
**Goal:** Compile-time channel flag `-DREASAMPLER_CHANNEL=beta` → fully isolated
`reaper_reasampler_beta` binary: ext-state namespace `reasampler_beta`, FOREVER-STABLE
command-id prefix `CEREBELLUM_REASAMPLER_BETA_`, `"ReaSampler beta: "` action names,
channel-qualified dock title/ident, `0.9.01-beta` display render, bank-panel footer
version/channel readout. Stable build byte-identical to prior identity.
**Verify (in DAW):** Both binaries load simultaneously in one REAPER via the startup
dlopen. Stable produces no change to any existing action id, ext-state key, or panel
string. Beta reads/writes only `"reasampler_beta"` namespace; its actions carry
`CEREBELLUM_REASAMPLER_BETA_` prefix; its panel shows `0.9.01-beta`. No shared-state
collision path between channels.
- [x] `app_version` extended as the single source of truth for channel identity (V4):
`channel()`, `isBeta()`, `extStateNamespace()`, `commandIdPrefix()`,
`actionDisplayPrefix()`, `binaryName()`, `dockTitle()`, `dockIdent()` — all derived
from the one `REASAMPLER_CHANNEL_IS_BETA` bit. Stable values byte-identical to
pre-V4 build.
- [x] `channelCommandId(suffix)` / `channelActionName(phrase)` composition helpers:
every action-registering shell funnels through these so no shell re-implements the
channel-qualified concatenation. FOREVER-STABLE per channel.
- [x] `configure_file` threads `REASAMPLER_CHANNEL_IS_BETA` (0 for the default build,
1 for `-DREASAMPLER_CHANNEL=beta`) alongside the version string. Beta binary name,
namespace, prefix, and display suffix all derive from this one bit.
- [x] All shells (`main.cpp`, `actions.cpp`, `bank_panel.cpp`, `persist.cpp`) updated
to compose ids/names via `channelCommandId`/`channelActionName` and read
`extStateNamespace()` — no scattered `#ifdef` forks in the shells.
- [x] Bank-panel footer version/channel readout: displays `appVersion()` (stable:
`"0.9.01"`, beta: `"0.9.01-beta"`).
- [x] The lane-name `reasampler:` prefix is deliberately NOT channel-qualified (shared
naming convention; ownership isolated by namespace).
- [x] Stable build: byte-identical to pre-V4 identity on every string that was
previously shipped.
**Notes/decisions:**
- The stamp value (`stampVersion()`) is the numeric triple only on BOTH channels —
no `-beta` suffix in the stamp. The channel is carried by the isolated namespace
(`extStateNamespace()`), not baked into the stamp, so the stamp parses as `Stamped`
on read-back and stable's stamp is byte-identical regardless of channel build.
- Two permanent commitments accepted: a second forever-stable command-id prefix
(`CEREBELLUM_REASAMPLER_BETA_`) and a second ext-state namespace
(`"reasampler_beta"`). Beta keybindings are a distinct forever-family from stable's.
- Isolation semantics (accepted, not a bug): a channel reads/writes only its own
namespace — a stable project looks empty/default when opened in beta, and vice versa.
No cross-namespace read, migration, or fallback.
- Deploy implication (dev-ops hand-off): two named artifacts per platform
(`reaper_reasampler` + `reaper_reasampler_beta`), built by toggling
`-DREASAMPLER_CHANNEL`.
---
# Phase B — Multi-bank (parallel to the M0M11 capture roadmap and Phase D)
> **Separate phase namespace.** The M-numbers belong to the capture pillar