Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ Promoted from patterns in past-session feedback — the things Christian kept ha
| `docs/progression-leveling-detail.md` | The deep-dive companion: tier-ladder mechanics, the full leveling math + Lifer graduation, PBs/recognizers/specBest, the proof loop, summit invite, node states, streaks, woodshed, per-block credit, designed-not-built. |
| `docs/sources/` | Source PDFs — reference material only. |
| `docs/images/` | Screenshots embedded in the docs / README (the four renderers, the modes, result cards). |
| `scripts/cut-beta.mjs` | Regenerates the renamed `virtuoso-beta` branch from `virtuoso-dev` (the beta channel — see Part 3 session-end checklist). |
| `scripts/cut-beta.mjs` | Regenerates the renamed `virtuoso-beta` branch from `main` (or a feature branch via `--source` — the beta channel; see Part 3 session-end checklist). |
| `scripts/check-brand-hygiene.mjs` + `.githooks/pre-commit` | **Brand/IP-hygiene guard** — fails if a competitor product/company name (curated denylist) appears in any git-tracked file. Enforces the "market lane" rule: named comps live ONLY in local-only (gitignored) `.claude/` market-analyst files, never the published repo. The `pre-commit` hook blocks such commits (enable once per clone: `git config core.hooksPath .githooks`); also in the session-end checklist. Escape hatch: `brand-ok` on the line for a genuine external SOURCE citation. |
| `docs/local-dogfood.md` | **Repeatable local dogfood + dev-beta runbook** — the canonical launch pathway (`launch-desktop.ps1` = real desktop with the live repo; `launch.ps1` = headless smoke host), the userData-symlink load mechanism + the stale-link gotcha (the actual cause of "my edits don't show / behaves differently from the game"), and cut-beta. **Read before debugging test-instance inconsistency.** |
| `start-session.cmd` / `start-session.ps1` | Convenience session launchers — double-click `start-session.cmd` to open an elevated PowerShell in this folder and start Claude Code (`start-session.ps1` is the script it invokes). Not part of the dev/test path. |
Expand Down Expand Up @@ -228,7 +228,7 @@ A lightweight ritual the **main thread** follows so context survives across sess
- If conventions changed, keep `CLAUDE.md` and `AGENTS.md` **in sync** (they mirror).
- If `screen.js` changed, run the smoke suites (`npm test` in `.claude/skills/run-virtuoso/`, host running). Commit working changes following the repo's **Conventional Commits** style (`type(scope): …` — e.g. `feat(audio):`, `feat(ui):`, `docs:`); **commit/push only when asked.**
- **Brand/IP hygiene:** before committing docs/prose, run `node scripts/check-brand-hygiene.mjs` (no competitor product/company names in tracked files — only local-only `.claude/` may name comps; the `pre-commit` hook enforces it once `git config core.hooksPath .githooks` is set). Generalize the lane instead of naming the product; `brand-ok` on a line sanctions a genuine external source citation.
- **`main` HEAD is a PUBLISHED end-user artifact** (since FeedBack Desktop v0.2.9, 2026-06-08): Virtuoso is a bundled host plugin AND the host's `update_manager` zips our default-branch HEAD when a Desktop user updates (the user-dir copy wins over the bundled snapshot). So **keep WIP on a branch; only land on `main` when green**, and **bump `plugin.json` version on every shippable change** (the host caches by id+version) — **AND bump the `VIRTUOSO_VERSION` constant in `screen.js` to match** (it's the header version badge; the host doesn't inject a plugin's own version, so the badge mirrors `plugin.json` by hand — keep them equal). On a NEW FeedBack release, run the **host-release overlap sweep** (ROADMAP standing ritual) before building — it's the recurring counterpart to the per-feature HOST CHECK in "Agent workflow" rule 4. Full mechanics: project memory `project_host_release_v029_audit`. **Beta channel:** to let testers run WIP *alongside* stable, `node scripts/cut-beta.mjs --push` regenerates the renamed `virtuoso-beta` branch (id `virtuoso_beta`, "Virtuoso (Beta)") from `virtuoso-dev` so it coexists with stable; promote dev→`main` on the word. See `docs/beta-testing.md` / memory `project_beta_channel`.
- **`main` HEAD is a PUBLISHED end-user artifact** (since FeedBack Desktop v0.2.9, 2026-06-08): Virtuoso is a bundled host plugin AND the host's `update_manager` zips our default-branch HEAD when a Desktop user updates (the user-dir copy wins over the bundled snapshot). So **keep WIP on a branch; only land on `main` when green**, and **bump `plugin.json` version on every shippable change** (the host caches by id+version) — **AND bump the `VIRTUOSO_VERSION` constant in `screen.js` to match** (it's the header version badge; the host doesn't inject a plugin's own version, so the badge mirrors `plugin.json` by hand — keep them equal). On a NEW FeedBack release, run the **host-release overlap sweep** (ROADMAP standing ritual) before building — it's the recurring counterpart to the per-feature HOST CHECK in "Agent workflow" rule 4. Full mechanics: project memory `project_host_release_v029_audit`. **Beta channel:** `node scripts/cut-beta.mjs --push` regenerates the renamed `virtuoso-beta` branch (id `virtuoso_beta`, "Virtuoso (Beta)") from `main` so it installs alongside stable. Since the 2026-07-16 dev→`main` consolidation, `main` is the **single trunk** (no standing `virtuoso-dev`); to let testers run WIP *alongside* stable, cut the beta from a feature branch with `--source <branch>`. See `docs/beta-testing.md` / memory `project_beta_channel`.

## Agent workflow (required)

Expand Down
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ Promoted from patterns in past-session feedback — the things Christian kept ha
| `docs/progression-leveling-detail.md` | The deep-dive companion: tier-ladder mechanics, the full leveling math + Lifer graduation, PBs/recognizers/specBest, the proof loop, summit invite, node states, streaks, woodshed, per-block credit, designed-not-built. |
| `docs/sources/` | Source PDFs — reference material only. |
| `docs/images/` | Screenshots embedded in the docs / README (the four renderers, the modes, result cards). |
| `scripts/cut-beta.mjs` | Regenerates the renamed `virtuoso-beta` branch from `virtuoso-dev` (the beta channel — see Part 3 session-end checklist). |
| `scripts/cut-beta.mjs` | Regenerates the renamed `virtuoso-beta` branch from `main` (or a feature branch via `--source` — the beta channel; see Part 3 session-end checklist). |
| `scripts/check-brand-hygiene.mjs` + `.githooks/pre-commit` | **Brand/IP-hygiene guard** — fails if a competitor product/company name (curated denylist) appears in any git-tracked file. Enforces the "market lane" rule: named comps live ONLY in local-only (gitignored) `.claude/` market-analyst files, never the published repo. The `pre-commit` hook blocks such commits (enable once per clone: `git config core.hooksPath .githooks`); also in the session-end checklist. Escape hatch: `brand-ok` on the line for a genuine external SOURCE citation. |
| `docs/local-dogfood.md` | **Repeatable local dogfood + dev-beta runbook** — the canonical launch pathway (`launch-desktop.ps1` = real desktop with the live repo; `launch.ps1` = headless smoke host), the userData-symlink load mechanism + the stale-link gotcha (the actual cause of "my edits don't show / behaves differently from the game"), and cut-beta. **Read before debugging test-instance inconsistency.** |
| `start-session.cmd` / `start-session.ps1` | Convenience session launchers — double-click `start-session.cmd` to open an elevated PowerShell in this folder and start Claude Code (`start-session.ps1` is the script it invokes). Not part of the dev/test path. |
Expand Down Expand Up @@ -228,7 +228,7 @@ A lightweight ritual the **main thread** follows so context survives across sess
- If conventions changed, keep `CLAUDE.md` and `AGENTS.md` **in sync** (they mirror).
- If `screen.js` changed, run the smoke suites (`npm test` in `.claude/skills/run-virtuoso/`, host running). Commit working changes following the repo's **Conventional Commits** style (`type(scope): …` — e.g. `feat(audio):`, `feat(ui):`, `docs:`); **commit/push only when asked.**
- **Brand/IP hygiene:** before committing docs/prose, run `node scripts/check-brand-hygiene.mjs` (no competitor product/company names in tracked files — only local-only `.claude/` may name comps; the `pre-commit` hook enforces it once `git config core.hooksPath .githooks` is set). Generalize the lane instead of naming the product; `brand-ok` on a line sanctions a genuine external source citation.
- **`main` HEAD is a PUBLISHED end-user artifact** (since FeedBack Desktop v0.2.9, 2026-06-08): Virtuoso is a bundled host plugin AND the host's `update_manager` zips our default-branch HEAD when a Desktop user updates (the user-dir copy wins over the bundled snapshot). So **keep WIP on a branch; only land on `main` when green**, and **bump `plugin.json` version on every shippable change** (the host caches by id+version) — **AND bump the `VIRTUOSO_VERSION` constant in `screen.js` to match** (it's the header version badge; the host doesn't inject a plugin's own version, so the badge mirrors `plugin.json` by hand — keep them equal). On a NEW FeedBack release, run the **host-release overlap sweep** (ROADMAP standing ritual) before building — it's the recurring counterpart to the per-feature HOST CHECK in "Agent workflow" rule 4. Full mechanics: project memory `project_host_release_v029_audit`. **Beta channel:** to let testers run WIP *alongside* stable, `node scripts/cut-beta.mjs --push` regenerates the renamed `virtuoso-beta` branch (id `virtuoso_beta`, "Virtuoso (Beta)") from `virtuoso-dev` so it coexists with stable; promote dev→`main` on the word. See `docs/beta-testing.md` / memory `project_beta_channel`.
- **`main` HEAD is a PUBLISHED end-user artifact** (since FeedBack Desktop v0.2.9, 2026-06-08): Virtuoso is a bundled host plugin AND the host's `update_manager` zips our default-branch HEAD when a Desktop user updates (the user-dir copy wins over the bundled snapshot). So **keep WIP on a branch; only land on `main` when green**, and **bump `plugin.json` version on every shippable change** (the host caches by id+version) — **AND bump the `VIRTUOSO_VERSION` constant in `screen.js` to match** (it's the header version badge; the host doesn't inject a plugin's own version, so the badge mirrors `plugin.json` by hand — keep them equal). On a NEW FeedBack release, run the **host-release overlap sweep** (ROADMAP standing ritual) before building — it's the recurring counterpart to the per-feature HOST CHECK in "Agent workflow" rule 4. Full mechanics: project memory `project_host_release_v029_audit`. **Beta channel:** `node scripts/cut-beta.mjs --push` regenerates the renamed `virtuoso-beta` branch (id `virtuoso_beta`, "Virtuoso (Beta)") from `main` so it installs alongside stable. Since the 2026-07-16 dev→`main` consolidation, `main` is the **single trunk** (no standing `virtuoso-dev`); to let testers run WIP *alongside* stable, cut the beta from a feature branch with `--source <branch>`. See `docs/beta-testing.md` / memory `project_beta_channel`.

## Agent workflow (required)

Expand Down
12 changes: 7 additions & 5 deletions docs/beta-testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Virtuoso ships on two channels:
| **Stable** | `main` | `virtuoso` | Bundled with FeedBack Desktop **and** auto-updated to `main` HEAD by the host's `update_manager` (the host only ever auto-ships the default branch). |
| **Beta** | `virtuoso-beta` | `virtuoso_beta` | **Opt-in manual install** of the `virtuoso-beta` branch (below). The host cannot auto-update anyone to a non-default branch — that's what keeps beta opt-in. |

The beta is a **renamed mirror of `virtuoso-dev`**: every `virtuoso` token (plugin id, on-screen element ids, `/api/plugins/virtuoso/…` URLs, storage tables, localStorage keys) is swapped to `virtuoso_beta`. That distinct identity is what lets it install **alongside** the stable build — FeedBack keys plugins by `id` and inlines every plugin screen into one shared page, so two `virtuoso` installs would collide (registration + duplicate DOM ids). With a different id they coexist: two nav entries, fully independent (own settings, own saved presets, own progress). Proven side-by-side via `.claude/skills/run-virtuoso/probe-coexist.mjs`.
The beta is a **renamed mirror of `main`** (or a feature branch via `--source`): every `virtuoso` token (plugin id, on-screen element ids, `/api/plugins/virtuoso/…` URLs, storage tables, localStorage keys) is swapped to `virtuoso_beta`. That distinct identity is what lets it install **alongside** the stable build — FeedBack keys plugins by `id` and inlines every plugin screen into one shared page, so two `virtuoso` installs would collide (registration + duplicate DOM ids). With a different id they coexist: two nav entries, fully independent (own settings, own saved presets, own progress). Proven side-by-side via `.claude/skills/run-virtuoso/probe-coexist.mjs`.

---

Expand Down Expand Up @@ -46,20 +46,22 @@ git -C virtuoso_beta reset --hard origin/virtuoso-beta

## For the maintainer — cutting & promoting

**Cut / refresh a beta** (after committing your dev work):
**Cut / refresh a beta** (after landing your work on `main`, the single trunk since the 2026-07-16 consolidation):
```bash
git push origin virtuoso-dev # beta is built from the latest COMMIT on dev
git push origin main # beta is built from the latest COMMIT on the source ref (default main)
node scripts/cut-beta.mjs --push # regenerate the renamed tree → commit + push virtuoso-beta
```
`cut-beta.mjs` builds from the committed `virtuoso-dev` tree (tracked runtime files only — no `.claude`, docs, ROADMAP, agent-memory), auto-bumps the version to `X.Y.Z-beta.N` (the base `X.Y.Z` comes from `plugin.json`, stripped of `-dev`), and commits a snapshot to `virtuoso-beta` so testers' `git pull` stays fast-forward. Flags:
To let testers run **WIP alongside stable**, cut from a feature branch instead: `node scripts/cut-beta.mjs --push --source feat/my-branch`.

`cut-beta.mjs` builds from the committed source tree (default `main`; tracked runtime files only — no `.claude`, docs, ROADMAP, agent-memory), auto-bumps the version to `X.Y.Z-beta.N` (the base `X.Y.Z` comes from `plugin.json`, stripped of any `-dev`), and commits a snapshot to `virtuoso-beta` so testers' `git pull` stays fast-forward. Flags:
- `--dry-run [dir]` — write the renamed tree to a temp dir and inspect; no git.
- `--version 0.7.6-beta.3` — force a version.
- (no `--push`) — commit to the local `virtuoso-beta` branch only; push later.

When you bump `plugin.json` to a new base (e.g. `0.7.7-dev`), the beta counter resets to `0.7.7-beta.1`.

**Promote a beta to stable** (the usual release ritual):
1. Merge `virtuoso-dev` → `main`.
1. Land the work on `main` (short-lived feature branch → PR → merge when green).
2. Bump `plugin.json` `version` to the clean `X.Y.Z` **and** the `VIRTUOSO_VERSION` constant in `screen.js` to match (the host caches by id+version; the badge is mirrored by hand).
3. Tag, Discord post, README/GitHub page update.
4. The host's `update_manager` ships `main` HEAD to all updaters.
Expand Down
7 changes: 4 additions & 3 deletions docs/local-dogfood.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ highway, never by editing Virtuoso to match a drifted host.
## Cut a dev beta

`node scripts/cut-beta.mjs --push` regenerates the renamed `virtuoso-beta` branch (id
`virtuoso_beta`, "Virtuoso (Beta)") from `virtuoso-dev`, so testers run WIP alongside
stable. See `docs/beta-testing.md` / memory `project_beta_channel`. Promote
`virtuoso-dev` → `main` only when green (the smoke suite + the desktop dogfood both clean).
`virtuoso_beta`, "Virtuoso (Beta)") from `main` (the single trunk since the 2026-07-16
consolidation), or from a feature branch via `--source <branch>` so testers run WIP
alongside stable. See `docs/beta-testing.md` / memory `project_beta_channel`. Land work on
`main` only when green (the smoke suite + the desktop dogfood both clean).
```
12 changes: 7 additions & 5 deletions scripts/cut-beta.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* cut-beta.mjs — publish the "Virtuoso (Beta)" build.
*
* WHAT IT DOES
* Builds a RENAMED mirror of `virtuoso-dev` (plugin id `virtuoso_beta`,
* Builds a RENAMED mirror of `main` (plugin id `virtuoso_beta`,
* name/label "Virtuoso (Beta)", version `X.Y.Z-beta.N`) and commits it to the
* `virtuoso-beta` branch. Because the id differs, the beta INSTALLS ALONGSIDE
* the stable Virtuoso in FeedBack — two nav entries, fully independent
Expand All @@ -17,8 +17,10 @@
* ids, /api/plugins/virtuoso/ URLs, localStorage keys). Renaming by hand on
* every dev change is unmaintainable; this regenerates it mechanically.
*
* SOURCE = the latest COMMIT on the source ref (default virtuoso-dev), NOT your
* working tree. Commit your dev work first.
* SOURCE = the latest COMMIT on the source ref (default `main`, the single
* trunk since the 2026-07-16 dev→main consolidation), NOT your working tree.
* Commit/land your work first. Override with --source <ref> to cut a beta
* from a feature branch (the WIP-alongside-stable use case).
*
* USAGE
* node scripts/cut-beta.mjs build + commit to local virtuoso-beta (no push)
Expand Down Expand Up @@ -52,7 +54,7 @@ const has = (f) => args.includes(f);
const optVal = (f, d) => { const i = args.indexOf(f); return i >= 0 && args[i + 1] && !args[i + 1].startsWith('--') ? args[i + 1] : d; };
const DRY = has('--dry-run');
const PUSH = has('--push');
const SOURCE = optVal('--source', 'virtuoso-dev');
const SOURCE = optVal('--source', 'main');
const FORCE_VERSION = optVal('--version', null);

// ── git helpers (execFile = no shell, so quoting/newlines are safe) ─────────
Expand Down Expand Up @@ -175,7 +177,7 @@ try {
console.log(`[cut-beta] virtuoso-beta already matches ${SOURCE} @ ${srcSha} — nothing to do.`);
} else {
const msg =
`beta: sync virtuoso-dev @ ${srcSha} (v${betaVersion})\n\n` +
`beta: sync ${SOURCE} @ ${srcSha} (v${betaVersion})\n\n` +
`Auto-generated Virtuoso (Beta) build — a renamed (id: ${BETA_TOKEN}) mirror of\n` +
`${SOURCE} so it installs ALONGSIDE the stable Virtuoso. Do not edit by hand;\n` +
`regenerate with scripts/cut-beta.mjs.`;
Expand Down
Loading