Initial Commit
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
# OpenSpec Change: timing-spec-conformance
|
||||
|
||||
- **Change ID**: timing-spec-conformance
|
||||
- **Package**: `@suaveplan/timing`
|
||||
- **Status**: PROPOSED
|
||||
- **Date**: 2026-04-26
|
||||
|
||||
## Summary
|
||||
|
||||
Add `**Verified by:**` lines to every requirement in `openspec/specs/timing/spec.md`, fix two real implementation drifts inline, and add a consolidated `src/timing.spec-conformance.test.ts` so that `bun scripts/openspec-conformance.ts @suaveplan/timing` exits 0. No public surface trimming.
|
||||
|
||||
## Current state
|
||||
|
||||
`@suaveplan/timing` has 12 requirements (TM-01 through TM-12) and 137 passing tests across stopwatch, scheduler, throttle/debounce, decay, timer/countdown, vector-clock, errors, and OTel modules. Two real drifts surfaced during the audit:
|
||||
|
||||
1. **TM-11 incomplete OTel emission.** The spec required "stopwatch elapsed, scheduler queue depth, and timer tick counter" to emit. Only standalone helpers `recordStopwatchElapsed` and `incrementTimerTick` existed; they were never called by `stopwatch`, `scheduler`, or `timer` modules, and `recordSchedulerQueueDepth` did not exist at all.
|
||||
2. **No `**Verified by:**` lines** on any of the 12 requirements.
|
||||
|
||||
Plus the audit-level finding that `openspec/archive/2026-04-19-enterprise-timing/tasks.md` carries the historical phrase `retroactively ticked`; opening this change folder lifts that block.
|
||||
|
||||
## What changes
|
||||
|
||||
1. Add `recordSchedulerQueueDepth` to `src/otel/timing-otel.ts` (lazy `ObservableGauge` with mutable observed value, no-op without exporter). Re-export from `src/index.ts`.
|
||||
2. Wire `scheduler.schedule`, the per-task `finally`, handle-`cancel`, top-level `cancel`, and `dispose` to call `recordSchedulerQueueDepth(_tasks.size)` so queue-depth telemetry tracks the live task map.
|
||||
3. Wire `stopwatch.stop` to call `recordStopwatchElapsed(_accumulated)`.
|
||||
4. Wire `createTimer.start` to invoke `incrementTimerTick()` on each interval before the user's `onTick`.
|
||||
5. Add `src/timing.spec-conformance.test.ts` covering: throttle window count, debounce flush/cancel/maxWait, vector-clock relation matrix + JSON round-trip + `update` max-merge, scheduler drain order + pre-abort, countdown pause/resume invariant with injected clock, stopwatch monotonicity across laps, and OTel no-op smoke for the new gauge plus the existing helpers.
|
||||
6. Add `**Verified by:**` lines under every requirement in `openspec/specs/timing/spec.md`.
|
||||
|
||||
## Impact
|
||||
|
||||
- Public API gains one new export: `recordSchedulerQueueDepth`. No removals, no renames.
|
||||
- Stopwatch `.stop()`, scheduler enqueue/dequeue, and timer ticks now emit OTel telemetry (no-op without exporter, so observable behaviour for existing consumers is unchanged).
|
||||
- One new test file (~200 lines).
|
||||
- `openspec/specs/timing/spec.md` gains 12 `**Verified by:**` lines.
|
||||
@@ -0,0 +1,33 @@
|
||||
# Capability Spec Delta: timing (spec-conformance)
|
||||
|
||||
**Package**: `@suaveplan/timing`
|
||||
**Status**: PROPOSED
|
||||
|
||||
This delta annotates each existing requirement in `openspec/specs/timing/spec.md` with a `**Verified by:**` line, and records the inline drift fixes that wire scheduler queue-depth, stopwatch elapsed, and timer tick OTel emission so TM-11's "MUST emit" clause is satisfied at the module flow level (not just via standalone helpers). No requirement semantics change.
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
(See `openspec/specs/timing/spec.md` for the full requirement bodies; this delta only records the verification mapping.)
|
||||
|
||||
| Requirement | Verified by |
|
||||
|---|---|
|
||||
| TM-01 — Injectable clock | `src/stopwatch/stopwatch.test.ts` AND `src/throttle/throttle.test.ts` AND `src/timer/timer.test.ts` AND `src/timing.spec-conformance.test.ts` AND `tests/no-disallowed.test.ts` |
|
||||
| TM-02 — AbortSignal support | `src/scheduler/scheduler.test.ts` AND `src/timing.spec-conformance.test.ts` |
|
||||
| TM-03 — Stopwatch | `src/stopwatch/stopwatch.test.ts` AND `src/timing.spec-conformance.test.ts` |
|
||||
| TM-04 — Throttle / debounce | `src/throttle/throttle.test.ts` AND `src/throttle/debounce.test.ts` AND `src/timing.spec-conformance.test.ts` |
|
||||
| TM-05 — Decay | `src/decay/decay.test.ts` |
|
||||
| TM-06 — Scheduler | `src/scheduler/scheduler.test.ts` AND `src/timing.spec-conformance.test.ts` |
|
||||
| TM-07 — Timer and countdown | `src/timer/timer.test.ts` AND `src/timing.spec-conformance.test.ts` |
|
||||
| TM-08 — Vector clock | `src/vector-clock/vector-clock.test.ts` AND `src/timing.spec-conformance.test.ts` |
|
||||
| TM-09 — Structured errors | `src/errors/timing-error.test.ts` |
|
||||
| TM-10 — Zod schemas | `src/*/*.schemas.ts` AND `tests/dep-graph.test.ts` |
|
||||
| TM-11 — OTel instrumentation | `src/otel/timing-otel.test.ts` AND `src/timing.spec-conformance.test.ts` |
|
||||
| TM-12 — sideEffects: false + coverage 100% | `tests/tree-shake.test.ts` AND `tests/no-disallowed.test.ts` AND coverage gate |
|
||||
|
||||
## Newly added tests in this change
|
||||
|
||||
- `src/timing.spec-conformance.test.ts` — pins throttle window-count edge, debounce flush/cancel/maxWait, vector-clock relation matrix and JSON round-trip, scheduler drain order + pre-abort, countdown pause/resume invariant with injected clock, stopwatch monotonicity across laps, and OTel no-op smoke for the new `recordSchedulerQueueDepth` gauge.
|
||||
|
||||
## Inline drift fixes folded into this change
|
||||
|
||||
- TM-11: stopwatch `.stop()`, scheduler enqueue/dequeue/dispose, and timer ticks now emit via `@opentelemetry/api`. New `recordSchedulerQueueDepth` helper added (lazy `ObservableGauge`, mutable observed value, no-op without exporter).
|
||||
23
openspec/archive/2026-04-29-timing-spec-conformance/tasks.md
Normal file
23
openspec/archive/2026-04-29-timing-spec-conformance/tasks.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# Tasks: timing-spec-conformance
|
||||
|
||||
## 1. Inline drift fixes
|
||||
|
||||
- [x] 1.1 Add `recordSchedulerQueueDepth` (lazy `ObservableGauge`) to `src/otel/timing-otel.ts`.
|
||||
- [x] 1.2 Re-export `recordSchedulerQueueDepth` from `src/index.ts`.
|
||||
- [x] 1.3 Wire `scheduler.schedule` / per-task `finally` / handle-`cancel` / top-level `cancel` / `dispose` to call `recordSchedulerQueueDepth(_tasks.size)`.
|
||||
- [x] 1.4 Wire `stopwatch.stop` to call `recordStopwatchElapsed(_accumulated)`.
|
||||
- [x] 1.5 Wire `createTimer.start` interval callback to call `incrementTimerTick()` before user `onTick`.
|
||||
|
||||
## 2. Spec-conformance tests
|
||||
|
||||
- [x] 2.1 Add `src/timing.spec-conformance.test.ts` covering TM-03/04/06/07/08/11 implicit scenarios and the new queue-depth helper.
|
||||
|
||||
## 3. Spec annotations
|
||||
|
||||
- [x] 3.1 Add `**Verified by:**` line under every TM-NN requirement in `openspec/specs/timing/spec.md`.
|
||||
|
||||
## 4. Verify
|
||||
|
||||
- [x] 4.1 `bunx turbo lint typecheck test --filter=@suaveplan/timing` green.
|
||||
- [x] 4.2 `bunx turbo test:coverage --filter=@suaveplan/timing` 100/100/100/100.
|
||||
- [x] 4.3 `bun scripts/openspec-conformance.ts @suaveplan/timing` exits 0.
|
||||
Reference in New Issue
Block a user