## 0. Pre-flight (non-negotiable) - [ ] 0.1 Confirm clean working tree (`git status` reports nothing) and no in-flight worktrees with uncommitted work (`git worktree list` then `git status` in each) - [ ] 0.2 If any worktrees exist under `.claude/worktrees/`, account for each one: still-active agent, work-pending-merge, or stale-and-prune. Stale worktrees MUST be removed (`git worktree remove`) before opening a new one — code that has been lost twice on main is the failure mode this guards against. - [ ] 0.3 Confirm the package set in `MANIFEST.md` matches `find packages -maxdepth 3 -name package.json` count. Drift here means a prior change archived without regenerating the manifest. ## 1. Package skeleton — `@suaveplan/testing-contract` - [ ] 1.1 Create `packages/testing/testing-contract/` with `package.json` (version `0.1.0`, `type: "module"`, `sideEffects: false`, only `@suaveplan/types` as a `workspace:^` internal dep, catalog deps on `zod` only). - [ ] 1.2 Add `tsconfig.lib.json` extending `@suaveplan/typescript-config/library.json`; add `vite.config.ts` (`preserveModules: true`); add `vitest.config.ts` via `createTestConfig()`. - [ ] 1.3 Stub `README.md` (one-paragraph description, install, quick start, **Modules** index linking each co-located `.md`). ## 2. Pact data model - [ ] 2.1 Implement `src/pact-file/pact-file.types.ts` — types matching Pact Specification v3 (`PactFile`, `PactInteraction`, `PactRequest`, `PactResponse`, `PactProviderState`). - [ ] 2.2 Implement `src/pact-file/pact-file.schemas.ts` — Zod schemas for every type above; round-trip parse/serialise covered by tests. - [ ] 2.3 Implement `src/pact-file/read-write.ts` — `readPactFile(path)` and `writePactFile(path, pact)` with deterministic key order (consumer / provider / interactions / metadata) so diffs are reviewable. ## 3. Consumer-side recording - [ ] 3.1 Implement `src/define/define-consumer-interaction.ts` — `defineConsumerInteraction({ provider, request, response, state? })`; registers the expectation against a per-process registry; returns a handle for cleanup. - [ ] 3.2 Implement `src/record/record-pact-interaction.ts` — `recordPactInteraction(httpClient)` wraps a `FetchLike` and matches each request/response pair against registered interactions; on `flushPact(path)` writes the pact file. - [ ] 3.3 Implement `src/record/match-interaction.ts` — match algorithm (method + path + headers subset + body shape); reports unmatched interactions distinctly from interactions with no traffic. - [ ] 3.4 Co-locate tests, schemas, and `.md` per file (≥200 words with simple + advanced examples per `openspec/AGENTS.md` §4). ## 4. Provider-side verification - [ ] 4.1 Implement `src/verify/verify-provider-against-pact.ts` — `verifyProviderAgainstPact(pactFile, providerUrl, options)`; replays each interaction via injectable `fetchFn`; asserts response matches recorded shape modulo `options.ignoreFields`. - [ ] 4.2 Implement `src/verify/state-handler.ts` — provider-state handler registry; `options.stateHandlers: Record Promise>` runs before each interaction whose `state` is registered. - [ ] 4.3 Implement `src/verify/diff-report.ts` — produce a structured diff when a verification fails (path → expected vs actual); included in the thrown error's `context`. ## 5. Pact Broker integration - [ ] 5.1 Implement `src/broker/publish-pact.ts` — `publishPact(brokerUrl, version)` HTTP POST to `/pacts/provider/

/consumer//version/`; auth via `PACT_BROKER_TOKEN`. - [ ] 5.2 Implement `src/broker/pull-pacts.ts` — `pullPactsForVerification(brokerUrl, providerName)` returns `PactFile[]`; uses the broker's `provider-pacts-for-verification` endpoint. - [ ] 5.3 Implement `src/broker/auth.ts` — read `PACT_BROKER_TOKEN`; throw `TestingContractError("TESTING_CONTRACT.BROKER.MISSING_TOKEN")` when broker calls are made without auth. ## 6. Errors - [ ] 6.1 Implement `src/errors/testing-contract-error.ts` — `TestingContractError extends Error` with `{ code, cause?, context? }`; subclasses for the recording, verification, and broker domains. - [ ] 6.2 Implement `src/errors/codes.ts` — string-literal-union of every `TESTING_CONTRACT..` code. ## 7. Spec deltas - [ ] 7.1 Land `specs/testing-contract/spec.md` with `## ADDED Requirements` (data model, consumer recording, provider verification, broker integration, error code prefix, coverage gate). - [ ] 7.2 Land `specs/oauth-client/spec.md` with `## ADDED Requirements` for consumer-side pact recording. - [ ] 7.3 Land `specs/webhook-client/spec.md` with `## ADDED Requirements` for consumer-side and provider-side pact requirements. - [ ] 7.4 Land `specs/schema-registry/spec.md` with `## ADDED Requirements` for consumer-side and provider-side pact requirements. - [ ] 7.5 Land `specs/api-schemas/spec.md` with `## ADDED Requirements` for consumer-side pact recording over envelope shapes. ## 8. Per-consumer wiring - [ ] 8.1 Add `oauth-client.contract.test.ts` to `@suaveplan/oauth-client`; record token endpoint + discovery + introspection; commit `pacts/oauth-client__oidc-issuer.json`. - [ ] 8.2 Add `webhook-client.contract.test.ts` to `@suaveplan/webhook-client` (consumer side: signed delivery POST); add `webhook-client.provider.test.ts` (verifies receiver against the same pact); commit `pacts/webhook-client__webhook-receiver.json`. - [ ] 8.3 Add `schema-registry.contract.test.ts` to `@suaveplan/schema-registry` (consumer side: schema lookup); add `schema-registry.provider.test.ts` (verifies the registry server); commit `pacts/schema-registry__upstream-registry.json`. - [ ] 8.4 Add `api-schemas.contract.test.ts` to `@suaveplan/api-schemas`; record envelope-shape interactions for `common`/`auth`/`admin`/`events`; commit `pacts/api-schemas__enterprise-api.json`. ## 9. CI - [ ] 9.1 Add a `pact:verify` Turborepo task that runs every provider-shaped package's `verifyProviderAgainstPact` against the committed pact files. - [ ] 9.2 Wire `pact:verify` into the pre-publish gate alongside `lint typecheck test`. ## 10. Verification - [ ] 10.1 `bunx turbo lint typecheck test --filter=@suaveplan/testing-contract` green. - [ ] 10.2 `bunx turbo test:coverage --filter=@suaveplan/testing-contract` at 100% statement / branch / function / line. - [ ] 10.3 `bunx turbo pact:verify --filter=@suaveplan/{oauth-client,webhook-client,schema-registry,api-schemas}` green. - [ ] 10.4 Banned-pattern scan clean. ## 11. Archive - [ ] 11.1 Move `openspec/changes/enterprise-testing-contract/` → `openspec/archive/-enterprise-testing-contract/` after all gates pass.