- vcv/build-mac.sh: bounded Docker osxcross build (system clang, NOT LLVM-from-
source; cached toolchain image for fast reruns) → ad-hoc-signed mac-x64 +
mac-arm64 .vcvplugin. MacOSX12.3 SDK from joseluisq/macosx-sdks.
- DISTRIBUTION.md: macOS is now a host bounded cross-build, not CI-only.
All four platforms (lin/win/mac-x64/mac-arm64) now published at /next/vcv.
- vcv/Makefile: include arch.mk early, link -lws2_32 when ARCH_WIN (the OSC
server uses Winsock; mingw ignores the MSVC #pragma comment lib).
- vcv/build-win.sh: bounded Docker mingw cross-build (hard CPU/mem caps, no
extra swap, prebuilt mingw — no toolchain compile). Produces win-x64 .vcvplugin.
- DISTRIBUTION.md: reflect the no-dedicated-box reality — Linux + Windows built
locally (supervised + bounded), macOS needs the Apple SDK (CI or a Mac).
- add .github/workflows/vcv-plugin.yml: official rack-plugin-toolchain
(pinned to commit 4fd1318, Rack SDK 2.6.6, image v19) cross-builds the
MEMLNaut plugin for lin-x64/win-x64/mac-x64/mac-arm64 on CI, uploads
.vcvplugin artifacts, and attaches them to GitHub Releases on v* tags.
- add vcv/DISTRIBUTION.md: build + publish flow, how to add CI release
artifacts to meml.lnfinitemonkeys.org/next/vcv.
- add vcv/.gitignore for build products (build/, dist/, *.vcvplugin, binaries).
- BUILDING.md: point at DISTRIBUTION.md; note make dist supersedes Makefile.dist.
Linux x64 .vcvplugin built + verified locally via make dist and published to
/next/vcv (additive subdir). Windows/macOS deferred to CI per prod-host policy.
8 inputs x 16 outputs; per-output LED ring widget (drawLayer+nvgArc); palette
from frontend tokens; OSC bridge verbs for bidirectional browser training;
vendored self-contained iml.hpp (retired nisps-core); compiles against Rack
SDK 2.6.4. See SPEC.md BUILD DELTAS.
Fixes from Opus 4.6 review (C1-C6, I1, I3, I4, I8):
C1: static lastOutputs → per-instance lastOutputsForDelta member
C2: add_example() now on audio thread only (owns iml); worker reads
from mutex-protected staging area (stagedFeatures/stagedLabels)
C3: Worker reads stagedWeightsForWorker (not iml.get_weights()),
eliminating concurrent read/write on iml's MLP
C4: Worker spins on weightsPending before writing pendingWeights,
preventing double-write race
C5: RAND and CLEAR now enqueue Randomize/Clear jobs through worker
instead of directly mutating iml on the audio thread
C6: OSC callbacks stage JSON into oscStagedJson + atomic flag;
audio thread applies in process() (no recv-thread mutation)
Also fixed:
- I4: Separate pendingJob field (enqueueJob no longer overwrites currentJob)
- I8: Removed redundant swapReady atomic
- noiseLevel, cachedNovelty, cachedConfidence now std::atomic<float>
- Worker syncs examples back to iml after training via load_examples()
Replace direct-mutation threading with shadow IML:
- Background thread clones weights from main → shadow IML
- Training and perturbation operate only on shadow instance
- New weights staged in pendingWeights, swapped atomically by audio thread
- Thumbs-down now enqueues Perturb job instead of calling move_weights directly
- Audio thread applies new weights via iml.set_weights() at safe point
- Examples copied to shadow for training, results copied back as weights only
Threading invariant now fully enforced: background thread never writes to
the inference IML. Audio thread applies staged weights between inference calls.
Standalone test exercising IML inference pipeline without VCV runtime:
- Basic inference: all 12 outputs valid in [0,1]
- Input responsiveness: 12/12 outputs change between corners
- Randomize: weights change produces different output mapping
- Spread parameter: measurably different distributions at 0 vs 1
- Expressiveness: 6/6 corner pairs distinct, full range utilized
- Smoothness: 100% of sweep steps are smooth (no binary jumps)
Finding: spread sigmoid saturation effect is architecture-dependent
with small [16,24,16] network (filed as meml-l5a for investigation).
Full spec for MEMLNaut VCV Rack module based on interview:
- 2-8 configurable CV inputs, 12 raw + 5 derived CV outputs
- RL feedback via panel buttons + CV triggers with learn gate guard
- nisps-core C++ engine with background thread training
- User-configurable inference rate (block to audio rate)
- Bidirectional state transfer with companion webapp (file + OSC)
- 10-phase development plan from skeleton to distribution