## Why Section 2 of the test-suite audit (`/mnt/s/web/genesis/docs/superpowers/specs/2026-04-25-test-suite-audit.md` row "No contract tests") lists consumer/provider contract testing as a critical missing tier of the test pyramid: `@suaveplan/oauth-client`, `@suaveplan/webhook-client`, `@suaveplan/schema-registry`, and `@suaveplan/api-schemas` are textbook Pact candidates whose failure modes (provider drifting from consumer expectations, schema breaking changes, OAuth token-endpoint shape mutations, webhook signature drift) are not catchable by today's unit, integration, or E2E tiers. Today the only schema-shaped guard is hand-written Zod validation in each package's tests, which proves the consumer's encoder agrees with itself, not that a real provider's responses still match what the consumer was built against. This change introduces a project-wide Pact-style consumer/provider contract testing capability and wires it into every consumer package whose surface crosses a network boundary. ## What Changes ### New package — `@suaveplan/testing-contract` - Lives at `packages/testing/testing-contract` and follows the same dependency-graph exception as `@suaveplan/testing-integration`: zero `@suaveplan/*` runtime deps except `@suaveplan/types` (per `CLAUDE.md` rule 8 testing-infrastructure carve-out). - Public API: - `defineConsumerInteraction({ provider, request, response, state? })` — declarative interaction record. - `recordPactInteraction(httpClient)` — wraps a `fetch`-shaped client; while wrapped, every request/response pair is recorded against the matching `defineConsumerInteraction` declarations into a `.pact.json` file. - `verifyProviderAgainstPact(pactFile, providerUrl, options)` — replays a pact file's interactions against a running provider and asserts each response matches the recorded shape. - `publishPact(brokerUrl, version)` and `pullPactsForVerification(brokerUrl, providerName)` — optional Pact Broker integration; auth via `PACT_BROKER_TOKEN` env. - Pact file shape conforms to Pact Specification v3 `interactions[]` (consumer/provider names, request, response, providerStates). - Errors prefixed `TESTING_CONTRACT.*`. Coverage gate at 100% (Istanbul, all four metrics). ### Cross-cutting requirements on consumer packages Each of the four packages SHALL ship a `*.contract.test.ts` that records interactions against its public API surface using `recordPactInteraction`. The recorded `.pact.json` files are committed to `pacts/__.json` so PR review surfaces wire-format drift. Provider-side specs (where the package itself implements a server / receiver — `webhook-client` receivers, `schema-registry` server) SHALL run `verifyProviderAgainstPact` in CI against the same pact files. ### Capability deltas Each consumer package gets an `## ADDED Requirements` block carrying: - A **Consumer-side pact recording** requirement (must produce a pact file in `pacts/`). - For server-shaped packages (`webhook-client` receiver, `schema-registry` server), a **Provider-side pact verification** requirement. ## Capabilities ### New Capabilities - `testing-contract` — Pact-style consumer/provider contract testing primitives (`defineConsumerInteraction`, `recordPactInteraction`, `verifyProviderAgainstPact`, `publishPact`, `pullPactsForVerification`). ### Modified Capabilities - `oauth-client` — adds consumer-side pact requirement against the OAuth/OIDC provider's token + discovery endpoints. - `webhook-client` — adds consumer-side (signing) and provider-side (receiver) pact requirements. - `schema-registry` — adds consumer-side (schema lookup) and provider-side (registry server) pact requirements. - `api-schemas` — adds consumer-side pact recording over the `common`/`auth`/`admin`/`events` envelope shapes that consumers send to API plugins. (None of these capabilities have a pre-existing `openspec/specs//spec.md` yet; the deltas in this change land them as new files when folded.) ## Impact - **Affected code:** new package at `/mnt/s/web/genesis/packages/testing/testing-contract/**`; new `*.contract.test.ts` files inside the four consumer packages; new `pacts/` directories per consumer package. - **Affected consumers:** every `@suaveplan/*` package whose surface crosses a network boundary inherits the requirement on its first OpenSpec change after this one lands. - **Catalog additions (root `package.json`):** none — `testing-contract` synthesises pact JSON itself rather than depending on `@pact-foundation/pact` (which is Node-only and pulls a Ruby toolchain). The optional broker-publish path uses native `fetch`. - **CI:** a new `pact:verify` Turborepo task runs `verifyProviderAgainstPact` on every commit for the provider-shaped packages. - **Pre-publish gate:** every package with contract tests must pass `pact:verify` in addition to `lint typecheck test` and 100% coverage. - **Cross-cutting:** five new spec files land on archive (`testing-contract`, `oauth-client`, `webhook-client`, `schema-registry`, `api-schemas`).