Files
suaveplan/openspec/archive/2026-05-24-profiler/proposal.md
2026-05-27 23:29:53 +01:00

3.2 KiB

Proposal — Migrate @suaveplan/profiler to genesis

Why

@suaveplan/profiler is the universal-tier runtime performance profiling primitive consumed by downstream observability tooling. The upstream package at /mnt/s/web/suaveplan/packages/universal/profiler/ reached 93.95% test coverage and lacks the genesis enterprise gates (Clock/TimersLike/LoggerLike injection, defineCodes error registry, OTel meter wiring, Zod-validated boundaries, 100/100/100/100 coverage). This change re-lands the package at packages/devtools/tooling/profiler/ with the full feature surface and the genesis enterprise contract.

What

Land @suaveplan/profiler@0.1.0 with the following modules (one per feature folder, 5-files-per-feature):

  • profiler/ — Profiler class: start/stop/mark/measure/measureAsync
  • sampler/ — periodic metric sampler with injectable Clock+TimersLike
  • memory/ — heap snapshot capture with injectable capture-fn; leak detection
  • bottleneck/ — hot-path detector + budget-violation finder
  • comparison/ — diff two profiles; regression/improvement classifier
  • flamegraph/ — flamegraph JSON tree builder + recursive-call collapse
  • reporter/ — text formatter + percentile statistics
  • otel/ — OTLP-compatible span exporter (HTTP fetch)
  • error-codes/ — PROFILER_CODES via defineCodes + ProfilerError
  • telemetry/ — OTel meter for the profiler itself (counter + histogram)
  • types/ — shared ProfileEntry/ProfileMark/SamplePoint/etc

Source mapping

Upstream file Genesis file Notes
src/profiler/profiler.ts src/profiler/profiler.ts Clock+TimersLike injected; Zod options
src/sampler/sampler.ts src/sampler/sampler.ts TimersLike.setTimer replaces setInterval
src/memory/memory-profiler.ts src/memory/memory.ts Injectable HeapCapture fn replaces global probe
src/bottleneck/bottleneck-detector.ts src/bottleneck/bottleneck.ts Same algorithm, renamed file
src/comparison/profile-comparator.ts src/comparison/comparison.ts Same algorithm
src/flamegraph/flamegraph-generator.ts src/flamegraph/flamegraph.ts Same algorithm
src/reporter/reporter.ts src/reporter/reporter.ts Same algorithm
src/otel/otel-exporter.ts src/otel/otel.ts fetch is injectable for tests
src/index.ts src/index.ts Explicit named re-exports only
(none) src/error-codes/error-codes.ts New — required by genesis rule
(none) src/telemetry/telemetry.ts New — required by genesis rule

Deviations from upstream

  1. Upstream uses @suaveplan/events EventEmitter with variadic tuple payloads. Genesis @suaveplan/events exposes EventBus with single-payload (emit(type, payload)) — event maps reshaped to single-object payloads.
  2. Upstream calls Date.now() and setInterval directly. Genesis injects Clock + TimersLike per the universal-tier contract.
  3. Upstream has no error-code registry. Genesis adds PROFILER_CODES/ProfilerError.
  4. Upstream emits no profiler-self-telemetry. Genesis adds a telemetry/ module emitting per-public-call counters + duration histograms.
  5. Boundary validation: every public constructor option object is now Zod-validated.