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,215 @@
# Tasks: enterprise-audio-codec-ffmpeg-native
Implementation checklist for `@suaveplan/audio-codec-ffmpeg-native`. Tasks are ordered;
each section must be complete before the next begins. Every `### Requirement` and
`#### Scenario` from `specs/audio-codec-ffmpeg-native/spec.md` is enumerated in §0c
working notes and checked off as implementation lands.
---
## 1. Scaffold
- [ ] Create `packages/media/audio/audio-codec-ffmpeg-native/` with `package.json`,
`tsconfig.json`, `vitest.config.ts` (use `createTestConfig()` from
`@suaveplan/testing/config`; `pool: 'forks'`).
- [ ] `package.json` declares `"engines": { "node": ">=20" }`, no `"browser"` field,
`"sideEffects": false`, `"type": "module"`, and `version: "0.1.0"`.
- [ ] `dependencies`: `@suaveplan/audio-codecs workspace:^`,
`@suaveplan/audio-core workspace:^`, `@suaveplan/streams workspace:^`,
`@suaveplan/error workspace:^`, `@suaveplan/types workspace:^`,
`fluent-ffmpeg catalog:audio`, `zod catalog:forms`,
`@opentelemetry/api catalog:observability`, `tslib catalog:build`.
- [ ] `optionalDependencies`: `@ffmpeg-installer/ffmpeg catalog:audio`.
- [ ] `devDependencies`: `@suaveplan/testing workspace:^`, `vitest catalog:testing`,
`@vitest/coverage-istanbul catalog:testing`, `fast-check catalog:testing`,
`mitata catalog:testing`, `@types/fluent-ffmpeg catalog:types`.
- [ ] If `fluent-ffmpeg`, `@ffmpeg-installer/ffmpeg`, or `@types/fluent-ffmpeg` are
not yet in the root `package.json` catalog block, add them under
`catalog.audio` / `catalog.types` and re-run `bun install`.
- [ ] Declare subpath `exports` for every feature module listed in `proposal.md`
"Module layout" plus the root barrel — every entry resolves to a typed
`import` condition under `dist/`.
- [ ] Add per-package `tsconfig.json` extending the shared preset.
## 2. Types + error codes
- [ ] `src/error-codes.ts` — `defineCodes` with the eight
`AUDIO_CODEC_FFMPEG_NATIVE.*` codes; export
`AudioCodecFfmpegNativeError extends SuaveplanError`,
`AUDIO_CODEC_FFMPEG_NATIVE_ERROR_METADATA`,
`registerAudioCodecFfmpegNativeErrorCodes()`.
- [ ] `src/error-codes.test.ts` — assert each code is thrown by at least one call
site (this test cross-references the per-feature tests once they exist).
- [ ] `src/error-codes.md` — Purpose / Features / Basic / Advanced / API / Notes.
- [ ] `src/constants/index.ts` — supported format lists, MIME types, default
timeouts, default concurrency.
## 3. Binary resolver
- [ ] `src/binary/binary.ts` — `resolveBinary(opts): Promise<string>` implementing
the 4-step discovery order; cache result on success.
- [ ] `src/binary/binary.types.ts` — `BinaryResolverOptions`,
`ResolvedBinary` shapes.
- [ ] `src/binary/binary.test.ts` — covers `binaryProvider` precedence, explicit
`binaryPath`, dynamic-import fallback, and `BINARY_MISSING` throw path.
- [ ] `src/binary/binary.md`.
- [ ] `src/binary/index.ts` — explicit named exports.
## 4. Semaphore
- [ ] `src/semaphore/semaphore.ts` — ~30-line FIFO semaphore with `acquire` /
`release`; no external dep.
- [ ] `src/semaphore/semaphore.types.ts`.
- [ ] `src/semaphore/semaphore.test.ts` — concurrency cap, FIFO ordering,
slot-release on error.
- [ ] `src/semaphore/semaphore.md`, `index.ts`.
## 5. Subprocess runner (the only place `node:child_process` / `fluent-ffmpeg` is imported)
- [ ] `src/runner/runner.ts` — `runDecode(opts)` and `runEncode(opts)`. Owns spawn,
stdin pipe, stdout drain (chunk-by-chunk, no full-output `Buffer.concat`),
stderr ring buffer, exit handling, timeout enforcement, semaphore release.
- [ ] `src/runner/runner.types.ts` — `RunDecodeOptions`, `RunEncodeOptions`,
`RunnerCallbacks`, `RunnerHandles`.
- [ ] `src/runner/runner.test.ts` — happy path, non-zero exit → `_DECODE_FAILED`
with stderr context, spawn failure → `_SPAWN_FAILED`, timeout →
`_TIMEOUT` with SIGTERM/SIGKILL escalation observed.
- [ ] `src/runner/runner.md`, `index.ts`.
## 6. Decode pipeline
- [ ] `src/decode/decode.ts` — `decodeOneShot(bytes, opts)` orchestrating
`runDecode` + per-channel `Float32Array` accumulators + interleave splitter.
- [ ] `src/decode/decode.types.ts`.
- [ ] `src/decode/decode.test.ts` — well-formed `DecodeResult`,
chunk-by-chunk assertion (instrument runner to count `Buffer.concat`),
`_DECODE_FAILED` with stderr in context, `canDecode` delegation.
- [ ] `src/decode/decode.md`, `index.ts`.
## 7. Encode pipeline
- [ ] `src/encode/encode.ts` — `encodeOneShot(pcm, opts)` with PCM-shape validation,
interleaver writing into a 64 KiB working buffer, runner invocation.
- [ ] `src/encode/encode.types.ts`.
- [ ] `src/encode/encode.test.ts` — round-trip through decode, `_INVALID_PCM` for
ragged channels, `_UNSUPPORTED_CODEC` for unknown format and for WMA encode.
- [ ] `src/encode/encode.md`, `index.ts`.
## 8. Streaming adapters
- [ ] `src/stream/stream-decoder.ts` — `createDecoder(opts)` returning
`StreamingDecoder`; `createDecodeTransform(opts)` returning a
`@suaveplan/streams` `TransformStream<Uint8Array, AudioPage>`.
- [ ] `src/stream/stream-encoder.ts` — `createEncoder(opts)` returning
`StreamingEncoder`; `createEncodeTransform(opts)` returning a
`TransformStream<Float32Array[], Uint8Array>`.
- [ ] Sibling `.types.ts`, `.test.ts`, `.md` for each; tests cover chunked-write
equivalence, TransformStream composition, encoder yielding before flush.
- [ ] `src/stream/index.ts` — explicit named exports.
## 9. AbortSignal wiring
- [ ] `src/abort/abort.ts` — `attachAbort(child, signal, semaphoreRelease)`:
sends `SIGTERM`, starts 1 s timer, escalates to `SIGKILL`, releases slot,
rejects with `_ABORTED`. Short-circuit path for pre-aborted signals.
- [ ] `src/abort/abort.types.ts`.
- [ ] `src/abort/abort.test.ts` — pre-aborted short-circuit (no spawn observed),
mid-decode SIGTERM → SIGKILL escalation under a child that ignores SIGTERM.
- [ ] `src/abort/abort.md`, `index.ts`.
## 10. OpenTelemetry instrumentation
- [ ] `src/otel/otel.ts` — span / counter / histogram / inflight-gauge helpers;
inert without exporter; no import-time side effects.
- [ ] `src/otel/otel.types.ts`, `otel.test.ts` (in-memory `MeterProvider` +
`TracerProvider`), `otel.md`, `index.ts`.
## 11. Codec class + register helper
- [ ] `src/codec/codec.ts` — `FfmpegNativeCodec` implementing `AudioCodec`. Owns
the per-instance semaphore, the cached binary path, the OTel handles, and
delegates to `decode/`, `encode/`, `stream/` modules.
- [ ] `src/codec/codec.schemas.ts` — `FfmpegNativeCodecOptionsSchema`,
`EncodeOptsSchema` (Zod).
- [ ] `src/codec/codec.types.ts`, `codec.test.ts` (constructor Zod validation,
`canDecode` rejection without spawn, WMA encode short-circuit, full
`DecodeResult` shape), `codec.md`, `index.ts`.
- [ ] `src/register/register.ts` — `register(registry, options?)` idempotent
installer.
- [ ] `src/register/register.test.ts`, `register.types.ts`, `register.md`,
`index.ts`.
## 12. Root barrel
- [ ] `src/index.ts` — explicit named re-exports of every public symbol from each
feature module. No `export *` (rule 10 / §6a).
## 13. Tests — purity, integration, exports
- [ ] `tests/purity.test.ts` — built dist has no browser globals; `child_process`
imported only from `src/runner/runner.ts`; package import mutates no global
OTel state.
- [ ] `tests/integration.test.ts` — full round-trip across every declared
encodable format using the bundled `@ffmpeg-installer/ffmpeg` binary.
- [ ] `tests/exports.test.ts` — every feature module has a working subpath export
entry and is independently importable.
- [ ] Every test file imports runner primitives from
`@suaveplan/testing/runner` (rule 11 / §7).
## 14. Benchmarks
- [ ] `src/__benchmarks__/codec.bench.ts` — mitata suite: decode 10 s WAV,
decode 10 s MP3, encode 10 s WAV→MP3, concurrent-decode at `concurrencyLimit`
= 4. Use `--cpu-prof-md` / `--heap-prof-md` for LLM-assisted analysis.
- [ ] Publish baseline numbers in `README.md`.
## 15. Documentation
- [ ] Every `.ts` (excluding `.test.ts`, `.types.ts`, `.schemas.ts`, barrel
`index.ts`) has a sibling `.md` meeting §4: ≥200 words, Purpose / Features
/ Basic / Advanced / API Reference / Implementation Notes.
- [ ] `README.md` at package root: name, one-paragraph description, install,
quick-start, Modules section linking every `src/<feature>/<feature>.md`,
format support matrix from `design.md`, baseline benchmark numbers.
## 16. Pre-publish gates (§13)
- [ ] Step 0 — Spec reconciliation: walk every requirement and `Verified by` from
the spec delta; confirm every symbol, span, counter, error code, and test
name exists verbatim in `src/`. STOP if any item is unmatched.
- [ ] `bunx turbo lint typecheck test --filter=@suaveplan/audio-codec-ffmpeg-native`.
- [ ] `bun run check` (biome).
- [ ] `bunx turbo test:coverage --filter=@suaveplan/audio-codec-ffmpeg-native`
reports 100 / 100 / 100 / 100 (istanbul).
- [ ] `bunx turbo build --filter=@suaveplan/audio-codec-ffmpeg-native`.
- [ ] Banned-pattern scan: zero hits for `@deprecated`, `TODO`, `FIXME`,
`ts-ignore`, `ts-expect-error`, `.skip`, `.only`, bare `any`, `console.log`.
- [ ] Barrel scan (§13 step 4a): zero `export *` in feature barrels.
- [ ] Test-runner import scan (§13 step 4b): zero direct
`from "vitest"` / `from "bun:test"` imports.
- [ ] Missing-`.md` scan returns zero output.
- [ ] `README.md` present.
- [ ] Bare-version scan returns zero output.
- [ ] Subpath-export count matches feature-module count.
- [ ] Security scan for hardcoded secrets returns zero output.
- [ ] (Not a foundation package — dependent sweep optional; run it anyway since
this is a fresh public surface.)
## 17. Root-doc refresh + markdownlint (§13b)
- [ ] `bun scripts/folder-reorg/generate-manifest.ts` → refresh `MANIFEST.md`.
- [ ] `bun scripts/generate-missing.ts` → refresh `MISSING.yml`.
- [ ] Move the package row from Pending → Completed in `STATUS.md`.
- [ ] Add the per-package paragraph in `SUMMARY.md`.
- [ ] `bunx markdownlint-cli2 --fix`; resolve any remaining violations by hand.
## 18. Fold spec into canonical location
- [ ] Fold
`openspec/changes/enterprise-audio-codec-ffmpeg-native/specs/audio-codec-ffmpeg-native/spec.md`
into `openspec/specs/audio-codec-ffmpeg-native/spec.md` per §14.
## 19. Archive
- [ ] Move `openspec/changes/enterprise-audio-codec-ffmpeg-native/` to
`openspec/archive/2026-05-15-enterprise-audio-codec-ffmpeg-native/`.