Files
2026-05-27 23:29:53 +01:00

4.3 KiB

Tasks: enterprise-dmx

Change ID: enterprise-dmx Package: @suaveplan/dmx Target path: universal/media/dmx Prerequisite packages on Verdaccio: @suaveplan/error, @suaveplan/types, @suaveplan/events


0. Pre-flight (non-negotiable)

  • 0.1 Confirm clean working tree (git status reports nothing) and no in-flight worktrees with uncommitted work (git worktree list then git status in each)
  • 0.2 If any worktrees exist under .claude/worktrees/, account for each one: still-active agent, work-pending-merge, or stale-and-prune. Stale worktrees MUST be removed (git worktree remove) before opening a new one — code that has been lost twice on main is the failure mode this guards against.
  • 0.3 Confirm the package set in MANIFEST.md matches find packages -maxdepth 3 -name package.json count. Drift here means a prior change archived without regenerating the manifest.

1. Scaffold

  • Create directory universal/media/dmx/ 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:^, 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/types/common.ts — all interfaces and type aliases from proposal.
  • Write src/types/common.md.
  • Write src/error-codes.ts — DmxErrorCode, DMX_ERROR_METADATA, registerDmxErrorCodes().
  • Write Zod schemas: FixtureDefinitionSchema, FixtureInstanceSchema, SceneSchema, FadeOptionsSchema, DmxEngineOptionsSchema, CueStepSchema.
  • Write src/constants/index.ts — DMX_UNIVERSE_SIZE = 512, DMX_MIN_VALUE = 0, DMX_MAX_VALUE = 255.

3. NullTransport

  • Implement NullTransport implements DmxTransport — captures all send calls in a calls: Array<{universe: Uint8Array; universeId: string}> array; exposes reset().
  • Write null-transport.test.ts and null-transport.md.

4. Interpolation utilities

  • Implement interpolate(from, to, t): DmxValue — four easing functions (linear, ease-in, ease-out, ease-in-out). Clamp result to [0, 255].
  • Implement buildScene(id, values): Scene.
  • Write interpolate.test.ts, interpolate.md, scene.test.ts, scene.md.

5. DmxEngine

  • Implement DmxEngine: universe management, fixture registry with address-conflict detection, setChannel/getChannel, getUniverse, applyScene with fade interpolation (uses injectable Clock for frame timing), blackout, start/stop render loop.
  • Wire OTel: counter dmx.frame_total, histogram dmx.frame_render_ms, counter dmx.scene_apply_total.
  • Write dmx-engine.test.ts (≤500 lines): universe CRUD, fixture conflict detection, scene apply, blackout, fade end-state, abort on stop.
  • Write dmx-engine.md.

6. ChaseSequencer

  • Implement ChaseSequencer — step list, start(looping), stop, jumpToStep; uses injectable Clock; emits step events via @suaveplan/events.
  • Write chase-sequencer.test.ts (≤500 lines): step progression, loop restart, manual jump, stop mid-sequence.
  • Write chase-sequencer.md.

7. Benchmarks

  • Write src/__benchmarks__/dmx.bench.ts — single-universe 512-channel render loop, 8-fixture scene apply.

8. Tests

  • Write tests/integration.test.ts — engine + sequencer end-to-end with NullTransport.
  • Write tests/property.test.ts (fast-check) — channel value clamping, fade interpolation monotonicity, scene round-trip.

9. Docs + verify + publish

  • All co-located .md files (≥200 words each).
  • Write README.md at package root.
  • bunx turbo lint typecheck test --filter=@suaveplan/dmx — green.
  • bunx turbo test:coverage --filter=@suaveplan/dmx — 100%.
  • bun scripts/publish.ts --package @suaveplan/dmx.
  • Archive to openspec/archive/2026-04-24-enterprise-dmx/.