Claude Code and Cursor are great for shipping features
The logic of state restoration
The instinct is often to "persist domain state and discard UI state," but that's too simplistic. In a real-world AI workflow, some UI state (like a half-typed clue) should survive a reload, while other ephemeral states (like AI-generated suggestions) should be wiped.
If you're building something similar, you have to decide what actually constitutes a "saved" state. In my gamePersistence.ts file, I had to explicitly define what gets snapshotted and what gets purged.
- Persisted: Board layout, revealed cards, team assignments, and human-typed clue text.
- Purged: Human-intended target highlights, manual count overrides, and unsubmitted AI-generated clues.
The reason for purging AI-generated clues is critical: if a user refreshes the page, they should get a fresh request to the model. If the model is upgraded or the config changes, the next reload should reflect that, rather than replaying a stale, cached output that might now be suboptimal.
Implementing the "Clear Drafting Pose" pattern
To fix the leak, I stopped trying to "rehydrate everything" and instead implemented a specific cleanup sequence. The logic is now: restore the saved game state, then immediately execute a function to clear the drafting pose. This ensures that leftover thinking aids don't leak into the next turn or a different game mode.
For those of you managing complex state in React or similar frameworks, I'd suggest a behavioral test suite for your persistence layer. I specifically test for "grid reference" leaks:
1. Highlight a card on Board A.
2. Switch to Board B.
3. Verify that the highlight is gone, even if the card at that position is the same.
If you're using an LLM agent like Claude Code to refactor your state management, don't just tell it to "fix the bug." Give it the specific lifecycle of your state. Tell it: "The snapshot must encode what the product has accepted as true, not whatever happened to exist in the UI." That distinction is the difference between a buggy "save" feature and a polished user experience.