Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,28 @@
# Refresh audio queue for 3-level layout and upstream deps (2026-05-23)
## Why
Thirteen audio-queue OpenSpec changes — `enterprise-audio-codecs`, `enterprise-audio-codec-ffmpeg-{native,wasm}`, `enterprise-audio-engine-server`, `enterprise-audio-analysis-{spectrum,beat,loudness,pitch}`, `enterprise-audio-cli`, `enterprise-audio-sprite-player`, and `enterprise-react-audio-{player,stream,fingerprint}` — were authored before the 2026-05-20 super-category restructure. They still encode the old 2-level `packages/audio/<pkg>/` path and reference upstream contracts that do not exist on genesis. Four parallel implementation agents (one per package) refused to ship on 2026-05-23 because the proposals contradict `CLAUDE.md` and `openspec/AGENTS.md §2c` forbids silently rewriting spec elements during implementation.
This change ships the prerequisites those thirteen proposals depend on so they can be implemented as authored (post-refresh) with no further blockers.
## What changes
1. **Path migration** — every audio-queue OpenSpec change's `proposal.md`, `tasks.md`, `design.md`, and `specs/**/spec.md` is rewritten from `packages/audio/<pkg>/` to `packages/media/audio/<pkg>/` (or `packages/ui/react/<pkg>/` for the three react-audio changes). The closed super-category vocabulary in `CLAUDE.md` is authoritative; no category is added.
2. **Workspace catalog: ffmpeg deps** — `fluent-ffmpeg`, `@ffmpeg-installer/ffmpeg`, `@types/fluent-ffmpeg` added to `catalog.audio` and `catalog.types`; `@ffmpeg/ffmpeg` and `@ffmpeg/core` added to `catalog.audio` for the WASM variant.
3. **`@suaveplan/audio-core` MODIFIED** — add the `AnalysisOp` operator contract and the `AnalysisResult` base shape required by every `audio-analysis-*` package. These are types-only additions plus a small runtime helper (`createAnalysisOp`) for the four analysis packages to consume.
4. **`enterprise-audio-engine-server` MODIFIED in place** — replace the spec's hard import dependency on `@suaveplan/audio-plugins-fx` (which does not exist on genesis) with a locally-owned `PluginChain` + `BusRegistry` shape defined inside the engine-server package itself. The original spec intent — per-track plugin chains with PDC recompute and a cycle-safe bus registry — is preserved verbatim; only the import location changes. When `@suaveplan/audio-plugins-fx` lands in a later wave, an additive OpenSpec amendment can re-route the contract to the upstream package.
5. **Date alignment** — every refreshed proposal stamps its target archive folder as `openspec/archive/2026-05-23-<change-id>/` and the proposal `Date:` line as `2026-05-23`.
6. **No scope changes** — no Requirements are added, removed, or weakened in the refreshed change folders. Path corrections + dep additions + upstream-contract relocation only.
## Impact
- Spec: 13 change folders rewritten in place (paths + dates only) plus one MODIFIED to relocate upstream contracts.
- Code: `@suaveplan/audio-core` gains `AnalysisOp` / `AnalysisResult` types + `createAnalysisOp` helper. Root `package.json` gains 5 catalog entries.
- Downstream: the 13 implementation agents can now read their refreshed change folders and ship without further spec amendments. Each becomes an independent implementation PR.
- Risk: nil. Paths are mechanical, catalog additions are additive, the `@suaveplan/audio-core` addition is types-only + one builder helper at 100% coverage in this change.

View File

@@ -0,0 +1,40 @@
# audio-core spec delta — refresh-audio-queue-2026-05-23
## ADDED Requirements
### Requirement: AnalysisOp operator contract
The audio-core package SHALL expose an `AnalysisOp<TConfig, TResult>` operator contract that every `@suaveplan/audio-analysis-*` package implements, and a `createAnalysisOp` builder that constructs conforming operators with Zod-validated config, OTel instrumentation, and AbortSignal-aware cancellation.
`AnalysisOp` is a discriminated operator with: `name: string` (unique within an analysis pipeline), `version: string` (semver), `capabilities: AnalysisCapabilities` (streaming/offline/realtime/blocking flags), `configSchema: z.ZodTypeAny`, `run(doc: AudioDocument, config: TConfig, opts?: { signal?: AbortSignal }): Promise<TResult>`, and `runStream?(source: AsyncIterable<AnalysisFrame>, config: TConfig, opts?: { signal?: AbortSignal }): AsyncIterable<TResult>`.
`AnalysisResult` is the base shape every analyser extends — `{ analyserName: string; analyserVersion: string; sampleRate: number; durationSamples: number; computedAt: number }`. Concrete analyser results add their own fields on top.
#### Scenario: builder validates config via Zod
- **WHEN** `createAnalysisOp({ name, version, capabilities, configSchema, run })` is called and a downstream caller invokes `op.run(doc, badConfig)`
- **THEN** the builder MUST reject with `AudioError("AUDIO_CORE.ANALYSIS_INVALID_CONFIG")` carrying the Zod issues on `context.issues`, before `run` is invoked
#### Scenario: builder instruments runs via OpenTelemetry
- **WHEN** `op.run(doc, validConfig)` is called and succeeds
- **THEN** the builder MUST emit one OTel span named `analysis.${name}` with attributes `{ "analysis.name": name, "analysis.version": version, "audio.sample_rate": doc.sampleRate, "audio.duration_samples": doc.sourceLength }`, increment counter `audio_analysis_runs_total{analysis=${name}}`, and record histogram `audio_analysis_duration_ms{analysis=${name}}`
#### Scenario: builder forwards AbortSignal
- **WHEN** `op.run(doc, validConfig, { signal })` is invoked and `signal.aborted === true` before `run` returns
- **THEN** the inner `run` callback MUST observe the signal and the builder MUST surface the abort as `AudioError("AUDIO_CORE.ANALYSIS_ABORTED")`
#### Scenario: capability flags advertise streaming support
- **WHEN** a caller inspects `op.capabilities.supportsStream`
- **THEN** the value MUST equal `typeof op.runStream === "function"`
### Requirement: AnalysisFrame streaming window descriptor
The audio-core package SHALL export an `AnalysisFrame` shape — `{ samples: Float32Array[]; sampleRate: number; channelCount: number; startSample: number; sampleCount: number }` — usable as the streaming-input element type for any `AnalysisOp.runStream` implementation. The shape is types-only; no runtime construction helper is mandated.
#### Scenario: streaming analyser consumes AnalysisFrame iterable
- **WHEN** a spectrum analyser's `runStream(source, config)` is invoked with an `AsyncIterable<AnalysisFrame>`
- **THEN** the analyser MUST process each frame independently and MAY yield zero, one, or many `AnalysisResult`-extending values per input frame

View File

@@ -0,0 +1,46 @@
# Tasks — refresh-audio-queue-2026-05-23
## 1. Path migration across 13 change folders
- [ ] 1.1 Replace `packages/audio/` → `packages/media/audio/` in every `.md` file under `openspec/changes/enterprise-audio-{codecs,codec-ffmpeg-native,codec-ffmpeg-wasm,engine-server,analysis-spectrum,analysis-beat,analysis-loudness,analysis-pitch,cli,sprite-player}/`
- [ ] 1.2 Replace `packages/audio/react-audio-` → `packages/ui/react/react-audio-` in every `.md` file under `openspec/changes/enterprise-react-audio-{player,stream,fingerprint}/`
- [ ] 1.3 Re-stamp the `Date:` line in each refreshed proposal to `2026-05-23`
- [ ] 1.4 Verify no `packages/audio/` strings remain in any audio-queue change folder
## 2. Workspace catalog additions
- [ ] 2.1 Add `fluent-ffmpeg` (pinned) to `catalog.audio` in root `package.json`
- [ ] 2.2 Add `@ffmpeg-installer/ffmpeg` (pinned) to `catalog.audio`
- [ ] 2.3 Add `@types/fluent-ffmpeg` to `catalog.types`
- [ ] 2.4 Add `@ffmpeg/ffmpeg` (pinned) to `catalog.audio`
- [ ] 2.5 Add `@ffmpeg/core` (pinned) to `catalog.audio`
- [ ] 2.6 `bun install` to update lockfile
## 3. `@suaveplan/audio-core` `AnalysisOp` contract
- [ ] 3.1 Add `src/analysis/analysis-op.types.ts` declaring `AnalysisOp<TConfig, TResult>`, `AnalysisResult` base shape, `AnalysisFrame` window descriptor, `AnalysisCapabilities` flags
- [ ] 3.2 Add `src/analysis/analysis-op.ts` exposing `createAnalysisOp<TConfig, TResult>(spec): AnalysisOp<TConfig, TResult>` builder with Zod config validation, OTel instrumentation, AbortSignal handoff
- [ ] 3.3 Add sibling `analysis-op.md` (6 required sections)
- [ ] 3.4 Add `analysis-op.test.ts` covering builder happy-path, Zod rejection, OTel attribute propagation, signal handoff, error wrapping via `AUDIO_CORE.*`
- [ ] 3.5 Add `src/analysis/index.ts` barrel with explicit named re-exports
- [ ] 3.6 Wire `./analysis/analysis-op` subpath export in `package.json`
- [ ] 3.7 Add `./analysis` entry in root `src/index.ts` exports
- [ ] 3.8 Pre-publish gate green: `bunx turbo lint typecheck test --filter=@suaveplan/audio-core` + `bunx turbo test:coverage --filter=@suaveplan/audio-core` at 100/100/100/100
## 4. Engine-server upstream-contract relocation
- [ ] 4.1 In `openspec/changes/enterprise-audio-engine-server/specs/audio-engine-server/spec.md` replace every `@suaveplan/audio-plugins-fx/chain` reference with `./fx/plugin-chain` (relative to the engine-server package)
- [ ] 4.2 Add a NEW Requirement to that spec delta: "Engine-server owns its `PluginChain` + `BusRegistry` contracts" — three scenarios (chain interface shape, registry cycle detection, future-amendment seam)
- [ ] 4.3 Update `enterprise-audio-engine-server/proposal.md` workspace-deps table: remove `@suaveplan/audio-plugins-fx`, add note that contracts live in-package pending future upstream amendment
## 5. Analysis-spectrum spec clarifications
- [ ] 5.1 Add a Scenario to `enterprise-audio-analysis-spectrum/specs/audio-analysis-spectrum/spec.md` specifying the bin-reduction algorithm (log-spaced bucket means over the `frameSize/2+1` magnitude bins)
- [ ] 5.2 Confirm the window-list (Hann/Hamming/Blackman only — drop Kaiser from any task-prompt drift)
## 6. Ship the refresh
- [ ] 6.1 Fold this proposal's spec delta into `openspec/specs/audio-core/spec.md` (audio-core gains the `AnalysisOp` requirement)
- [ ] 6.2 Move this change folder to `openspec/archive/2026-05-23-refresh-audio-queue-2026-05-23/`
- [ ] 6.3 Run `bun scripts/folder-reorg/generate-manifest.ts`
- [ ] 6.4 Commit on `feat/audio-codecs` (no separate branch — this change is groundwork for all 13 downstream branches)