docs: frame versioning scheme + beta side-channel (Phase V)
Add docs/product/versioning-and-release.md and a PLAN.md Phase V pointer laying out release versioning and the beta side-channel as decidable options (V1-V4, unsettled - awaiting Daniel).
This commit is contained in:
@@ -435,3 +435,39 @@ untouched.
|
|||||||
|
|
||||||
Both docs of record: `docs/product/removal-and-prune.md` §Fork R-C/R-D/R-E and
|
Both docs of record: `docs/product/removal-and-prune.md` §Fork R-C/R-D/R-E and
|
||||||
CONTEXT.md §Prune (Settled forks).
|
CONTEXT.md §Prune (Settled forks).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase V — Versioning & release (release-milestone pillar, own lettered namespace)
|
||||||
|
|
||||||
|
> **New pillar, own lettered namespace.** Version scheme + beta side-channel — the
|
||||||
|
> release-deployment path M11 forward-implies but that had no phase or points.
|
||||||
|
> Namespaced **`V` (Versioning)** alongside `M`/`D`/`B`/`R` because it is a distinct
|
||||||
|
> concern (build identity + channel isolation) that touches CMake, `main.cpp`'s
|
||||||
|
> forever-stable command-id contract, and the `"reasampler"` ext-state — not a
|
||||||
|
> capture step. Product framing + the full option analysis + open forks:
|
||||||
|
> `docs/product/versioning-and-release.md`. **Forks V1–V4 UNSETTLED — awaiting
|
||||||
|
> Daniel.** No points are scoped-to-build until Daniel picks; the note lays out the
|
||||||
|
> recommendation (semver via `project(VERSION)` + ext-state version stamp; beta =
|
||||||
|
> branch-discipline/one-at-a-time built on a compile-time channel flag, with true
|
||||||
|
> simultaneous coexistence designed-as-a-seam but deferred). Deploy/CD wiring hands
|
||||||
|
> off to dev-ops.
|
||||||
|
|
||||||
|
## Open forks — for Daniel (see `docs/product/versioning-and-release.md`)
|
||||||
|
- **V1 — version scheme.** Recommend semver, single source of truth in CMake
|
||||||
|
`project(reaper_reasampler VERSION x.y.z)`, threaded into the binary; **plus a
|
||||||
|
writing-version stamp in the `"reasampler"` ext-state blob** for forward
|
||||||
|
migration/detection. Approve scheme + whether the ext-state stamp lands first wave.
|
||||||
|
- **V2 — beta suffix source.** Recommend `git describe` decorating beta builds while
|
||||||
|
`project(VERSION)` owns the release triple. Approve or simplify to plain `-beta`.
|
||||||
|
- **V3 — user-visible home.** Recommend startup console line (`"ReaSampler x.y.z
|
||||||
|
loaded"`) + a bank-panel version/channel readout; about-box deferred. Panel
|
||||||
|
placement is the residual polish call.
|
||||||
|
- **V4 — beta channel shape (the big one).** Recommend **branch-discipline /
|
||||||
|
one-installed-at-a-time (Option B) built on a compile-time channel flag (Option
|
||||||
|
C)**, with **true simultaneous coexistence (Option A) seam-designed but deferred**.
|
||||||
|
Sharp edges that must be decided explicitly: the forever-stable command-id prefix
|
||||||
|
(`CEREBELLUM_REASAMPLER_`) must not collide between coexisting builds, and the
|
||||||
|
`"reasampler"` ext-state namespace must not let a beta corrupt a stable project's
|
||||||
|
state — so the **ext-state-across-a-channel-swap policy** (isolate vs.
|
||||||
|
stay-compatible/stamp-and-detect vs. accept-discipline) is genuinely Daniel's call.
|
||||||
|
|||||||
@@ -0,0 +1,334 @@
|
|||||||
|
# Versioning & release — product notes
|
||||||
|
|
||||||
|
Framing behind two release-milestone (M11-adjacent) capabilities Daniel wants made
|
||||||
|
concrete and decidable:
|
||||||
|
|
||||||
|
1. **A release version scheme** — so a "real" stable build can be deployed and
|
||||||
|
identified.
|
||||||
|
2. **A beta side-channel** — so development can continue and a beta build run
|
||||||
|
*alongside* the stable one without the beta clobbering the release.
|
||||||
|
|
||||||
|
This doc holds the *why*, the forks, and a recommendation. When Daniel picks, the
|
||||||
|
tickable points land in `PLAN.md` and the deploy/build wiring hands off to dev-ops.
|
||||||
|
This is a framing note; it changes no source or CMake.
|
||||||
|
|
||||||
|
Status: framed by product-designer (2026-07-26). **Forks V1–V4 open — awaiting
|
||||||
|
Daniel.** Nothing here is settled.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## The one constraint that shapes everything: REAPER's startup dlopen
|
||||||
|
|
||||||
|
REAPER, at startup only, scans `UserPlugins/` and `dlopen()`s **every** file
|
||||||
|
matching `reaper_*.dll|dylib|so`, then calls each one's `ReaperPluginEntry`
|
||||||
|
(CLAUDE.md §REAPER extension contract). Three consequences drive every decision
|
||||||
|
below:
|
||||||
|
|
||||||
|
- **Two matching files load simultaneously.** If both `reaper_reasampler.dll` and
|
||||||
|
`reaper_reasampler_beta.dll` sit in `UserPlugins/`, REAPER loads *both* — two
|
||||||
|
independent extension instances in one REAPER process. This is the mechanism a
|
||||||
|
beta side-channel would exploit, and also its central hazard.
|
||||||
|
- **No hot reload.** Deploy = copy the binary in, restart REAPER. Any scheme is
|
||||||
|
"restart to pick up," never live-swap.
|
||||||
|
- **Everything is process-global inside REAPER.** Two coexisting instances share
|
||||||
|
one REAPER, one Actions list, one project, one ext-state store. Anything keyed by
|
||||||
|
a global string (command ids, ext-state namespace, docked-window identity) is a
|
||||||
|
potential collision surface between the two.
|
||||||
|
|
||||||
|
Two sharp edges follow directly and recur throughout this note:
|
||||||
|
|
||||||
|
- **The `STABLE_FOREVER_STRING` command-id contract** (CLAUDE.md; `main.cpp:41`,
|
||||||
|
prefix `CEREBELLUM_REASAMPLER_`). Command-id strings are minted once and **never
|
||||||
|
changed after shipping** — user keybindings key off them. Two coexisting binaries
|
||||||
|
that register the *same* id strings collide in REAPER's Actions list.
|
||||||
|
- **The `"reasampler"` project ext-state namespace** (shared by the `banks`,
|
||||||
|
`view_state`, `project_guid`, `tail_setting` keys, plus the retired `bank_index`).
|
||||||
|
Both binaries reading/writing the same namespace on the same open project means a
|
||||||
|
**beta can read — and rewrite — a stable project's saved bank/view state.** Given
|
||||||
|
the forward-only migrations already in the design (legacy `bank_index` retired
|
||||||
|
after promotion; `banks` authoritative thereafter — CONTEXT.md §Multi-bank), a
|
||||||
|
beta that writes a newer schema into a project a user then reopens in stable is a
|
||||||
|
real corruption path, not a theoretical one.
|
||||||
|
|
||||||
|
Everything below is really about how much of that global surface a beta channel is
|
||||||
|
allowed to touch.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Part 1 — Version scheme + where the version lives
|
||||||
|
|
||||||
|
## What we have today
|
||||||
|
|
||||||
|
- No version anywhere. `CMakeLists.txt:2` is `project(reaper_reasampler LANGUAGES
|
||||||
|
CXX)` — no `VERSION`. The binary announces itself only as `"ReaSampler loaded.\n"`
|
||||||
|
to the console (`main.cpp:960`). There is no number a user, a bug report, or a
|
||||||
|
future migration can key off.
|
||||||
|
- The natural user-visible readout already exists: the docked LICE bank panel, and
|
||||||
|
the console (`ShowConsoleMsg`). A version has cheap homes; none is wired.
|
||||||
|
|
||||||
|
## The number itself (V1) — recommendation: **semver, sourced from CMake**
|
||||||
|
|
||||||
|
Recommend **semantic versioning** (`MAJOR.MINOR.PATCH`) with the number's single
|
||||||
|
source of truth in `CMakeLists.txt` via `project(reaper_reasampler VERSION x.y.z)`,
|
||||||
|
threaded into the binary as a compile definition and surfaced to the user.
|
||||||
|
|
||||||
|
Semver fits because ReaSampler already has the two events semver exists to signal,
|
||||||
|
and they matter here specifically:
|
||||||
|
|
||||||
|
- **MAJOR / MINOR** track user-visible capability (a new pillar landing: Phase R
|
||||||
|
prune, M9 slots).
|
||||||
|
- **PATCH** tracks fixes.
|
||||||
|
- Most importantly, ReaSampler carries **persisted, migrating project state** (the
|
||||||
|
`"reasampler"` ext-state, forward-only migrations). A version stamped *into the
|
||||||
|
saved blob* is what lets a future build say "this project was written by 1.4, I am
|
||||||
|
1.6, run the 1.4→1.6 migration" — or refuse gracefully. That is a concrete,
|
||||||
|
already-latent need, not ceremony. **Recommend stamping the writing version into
|
||||||
|
the ext-state blob** as part of whichever release wave ships (small addition to
|
||||||
|
the persist section; a sibling `schema`/`app_version` field).
|
||||||
|
|
||||||
|
**Source of truth: CMake `project(VERSION)`.** One number, in the build system,
|
||||||
|
flowed outward — never hand-edited in a header. `project(... VERSION x.y.z)`
|
||||||
|
populates `PROJECT_VERSION` / `PROJECT_VERSION_MAJOR|MINOR|PATCH`, which a
|
||||||
|
`target_compile_definitions` (e.g. `REASAMPLER_VERSION="…"`) threads into the
|
||||||
|
binary. This is the standard CMake idiom and keeps the tag, the binary, and any
|
||||||
|
about-string in lockstep from one edit.
|
||||||
|
|
||||||
|
**Alternatives considered:**
|
||||||
|
|
||||||
|
- **Git-derived version (`git describe --tags`)** baked at configure time. Pro: the
|
||||||
|
build literally cannot disagree with the tag; encodes commits-since-tag + dirty
|
||||||
|
state, which is *excellent for a beta* ("1.4.0-beta.3+7.gab12cd"). Con: needs git
|
||||||
|
present at build and a tag discipline; a source tarball without `.git` builds
|
||||||
|
"unknown." **Recommendation: use it for the beta channel's suffix, not as the base
|
||||||
|
number.** Best of both: `project(VERSION)` owns the release triple; `git describe`
|
||||||
|
decorates beta builds. (See V2.)
|
||||||
|
- **A hand-maintained `version.h`.** Rejected — a second source of truth that drifts
|
||||||
|
from the tag. The whole point of one source is that release can't ship a binary
|
||||||
|
that lies about its number.
|
||||||
|
- **Date-based / CalVer (`2026.07`).** Coherent, but ReaSampler's changes are
|
||||||
|
capability-shaped (pillars landing), not time-shaped, and CalVer says nothing
|
||||||
|
about migration compatibility, which is the load-bearing use here. Semver earns
|
||||||
|
its place; CalVer doesn't.
|
||||||
|
|
||||||
|
## Where the user sees it (V3) — recommendation: **panel readout + startup log, defer an about box**
|
||||||
|
|
||||||
|
Three candidate homes, cheap to expensive:
|
||||||
|
|
||||||
|
1. **Startup console line** — upgrade `"ReaSampler loaded.\n"` to `"ReaSampler
|
||||||
|
x.y.z loaded.\n"`. Nearly free, and it lands the version in exactly the place a
|
||||||
|
user copies from when filing a bug. **Do this regardless of the other choices.**
|
||||||
|
2. **Bank-panel readout** — a small version string in the docked LICE panel
|
||||||
|
(header corner or footer, near the existing tail toggle / mode switch). Always
|
||||||
|
visible, no new window, matches the LICE-drawn house style. **Recommend this as
|
||||||
|
the primary user-facing home.**
|
||||||
|
3. **An "about" action / dialog** — a bindable `ReaSampler: about` that pops
|
||||||
|
version + build channel + build hash. More than the moment needs; a SWELL dialog
|
||||||
|
is real surface to maintain. **Defer** — the panel readout + console line cover
|
||||||
|
the actual need (identify the running build). Pick this up only if a beta channel
|
||||||
|
makes "which build am I running" a frequent question.
|
||||||
|
|
||||||
|
Recommendation: **(1) + (2) now, (3) deferred.** The version wants to be visible
|
||||||
|
*passively* (panel) and *copyably* (console), and a beta channel makes the panel
|
||||||
|
readout do double duty as the channel indicator (Part 2).
|
||||||
|
|
||||||
|
**Open decision V3 for Daniel:** panel placement — header corner vs. footer strip
|
||||||
|
vs. folded into the existing mode-switch/tail-toggle chrome. This is a small panel
|
||||||
|
polish call, same class as the settled "active-bank indicator placement" residual.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Part 2 — Beta side-channel
|
||||||
|
|
||||||
|
The goal: keep shipping a stable build users depend on, while running a beta of
|
||||||
|
in-progress work **alongside** it, so the beta can be exercised in real projects
|
||||||
|
without the beta's newer/rougher state clobbering the stable install or stable
|
||||||
|
projects.
|
||||||
|
|
||||||
|
The design axis is **coexistence**: must stable and beta load into the *same REAPER
|
||||||
|
at the same time* (true side-by-side), or is it enough to run *one at a time* with
|
||||||
|
clean, safe switching? That axis splits the options.
|
||||||
|
|
||||||
|
## Option A — Separate binary name, both load simultaneously (true coexistence)
|
||||||
|
|
||||||
|
Ship `reaper_reasampler_beta.dll` next to `reaper_reasampler.dll`. REAPER loads
|
||||||
|
both; the user has a stable ReaSampler and a beta ReaSampler live in one session.
|
||||||
|
|
||||||
|
This is the most powerful shape — and the most dangerous, because of the three
|
||||||
|
global-collision surfaces the startup-dlopen constraint creates. **A separate
|
||||||
|
binary name alone does not isolate them; it just makes them coexist.** For Option A
|
||||||
|
to be safe, *three* things must diverge in lockstep, not just the filename:
|
||||||
|
|
||||||
|
1. **Command-id strings must diverge.** Both binaries register actions; if the beta
|
||||||
|
mints `CEREBELLUM_REASAMPLER_CAPTURE_TRACK` too, REAPER's Actions list has two
|
||||||
|
entries claiming one id — collision, and the `STABLE_FOREVER_STRING` contract is
|
||||||
|
violated. The beta needs its **own prefix** (e.g. `CEREBELLUM_REASAMPLER_BETA_`).
|
||||||
|
Sharp edge: that means the beta's ids are a *distinct forever-family* — a user's
|
||||||
|
beta keybindings won't carry to stable, and vice versa. That is arguably correct
|
||||||
|
(they're different installs), but it must be a deliberate decision, because once
|
||||||
|
the beta ships those beta ids are *also* forever-stable. **You are minting a
|
||||||
|
second permanent id namespace, not a throwaway.**
|
||||||
|
|
||||||
|
2. **The ext-state namespace must diverge — or the beta corrupts stable projects.**
|
||||||
|
This is the severe one. If the beta writes `banks`/`view_state` under
|
||||||
|
`"reasampler"`, a project saved by the beta carries beta-schema state that stable
|
||||||
|
then reads (and the forward-only migration may have already retired the key
|
||||||
|
stable expected). The beta must write under its **own namespace** (e.g.
|
||||||
|
`"reasampler_beta"`). Consequence, and it cuts both ways: a **beta cannot see a
|
||||||
|
stable project's bank** (different namespace), so testing the beta against a real
|
||||||
|
populated project means the bank looks empty until re-captured. That is the price
|
||||||
|
of isolation, and it is the *right* price — a beta that shares stable's namespace
|
||||||
|
is a data-loss bug waiting to happen. **This divergence is non-negotiable if
|
||||||
|
Option A is chosen.**
|
||||||
|
|
||||||
|
3. **The docked-window / docker identity should diverge**, so the two panels are
|
||||||
|
distinguishable and don't fight over one dock slot. Lower-severity (a UX
|
||||||
|
annoyance, not corruption), but part of the same "everything global must fork"
|
||||||
|
picture.
|
||||||
|
|
||||||
|
Net: Option A delivers genuine side-by-side at the cost of forking *every global
|
||||||
|
identity the extension owns*. It is a **compile-time-parameterized second product**,
|
||||||
|
not a branch artifact — which points straight at Option C as the *mechanism* for how
|
||||||
|
you'd actually build it.
|
||||||
|
|
||||||
|
## Option B — One binary, branch discipline, one installed at a time
|
||||||
|
|
||||||
|
`dev` → beta builds, `main` → release builds; the version string carries a
|
||||||
|
`-beta`/`-dev` suffix so the running build self-identifies; **only one is installed
|
||||||
|
at a time.** No coexistence — you swap the binary and restart REAPER to change
|
||||||
|
channels.
|
||||||
|
|
||||||
|
- **Pro:** *zero* collision surface. Same command ids, same ext-state namespace, one
|
||||||
|
file — because only one is ever loaded. Nothing forks. Simplest by a wide margin.
|
||||||
|
- **Pro:** matches the repo's existing branch reality (`dev` is the working branch,
|
||||||
|
`main` the release branch — visible in the current git state).
|
||||||
|
- **Con:** no true side-by-side. To A/B stable against beta you swap files and
|
||||||
|
restart. For a solo developer this is often *entirely fine* — the friction is a
|
||||||
|
file copy + restart, not a corruption risk.
|
||||||
|
- **Sharp edge (the reason it's still not free):** if the beta writes a
|
||||||
|
newer/experimental ext-state schema into a real project, then you swap back to
|
||||||
|
stable and open that project, **stable reads beta-written state.** One-binary
|
||||||
|
branch discipline removes the *simultaneous* collision but not the *sequential*
|
||||||
|
one — the project file is the shared surface across a channel swap. Mitigation:
|
||||||
|
either (a) keep the beta strictly schema-compatible with stable (no ext-state
|
||||||
|
shape changes on the beta channel — often true, since most beta work is behavior,
|
||||||
|
not persistence), or (b) accept "don't open beta-touched real projects in stable"
|
||||||
|
as a discipline, or (c) stamp the writing version into the blob (V1) so stable can
|
||||||
|
at least *detect* and refuse/migrate rather than silently mis-read.
|
||||||
|
|
||||||
|
## Option C — Compile-time build flag (the mechanism, usable under A or B)
|
||||||
|
|
||||||
|
A CMake/preprocessor switch (`-DREASAMPLER_CHANNEL=beta`) that, in one build tree,
|
||||||
|
sets: output name, command-id prefix, ext-state namespace, version suffix, and the
|
||||||
|
panel channel indicator. This is not really a *third* strategy — it's *how you
|
||||||
|
implement* the divergence Option A demands, or *how you stamp the suffix* Option B
|
||||||
|
wants. It's the knob; A and B are policies for the knob.
|
||||||
|
|
||||||
|
- Under **Option A**, the flag is what forks the two binaries from one source
|
||||||
|
cleanly — flip `REASAMPLER_CHANNEL`, get the beta's name/prefix/namespace/suffix
|
||||||
|
as a coordinated set, so the three-way divergence can't get out of sync by hand.
|
||||||
|
- Under **Option B**, the flag just sets the suffix + a channel tag; name/prefix/
|
||||||
|
namespace stay shared because only one loads.
|
||||||
|
|
||||||
|
The flag is worth having either way because it makes "what makes a beta a beta" a
|
||||||
|
**single, auditable definition** instead of scattered `#ifdef`s.
|
||||||
|
|
||||||
|
## Recommendation: **B now, built on C, with A as the deliberate upgrade later**
|
||||||
|
|
||||||
|
Start with **Option B (branch discipline, one at a time) implemented through a
|
||||||
|
compile-time channel flag (Option C)**:
|
||||||
|
|
||||||
|
- Ship the release from `main` as `reaper_reasampler` with a clean semver
|
||||||
|
(`x.y.z`).
|
||||||
|
- Build beta from `dev` through `-DREASAMPLER_CHANNEL=beta`, which stamps a
|
||||||
|
`-beta`/`-dev.<git-describe>` **version suffix** and a **panel channel indicator**
|
||||||
|
(so a beta is unmistakable at a glance — the version readout from Part 1 doubles as
|
||||||
|
the channel badge). This is where `git describe` earns its keep (V2): the beta
|
||||||
|
suffix carries commits-since-tag so two betas are distinguishable.
|
||||||
|
- **Do not fork the command-id prefix or the ext-state namespace yet** — because
|
||||||
|
under B only one binary loads, so there is nothing to collide with, and forking
|
||||||
|
them prematurely commits you to a second forever-stable id family and splits your
|
||||||
|
own test data for no gain.
|
||||||
|
|
||||||
|
Then treat **Option A (true coexistence) as a later, deliberate upgrade** if and
|
||||||
|
only if "swap-and-restart" proves too slow — i.e. you find you genuinely need stable
|
||||||
|
and beta live in one REAPER to compare them. The upgrade is *clean* precisely
|
||||||
|
because you built B on the channel flag: flipping A "on" means extending the same
|
||||||
|
flag to also fork the output name, the command-id prefix (`_BETA_`), and the
|
||||||
|
ext-state namespace (`"reasampler_beta"`). The seam is designed now; the feature is
|
||||||
|
deferred (the same *defer-the-feature-design-the-seam* discipline the project
|
||||||
|
already applies to the owned-file manifest and Phase D adaptability).
|
||||||
|
|
||||||
|
Why not A first: A's power is real but it forces you to mint a **second permanent
|
||||||
|
command-id namespace** and a **second ext-state namespace** on day one — both
|
||||||
|
irreversible-ish commitments (the ids are forever-stable; the namespace split means
|
||||||
|
beta and stable never share a project's bank). That is a large, permanent price for
|
||||||
|
a convenience (simultaneous compare) you may not need. B pays nothing permanent and
|
||||||
|
keeps A one flag away.
|
||||||
|
|
||||||
|
Why not B without the flag: hand-managing the suffix and channel badge across two
|
||||||
|
branches drifts. The flag makes "beta vs. release" one definition and is the exact
|
||||||
|
thing you'd extend for A — so building B *through* C costs little now and saves the
|
||||||
|
A upgrade later.
|
||||||
|
|
||||||
|
### The sharp edge that survives every option: ext-state across a channel swap
|
||||||
|
|
||||||
|
Whichever way this goes, call out loudly (and this is a genuine **Daniel decision**,
|
||||||
|
V4): **can a beta build write experimental `"reasampler"` ext-state schema that a
|
||||||
|
stable build might later read?**
|
||||||
|
|
||||||
|
- Under **A** with a forked namespace: no — isolated, safe, at the cost of beta not
|
||||||
|
seeing stable's bank.
|
||||||
|
- Under **B**: yes, sequentially — the project file is shared across a swap. Needs a
|
||||||
|
policy: beta stays schema-compatible, **or** the version-stamp-in-blob (V1) lets
|
||||||
|
stable detect-and-refuse, **or** "don't open beta-touched real projects in stable"
|
||||||
|
is an accepted discipline.
|
||||||
|
|
||||||
|
The cheapest robust mitigation across both is **V1's version stamp in the ext-state
|
||||||
|
blob** — it turns a silent mis-read into a detectable "this project was written by a
|
||||||
|
newer/other build." Recommend adopting it as part of the first release wave
|
||||||
|
regardless of the A/B choice, because it's the seam that makes every later channel
|
||||||
|
and migration decision safe.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Part 3 — Deploy / CD touchpoints (hand-off to dev-ops)
|
||||||
|
|
||||||
|
Framing only — the actual pipeline is dev-ops's to author. The strategy above
|
||||||
|
implies these touchpoints:
|
||||||
|
|
||||||
|
- **Tag → version.** Release is cut from a git tag on `main`; `project(VERSION)` is
|
||||||
|
bumped to match the tag (or the tag is derived from it — pick one direction and
|
||||||
|
keep it one-way). Beta builds from `dev` carry `git describe` in the suffix.
|
||||||
|
- **Channel is a build parameter.** `-DREASAMPLER_CHANNEL=release|beta` selects the
|
||||||
|
suffix/badge now (Option B) and, if Option A is ever turned on, the output
|
||||||
|
name/prefix/namespace too. One flag, one definition of "what is a beta."
|
||||||
|
- **Artifact per platform.** The binary is `reaper_*.dll|.dylib|.so`; the macOS/Linux
|
||||||
|
builds need the SWELL resgen step (CLAUDE.md §SWELL dialog resources) baked into
|
||||||
|
the pipeline. Three platform artifacts per channel per release.
|
||||||
|
- **Install is copy-in + restart** (no hot reload). A release "deploy" is publishing
|
||||||
|
the artifact for the user to drop into `UserPlugins/`; there is no server-side
|
||||||
|
rollout. Any auto-update story is out of scope here and would be its own note.
|
||||||
|
- **The ext-state version stamp (V1)** is the one piece of forward-compatibility
|
||||||
|
plumbing the pipeline should ensure ships in the first versioned release, so every
|
||||||
|
subsequent build can reason about older saved state.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Open decisions for Daniel
|
||||||
|
|
||||||
|
- **V1 — version scheme.** Recommend semver via `project(VERSION)` as single source
|
||||||
|
of truth, **plus a writing-version stamp in the `"reasampler"` ext-state blob** for
|
||||||
|
forward migration/detection. Approve scheme + whether the ext-state stamp lands in
|
||||||
|
the first release wave.
|
||||||
|
- **V2 — beta suffix source.** Recommend `git describe` decorating beta builds
|
||||||
|
(`x.y.z-beta.N+g<hash>`) while `project(VERSION)` owns the release triple. Approve
|
||||||
|
or simplify to a plain `-beta` suffix.
|
||||||
|
- **V3 — user-visible home + placement.** Recommend startup console line + a
|
||||||
|
bank-panel version/channel readout now; about-box deferred. Panel placement
|
||||||
|
(header corner / footer / folded into existing chrome) is the residual call.
|
||||||
|
- **V4 — beta channel shape (the big one).** Recommend **Option B (branch
|
||||||
|
discipline, one at a time) built on an Option C compile-time channel flag**, with
|
||||||
|
**Option A (true simultaneous coexistence) designed-as-a-seam but deferred**. The
|
||||||
|
sub-decision that must be made explicitly either way: **the ext-state-across-a-
|
||||||
|
channel-swap policy** — isolate (A), stay schema-compatible / stamp-and-detect (B),
|
||||||
|
or accept the discipline. This is genuinely Daniel's call, not one to default.
|
||||||
Reference in New Issue
Block a user