Files
suaveplan/openspec/archive/2026-04-19-enterprise-timing/tasks.md
2026-05-27 23:29:53 +01:00

5.9 KiB

Archived 2026-04-19: all tasks retroactively ticked; package shipped under universal/primitives/timing.

Tasks: enterprise-timing

1. Scaffold

  • 1.1 Create packages/universal/timing/ with package.json, tsconfig.json, tsconfig.lib.json, vite.config.ts, vitest.config.ts, README.md skeleton
  • 1.2 Register coverage thresholds at 100/100/100/100 in vitest.config.ts; provider = istanbul
  • 1.3 Add cross-cutting guard tests in tests/: dep-graph, no-disallowed, tree-shake
  • 1.4 Add package to root CLAUDE.md, README.md, and STRUCTURE.yml

2. Errors + types

  • 2.1 Implement src/errors/timing-error.ts — TimingError extends SuaveplanError; defineCodes for TIMING.SCHEDULER.DISPOSED, TIMING.COUNTDOWN.INVALID_DURATION, TIMING.VECTOR_CLOCK.UNKNOWN_NODE
  • 2.2 Tests for error construction and code narrowing

3. Stopwatch module

  • 3.1 Implement src/stopwatch/stopwatch.ts — createStopwatch(opts?) returning Stopwatch with .start(), .stop(), .reset(), .lap(), .elapsed, .laps
  • 3.2 Implement src/stopwatch/stopwatch.types.ts — StopwatchOptions, StopwatchLap, Stopwatch
  • 3.3 Accept { clock?: Clock } in StopwatchOptions
  • 3.4 Zod schema StopwatchOptionsSchema
  • 3.5 Unit tests: start/stop/reset, lap timing, nested laps, clock injection
  • 3.6 Co-located src/stopwatch/stopwatch.md

4. Throttle + debounce module

  • 4.1 Implement src/throttle/throttle.ts — throttle(fn, wait, opts?), debounce(fn, wait, opts?)
  • 4.2 throttle: leading/trailing edge, { leading?: boolean; trailing?: boolean; clock?: Clock }
  • 4.3 debounce: leading/trailing, .flush(), .cancel(), { maxWait?: number; clock?: Clock }
  • 4.4 Implement src/throttle/throttle.types.ts — ThrottleOptions, DebounceOptions, ThrottledFunction, DebouncedFunction
  • 4.5 Zod schemas ThrottleOptionsSchema, DebounceOptionsSchema
  • 4.6 Unit tests: leading/trailing combos, flush, cancel, maxWait, clock injection
  • 4.7 Property-based tests: throttle output count ≤ ceil(events / wait)
  • 4.8 Co-located src/throttle/throttle.md

5. Decay module

  • 5.1 Implement src/decay/decay.ts — createDecay(opts) returning Decay with .tick(elapsed), .reset(), .value
  • 5.2 Support exponential, linear, and custom DecayFunction
  • 5.3 Implement src/decay/decay.types.ts — DecayOptions, DecayFunction, Decay
  • 5.4 Zod schema DecayOptionsSchema
  • 5.5 Unit tests: exponential to zero, linear decay, custom function, reset
  • 5.6 Property-based tests: exponential decay is monotonically decreasing
  • 5.7 Co-located src/decay/decay.md

6. Scheduler module

  • 6.1 Implement src/scheduler/scheduler.ts — createScheduler(opts?) returning Scheduler with .schedule(fn, delay), .cancel(id), .drain(signal?), .dispose()
  • 6.2 Scheduler uses injected clock; drain honours AbortSignal
  • 6.3 Implement src/scheduler/scheduler.types.ts — SchedulerOptions, SchedulerHandle, Scheduler
  • 6.4 Throw TIMING.SCHEDULER.DISPOSED on operations after dispose()
  • 6.5 Zod schema SchedulerOptionsSchema
  • 6.6 Unit tests: schedule/cancel, drain, dispose, signal abort during drain, clock injection
  • 6.7 Co-located src/scheduler/scheduler.md

7. Timer + countdown module

  • 7.1 Implement src/timer/timer.ts — createTimer(opts) with .start(), .stop(), .reset() and tick event; createCountdown(duration, opts?) with .start(), .pause(), .resume(), .stop(), .remaining
  • 7.2 Validate duration > 0, throw TIMING.COUNTDOWN.INVALID_DURATION otherwise
  • 7.3 Implement src/timer/timer.types.ts — TimerOptions, CountdownOptions, Timer, Countdown
  • 7.4 Zod schemas TimerOptionsSchema, CountdownOptionsSchema
  • 7.5 Unit tests: interval firing, pause/resume, stop/reset, clock injection, AbortSignal
  • 7.6 Co-located src/timer/timer.md

8. Vector clock module

  • 8.1 Implement src/vector-clock/vector-clock.ts — createVectorClock(nodeId, opts?), vectorClockCompare(a, b)
  • 8.2 Implement src/vector-clock/vector-clock.types.ts — VectorClockOptions, VectorClockState, VectorClock
  • 8.3 Throw TIMING.VECTOR_CLOCK.UNKNOWN_NODE when merging clocks with nodes not in the local registry
  • 8.4 Zod schema VectorClockOptionsSchema, VectorClockStateSchema
  • 8.5 Unit tests: increment, merge, compare (before/after/concurrent/equal), toJSON/fromJSON round-trip
  • 8.6 Property-based tests: ordering transitivity, anti-symmetry; merge commutativity
  • 8.7 Co-located src/vector-clock/vector-clock.md

9. OTel instrumentation

  • 9.1 Histogram timing.stopwatch.elapsed_ms
  • 9.2 Histogram timing.scheduler.queue_depth (gauge snapshot on drain)
  • 9.3 Counter timing.timer.tick.total
  • 9.4 All instrumentation no-ops without OTel exporter (tested)

10. Benchmarks

  • 10.1 src/__benchmarks__/throttle.bench.ts — 10 000 events at 16ms window (mitata)
  • 10.2 src/__benchmarks__/vector-clock.bench.ts — merge 1 000 nodes
  • 10.3 src/__benchmarks__/scheduler.bench.ts — drain 1 000 tasks
  • 10.4 Publish baseline numbers in README

11. Docs

  • 11.1 Co-located .md for every implementation file (≥200 words, simple + advanced examples, full API reference)
  • 11.2 Rewrite README.md with public API overview, design rationale, consumer guide
  • 11.3 bun run docs:check --filter=@suaveplan/timing ≥ 90%

12. Verify and publish

  • 12.1 bunx turbo lint typecheck test --filter=@suaveplan/timing green
  • 12.2 bunx turbo test:coverage --filter=@suaveplan/timing at 100/100/100/100
  • 12.3 bunx turbo build --filter=@suaveplan/timing green
  • 12.4 bun scripts/publish.ts --package @suaveplan/timing to Verdaccio at 0.0.0
  • 12.5 Archive OpenSpec change to openspec/archive/2026-04-18-enterprise-timing/