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

160 lines
8.0 KiB
Markdown

# Tasks: enterprise-audio-core
**Change ID**: enterprise-audio-core
**Package**: `@suaveplan/audio-core`
**Target path**: `packages/audio/audio-core/`
**Prerequisite packages on Verdaccio**: `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/events`, `@suaveplan/streams`, `@suaveplan/serialize`
---
## 1. Scaffold
- [ ] Create directory `packages/audio/audio-core/` with `src/`, `tests/`, `src/__benchmarks__/`, and all feature subdirectories per the layout in `proposal.md`.
- [ ] Write `package.json` at version `0.1.0` with `"type": "module"`, `"sideEffects": false`, full `exports` map, deps: `@suaveplan/error workspace:^`, `@suaveplan/types workspace:^`, `@suaveplan/events workspace:^`, `@suaveplan/streams workspace:^`, `@suaveplan/serialize workspace:^`, `zod catalog:forms`, `@opentelemetry/api catalog:observability`.
- [ ] Write `tsconfig.json` extending `@suaveplan/typescript-config/library.json`.
- [ ] Write `vitest.config.ts` using `createTestConfig()` from `@suaveplan/testing/config`.
- [ ] Add `lint`, `typecheck`, `test`, `test:coverage`, `build`, `docs:check` scripts.
---
## 2. Types + errors
- [ ] Write `src/document/document.types.ts` — `AudioDocumentOptions`, `AudioDocumentJSON`, `AudioPage`, `AudioEdit`, `AudioStats`, `StreamOptions`, `PCMFormat`, `AudioDocumentEventMap`.
- [ ] Write `src/document/document.md`.
- [ ] Write `src/plan/plan-engine.types.ts` — `CompiledPlan`, `Segment`, `PlanContext`, `PlanFn`, `ResolveFn`, `SampleRateTransformFn`, `ChannelTransformFn`.
- [ ] Write `src/plan/plan-engine.md`.
- [ ] Write `src/plan/segment.types.ts` — segment helpers and Zod schema.
- [ ] Write `src/plan/segment.md`.
- [ ] Write `src/process/process-pipeline.types.ts` — `ProcessState`, `BlockContext`, `ProcessFn`.
- [ ] Write `src/process/process-pipeline.md`.
- [ ] Write `src/process/block-processor.types.ts` — `ProcessorConfig`, `BlockProcessor`.
- [ ] Write `src/process/block-processor.md`.
- [ ] Write `src/registry/op-registry.types.ts` — `AudioOpDescriptor`.
- [ ] Write `src/registry/op-registry.md`.
- [ ] Write `src/stream/stream.types.ts` — stream option types.
- [ ] Write `src/stream/stream.md`.
- [ ] Write `src/stats/stats.types.ts` — `AudioStats` and computed-stat types.
- [ ] Write `src/stats/stats.md`.
- [ ] Write `src/error-codes.ts` — `AudioCoreErrorCode`, `AUDIO_CORE_ERROR_METADATA`, `registerAudioCoreErrorCodes()`.
- [ ] Write Zod schemas for every public options object (`AudioDocumentOptionsSchema`, `AudioPageSchema`, `AudioEditSchema`, `AudioStatsSchema`, `StreamOptionsSchema`, `CompiledPlanSchema`, `AudioOpDescriptorSchema`, `ProcessorConfigSchema`).
---
## 3. Page primitives
- [ ] Implement `PAGE_SIZE` and `BLOCK_SIZE` constants.
- [ ] Implement `walkPages()` — iterate overlapping pages with a visitor callback.
- [ ] Implement `copyPages()` — copy samples to a pre-allocated target buffer.
- [ ] Implement `readPages()` — read a range as `Float32Array[]`.
- [ ] Implement page-pool allocator (`allocatePage`, `releasePage`) to reduce GC pressure.
- [ ] Write `src/page/page.ts` and `src/page/page.test.ts`.
- [ ] Write `src/page/page.md`.
---
## 4. AudioDocument
- [ ] Implement `AudioDocument` constructor with id, sampleRate, channels, sourceLength, pages, edits.
- [ ] Implement virtual `length` and `duration` getters (cached, invalidated by version).
- [ ] Implement `run(...edits)` — append edits, increment version, emit `edit` event.
- [ ] Implement `undo(n?)` — pop last n edits, emit `undo` event, return removed edits.
- [ ] Implement `clone()` — deep copy with independent page array.
- [ ] Implement `toJSON()` / from-JSON round-trip via `@suaveplan/serialize`.
- [ ] Implement `read(offset?, duration?)` — resolve through `PlanEngine` then `readPages`.
- [ ] Implement `stream(opts?)` — async generator yielding `Float32Array[]` blocks via compiled plan + process pipeline.
- [ ] Implement `push(data, fmt?)` / `stop()` — recorder push model.
- [ ] Implement `on` / `off` event subscription via `@suaveplan/events`.
- [ ] Wire `AbortSignal` through `read()` and `stream()`.
- [ ] Write `src/document/document.test.ts` (≤500 lines): construct, run edit, undo, clone equality, read range, stream total samples, abort.
- [ ] Write `src/document/document.md`.
---
## 5. PlanEngine
- [ ] Implement `compilePlan()` two-pass resolver + plan compiler per spec algorithm.
- [ ] Implement `PlanEngine.compile(doc, final?)` — returns `CompiledPlan` with segs, pipeline, totalLen, sampleRate, limit.
- [ ] Implement `PlanEngine.readPlan()` — render a static range using compiled segments.
- [ ] Implement `PlanEngine.streamPlan()` — async generator over compiled plan blocks.
- [ ] Implement `PlanEngine.ensurePages()` — preload evicted pages needed for a range.
- [ ] Wire OTel span on `plan.compile` + histogram `audio_core_compile_duration_ms`.
- [ ] Write `src/plan/plan-engine.test.ts`.
- [ ] Write `src/plan/segment.test.ts` — segment overlap, merge, split helpers.
- [ ] Write `src/plan/plan-engine.md`.
- [ ] Write `src/plan/segment.md`.
---
## 6. ProcessPipeline
- [ ] Implement `ProcessPipeline.init()` — allocate `ProcessState[]` for a pipeline.
- [ ] Implement `ProcessPipeline.patch()` — hot-swap pipeline edits without re-allocating buffers.
- [ ] Implement `ProcessPipeline.process()` — run each process op in order with error isolation (emit `plugin:error`, pass input through on crash).
- [ ] Wire OTel span on `process.block` + histogram `audio_core_process_duration_ms`.
- [ ] Write `src/process/process-pipeline.test.ts`.
- [ ] Write `src/process/process-pipeline.md`.
---
## 7. OpRegistry + built-in ops
- [ ] Implement `OpRegistry.register()` / `unregister()` / `get()` / `list()`.
- [ ] Implement `OpRegistry.createWithDefaults()` — pre-register all built-in ops.
- [ ] Implement plan ops: `trim`, `crop`, `speed`, `stretch`, `reverse`, `insert`, `remove`, `repeat`, `pad`, `resample`.
- [ ] Implement process ops: `gain`, `normalize`, `fade`, `pan`, `mix`, `dither`, `transform`.
- [ ] Write `src/registry/op-registry.test.ts`.
- [ ] Write `src/registry/op-registry.md`.
- [ ] Write per-op tests under `src/registry/built-in/` (co-located with each `.ts` file).
---
## 8. BlockProcessor
- [ ] Implement `BlockProcessor` interface and a `NoopBlockProcessor` reference implementation for tests.
- [ ] Write `src/process/block-processor.test.ts`.
- [ ] Write `src/process/block-processor.md`.
---
## 9. Stream renderer
- [ ] Implement `renderBlock()` — copy source segments into output buffers per compiled plan.
- [ ] Integrate with `@suaveplan/streams` `TransformStream` for downstream transforms.
- [ ] Write `src/stream/stream.test.ts`.
- [ ] Write `src/stream/stream.md`.
---
## 10. Stats
- [ ] Implement `computeStats(pages)` — peak, RMS, DC offset over a page set.
- [ ] Write `src/stats/stats.test.ts`.
- [ ] Write `src/stats/stats.md`.
---
## 11. Benchmarks
- [ ] Write `src/__benchmarks__/plan.bench.ts` — compile 100 edits into a plan (1000 iterations).
- [ ] Write `src/__benchmarks__/stream.bench.ts` — stream 5 minutes of 48kHz stereo audio through 10 process ops.
- [ ] Write `src/__benchmarks__/process.bench.ts` — run `normalize` + `fade` + `pan` over 1M samples.
---
## 12. Integration + property tests
- [ ] Write `tests/integration.test.ts` — full round-trip: construct document, run edits, compile plan, stream, read range, clone, toJSON round-trip.
- [ ] Write `tests/property.test.ts` (fast-check) — identity edit preserves plan length; stream yields exact total sample count; clone `toJSON()` equals original `toJSON()`.
---
## 13. Docs + verify + publish
- [ ] All co-located `.md` files (≥200 words each).
- [ ] Write `README.md` at package root.
- [ ] `bunx turbo lint typecheck test --filter=@suaveplan/audio-core` — green.
- [ ] `bunx turbo test:coverage --filter=@suaveplan/audio-core` — 100%.
- [ ] `bun scripts/publish.ts --package @suaveplan/audio-core`.
- [ ] Fold `specs/audio-core/spec.md` into `openspec/specs/audio-core/spec.md`.
- [ ] Archive change folder to `openspec/archive/2026-05-14-enterprise-audio-core/`.