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

2.5 KiB

Capability Spec Delta: testing (testing)

Package: @suaveplan/testing Status: PROPOSED

Every requirement below carries a **Verified by:** line at authoring time. No exceptions.

MODIFIED Requirements

Requirement: Rng surface re-exports the canonical type

@suaveplan/testing SHALL re-export the canonical Rng interface from @suaveplan/types rather than declaring a local interface Rng. The re-export lives at src/context/context.ts and is named Rng, preserving the existing consumer import path (import type { Rng } from "@suaveplan/testing") for one release cycle. The local cryptoRng and seededRng(seed) factories SHALL continue to satisfy the canonical type — they provide the required nextUint32 / nextFloat members and omit the optional nextBytes / nextIntInRange members. The package SHALL add @suaveplan/types to dependencies as workspace:^; this is the sole @suaveplan/* runtime dependency permitted for testing-infrastructure packages under CLAUDE.md rule 8, and is allowed because @suaveplan/types is types-only and emits zero runtime (verified by the byte-size guard).

Verified by: packages/testing/testing/src/context/context.ts (re-export line export type { Rng } from "@suaveplan/types") AND packages/testing/testing/src/context/context.test.ts::"cryptoRng satisfies canonical Rng" AND packages/testing/testing/src/context/context.test.ts::"seededRng satisfies canonical Rng" AND packages/testing/testing/package.json dependencies contains "@suaveplan/types": "workspace:^" AND bunx turbo test --filter=...@suaveplan/testing (foundation dependent sweep).

Scenario: local Rng re-export forwards canonical

  • WHEN a consumer writes import type { Rng } from "@suaveplan/testing"
  • THEN the imported type is structurally identical to import type { Rng } from "@suaveplan/types"

Scenario: cryptoRng satisfies canonical

  • WHEN const r: import("@suaveplan/types").Rng = cryptoRng
  • THEN tsc accepts (cryptoRng provides nextUint32 + nextFloat; optional members omitted)

Scenario: seededRng satisfies canonical

  • WHEN const r: import("@suaveplan/types").Rng = seededRng(42)
  • THEN tsc accepts AND r.nextUint32() is deterministic given seed 42

Scenario: byte-size guard remains green

  • WHEN the testing-infra byte-size guard runs after @suaveplan/types is added as a dependency
  • THEN the guard exits zero (because @suaveplan/types emits zero runtime bytes — it is a types-only package)