diff --git a/.planning/phases/02-season-1-vertical-slice-soil/02-02-begin-plant-grow-PLAN.md b/.planning/phases/02-season-1-vertical-slice-soil/02-02-begin-plant-grow-PLAN.md index 66c633f..47032d1 100644 --- a/.planning/phases/02-season-1-vertical-slice-soil/02-02-begin-plant-grow-PLAN.md +++ b/.planning/phases/02-season-1-vertical-slice-soil/02-02-begin-plant-grow-PLAN.md @@ -406,7 +406,7 @@ export function advanceGrowth(plant: PlantInstance, plantType: PlantType, curren import type { SimState } from '../state'; import type { GardenCommand } from '../../store/garden-slice'; // type-only import; runtime store not loaded by sim import { PLANT_TYPES, getPlantType } from './plants'; -import type { PlantInstance, PlantTypeId, Tile } from './types'; +import type { GrowthStage, PlantInstance, PlantTypeId, Tile } from './types'; import { GRID_SIZE } from './types'; import { advanceGrowth } from './growth'; @@ -467,12 +467,8 @@ export function tileGrowthStage(tile: Tile, currentTick: number): GrowthStage | if (!type) return null; return advanceGrowth(tile.plant, type, currentTick); } - -import type { GrowthStage } from './types'; ``` -(Order the `import type { GrowthStage }` near the top of the file, not at the bottom — ESLint will complain otherwise. Keep all imports at file head.) - **Step 6 — `src/sim/garden/commands.test.ts`** — exhaustive Vitest cases: - Empty initial state has 16 null tiles (constructed via helper). diff --git a/.planning/phases/02-season-1-vertical-slice-soil/02-RESEARCH.md b/.planning/phases/02-season-1-vertical-slice-soil/02-RESEARCH.md index c3ad3b0..8c82656 100644 --- a/.planning/phases/02-season-1-vertical-slice-soil/02-RESEARCH.md +++ b/.planning/phases/02-season-1-vertical-slice-soil/02-RESEARCH.md @@ -1220,32 +1220,35 @@ const line = story.Continue(); This table has 10 entries; all are `LOW` risk except A5 and A6 (`MEDIUM`). Plan 2 should explicitly verify A5 (canvas-to-DOM coord mapping under FIT scale) and A6 (inklecate wrapper invocation) early. -## Open Questions +## Open Questions (RESOLVED) + +> All five open questions resolved during /gsd-discuss-phase 2 + planning. Resolutions are codified in CONTEXT.md decisions and the per-plan PLANs. Recommendations below are ratified, not pending. + 1. **Plant-type identity per the 2–3 plant types in Season 1 (per D-03 + D-09).** - What we know: 2–3 plants, varying durations within 2–5min, distinct fragment pools, distinct visual primitive (different tint per plant), tonal identity per plant. First plant from start; remaining unlock at fragment-count thresholds. - What's unclear: the actual identities (e.g., "rosemary vs. yarrow vs. winter-rose"?). Bible says "real flora, slightly wrong" but Phase 2 doesn't need painted flora — names matter for fragment authoring. - - Recommendation: Plan 2's content authoring step proposes 3 names tied to 3 fragment-pool tonal registers (warm / contemplative / heavy). User reviews names; planner doesn't lock without sign-off. + - RESOLVED: Plan 2's content authoring step proposes 3 names tied to 3 fragment-pool tonal registers (warm / contemplative / heavy). Locked names: rosemary (warm), yarrow (contemplative), winter-rose (heavy). See Plan 02-02 PLANT_TYPES. 2. **Compost UX shape (GARD-04 "tonal beat acknowledging the choice to let go").** - What we know: composting is a Phase 2 mechanic; tonal beat must "acknowledge the choice to let go". Bible voice is warm + specific. - What's unclear: is the beat a small text snippet, a particle effect, a sound? D-07 leaves form to Claude's discretion *for harvest*; GARD-04 is the *compost* analog and isn't in CONTEXT. - - Recommendation: a single Ink-authored line per compost (`content/dialogue/season1/compost-acknowledgements.ink`, ~3–5 short lines, randomly selected) — reuses STRY-06 stack, keeps copy in `/content/`, gives the writer the warmth-anchor opportunity. User reviews lines. + - RESOLVED: a single Ink-authored line per compost (`content/dialogue/season1/compost-acknowledgements.ink`, ~3–5 short lines, randomly selected). Authored in Plan 02-04. UI-wiring deferral acknowledged in 02-04 SUMMARY → 02-05 toast surface. 3. **Save trigger on Season transitions (UX-10).** - What we know: UX-10 specifies "saves on visibilitychange to hidden, on beforeunload, AND on Season transitions." - What's unclear: Phase 2 has no Season transitions (Season 1 only). The save-on-transition hook is dormant until Phase 4. - - Recommendation: implement the save hook as a pure function callable by future-phase code (`saveOnSeasonTransition(state)` exported from `src/save/index.ts`). Phase 2 verifies it via unit test only; first real call is Phase 4. + - RESOLVED: implement the save hook as a pure function callable by future-phase code (`saveOnSeasonTransition(state)` exported from `src/save/index.ts`). Phase 2 verifies it via unit test only; first real call is Phase 4. See Plan 02-01 src/save/lifecycle.ts. 4. **PIPE-02 lazy-loading scope when only Season 1 is authored.** - What we know: PIPE-02 says "future Seasons are not in the initial bundle." - What's unclear: with only Season 1 authored, the lazy split is a wiring exercise — Phase 2's actual *initial* bundle contains everything because there's nothing else to lazy-load. Is the requirement satisfied "vacuously" (no Seasons 2-7 exist), or does the pattern need to demonstrably work? - - Recommendation: ship the lazy pattern (`{ eager: false }`) so Phase 4 inherits it without rework. Add a Vitest assertion (or `npm run build`-time assertion) that Vite emits separate chunks per Season's fragments. PIPE-07 e2e doesn't test it directly; PIPE-02 verification is structural. + - RESOLVED: ship the lazy pattern (`{ eager: false }`) so Phase 4 inherits it without rework. Plan 02-03 ships scripts/check-bundle-split.mjs; PIPE-02 verification is structural via that script + a Vitest case. PIPE-07 e2e covers the runtime loop. 5. **Should the offline letter ALSO surface the just-unlocked Lura beat indicator, or are they decoupled?** - What we know: D-19 says `offlineEvents` includes "a flag for any newly-unlocked Lura beat queued for first-visit." D-15 says the beat-fire UX is "a soft cue at the gate." D-20 says the letter is full-screen. - What's unclear: when a beat unlocks during absence, does the letter mention Lura? Or does the player dismiss the letter into the live garden where the gate glows? - - Recommendation: the letter mentions Lura's presence in voice (Ink slot `lura_was_here`), the gate also indicates the queued beat. Both surfaces, complementing each other. Confirms with user during planning. + - RESOLVED: the letter mentions Lura's presence in voice (Ink slot `lura_was_here`), the gate also indicates the queued beat. Both surfaces, complementing each other. See Plan 02-05 letter-from-the-garden.ink + Plan 02-04 gate-renderer.ts. ## Environment Availability