Files
serumalt/AGENT.md
T
biggy 05fd6440bd docs: add agent guidance and historical audit report
Add root AGENT.md with project conventions, build verification steps,
source layout, style rules, and real-time/concurrency requirements.
Add per-module AGENT.md files for each existing and proposed source
subdirectory. Add AUDIT_REPORT.md as a historical Phase 1 snapshot
documenting memory management, error handling, concurrency model,
naming conventions, and anti-pattern catalog.
2026-09-09 13:25:02 +02:00

4.4 KiB

SerumAlt agent guidance

Project

SerumAlt is a JUCE 7 wavetable synthesiser using C++17. Project metadata is in CMakeLists.txt. Production formats are VST3 and Standalone on Linux, VST3/AU/Standalone on macOS, and VST3 on Windows. First-party classes use namespace serum; executable entry points and JUCE's createPluginFilter are outside that namespace.

Build and verification

Read README.md's Building section before changing scripts, dependencies, or CMake. It is the maintained source for prerequisites, options and artifact paths.

  • Linux production: ./build_linux.sh.
  • macOS production, on a Mac: ./build_macos.sh.
  • Windows x64 VST3, cross-compiled on Linux: ./build_windows.sh.
  • Native QA build and execution: ./build_harness.sh --run.
  • Shell syntax: for script in build_*.sh; do bash -n "$script"; done.

Production scripts explicitly enable SERUMALT_BUILD_PLUGIN and disable SERUMALT_BUILD_TESTS. The harness script does the reverse in a separate directory. Building SerumAltTest alone does not execute it; --run invokes CTest. When changing CMake, verify production has no SerumAltTest target and the harness-only build has no SerumAlt, VST3, AU, or Standalone target.

Keep existing build trees and local changes intact. Use a new BUILD_DIR for clean-build verification. Use a fresh Windows OUTPUT_DIR for distribution checks, since staging does not remove extra files. Never edit generated CMakeCache.txt files. The checked-in MinGW toolchain is the single source of cross-compiler configuration.

Current source layout

CMakeLists.txt owns the explicit SERUMALT_SOURCES list and shared target setup. cmake/Plugin.cmake owns production formats and MinGW link flags; cmake/Harness.cmake owns the console harness and CTest registration. The harness compiles the same processor/editor sources independently of the plugin.

Most C++ files still live directly under Source/. Existing implementation subdirectories are EffectUnits/, GUI/, Presets/, Resources/, and Tests/. FXProcessor, PluginEditor, Resources, and RAVEButton remain at the source root. RAVEButton.{h,cpp} defines RaveController.

The lowercase Source/engine, modulation, params, plugin, and synth directories currently hold guidance, not relocated implementations. Consult their AGENT.md files when editing the related root-level sources. Consult the matching AGENT.md when editing an existing implementation subdirectory. AUDIT_REPORT.md is a historical audit and proposed refactor, not a pending instruction to move files. Update the explicit source list and includes only when an actual source move is part of the requested task.

Style and ownership

Follow the surrounding file. Existing C++ generally uses four-space indentation, #pragma once, PascalCase types, camelCase members without prefixes, k-prefixed constants, scoped enums, and noexcept on cheap getters and DSP paths. Use Count only for enums that need a size or iteration sentinel. Headers include JuceHeader; implementation files normally include their own header first.

Prefer value members or std::unique_ptr for owned objects and attachments. addAndMakeVisible does not transfer ownership or delete children. Raw allocations returned by createEditor and createPluginFilter transfer ownership to JUCE callers. Guard parameter lookups and invalid state data. Use jassert sparingly for programmer errors and return bool from bounded inserts to report failure.

Real-time and concurrency requirements

For new or changed audio paths, allocate buffers during preparation and avoid heap allocation, blocking locks and I/O in processBlock or per-sample DSP. Account for variable host block sizes without allocating in the callback. Keep GUI updates on the JUCE message thread. Exchange GUI/audio state through a safe snapshot or bounded handoff; a timer or a writer-only mutex does not make concurrent access safe.

These are requirements, not claims that the current code already satisfies them. The historical audit records lazy wavetable allocation, per-block buffer resizing, and unsynchronised modulation/LFO edits. When changing those paths, inspect the current implementation and verify the fix separately. The QA smoke test does not prove real-time safety or absence of data races.

Scope of guidance

Module guidance refines this file for its related sources. Preserve the root real-time and ownership requirements if an example conflicts with them.