The question behind [turning `pvpGameState.svelte.ts` into an injectable factory](/posts/the-store-that-had-never-been-tested) had always been about two stores, not one: `duelGameState.svelte.ts`, the AI-duel side of the same untestable-Svelte-store problem, was in scope from the start. The follow-on ticket filed at the time deliberately deferred it, reasoning that PvP was the harder case, SSE plus a localStorage session versus AI duel's plain `fetch`-based turn polling, and the more informative one to spike first. Once that spike had already proven the runes tolerate the shape and the factory pattern had a locked design to copy, there was nothing left in the AI-duel version to investigate, only to build.

The ticket's own prediction held exactly: converting `duelGameState.svelte.ts` was a smaller lift, because its whole transport surface was smaller to begin with.

```typescript
export interface DuelGameApi {
	startDuelGame(language?: string): Promise<{ gameId: string; seed: number }>;
	fetchOpponentMove(
		gameId: string,
		state: DuelGameState,
		config: DuelGameConfig
	): Promise<DuelOpponentMoveResponse>;
	logPlayerMove(params: LogPlayerMoveParams): void;
	endDuelGame(params: EndDuelGameParams): void;
}

export interface DuelGameStoreDeps {
	api?: DuelGameApi;
	clock?: Clock;
}
```

Two optional fields against PvP's four: no `EventSource` constructor to inject, since there is no SSE here, and no `Storage` to fake, since AI duel keeps no session token across reloads. `fetchOpponentMove` already routed through the already-injectable `DuelTurnEngine`, so the rest of the module's per-turn logic moved into the factory as closures, unreshaped, the same way PvP's outcome-application quartet had. `createDuelGameStore()` still sits at the bottom as the real production singleton, so `+layout.svelte` and the AI-duel page needed no changes at all.

The new tests prove the two things that actually mattered: a full player turn running end to end through a fake `api` and clock with zero real `fetch` calls reaching the network, and two factory instances built side by side staying genuinely independent, one appending a letter to its input without the other seeing it. Neither assertion had anywhere to live before this store had a seam to test through; the whole file's coverage used to stop at whatever the end-to-end suite happened to exercise through a real page.