# Tasks — testing-msw-carve-out This proposal is **deferred until activation**. Activation = the first time a React/R3F-tier package legitimately needs MSW (likely Wave 7). ## 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. ## Phase 1: Activation trigger (do nothing until then) - [ ] 1.1 A package author files an OpenSpec sub-change requesting MSW under this carve-out, citing the concrete blocker (e.g. "Playwright E2E needs slow-body 503 response that real-server setup can't reproduce in < 50 LOC"). - [ ] 1.2 Sub-change is reviewed against the carve-out's "Allowed / Forbidden" tables in `proposal.md`. If it doesn't fit, the answer is "use injection / real server" and this carve-out stays dormant. ## Phase 2: Build the testing-msw package - [ ] 2.1 Create `packages/testing/testing-msw/` with standard testing-infra package shape (zero `@suaveplan/*` runtime deps). - [ ] 2.2 Add `msw` to root catalog under a new `testing-msw` group key. - [ ] 2.3 Author `createMswServer(handlers, options?)` — wraps `setupServer` with injectable `Clock` and `AbortSignal` integration. - [ ] 2.4 Author `createMswWorker(handlers, options?)` — browser-tier equivalent for Storybook + Playwright. - [ ] 2.5 Author `expectRequest(server, predicate, opts?)` — async wait-for-match helper with timeout + abort. - [ ] 2.6 Author `requestRecorder()` — ordered-assertion harness. - [ ] 2.7 Author `runMswConformance(label, makeFactory)` — shared conformance harness exposed under the `./testing` subpath (mirrors `i18n-shared/testing` pattern). - [ ] 2.8 100/100/100/100 coverage on the testing-msw surface itself. ## Phase 3: Codify the rule - [ ] 3.1 Add §1 #2a "MSW carve-out" to `CLAUDE.md`, exact text from `proposal.md`. - [ ] 3.2 Author `openspec/specs/testing/spec.md` (or extend existing testing spec) with `## ADDED Requirements` capturing: - MSW MAY be used only through `@suaveplan/testing-msw`. - Tier restriction (React/R3F only). - Conformance-test requirement. - Handler co-location requirement. - [ ] 3.3 Update `openspec/AGENTS.md` if any §0a parity checklist row would conflict. ## Phase 4: Ship the first consumer - [ ] 4.1 The triggering package (likely `react-network-libp2p-demo` or `r3f-networking`) consumes `@suaveplan/testing-msw` for its first MSW-backed test. - [ ] 4.2 That same package ships at least one Playwright E2E against a real protocol implementation (the conformance requirement). - [ ] 4.3 Both tests demonstrably exercise the same component code path. ## Phase 5: Verification - [ ] 5.1 `bunx turbo lint typecheck test:coverage --filter=@suaveplan/testing-msw` green at 100/100/100/100. - [ ] 5.2 First consumer's tests green. - [ ] 5.3 `bun run docs:check` green on testing-msw. - [ ] 5.4 `STATUS.md` row added for `@suaveplan/testing-msw` (status `❌`-net-new → `✅`). - [ ] 5.5 `CLAUDE.md` and `openspec/specs/testing/spec.md` reflect the new rule. ## Pre-archive checklist - [ ] Row 1 — Phase 5 green. - [ ] Row 2 — A real consumer is using the carve-out (no theoretical adoption). - [ ] Row 3 — Conformance-test requirement demonstrably enforced on the first consumer. - [ ] Row 4 — Folder moved to `openspec/archive/-testing-msw-carve-out/`. ## Anti-tasks (DO NOT do) - [ ] DO NOT add MSW to any universal-tier or server-tier package's test suite. - [ ] DO NOT use MSW to work around an injectable-`fetchFn` design. If the package can be made injectable, do that instead. - [ ] DO NOT use MSW in production code paths. - [ ] DO NOT re-introduce `vi.mock`/`jest.mock` under the cover of "but MSW is fine now". The two are different layers and the second remains banned. - [ ] DO NOT centralise MSW handlers in a top-level `mocks/` directory. Handlers co-locate with tests.