SpaceAge Build, Test, And Package Workflow
SpaceAge Build, Test, And Package Workflow
This document records the short repo-local commands used to reduce approval churn during Codex work.
Performance Change Requirement
Performance is a correctness gate, not optional polish. Any feature with meaningful realtime, scaling, memory, disk, worker, or UI-refresh cost must include a prediction before implementation and measured evidence afterward. Run focused sound/behavior tests together with an appropriate Release performance workload, repeat noisy timing results, and record accepted or rejected impact in docs/Performance_Optimization_Rule_And_Impact_Report.md.
Do not accept an optimization merely because it removes source-level operations. Eager cache preparation, branches, host calls, memory traffic, and idle-state work can cost more than the calculation they replace.
Refactoring Requirement
Follow docs/Refactoring_Policy.md. Clean touched boundaries continuously,
review affected subsystems after every 5-10 meaningful changes, and perform a
deeper pass at subsystem milestones. Refactors must preserve focused behavioral
evidence; DSP refactors require exact or explicitly tolerance-defined audio
comparison. Avoid broad cleanup during urgent defect fixes and feature freezes.
Scripts
All scripts live in tools/.
tools/run_tests.ps1- Builds
SampleSquadAudioTest - Runs the regression executable
- Builds
tools/test-convolution.ps1- Builds the small
ConvTesttarget independently of the plugin UI and asset suite - Verifies the neutral FIR/reset contract, procedural convolution-reverb output, and sample-aligned automation invariance across fixed and variable host blocks
- See
docs/Convolution_Architecture.mdfor design boundaries, synthesis reuse, tail contracts, licensing posture, and remaining listening decisions
- Builds the small
tools/build_release.ps1- Builds the full Release configuration
- Verifies the standalone
.exeand.vst3artifacts exist - Refreshes
docs/reports/index.htmlafter successful validation
tools/update-reports-index.ps1- Rebuilds the searchable webpage of live links to every repository Markdown file
- Must be run before handing the user any requested development build produced
outside
build_release.ps1
tools/package_release.ps1- Always builds Release from the exact clean commit; there is no stale-binary bypass
- Refuses public packaging until all 72 canonical release-readiness checks are complete; ordinary development builds remain available
- Rejects a public-package build-directory override, verifies the upstream-proven JUCE source fingerprint, and records the CMake/generator/compiler/PowerShell/Windows toolchain
- Stages the standalone
.exe,.vst3, README, third-party ledger, and required license notices - Reopens the finished archive and verifies its manifest, artifact hashes, evidence hashes, source commit, and runtime-import inventory
- Writes a clean timestamped zip,
.sha256sidecar, and hash-bound human attestation into theoutputsfolder without leaving loose binaries in the repo root
tools/test-release-hygiene.ps1- Verifies product identity, offline boundaries, legal-source files, and package notice coverage
- Runs automatically as gate
R02-Ain release convergence
tools/test-release-archive-contract.ps1- Builds a synthetic package, verifies it, corrupts its executable, adds an unmanifested file, and proves both invalid archives are rejected
tools/test-release-juce-source.ps1- Recomputes the complete local JUCE tree fingerprint offline and requires the official 8.0.8 commit identity
tools/test-release-archive-attestation.ps1- Binds final human approval to one exact ZIP filename, SHA-256, and source commit
Typical Commands
Show one consolidated release-candidate status without building:
powershell -NoProfile -ExecutionPolicy Bypass -File '.\tools\get-release-candidate-status.ps1'
Run tests:
powershell -NoProfile -ExecutionPolicy Bypass -File '.\tools\run_tests.ps1'
Run the fast focused convolution test:
powershell -NoProfile -ExecutionPolicy Bypass -File '.\tools\test-convolution.ps1'
External PCM WAV references can be measured in place without importing them:
python tools/analyse_convolution_references.py --spaceage <reference.wav> [more.wav ...]
See docs/Convolution_Reference_Calibration.md for the release boundary and
current procedural-room calibration.
Render nine deterministic 48 kHz/24-bit listening references from the same shipping DSP: five production-mix comparisons, a dry reference, and wet-only Compact/Medium/Deep files for inspecting the continuous Size morph in isolation:
powershell -NoProfile -ExecutionPolicy Bypass -File '.\tools\test-convolution.ps1' -NoBuild -RenderAuditionDirectory '.\outputs\convolution-audition'
Add -VerifyAuditionDeterminism to render all nine WAVs twice and require an
identical sorted filename, byte-length, and SHA-256 manifest from both passes.
The audition mode is intentionally separate from the regression run. It writes synthetic first-party excitation plus the wet return, requires no DAW or external audio asset, and does not alter the release package.
After configuring with CMake's default BUILD_TESTING=ON, the same focused
binary is also registered as SpaceAgeConvolutionFocused for standard CTest
discovery. It carries the audio and convolution labels and a 180-second
timeout. CTest runs it serially so parallel test workers do not invalidate its
wall-clock real-time watchdog:
ctest --test-dir '<build-directory>' -C Release -R SpaceAgeConvolutionFocused --output-on-failure
Build Release:
powershell -NoProfile -ExecutionPolicy Bypass -File '.\tools\build_release.ps1'
Refresh the persistent reports webpage without building:
powershell -NoProfile -ExecutionPolicy Bypass -File '.\tools\update-reports-index.ps1'
Every user-requested build handoff must include a link to both the executable and
docs/reports/index.html. Report links target the source Markdown files directly,
so edits to an existing report are visible immediately; regenerating the index
adds newly created reports and refreshes titles, timestamps, and sizes.
Package a test build:
powershell -NoProfile -ExecutionPolicy Bypass -File '.\tools\package_release.ps1' -Label 'SPACEAGE_SOME_FEATURE' -CleanCheckoutReceiptPath '.\test-reports\clean-checkout-convergence-<sha>-<time>.out'
The receipt must come from the exact commit being packaged and contain a
completed PASS. Packaging copies it into the archive and binds its hash in the
release manifest. Public packaging also requires Release_Readiness_Checklist.md
to contain exactly the canonical 72 unique IDs with no remaining open check.
Compare two independently produced candidates from the same exact commit:
powershell -NoProfile -ExecutionPolicy Bypass -File '.\tools\compare-release-candidates.ps1' -ArchiveA '<first.zip>' -ArchiveB '<second.zip>' -ExpectedCommit '<40-character-sha>'
The comparison ignores archive timestamps and generatedUtc, but requires the
same customer binaries, package files, evidence, runtime imports, and toolchain.
Environment Overrides
Development build and test scripts default to the current Windows setup and can use these overrides. Public packaging deliberately rejects SPACEAGE_BUILD_DIR so a stale or foreign cache cannot be substituted:
SPACEAGE_BUILD_DIRSPACEAGE_VSDEVCMDSPACEAGE_CMAKE_EXE
Why This Exists
The old workflow used long one-off PowerShell commands for build, test, copy, zip, and push operations. Those commands were harder for Codex sandbox approval to classify and harder for humans to review.
The new workflow keeps the risky details in versioned scripts and lets future sessions run short, repeatable commands.
Candidate Clean-Checkout Convergence
After all release-proof source, test, resource, and tool dependencies are committed, certify the exact candidate commit without using the current build tree:
powershell -NoProfile -ExecutionPolicy Bypass -File '.\tools\test-clean-checkout-convergence.ps1' -CandidateSha '<full-or-resolvable-SHA>'
Use -ValidateOnly for the inexpensive syntax/manifest/dependency-status check. Use -ReceiptPath '<path>' to choose the receipt destination; otherwise the script writes an exact-SHA receipt under test-reports/.
The full command refuses dirty or untracked required dependencies before doing expensive work. It creates a guarded detached worktree outside the repository, verifies CMake/package dependencies are tracked at the candidate, configures from scratch, builds only SampleSquadAudioTest, invokes tools/run-release-convergence.ps1 -SkipBuild, runs git diff --check, rejects candidate-worktree mutations, records the exact SHA, and cleans only its own temporary worktree. It does not stage, commit, package, build a customer executable, or remove artifacts from the current workspace.
VST3 wrapper preflight
The canonical release build now produces CinematicDrums_VST3 and SpaceAgeVst3HostSmokeTest alongside the standalone and self-test. tools/test-vst3-host-smoke.ps1 runs the plugin in an isolated process with a 120-second timeout. tools/package_release.ps1 repeats the proof against the exact copied staging bundle before archive creation. A PASS requires discovery, note-driven audio above a silence baseline at two sample rates, a real continuous-parameter mutation, byte and semantic state restoration, and two native-peer editor lifecycles with JUCE message dispatch between open and close.
Deterministic release archives
tools/release_archive_helpers.ps1 is the only supported public ZIP writer. It sorts every file path, includes hidden files, and fixes ZIP entry timestamps. ReleaseManifest.json binds generatedUtc to the source commit timestamp rather than the packaging clock. The archive contract builds the same fixture twice and requires identical ZIP hashes, then proves that generation-time and toolchain drift are both rejected.
Project CPU Gate Asset Handling (2026-08-29)
PROJECT_CPUandPROJECT_CPU_SWEEPuse named-argument splatting when invoking their profiling scripts.- A silent isolated lane passes as
unavailableonly when its stored instrument source is confirmed missing. It is omitted from workload rankings but retained in raw output. Silent lanes without missing-asset evidence remain failures.