Files
suaveplan/openspec/archive/2026-05-17-enterprise-audio-plugins-fx/tasks.md
2026-05-27 23:29:53 +01:00

13 KiB
Raw Blame History

Tasks: enterprise-audio-plugins-fx

Change ID: enterprise-audio-plugins-fx Package: @suaveplan/audio-plugins-fx Target path: packages/audio/audio-plugins-fx Prerequisite packages on Verdaccio: @suaveplan/audio-core, @suaveplan/audio-transport, @suaveplan/schema-registry, @suaveplan/error, @suaveplan/types, @suaveplan/opentelemetry, @suaveplan/events

No behavior change is permitted to ship without a corresponding spec scenario AND a **Verified by:** test. Every task below must reflect work actually done.


1. Scaffold

  • 1.1 Create directory tree per design.md §13. All feature subdirs (base/, chain/, registry/, plugins/<name>/, presets/<name>/, __benchmarks__/, tests/, tests/bundle-size/).
  • 1.2 Write package.json at version 0.1.0 with "type": "module", "sideEffects": false, deps @suaveplan/audio-core workspace:^, @suaveplan/audio-transport workspace:^, @suaveplan/schema-registry workspace:^, @suaveplan/error workspace:^, @suaveplan/types workspace:^, @suaveplan/opentelemetry workspace:^, @suaveplan/events workspace:^, zod catalog:forms, tslib catalog:build.
  • 1.3 Write a full exports map: ., ./base, ./chain, ./registry, and one entry per plugin path: ./eq, ./filter, ./compressor, ./limiter, ./gate, ./reverb, ./delay, ./chorus, ./phaser, ./flanger, ./tremolo, ./auto-filter, ./distortion, ./pitch-shifter, ./synthesizer, ./sampler, ./mixer, ./widener, ./spatial-positional, ./proximity-voice, ./music-layer-mixer, ./voice-transform, ./microphone, ./glados, ./audio-player. Plus ./presets/* lazy.
  • 1.4 Write tsconfig.json, vitest.config.ts via createTestConfig(), lint/typecheck/test/test:coverage/build/docs:check scripts.

2. Error codes + Zod schemas

  • 2.1 Write src/error-codes.ts — defineCodes("AUDIO_FX", [...]) for every code listed in the "Structured error codes" requirement (17 codes total). Export AudioFxErrorCode, AUDIO_FX_ERROR_METADATA, registerAudioFxErrorCodes(), and AudioError class.
  • 2.2 Write src/error-codes.test.ts — every registered code reachable from a real call site (per Requirement "Structured error codes").
  • 2.3 Write src/error-codes.md.

3. Base contract (src/base/)

  • 3.1 Write src/base/plugin-io.ts — PluginIo, ChannelSpec, ChannelLayout, validateChainIo() helper. + .types.ts, .test.ts, .md.
  • 3.2 Write src/base/capabilities.ts — PluginCapabilities interface + deriveCapabilities() helper that cross-checks method presence. + .types.ts, .test.ts, .md.
  • 3.3 Write src/base/parameter-schedule.ts — curve + transport-time schedule evaluator, sample-accurate; shared queue per parameter id. + .test.ts, .md.
  • 3.4 Write src/base/preset.ts — PresetSnapshot type, Zod-validated getPreset/applyPreset reference implementation. + .types.ts, .test.ts, .md.
  • 3.5 Write src/base/audio-fx-plugin.ts — AudioFxPlugin interface, AbstractAudioFxPlugin reference class (parameter storage, schedule evaluation, latency emission, capabilities defaults). + .types.ts, .test.ts, .md.
  • 3.6 Write src/base/index.ts barrel (explicit named re-exports only).

4. Chain primitive (src/chain/)

  • 4.1 Write src/chain/ambient-state.ts — AmbientState type, defaultAmbientState(), immutable patch-merge reducer. + .types.ts, .test.ts, .md.
  • 4.2 Write src/chain/bus-registry.ts — BusRegistry interface, SidechainBus, SidechainPublisher, DefaultBusRegistry reference implementation. + .types.ts, .test.ts, .md.
  • 4.3 Write src/chain/chain-context.ts — ChainContext factory; produces stable per-plugin context with PluginHandle peer views. + .types.ts, .test.ts, .md.
  • 4.4 Write src/chain/pdc.ts — PDC summing helper + per-plugin onLatencyChanged subscription manager. + .test.ts, .md.
  • 4.5 Write src/chain/bypass-wrapper.ts — chain-level bypass implementation; passthrough buffer reuse without allocation. + .test.ts, .md.
  • 4.6 Write src/chain/chain-snapshot.ts — Zod-validated ChainSnapshot shape, snapshot/restore against a PluginRegistry. + .test.ts, .md.
  • 4.7 Write src/chain/plugin-chain.ts — PluginChain class implementing composition (add/remove/move/replace with crossfade/bypass), lifecycle (setup/process/reset/dispose), inspection (plugins/findById/getEffectiveLatencySamples/getEffectiveOutputChannels), event surface. ≤300 lines (split helpers as needed). + .types.ts, .test.ts, .md.
  • 4.8 Write src/chain/index.ts barrel.

5. Registry (src/registry/)

  • 5.1 Write src/registry/plugin-registry.ts — PluginRegistry class; register/has/create/list. + .types.ts, .test.ts, .md.
  • 5.2 Each first-party plugin's barrel SHALL self-register its default factory at module load — but registration SHALL be opt-in: consumers import @suaveplan/audio-plugins-fx/registry/auto-register to get all factories pre-registered, otherwise nothing auto-registers (preserves sideEffects: false).

6. Tier-1 DSP plugins (universal)

  • 6.1 EQPlugin — 8-band parametric, shelves, HP/LP, presets flat/vocal/bass/podcast. createAudioNode returns BiquadFilterNode chain. + tests + .md + .schemas.ts.
  • 6.2 FilterPlugin — biquad / IIR / state-variable modes. + tests + .md + .schemas.ts.
  • 6.3 CompressorPlugin — threshold/knee/ratio/attack/release, soft-knee, sidechain (via setSidechain), mid/side mode (reads ChainContext.ambient.track.layout). createAudioNode returns DynamicsCompressorNode. + tests + .md + .schemas.ts.
  • 6.4 LimiterPlugin — brick-wall, lookahead with onLatencyChanged for dynamic latency. BlockProcessor only. + tests + .md + .schemas.ts.
  • 6.5 GatePlugin — threshold/attack/hold/release. + tests + .md + .schemas.ts.

7. Tier-2 time-based plugins

  • 7.1 ReverbPlugin — IR convolver + algorithmic fallback, loadImpulseResponse(url, { signal }) with AbortSignal, presets room/hall/plate/cathedral. wet parameter. + tests + .md + .schemas.ts.
  • 7.2 DelayPlugin — feedback / ping-pong / BPM-sync (reads ChainContext.ambient.transport.tempo). + tests + .md + .schemas.ts.
  • 7.3 ChorusPlugin, PhaserPlugin, FlangerPlugin — each implementing the time-based requirement. + tests + .md + .schemas.ts.

8. Tier-3 modulation + distortion + pitch + voice

  • 8.1 TremoloPlugin, AutoFilterPlugin — phase-continuous LFOs. + tests + .md + .schemas.ts.
  • 8.2 DistortionPlugin — waveshaper / bitcrusher / overdrive modes. + tests + .md + .schemas.ts.
  • 8.3 PitchShifterPlugin — phase-vocoder, worklet processor, getLatencySamples() reports FFT-frame latency. + tests + .md + .schemas.ts + worklet file.

9. Synth + sampler + mixer + widener

  • 9.1 SynthesizerPlugin — oscillator / ADSR / voice pool / portamento / triggerAttack/triggerRelease/triggerAttackRelease. + tests + .md + .schemas.ts.
  • 9.2 SamplerPlugin — loadSample(note, url, { signal }), polyphonic playback. + tests + .md + .schemas.ts.
  • 9.3 MixerPlugin — channel strips, sends/returns, master VU, per-channel EQ. + tests + .md + .schemas.ts.
  • 9.4 StereoWidenerPlugin — mid/side width. + tests + .md + .schemas.ts.

10. Game-audio building blocks

  • 10.1 SpatialPositionalPlugin — distance attenuation, amplitude panning, HRTF via createAudioNode (PannerNode). Reads ChainContext.ambient.listener with parameter fallback. + tests + .md + .schemas.ts.
  • 10.2 ProximityVoicePlugin — distance-based attenuation, VAD, optional spatial blend. + tests + .md + .schemas.ts.
  • 10.3 MusicLayerMixerPlugin — source plugin (io.inputs[0].count === 0), loadLayer(id, buffer), weights from ambient.extension.gameState, crossfade. + tests + .md + .schemas.ts.
  • 10.4 VoiceTransformPlugin — pitch + formant + ring-mod + distortion + reverb combo, presets child/giant/robot/monster/echo. + tests + .md + .schemas.ts.

11. Upstream-port plugins

  • 11.1 MicrophonePlugin — full mic processing chain (frequency, resonance, distortion, noise, dynamics, character, output gain) with worklet for the browser path. Presets vintage/radio/podcast/telephone/clean. + tests + .md + .schemas.ts + worklet file.
  • 11.2 GLaDOSPlugin — character vocoder built on phase-vocoder + formant + ring-mod + band-pass + bit-crusher. Presets glados-default/glados-cake/glados-deception/wheatley. + tests + .md + .schemas.ts + worklet file.
  • 11.3 AudioPlayerPlugin — track-style source plugin, load/play/pause/stop/seek/getCurrentTime/getDuration, loop + playbackRate parameters, 'ended' event. + tests + .md + .schemas.ts.

12. Presets

  • 12.1 src/presets/reverb/cathedrals.ts, rooms.ts, plates.ts — IR descriptor packs (lazy subpath imports).
  • 12.2 src/presets/synth/leads.ts, pads.ts, basses.ts.
  • 12.3 src/presets/glados/defaults.ts.
  • 12.4 Register every preset schema with @suaveplan/schema-registry.

13. Benchmarks

  • 13.1 src/__benchmarks__/eq.bench.ts — 1 s stereo through 8-band EQ.
  • 13.2 src/__benchmarks__/reverb.bench.ts — 1 s through 10 s IR + algorithmic.
  • 13.3 src/__benchmarks__/synth.bench.ts — render 32-voice polyphonic synth.
  • 13.4 src/__benchmarks__/chain.bench.ts — 8-plugin serial chain vs raw BlockProcessor loop; chain overhead ≤ 5 %.

14. Integration + purity + bundle-size tests

  • 14.1 tests/integration.test.ts — end-to-end chain with ambient + bus: load tracks A and B, A taps kick bus, B's compressor side-chains from kick, verify ducking; verify chain snapshot round-trip; verify PDC alignment.
  • 14.2 tests/purity.test.ts — built dist/ references no browser/Node globals on the processing path; no global state mutation at import time.
  • 14.3 tests/exports.test.ts — every subpath export resolves; every feature barrel uses explicit named re-exports (no export *); the parameterIndex / parameters cross-check across every plugin.
  • 14.4 tests/bundle-size/eq.size.test.ts, reverb.size.test.ts, synth.size.test.ts, chain.size.test.ts — assert tree-shaken bundles do not include unrelated plugins.
  • 14.5 tests/property.test.ts (fast-check) — gain plugin: 0 dB ⇒ identity, -∞ dB ⇒ silence; bypass ⇒ bit-identity; chain order invariance for known commutative pairs.

15. Verify

  • 15.1 bunx turbo lint typecheck test --filter=@suaveplan/audio-plugins-fx — green.
  • 15.2 bunx turbo test:coverage --filter=@suaveplan/audio-plugins-fx — 100/100/100/100.
  • 15.3 bunx turbo build --filter=@suaveplan/audio-plugins-fx — green.
  • 15.4 Banned-pattern scan: grep -rnE "@deprecated|TODO|FIXME|ts-ignore|ts-expect-error|\\.skip|\\.only|console\\.log|\\bany\\b" packages/audio/audio-plugins-fx/src/ --include="*.ts" — empty (only false-positive matches on word any allowed in comments).
  • 15.5 Runner-import scan: grep -rnE "from ['\"](vitest|bun:test)['\"]" packages/audio/audio-plugins-fx/src/ packages/audio/audio-plugins-fx/tests/ --include="*.ts" — empty.
  • 15.6 File-size sweep: every src file ≤ 300 lines, every test file ≤ 500 lines.
  • 15.7 Missing .md scan empty.
  • 15.8 README.md at package root with quick-start, chain example, ambient-state example, sidechain example, and links to every co-located .md.

16. Spec reconciliation (pre-archive)

  • 16.1 Walk every ### Requirement and #### Scenario in specs/audio-plugins-fx/spec.md; grep src/ and confirm each named class, function, error code, event, and parameter exists.
  • 16.2 Walk every **Verified by:** line; confirm the named test file exists AND the test name matches verbatim.
  • 16.3 Confirm every entry in AUDIO_FX_ERROR_METADATA is reachable from a real call site exercised by a test.

17. Root docs

  • 17.1 Run bun scripts/folder-reorg/generate-manifest.ts to refresh MANIFEST.md.
  • 17.2 Flip STATUS.md row @suaveplan/audio-plugins-fx from – to ✅.
  • 17.3 Update SUMMARY.md paragraph to reflect the shipped surface.
  • 17.4 bunx markdownlint-cli2 --fix over touched files; second pass without --fix must exit 0.

18. Archive

  • 18.1 Fold specs/audio-plugins-fx/spec.md into openspec/specs/audio-plugins-fx/spec.md.
  • 18.2 Move openspec/changes/enterprise-audio-plugins-fx/ → openspec/archive/YYYY-MM-DD-enterprise-audio-plugins-fx/.