feat: store adapter — redux/zustand writers ↔ readers (C6)#16
Merged
officialCodeWork merged 1 commit intoJul 14, 2026
Merged
Conversation
Step 2.4 (TRACKER). Failure mode C6, temporal decoupling: - detectStores: createSlice → one global StateNode per slice (stateKind redux); createAsyncThunk payload creators mined for data sources; extraReducers addCase(thunk.fulfilled/rejected/pending) associates thunk sources to their slice via data-source --writes-state--> slice edges. Zustand: create() stores named use* become StateNodes with their internal fetches wired as writers. - Readers: useSelector((s) => s.users.list) parses the slice path and links reads-state to the GLOBAL slice node (falling back to the old per-component node when no slice matches); zustand hook calls link to their store node; dispatch(fetchUsers()) gives the dispatching component a fetches-from edge. - traceLineage: visiting a StateNode now follows incoming writes-state edges back to the populating data sources — reader → slice → login-time API. - Fixture c6-store-decoupled: UserDirectory (NO fetch of its own) → /api/users; CartWidget → /api/cart; cross-store poison assertions. - Fixed a declaration-order bug (detectStores called before addEdge existed). - Scorecard: 129 pass / 0 fail; precision/recall 1.000. 85 unit tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
TRACKER Step 2.4 — failure mode C6, temporal decoupling. The hardest attribution case after C1: a component reads
useSelector(s => s.users.list)and contains no fetch at all — the API that populated the slice was dispatched at login, by a different component, on a different page.traceLineage(UserDirectory)→/api/users.traceLineage(LoginPage)→/api/userstoo (it initiates the fetch viadispatch(fetchUsers())).What's detected
createSlice(one global StateNode per slice),createAsyncThunk(payload creator mined with the full 1.x endpoint machinery),extraReducersaddCase(thunk.fulfilled)association →writes-stateedgescreate()stores nameduse*; internal fetches become writers; hook calls become readersuseSelectorslice-path parsing links to the global slice node (old per-component fallback kept);dispatch(thunk())links the dispatchertraceLineagefollowswrites-stateedges backward through state nodesEval
c6-store-decoupledwith cross-store poison assertions (redux slice's API must never bleed onto the zustand reader, and vice versa)Also fixed in passing: a declaration-order bug (
detectStoresreferencedaddEdgebefore initialization).Documentation
TRACKER.md— 2.4 done, Status → 2.5 (portals — the last step before Gate 2)🤖 Generated with Claude Code