diff --git a/.planning/STATE.md b/.planning/STATE.md index 5028897..4aad6b2 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -2,9 +2,9 @@ gsd_state_version: 1.0 milestone: v1.0 milestone_name: milestone -status: in_progress -stopped_at: "Phase 2 context gathered. 02-CONTEXT.md captures 34 implementation decisions across 8 gray areas (geometry, time density, Lura's arc, letter composition, begin screen, journal, plant placeholders, settings UI scope). Locked: 4×4 grid, click+inline seed picker, 2–3 plants (1-from-start + fragment-count unlocks), infinite seeds, 2–5min growth band per plant, auto-harvest offline / manual active, 3 Lura gate visits gated by 1st/4th/8th harvest, authored Ink letter skeleton + slots, full-screen letter ≥5min absence, tasteful placeholder Begin (skip-on-return), full-screen Journal modal revealing after 1st harvest, Phaser-primitive plants with glow/pulse ready cue, save-management-only Settings. Phase 2's first commits: BigQty wrapper, Zustand store, tick scheduler. Save schema is a v1 *extension*, not a v1→v2 migration. Next: /gsd-plan-phase 2." -last_updated: "2026-05-09T00:50:00.000Z" +status: ready_to_execute +stopped_at: "Phase 2 planned. 5 PLAN.md files across 3 waves (Wave 0: 02-01 foundations [BigQty + Zustand store + tick scheduler + V1Payload extension]; Wave 1 parallel: 02-02 begin-plant-grow + 02-03 harvest-journal-fragments; Wave 2 parallel: 02-04 lura-gate-beats + 02-05 letter-settings-e2e). 24/24 REQ-IDs covered in plan frontmatter; 34/34 CONTEXT.md decisions cited across plan must_haves. RESEARCH.md, PATTERNS.md, VALIDATION.md (nyquist_compliant: true) all in place. Plan-checker iterations: 13 issues → 3 issues → 0 issues (BLOCKER 3 lastTickAt-vs-tickCount split was the cross-plan defect; final fix introduced src/save/payload.ts as a shared two-arg helper module). Next: /gsd-execute-phase 2 (Wave 0 must land before Waves 1+2 can start)." +last_updated: "2026-05-09T01:30:00.000Z" last_activity: 2026-05-09 progress: total_phases: 8 @@ -21,14 +21,14 @@ progress: See: .planning/PROJECT.md (updated 2026-05-08) **Core value:** Every idle mechanic must function as a metaphor that the player absorbs without being told. When economy and meaning conflict, meaning wins. -**Current focus:** Phase 02 — Season 1 Vertical Slice (Soil) — context gathered; ready for `/gsd-plan-phase 2` +**Current focus:** Phase 02 — Season 1 Vertical Slice (Soil) — 5 plans ready; ready for `/gsd-execute-phase 2` ## Current Position -Phase: 02 (season-1-vertical-slice-soil) — context gathered -Plans: 0 of TBD (planning is the next step) -Status: 02-CONTEXT.md written with 34 decisions; ready for `/gsd-plan-phase 2` -Last activity: 2026-05-09 -- Phase 2 discuss-phase complete +Phase: 02 (season-1-vertical-slice-soil) — planned, ready to execute +Plans: 5 of 5 created (3 waves) +Status: All 24 REQ-IDs + 34 CONTEXT.md decisions covered. Plan-checker PASSED after 3 revision iterations. Ready for `/gsd-execute-phase 2`. +Last activity: 2026-05-09 -- Phase 2 plan-phase complete Progress: [█░░░░░░░░░] 12% @@ -117,5 +117,5 @@ Items acknowledged and carried forward: ## Session Continuity Last session: 2026-05-09 -Stopped at: Phase 2 context gathered — 02-CONTEXT.md and 02-DISCUSSION-LOG.md written, 8 gray areas discussed, 34 decisions captured. Phase 1 still verified complete; Phase 2 builds on its save layer + content pipeline + ESLint firewall + doctrine docs. -Next action: `/gsd-plan-phase 2` to plan the Season 1 Vertical Slice +Stopped at: Phase 2 planning complete — 5 PLAN.md files written across 3 waves; plan-checker PASSED after 3 revision iterations (13 issues → 3 → 0); all 24 REQ-IDs and 34 D-XX decisions covered. +Next action: `/gsd-execute-phase 2` to execute the Season 1 Vertical Slice (Wave 0 first; Waves 1+2 can run in parallel within their wave) diff --git a/.planning/phases/02-season-1-vertical-slice-soil/02-01-foundations-PLAN.md b/.planning/phases/02-season-1-vertical-slice-soil/02-01-foundations-PLAN.md index 71c79b1..7cb366c 100644 --- a/.planning/phases/02-season-1-vertical-slice-soil/02-01-foundations-PLAN.md +++ b/.planning/phases/02-season-1-vertical-slice-soil/02-01-foundations-PLAN.md @@ -50,8 +50,8 @@ must_haves: - "drainTicks(state, accumulatorMs<0) returns the original state with ticksApplied=0 (CORE-11 negative-delta refusal)" - "drainTicks(state, 25*3600*1000) clamps to floor(MAX_OFFLINE_MS / TICK_MS) ticks (CORE-03 24h cap)" - "drainTicks at TICK_MS=200ms over 24h completes ≤500ms on a modern machine (Vitest benchmark)" - - "Zustand 5 vanilla createStore composes 4 slices (garden / memory / narrative / session); useAppStore hook re-renders on selector changes; getState() works without React" - - "simAdapter (in src/store/) exposes applySimResult(next, events) and drainCommands(); src/sim/ never imports src/store/" + - "Zustand 5 vanilla createStore composes 4 slices (garden / memory / narrative / session); useAppStore hook re-renders on selector changes; getState() works without React. This store is the Phaser↔React bridge (D-32) — sim writes via the slim sim-adapter; React reads via selectors; sim never imports the store directly (CORE-10 enforced)" + - "simAdapter (in src/store/) exposes applySimResult(next, events) and drainCommands(); src/sim/ never imports src/store/ (D-32 / CORE-10)" - "V1Payload extension adds unlockedPlantTypes, luraBeatProgress, offlineEvents, settings.persistenceToastShown, AND tickCount (BLOCKER 3 — sim-internal monotonic counter, separate from lastTickAt) — CURRENT_SCHEMA_VERSION stays at 1; no migrations[2] entry exists" - "migrations[1] (the v0→v1 demo) returns a fully-populated V1Payload including all new fields (tickCount: 0) with sensible defaults" - "BLOCKER 3 invariant: SimState.lastTickAt is wall-clock milliseconds (written ONLY at saveSync time by the application layer); SimState.tickCount is the sim-internal monotonic counter (incremented inside simulateOneTick). The sim never writes lastTickAt." diff --git a/.planning/phases/02-season-1-vertical-slice-soil/02-04-lura-gate-beats-PLAN.md b/.planning/phases/02-season-1-vertical-slice-soil/02-04-lura-gate-beats-PLAN.md index 4cef90f..8d07948 100644 --- a/.planning/phases/02-season-1-vertical-slice-soil/02-04-lura-gate-beats-PLAN.md +++ b/.planning/phases/02-season-1-vertical-slice-soil/02-04-lura-gate-beats-PLAN.md @@ -39,7 +39,8 @@ tags: [vertical-slice, lura, ink, dialogue-overlay, narrative-gating, mvp] must_haves: truths: - - "All Lura dialogue is authored in Ink (.ink) under /content/dialogue/season1/; compiled at build time to JSON via `npm run compile:ink` invoking inklecate (STRY-06)" + - "Lura is present as discrete gate visits — not a persistent chat thread (D-12). 3 beats this Season: arrival, mid, farewell." + - "All Lura dialogue is authored in Ink (.ink) under /content/dialogue/season1/; compiled at build time to JSON via `npm run compile:ink` invoking inklecate; runtime-loaded via inkjs (STRY-06, D-16)" - "Beat 1 (arrival) fires when state.harvestedFragmentIds.length transitions from 0 to 1 (1st harvest); beat 2 (mid) at 4th harvest; beat 3 (farewell) at 8th harvest. Counts come from sim state — STRY-10." - "STRY-10: FakeClock advance alone (without harvest events) does NOT advance Lura beats. Tested in lura-gate.test.ts." - "When a beat fires, sim sets state.luraBeatProgress.pending = beatId; the gate visual (in Phaser) shows a soft glow indicator (D-15). Player clicks the gate → React DOM dialogue overlay opens (D-15)."