## Why `@suaveplan/testing` is the shared test infrastructure every other `@suaveplan/*` package imports from. As Layer 0 in the genesis dependency graph (zero `@suaveplan/*` workspace deps — rule #9 of `openspec/project.md`), every package downstream depends on it. Enterprise-quality testing unblocks enterprise quality everywhere else. The enterprise specification at `/mnt/s/web/suaveplan/enterprise/testing.md` sets the bar; this change translates that spec into genesis form, **preserving the full public surface** established in the archived `2026-04-08-testing-libraries` change (RequestBuilder, ResponseBuilder, FakeClock, Factory, FixtureManager, MemoryStore, helpers, dual-runner conditional exports, `createTestConfig` — full inventory in `design.md`) while upgrading internals to enterprise grade. This is the first implementation change on the `genesis` branch. There is no prior genesis code to audit — the "current state" is empty. Design intent comes from the enterprise doc; surface intent comes from the existing implementation on `main` at `/mnt/s/web/suaveplan/packages/universal/testing/src/`. ## What Changes All requirements from `enterprise/testing.md` §3 are carried forward, with **four explicit substitutions** forced by genesis rule #9 (testing packages may not depend on any `@suaveplan/*` workspace package). Each substitution is called out inline below. ### Carried forward verbatim - **Universal purity** — zero browser/Node/React deps in `src/`. Runs in Bun, Node, and modern browsers. Enforced by a tree-shake test that inspects the built bundle. - **Zod schemas** for all public function inputs and outputs, exported from sibling `*.schemas.ts` files alongside each implementation file. Zod is an **external catalog dep** (`catalog:forms`), not routed through `@suaveplan/schema-registry`. - **Property-based tests (fast-check)** for pure functions (clock arithmetic, builder composition, factory deterministic output given fixed RNG, memory-store TTL math, semver-ish helpers). - **Deterministic behaviour** — no `Math.random()` / `Date.now()` / `performance.now()` at module scope. Every function that reads time or randomness accepts an optional `{ clock?, rng?, signal? }` options parameter. Zero-config defaults preserved. - **Backpressure & cancellation** — `AbortSignal` on every iterative / async helper (`waitFor`, `FixtureManager.setupAll/teardownAll`, `Factory.build` in batch mode, `MemoryStore` eviction sweeps), checked at bounded intervals (≤ 256 items or ≤ 1 KB). - **Idempotency & retry primitives** wired for any helper with network-ish retry semantics (e.g. `waitFor` polling). - **Feature flags** — any risky new behaviour gated behind an options flag with safe defaults. - **Structured errors** with stable codes of the form `TESTING..` (e.g. `TESTING.CLOCK.MAX_TIMERS_EXCEEDED`, `TESTING.FIXTURES.SETUP_FAILED`). Every thrown error carries `{ code, cause?, context? }`. - **Benchmarks** via `mitata` (external catalog dep) under `src/__benchmarks__/.bench.ts`, baseline in `benchmarks/baselines.json`, CI gate at 10% regression floor. - **Plugin / extension interface** — `FixtureManager` accepts plugins implementing `beforeEach/afterEach/onError` hooks; `Factory` accepts `traits` that downstream packages can contribute without forking. - **Observability surface** — counters, histograms, spans for every public entrypoint. Gated: no-op when no OTEL SDK is registered; live when one is. Useful for diagnosing flaky test environments in CI without touching test source. - **Security** — input validation at the boundary via Zod, no prototype-pollution vectors in `MemoryStore`, dependency audit clean. - **Migration story** — N/A; genesis starts fresh at version `0.1.0`. - **Example / story** — `examples/` directory with runnable usage of each public entrypoint. ### Substitutions (enterprise-doc → genesis form) | Enterprise doc requires | Genesis substitution | Why | |---|---|---| | Errors extend `@suaveplan/error` | Local `TestingError extends Error` with the same `{ code, cause, context }` shape, stable `TESTING..` codes | Rule #9 — can't take `@suaveplan/*` deps. Shape-compatible so a future `@suaveplan/error` adapter can bridge without API change. | | OTEL via `@suaveplan/opentelemetry` | `@opentelemetry/api` (external, ~2 KB, no transitive Node deps). Spans/counters/histograms created via the standard API, no-op without a registered SDK | Rule #9. `@opentelemetry/api` is the canonical public API spec; the internal package will wrap this at a later layer. | | Schemas via `@suaveplan/schema-registry` | `zod` direct (catalog:forms). Schemas exported from `*.schemas.ts` under stable names (e.g. `BuilderSchemas.request.input`) so a future `schema-registry` adapter can enumerate them | Rule #9. | | Clock via `@suaveplan/datetime` | Local `Clock` interface in `src/context/context.ts`: `{ now(): number; hrtime(): bigint }`. `defaultClock` reads `Date.now()` / `performance.now()` directly. `FakeClock` implements the same interface. | Rule #9. | | i18n via `@suaveplan/i18n` or hard-coded message keys | English-only `message` fields. `code` is the machine contract; `message` is developer-facing. Matches the utils D10 precedent. | Rule #9. Test helpers emit messages to developers in logs, not to end users. | ### Public surface preserved Every export enumerated in `design.md` §Surface Inventory is retained unchanged in shape. Internals are rewritten; signatures gain the optional `{ clock?, rng?, signal? }` options parameter where appropriate (purely additive — zero-config callers are unaffected). ## Capabilities ### New Capabilities - `testing`: shared test infrastructure for the genesis monorepo — test primitives (vitest + bun-test conditional export), mock API, request/response builders, FakeClock, Factory, FixtureManager, MemoryStore, async helpers, vitest config factory, polyfills. Layer 0 leaf. ### Modified Capabilities (none — genesis has no prior spec) ## Impact - **Affected code:** `/mnt/s/web/genesis/packages/universal/testing/**` (fresh implementation). - **Affected consumers:** none on genesis yet; every subsequent genesis package depends on this one. - **Version:** `0.1.0` (genesis baseline; no bump until graduation cut). - **Catalogs added / extended in root `package.json`:** `zod` to `catalogs.forms`, `@opentelemetry/api` to a new `catalogs.observability`, `fast-check` and `mitata` to `catalogs.testing`. - **Root `package.json` `devDependencies` addition:** `@types/bun` already present; tooling catalogs unchanged. - **New capability spec:** `openspec/specs/testing/spec.md` (created on archive). - **Pre-publish gate:** full turbo `lint typecheck test` on `@suaveplan/testing` + istanbul coverage ≥ 95% before `bun scripts/publish.ts --package @suaveplan/testing`.