# Scope-Owned Server State Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Prevent previous-account query and optimistic state from remaining renderable or writable after an authentication scope transition. **Architecture:** The scope runtime is a fail-closed lifecycle authority. A bootstrap generation store owns a QueryClient and its concrete invalidation coordinator, swaps them only after the previous generation is closed, and exposes a stable invalidation facade plus a subscribable generation snapshot to React. **Tech Stack:** TypeScript 7, React 19, TanStack Query 5, Vitest 4, Testing Library. ## Global Constraints - FENCED is synchronous and no previous-account UI may render after it. - Mandatory participant or cache cleanup failure never publishes READY. - Snapshot subscriber defects never prevent reset scheduling. - Every READY generation owns a different QueryClient identity. - Late work from an old generation cannot write through the stable coordinator. - Preserve existing public application ports and dirty-worktree changes. --- ### Task 1: Fail-closed scope lifecycle **Files:** - Modify: `src/contracts/server-state-scope.ts` - Modify: `src/adapters/query-cache/server-state-scope-runtime.ts` - Modify: `tests/unit/server-state-scope-runtime.test.ts` **Interfaces:** - Adds phase `FAILED` and lifecycle event `{ kind: "FAILED"; generation: number }`. - Adds dependency callback `activateNextGeneration(): void | Promise` executed after old local reset and before READY. - [ ] Add failing tests for a throwing snapshot listener, participant failure, reset failure, and next-generation activation failure. - [ ] Run `corepack pnpm exec vitest run tests/unit/server-state-scope-runtime.test.ts` and confirm each new behavior fails for the intended reason. - [ ] Notify listeners from a stable snapshot with per-listener exception isolation. - [ ] Continue all cleanup participants, remember the first mandatory failure, and always attempt local reset. - [ ] Close old identities after cleanup, then publish FAILED if any mandatory step failed. - [ ] Call `activateNextGeneration` only after successful reset and publish READY only after it succeeds. - [ ] Re-run the focused unit test and confirm all lifecycle cases pass. ### Task 2: Render fence surface synchronously **Files:** - Modify: `src/presentation/adapters/query/server-state-scope-provider.tsx` - Create: `tests/component/server-state-scope-provider.test.tsx` **Interfaces:** - `ServerStateScopeProvider` subscribes to both snapshot and phase through one store notification. - Props add optional `transitionFallback?: ReactNode`; default is `null`. - Existing `useServerStateScope()` continues returning `CacheScopeSnapshot` for feature hooks. - [ ] Add a failing component test that renders private child data, triggers a deferred reset, and expects the child to disappear in the same `act()` turn. - [ ] Add a failing test that FAILED never remounts children. - [ ] Run the new component test and confirm old children remain with the current provider. - [ ] Subscribe in the provider and render children only for READY; render the supplied fallback for FENCED/FAILED and nothing after DISPOSED. - [ ] Re-run the test and confirm no old-data frame is observable. ### Task 3: QueryClient generation store and stable coordinator facade **Files:** - Create: `src/bootstrap/server-state-generation-store.ts` - Modify: `src/bootstrap/runtime-adapters.ts` - Modify: `src/bootstrap/runtime-application.tsx` - Modify: `tests/unit/runtime-adapters.test.ts` - Modify: `tests/component/runtime-application.test.tsx` **Interfaces:** - `ServerStateGenerationSnapshot = { generation: number; queryClient: QueryClient; coordinator: QueryInvalidationCoordinator; crossContextStatus(): CrossContextInvalidationStatus }`. - Store methods: `getSnapshot()`, `subscribe(listener)`, `activateNext()`, `resetCurrent()`, `dispose()`. - A stable `QueryInvalidationCoordinator` facade delegates only to the current snapshot and fences delegates by generation. - [ ] Add a failing unit test that captures the initial QueryClient, triggers session transition, completes reset, and expects a different current QueryClient. - [ ] Add a failing test that an old captured coordinator cannot invalidate after activation. - [ ] Add a component test that QueryClientProvider receives and renders against the new generation. - [ ] Implement generation factory ownership in bootstrap; create cross-context transport and concrete coordinator per generation. - [ ] Pass `resetCurrent` and `activateNext` to the scope runtime in the required order. - [ ] Make `RuntimeApplication` subscribe to the generation store and key the QueryClient provider by generation. - [ ] Dispose the current generation and store exactly once during application shutdown. - [ ] Run runtime-adapter and runtime-application tests until all pass. ### Task 4: Conditional validator and cleanup ordering **Files:** - Modify: `src/bootstrap/runtime-adapters.ts` - Modify: `tests/unit/runtime-adapters.test.ts` **Interfaces:** - Conditional validator clearing becomes an ordered mandatory scope participant rather than a general snapshot subscriber. - [ ] Add a failing order test proving validator clear occurs after admission fence and before cache disposal. - [ ] Register the validator closer with an explicit order and remove the generic subscription. - [ ] Re-run runtime-adapter tests and verify each closer executes once. ### Task 5: Verification - [ ] Run scope runtime, provider, runtime-adapter, runtime-application, and application-query focused suites. - [ ] Run `corepack pnpm check:types` and `corepack pnpm lint`. - [ ] Run the complete non-browser suite. - [ ] Record browser-only follow-up separately; do not claim it passed without Playwright evidence.