Imported from thomassresearch/orchestron (
AGENTS.md). Install upstream withnpx skills add thomassresearch/orchestron. Copyright stays with the author.
Orchestron Coding Agent Guide
Orchestron uses a React/TypeScript/Tailwind/Rete.js frontend and a FastAPI/Python/Csound backend. Legacy paths and environment variables retain the VisualCSound name. Keep this guide below 400 lines and around 1,500 words; link to detailed procedures and source definitions.
Working rules
- Keep
frontend/srcandbackend/appAPI contracts and behavior aligned. - Use
visualcsound-opcode-supportwhenever adding or updating opcodes. Use the patch and performance skills linked below for instrument/performance authoring. - For backend behavior changes, add or update regression tests in
backend/tests/test_api.pyand the relevant service tests. - Keep instrument/performance test data in versioned test fixtures, independent of developer
examples/. Tests must not read examples directly or through production imports. Frontend tests resolve the drumkit import to the sharedbackend/tests/fixtures/patches/snapshot. - Instrument/example work must be additive. Preserve existing examples and templates, especially
examples/instruments/template/analog_drumkit.patch.json, imported byfrontend/src/lib/audioTemplates.tsand copied byDockerfile. Native*.orch.instrument.jsonexports cannot replace that raw patch build dependency. - Before moving, renaming, converting, or removing examples, use
rgto find frontend imports, Docker copies, tests, and documentation/skill links. Update affected references together, preserve required inputs in.dockerignore, and include them in the same version-controlled change. - Before finishing instrument/example changes, verify shared build inputs exist; run
npm --prefix frontend run buildanddocker build --target frontend-build .. Report Docker validation as unperformed if unavailable. Patch/audio validation does not substitute for either build. - For user-visible workflow/UI changes, update README and relevant
documentation/pages. When layout or interaction changes, take new screenshots, save toscreenshots/(or update existing) and update the relevant documentation to reference the new screenshots. Keep labels and integrated help consistent across EN/DE/FR/ES. - README is for user capabilities, screenshots, and getting started. Preserve its title/opening through the user-documentation link and the full Built With Codex section unless the user requests changes. Keep implementation decisions here or in linked technical references.
- Preserve useful decisions as concise current contracts. Before removing detail from this guide, verify that a linked reference or source definition covers it.
Commands and verification
Run from the repository root; select checks appropriate to the change. Documentation-only
changes need Markdown/link validation and git diff --check.
| Task | Command |
|---|---|
| Run / debug backend | make run / make run-debug |
| Frontend lint, tests, build | npm --prefix frontend run check |
| Backend tests | uv run --extra dev pytest backend/tests |
| Backend lint / full checks | make backend-check / make check |
| Render and sequencer-boundary benchmarks | make benchmark-runtime |
For preparation timing, run .venv/bin/python -m backend.tools.benchmark_sequencer_preparation;
it measures cold, cached, and one-pad preparation using the versioned TB303 test fixture.
Critical architecture and compatibility decisions
Audio runtime and live edits
- All runtimes use
browser_clock. A dedicated browser worker owns PCM WebSocket refills and SharedArrayBuffer writes; AudioContext/AudioWorklet own playback. Csound renders on demand withperformKsmps(); React observes PCM-timed audible markers outside the refill path. - Internal MIDI uses an engine-local timestamped scheduler through
internal:loopback, even without OS MIDI devices. Session MIDI Input selects optional external MIDI from the Rust host helper, including host timestamps. - Keep Csound performance logging disabled normally to avoid blocking rendering through stdout.
Temporarily enable
VISUALCSOUND_CSOUND_PERFORMANCE_LOGGING=truefor diagnostics. - Live edits prepare in a persistent compiler process and apply at an engine block boundary without resetting transport. Buffering and synthesis settings are independent of preparation. Notes/curves edit the displayed pad; rapid edits coalesce after 80 ms.
- Playback/status updates and automatic pad changes must not resubmit full configurations. Queued launches retain loop-boundary timing. Stop cancels pending application.
- Failed preparation retains the previous playing configuration and edited draft, reports the error, and waits for another edit or explicit restart to retry. Shortening a finite arrangement past the playhead stops playback without rewinding.
- App-state validation, database work, and response serialization run in a worker thread so autosave cannot block audio refills.
Instruments and graph editing
- Normal Save compiles; templates may save incomplete graphs and stay excluded from Perform. Built-in starters work with an empty library. Continuous instruments need no MIDI notes or inlet unless receiving audio; other types use MIDI activation.
- Preserve instrument types through save, clone, restored tabs, and native bundle round trips. Legacy inference defaults to Melody; existing always-on patches become Continuous.
- Stereo blocks wrap ordinary
inleta/outleta;outsis Direct Audio Output. Keep nodes, channel mappings, and renames synchronized. Grouping/conversion preserves wiring and formulas, removes dedicated namingconst_snodes, and retains shared constants for other consumers. Apply cleanup to existing valid groups; repair performance routes after port changes. - If/Switch choose one synthesis case per note. Membership transfers require connected endpoints and formula bindings to move together or already belong to the destination. Preserve graph ownership, case sizes, and formulas through save/reload and export/import.
- Draft audition is temporary: prepare before explicitly stopping and auditioning. Closing restores original state/playhead with transport stopped. Isolated audition uses patch defaults; performance audition uses the selected instance's overrides.
Performance and persistence
- Tempo is global; sequencers retain independent meter, grid, and rational beat ratios. Preserve polymeter/polyrhythm without floating-point clock drift. Note and controller pads switch at loop boundaries; arpeggiators run in the backend with unique input MIDI channels.
- Melodic strums spread ordered chord attacks across 0–100% of a local step, preserving each note’s duration. Same-pitch retriggers replace owned releases; see backend strumming contracts.
- Arranger alone edits song order. Playback source uses
padLoopEnabled; lane end behavior usespadLoopRepeat. Delete leaves equivalent rests; closing time is explicit. Retain unused definitions and trailing rests. See the arranger reference for hierarchy and import fallback. - Melodic/drummer/controller/arpeggiator pattern workspaces keep loose items and per-definition drafts in editor state; Group creates a definition, Apply updates all uses, and only the arranger edits song order. Workspace Play is a temporary layer below 250 ms speaker previews; stopping restores prior playback.
- Audition is session-only and uses the shared clock. Live arpeggiator audition follows cycle/bar launch quantization; arranger speaker previews use a 250 ms hold, then the next cycle boundary while the arranger runs, or a render block while stopped without moving its cursor. Release restores prior playback. Save/export reads authored state. Arranger Play clears auditions, starts Arrangement tracks and preserves independent Manual pads; Stop clears auditions and preserves independently started Manual pads tracks. Composer Stop also stops the engine when composer Play started it; an already running engine stays running. Piano-roll Start is independent of arranger playback; retain the documented seek/reset behavior.
- Device Play explicitly starts its source. Running Manual pads clicks select for editing and queue at pattern boundaries (orange queued, cyan playing); stopped/Arrangement pad clicks only select for editing. Arrangement devices share a song-position mapping; Manual pads retain phase through song seeks/loops/end and arranger controls. Runtime intent and signed phase anchors never enter saved configuration. See backend independent-device transport.
- Arranger Undo/Redo stores 25 atomic actions and a cursor in optional
arrangerHistorymetadata; preserve it through save/load/autosave/native bundles. External conflicting edits clear it; runtime data and unrelated edits do not. See the arranger reference for scope and history controls. - Arranger lane Mute/Solo gates source-tagged MIDI without stopping its clock; controls are temporary, independent of the mixer, and excluded from save/export. See arranger and backend references for dependency, revision, and note-release contracts.
- Rack/topology changes lock while instruments run; mixer controls remain live. Direct output bypasses Master but retains strip controls. Legacy Level migrates to dB audio gain, not velocity.
- Mixer persistence arrived in performance config v11; current serializers/CLI write v20 and
accept v1–20. App state is v3 and reads v1–3. Distinguish these from the native bundle envelope version.
Preserve types, device names, routing, mixer state, instance overrides and optional
padLoopPattern.definitionColorsdisplay metadata across round trips. Colours never trigger audio preparation. - Master is the fixed
$masterendpoint, with no library patch or rack slot. Preserve its strip/inserts and direct-output bypass; see routing docs for legacy migration and backups. perf_controllervalues are per-instance I-rate settings: new notes adopt changes; continuous instruments require restart. Save Performance, native bundles, and both CSD modes preserve them.- Collapsed panels suspend visual work and meter subscriptions while playback continues. Preserve drafts, selections, clipboard, zoom, and scroll on expansion. Collapse closes menus, cancels drags, and releases held notes. Temporary editor state resets on New/Load/Import; collapse preferences survive view switches until reload and are not performance data.
Exports and limits
- Native bundles preserve the whole rack. CSD exports select assigned note instruments and routed/Master/insert continuous instances, counting stopped/empty devices and implicit direct continuous generators. Omit unused instances, routes, and exclusive assets before compilation.
- Both CSD modes seed enabled manual MIDI controller values and instance settings, render at
48 kHz with
ksmps=1and 32-bit float WAV, and retain always-on effect release tails. MIDI mode packages a MIDI file; SCORE embeds events and rewrites supported MIDI opcodes. - GEN01/
sfloadrequire uploaded/imported assets; reject raw backend paths before compile/start. Keep asset bundling and render instructions consistent with the export reference. - Enforce bundle limits before parsing, persisted JSON limits before storage, and GEN limits before storage/emission. Preserve session/observer/MIDI quotas and bounded offline exports. Read current values from settings and validators below; avoid duplicating default tables here.
References by task
Read the relevant reference before changing a subsystem; these contain detailed contracts, UI interactions, validation ranges, and operational procedures.
| Task | Reference |
|---|---|
| Backend services and APIs | Backend reference |
| Test fixture isolation and drumkit snapshots | Fixture rules |
| Audio settings, MIDI, and live editing | Browser clock, engine settings, live edits |
| Library, types, opcode defaults, and plugins | Patch toolbar, opcode catalog |
| Graph interfaces, branches, and audition | Graph editor, control flow, audition |
| Devices, timing, and editor state | Performance, arranger, manual index |
| Mixer, effects, and instance settings | Routing, effect implementation, performance controllers |
| Import/export formats and selection rules | Instruments, performances |
| Resource defaults and validation | Settings, JSON limits, GEN validation, export limits |
| Author instruments, formulas, and audio validation | Patch creator skill |
| Author performances, routes, and runtime updates | Performance creator skill |
| Interactive melody generation, audition, and score handoff | Composition creator skill |
| External MIDI and native timing probes | MIDI setup, host helper, diagnostic tools |
| Docker publishing, recovery, and retention | Release procedures |
