a641056364
BLOCKER 3 — cross-plan regression: Plans 02-03 and 02-05 BOTH re-author
src/sim/garden/commands.ts but had reverted simulateOneTick to the old
defective return shape (`return { ...next, lastTickAt: currentTick };`).
Wave 1's execution of 02-03 would overwrite 02-02's correct version,
breaking the invariant for the entire phase.
- 02-03: simulateOneTick return now matches 02-02 line 457 exactly:
`return { ...next, tickCount: next.tickCount + 1 };`
- 02-05: same fix for the silent-mode update (Step 6).
- 02-03 acceptance_criteria: add negative grep
(`! grep -E "lastTickAt:\s*(this|currentTick)" src/sim/garden/commands.ts`)
and positive grep (`grep -q "tickCount: next.tickCount" ...`).
- 02-05 acceptance_criteria: add the same two greps for commands.ts so
02-05's silent-mode edits cannot silently re-introduce the regression.
W1 — App.tsx import: 02-05 Step 11 used `useEffect` without importing it.
Combined `import { useState }` and `import { useRef }` into a single
`import { useState, useEffect, useRef } from 'react';` line.
W2 — helper arity divergence: Settings.tsx (one-arg, Date.now() inline)
and PhaserGame.tsx (two-arg, clock.now() injected) had two parallel
definitions of buildPayloadFromStore / hydrateStoreFromPayload. Fix:
- New Step 3.5 introduces `src/save/payload.ts` with the unified
two-arg signature: `buildPayloadFromStore(state, nowMs)` and
`hydrateStoreFromPayload(state, payload)`.
- `src/save/index.ts` re-exports both.
- Settings.tsx imports from save barrel; passes Date.now() at the
call site (no clock injection on hand).
- PhaserGame.tsx imports from save barrel; passes clock.now() (the
injected wallClock or FakeClock).
- Inline duplicate definitions in both files removed; replaced with
a comment pointing to the shared module.
- files_modified updated to include src/save/payload.ts.
- acceptance_criteria asserts: shared file exists, both helpers
exported, both consumers import from save barrel, no inline
duplicate definitions remain.
VALIDATION.md not updated — no `<automated>` verify command changed;
the new greps live inside `<acceptance_criteria>` (executor-checked
per task), and VALIDATION.md is not present in the phase dir.
All iteration-1 + iteration-2 fixes preserved; no regressions.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>