From 8f58e811b55ac3fecd4f62632013571560f5f585 Mon Sep 17 00:00:00 2001 From: josh Date: Fri, 8 May 2026 22:03:41 -0400 Subject: [PATCH] docs(01): capture phase 1 context MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User locked four implementation decisions: - AI asset pipeline: minimum-viable schema + sidecar provenance + CI gate; vendor/model deferred to Phase 5; 10–20 hand-curated AI generations as Phase 1 north-stars - Save v1: minimal payload (Phase 2 fields only); synthetic v0→v1 migration proves the chain works; first real migration ships in Phase 4 - Doctrine docs: anti-FOMO consolidation + Season 7 principle-level rest-state contract; both in .planning/; no CI/lint enforcement - Phase 1 scaffold caps at the 5 success criteria — BigQty, Zustand store, and tick scheduler defer to Phase 2 Pushback recorded: user prefers minimum-viable infrastructure for support systems; no ceremonial workflows. --- .planning/STATE.md | 9 +- .../01-foundations-and-doctrine/01-CONTEXT.md | 130 ++++++++++++++++++ .../01-DISCUSSION-LOG.md | 115 ++++++++++++++++ 3 files changed, 250 insertions(+), 4 deletions(-) create mode 100644 .planning/phases/01-foundations-and-doctrine/01-CONTEXT.md create mode 100644 .planning/phases/01-foundations-and-doctrine/01-DISCUSSION-LOG.md diff --git a/.planning/STATE.md b/.planning/STATE.md index 5a72932..4076767 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -11,8 +11,8 @@ See: .planning/PROJECT.md (updated 2026-05-08) Phase: 1 of 8 (Foundations & Doctrine) Plan: 0 of TBD in current phase -Status: Ready to plan -Last activity: 2026-05-08 — Roadmap created, 77 v1 requirements mapped across 8 phases. +Status: Context gathered — ready for `/gsd-plan-phase 1` +Last activity: 2026-05-08 — Phase 1 context discussed and committed; user locked AI pipeline to minimum-viable, save schema to minimal v1, doctrine docs to principle-level, Phase 1 scaffold capped at success criteria. Progress: [░░░░░░░░░░] 0% @@ -68,5 +68,6 @@ Items acknowledged and carried forward from previous milestone close: ## Session Continuity Last session: 2026-05-08 -Stopped at: Roadmap created and committed; ready to begin Phase 1 planning. -Resume file: None — next action is `/gsd-discuss-phase 1` +Stopped at: Phase 1 context gathered. User chose minimum-viable shape across all four gray areas (AI pipeline, save v1, doctrine docs, scaffold scope) — explicit pushback on overengineering recorded. +Resume file: .planning/phases/01-foundations-and-doctrine/01-CONTEXT.md +Next action: `/gsd-plan-phase 1` diff --git a/.planning/phases/01-foundations-and-doctrine/01-CONTEXT.md b/.planning/phases/01-foundations-and-doctrine/01-CONTEXT.md new file mode 100644 index 0000000..c9cf736 --- /dev/null +++ b/.planning/phases/01-foundations-and-doctrine/01-CONTEXT.md @@ -0,0 +1,130 @@ +# Phase 1: Foundations & Doctrine - Context + +**Gathered:** 2026-05-08 +**Status:** Ready for planning + + +## Phase Boundary + +Land every retrofit-hostile decision before any feature code: project scaffold (Phaser 4 + React 19 + Vite + TypeScript via the official template), versioned save framework (IndexedDB + localStorage fallback + lz-string + checksum + migration chain + last-3 snapshots + Base64 export/import + `navigator.storage.persist()`), content build pipeline (`/content/**/*.{md,yaml,ink}` → Zod-validated → per-Season compiled JSON), AI asset pipeline floor (provenance schema + CI gate + sample asset proving the gate refuses unprovenanced material + a 10–20-image north-star reference set), ESLint boundary rules enforcing `src/sim/` ↔ `src/render/`/`src/ui/` firewall, written anti-FOMO doctrine, written Season 7 end-state design (principle-level). + +**Phase 1 stops at the 5 success criteria from ROADMAP.md.** No `BigQty` wrapper, no Zustand store skeleton, no tick scheduler — those are Phase 2's first tasks. The discipline this phase establishes is what makes Phase 2 possible without rework. + +**Out of scope for Phase 1 (deferred to Phase 2 or later):** any user-facing feature code, the begin-gesture / `AudioContext.resume()` screen (AEST-07 lives in Phase 2), Howler bus setup, simulation tick loop, garden render scene, BigQty wrapper, Zustand store contents. + + + +## Implementation Decisions + +### AI Asset Pipeline Depth +- **D-01:** End-of-Phase-1 north-star reference set is **10–20 hand-curated AI generations** committed to the repo with full provenance metadata. Generated honestly with whatever tool was used (likely Claude/SD/Midjourney/etc. on a per-asset basis); the `model_id` and `checkpoint_hash` fields record what was actually used. +- **D-02:** **Tool/vendor choice deferred** — Phase 1 commits to the *schema* and *gate*, not a vendor. Tool consolidation happens in Phase 5 when production volume kicks in. This is consistent with `AEST-08`'s wording (pinned model + provenance) — the *pinning* can happen later as long as every shipped asset records what produced it. +- **D-03:** **Curation gate is minimum-viable.** Sidecar `name.provenance.json` per asset under `/assets/` carrying the 6 required fields (`model_id`, `checkpoint_hash`, `prompt`, `seed`, `sampler`, `params`); CI script walks the tree and fails the build on any missing/invalid sidecar. Sample refused asset under `/assets/__samples__/refused/` (no sidecar) proves the gate works. **No** curator workflow, **no** two-stage promotion directory, **no** pre-commit hook, **no** CURATION-LOG.md ceremony. The user explicitly rejected heavier alternatives — keep it light. + +### Save Schema v1 Scope +- **D-04:** v1 save payload is **minimal** — only what Phase 2 will write (garden tile state, plant growth data, harvested fragment IDs, `lastTickAt`, basic settings). It does NOT pre-allocate slots for Roothold, currentSeason, storyFlags, etc. Phase 4 ships a real `migrate_v1_to_v2` when Season-prestige state actually exists. +- **D-05:** Round-trip migration test in Phase 1 uses a **synthetic v0 → v1 migration** as the proof that the chain works. v0 is a tiny made-up prior schema (e.g., `{garden: []}`) used only to exercise the migration framework end-to-end. The first *real* migration is v1 → v2 in Phase 4. +- **D-06:** Save format `{schemaVersion, payload, checksum}` is locked from CLAUDE.md / ROADMAP.md. Checksum algorithm and exact migration registry shape are Claude's discretion. + +### Doctrine Docs Concreteness +- **D-07:** Anti-FOMO doctrine is a **consolidation document** in `.planning/` (or `docs/`) of the constraints already scattered across PROJECT.md (Out of Scope), REQUIREMENTS.md (UX-13 + Out of Scope table), CLAUDE.md (Hard Thematic Constraints), and the research SUMMARY.md banner concerns. It explicitly enumerates the banned patterns (no daily login bonuses, no streaks, no limited-time content, no nag notifications, no loss-aversion copy, no rewarded ads, no FOMO push notifications) and is written to be referenced at every UX/monetization design review going forward. **No** lint rule on UX strings — the doctrine is enforced by review, not code. +- **D-08:** Season 7 end-state design is **principle-level**, not treatment-level. The doc answers: (a) what does *rest state* mean (no new fragments, no new currency tiers — the player can return to a finite world they have understood); (b) what is the finite Roothold ceiling tied to (the count of authored fragments / Season count — concrete tie to authored content, not an arbitrary number); (c) what tonal register does the coda live in. It does **not** include the binary-choice scene text, both ending paragraphs, Lura's final line, or the credits/coda screen treatment — those are authored in Phase 7. +- **D-09:** Both doctrine documents live under `.planning/` (alongside PROJECT.md / ROADMAP.md / REQUIREMENTS.md), not under `docs/`. They are project-internal design constraints, not user-facing documentation. + +### Project Scaffold Layout +- **D-10:** Use `npm create @phaserjs/game@latest` (React + Vite + TypeScript template) as the starting point. Restructure `src/` to expose the boundary directories explicitly: `src/sim/`, `src/render/`, `src/ui/`, plus supporting `src/save/`, `src/content/` (loader/types), `src/audio/`, `src/store/` as siblings. This gives ESLint clean targets to enforce against and matches the firewall language in CLAUDE.md. +- **D-11:** Authored content (`/content/**/*.{md,yaml,ink}`) lives at **repo root**, alongside `src/`, `assets/`, `.planning/`. Confirms CLAUDE.md. +- **D-12:** `/assets/` (with provenance sidecars) lives at repo root, alongside `/content/`. Single package, **no monorepo / no workspaces** — solo dev. + +### Claude's Discretion +- Exact ESLint boundary rule choice (`eslint-plugin-boundaries` vs `eslint-plugin-import` `no-restricted-paths`) — pick whichever has cleanest config. +- Checksum algorithm (CRC32, simple hash, etc.) — any deterministic, fast hash works; record choice in CONTEXT for Phase 2's verifier. +- Migration registry shape (chain of named functions, registry object, etc.) — Claude designs. +- `idb` wrapper API surface inside `src/save/` — Claude designs. +- Vitest / Playwright config files, `vite.config.ts` boundary plugin choices — Claude designs. +- Where the Zod content schemas live (`src/content/schemas/`) and how the build step is invoked (Vite plugin vs separate `npm run build:content` script) — Claude designs. +- Specific images for the 10–20 north-star generations (Claude can produce prompts/specs; user can accept, reject, or replace). + + + + +## Canonical References + +**Downstream agents MUST read these before planning or implementing.** + +### Project-Level Source of Truth +- `.planning/PROJECT.md` — Story bible synthesis, core value ("every idle mechanic must function as a metaphor"), hard thematic constraints, Out of Scope, Key Decisions table. +- `.planning/REQUIREMENTS.md` — 77 v1 requirements with REQ-IDs. Phase 1 owns: CORE-01, CORE-04, CORE-05, CORE-06, CORE-07, CORE-08, CORE-09, CORE-10, PIPE-01, PIPE-03, PIPE-05, PIPE-06, AEST-08, AEST-09, STRY-09, UX-13. +- `.planning/ROADMAP.md` §"Phase 1: Foundations & Doctrine" — 5 success criteria. +- `.planning/STATE.md` — current position, accumulated decisions, banner concerns. +- `CLAUDE.md` — stack lock, architectural firewall, banner concerns 1–10, hard thematic constraints, code style rules. + +### Research Layer +- `.planning/research/SUMMARY.md` — stack at a glance, banner concerns, Phase 1 rationale. +- `.planning/research/STACK.md` — full stack rationale (Phaser 4, React 19, Vite, TS, Zustand, break_eternity.js, Ink/inkjs, Howler.js, idb + lz-string, Zod, Vitest, Playwright). +- `.planning/research/ARCHITECTURE.md` — three-layer firewall (sim → application → presentation), tick scheduler shape, save format `{schemaVersion, payload, checksum}`. +- `.planning/research/PITFALLS.md` — 14 critical pitfalls; Phase 1 directly addresses #1 (story-ends-but-loop-doesn't), #3 (save format untenable), #5 (AI style drift), #8 (storage eviction), #9 (FOMO), #10 (content/code divergence). +- `.planning/research/FEATURES.md` — must-have / should-have / defer / anti-feature classification. + +### Phase 1 Specific Inputs +- `npm create @phaserjs/game@latest` (React + Vite + TypeScript template) — official Phaser 4 starter; researcher should confirm current template structure. +- `idb` library docs — IndexedDB wrapper of choice. +- `lz-string` docs — save compression. +- `zod` docs — content + save schema validation. +- `navigator.storage.persist()` — MDN reference for browser-quota persistence. + +### Phase 1 Outputs (will be created during this phase) +- `.planning/anti-fomo-doctrine.md` — consolidated banned-pattern list and review checklist. +- `.planning/season-7-end-state.md` — principle-level rest-state contract, Roothold ceiling rationale, tonal register. +- `assets/north-stars/` — 10–20 hand-curated AI generations with provenance sidecars. +- `assets/__samples__/refused/` — sample asset(s) with no sidecar, used to prove the CI gate refuses them. + + + + +## Existing Code Insights + +No source code exists yet — repo is initial state with `.planning/`, `.git/`, `.claude/`, and `CLAUDE.md` only. Phase 1 introduces the project scaffold from scratch. + +### Reusable Assets +- None yet (greenfield). Phaser 4 official template provides the React + Vite + TS skeleton. + +### Established Patterns +- `.planning/PROJECT.md` / `REQUIREMENTS.md` / `ROADMAP.md` already follow the GSD pattern; new doctrine docs (`anti-fomo-doctrine.md`, `season-7-end-state.md`) should sit alongside them in `.planning/` for visibility. + +### Integration Points +- ESLint boundary rule must integrate with the Vite-template-provided ESLint config (don't replace it — extend it). +- Vitest + Playwright will be added to the template (the official Phaser template doesn't ship them). +- The Zod schema directory and build step must be wired so Phase 2 can drop content files into `/content/` and have them compile without rework. +- Provenance CI validator runs alongside (not inside) the Vite build — likely a `scripts/validate-assets.ts` invoked from `package.json` and run in CI. + + + + +## Specific Ideas + +- **Tone of feedback:** the user is solo, prefers minimum-viable infrastructure for support systems (pipelines, CI gates, doctrine docs). No ceremonial workflows. When AI asset pipeline questions implied a heavy curator workflow, user pushed back: "we are vastly overcomplicating this … I don't really care all that much" about pipeline shape. +- **Doctrine philosophy:** doctrine docs are *referenced at design reviews*, not enforced by tooling. Anti-FOMO is a banned-pattern list the human consults; Season 7 end-state is a principle the human consults when designing economy. No lint rule, no CI check on UX strings. +- **Save migrations are real but small:** the framework must work in Phase 1 (success criterion #2 demands a round-trip migration test), but the *real* migrations start at Phase 4. Phase 1 ships the chain with a synthetic v0 demo migration. +- **No premature scaffolding:** Phase 1 stops at the 5 success criteria. Phase 2 owns BigQty, Zustand store, tick scheduler — building them now risks designing for code that doesn't exist yet. + + + + +## Deferred Ideas + +- **AI vendor lock-in / model pinning** — Tool choice (local SD + watercolor LoRA, Scenario, Midjourney with licensed plan, etc.) deferred to early Phase 5 when production-volume asset generation begins. PROJECT.md / REQUIREMENTS.md AEST-08's "pinned model" requirement is satisfied honestly per-asset for now. +- **`BigQty` wrapper around break_eternity.js** — Phase 2's first task. CLAUDE.md says "from day one"; for this project, "day one of feature code" = Phase 2. +- **Empty Zustand store skeleton** — Phase 2 designs the store as part of wiring scenes ↔ UI. +- **Tick scheduler / monotonic clock** — Phase 2 (CORE-11 anchors on this). +- **Season 7 treatment-level details** (binary-choice scene text, Lura's final line, credits/coda screen) — Phase 7 authoring. +- **Anti-FOMO lint rule on UX strings** — explicitly rejected; doctrine is enforced by review, not code. +- **Curator workflow / two-stage asset promotion / pre-commit hook on assets** — explicitly rejected in favor of minimum-viable sidecar + CI validator. +- **Visual regression testing across asset library** — PIPE-04, owned by Phase 8. + + + +--- + +*Phase: 1-foundations-and-doctrine* +*Context gathered: 2026-05-08* diff --git a/.planning/phases/01-foundations-and-doctrine/01-DISCUSSION-LOG.md b/.planning/phases/01-foundations-and-doctrine/01-DISCUSSION-LOG.md new file mode 100644 index 0000000..50bcc82 --- /dev/null +++ b/.planning/phases/01-foundations-and-doctrine/01-DISCUSSION-LOG.md @@ -0,0 +1,115 @@ +# Phase 1: Foundations & Doctrine - Discussion Log + +> **Audit trail only.** Do not use as input to planning, research, or execution agents. +> Decisions are captured in CONTEXT.md — this log preserves the alternatives considered. + +**Date:** 2026-05-08 +**Phase:** 1-foundations-and-doctrine +**Areas discussed:** AI asset pipeline depth, Save schema v1 scope, Doctrine docs concreteness, Project scaffold layout + +--- + +## AI Asset Pipeline Depth + +### Sub-question A: north-star reference set state at end of Phase 1 + +| Option | Description | Selected | +|--------|-------------|----------| +| Hand-painted by a real artist | Commission a watercolor artist (or paint them yourself) to produce 10–20 hand-painted reference images now. AI pipeline (vendor TBD in Phase 5) later trains/conditions against them. Highest fidelity, real budget commitment. | | +| Hand-curated AI generations | Generate dozens of candidates in a chosen tool, hand-pick 10–20 that nail the watercolor target, commit them with full provenance. | ✓ | +| Placeholder refs + sealed slot | Phase 1 ships schema + gate + a marked 'north-star slot' with placeholders; real north-stars commissioned in early Phase 5. | | +| Public-domain watercolor refs | Curate 10–20 from public-domain or Creative Commons watercolor art. Zero budget; provenance is licensing, not generation. | | + +**User's choice:** Hand-curated AI generations. + +### Sub-question B: which generation tool for the Phase 1 north-stars + +| Option | Description | Selected | +|--------|-------------|----------| +| Local Stable Diffusion + watercolor LoRA | Local SD via ComfyUI/Automatic1111 with a watercolor-specialized LoRA. Full provenance natively (model checksum, exact sampler, seed, full params). | | +| Scenario (game-art-focused) | Purpose-built generative platform with custom-trained generators. Subscription-based ($29–$199/mo). Designed for reproducibility, style consistency. | | +| Midjourney with licensed plan | Best-in-class watercolor output, lowest skill floor. Provenance is messier (no checkpoint hash exposed). | | +| Defer tool choice, lock the discipline | Phase 1 commits to schema + gate; the model_id/checkpoint_hash fields are filled honestly per generation. Tool consolidation in Phase 5. | ✓ | + +**User's choice:** Defer tool choice, lock the discipline. + +### Sub-question C: how the curation gate refuses unreviewed assets + +| Option | Description | Selected | +|--------|-------------|----------| +| Sidecar JSON + CI validator | Each asset requires a sibling `name.provenance.json` carrying all 6 provenance fields plus reviewed:true and reviewedBy. CI walks the tree, fails build on any missing/invalid sidecar. | (locked at minimum-viable level after pushback) | +| Curated-pending two-stage | Generated assets land in `/assets-pending/`; curator script promotes to `/assets/` while writing a CURATION-LOG.md entry. | | +| Manifest-as-source-of-truth | Single `/assets/manifest.json` lists every shipped asset with full provenance + reviewer. | | +| Pre-commit hook + manifest | Combines manifest with a Git pre-commit hook that refuses to add files under `/assets/` without manifest entries. | | + +**User's choice:** *(rejected the framing)* "We are vastly overcomplicating this. When I said I wanted AI generated assets I figured that would be just something Claude could spit out. It isn't overly important and I don't really care all this much." + +**Notes:** Locked the *minimum viable* shape from option 1 (sidecar + CI validator) without the `reviewed` ceremony — just the 6 provenance fields + a sample refused asset proving the gate works. No curator workflow, no two-stage, no pre-commit hook, no CURATION-LOG.md. Saved a feedback memory ("avoid overengineering foundations") to recalibrate the rest of the discussion. + +--- + +## Save Schema v1 Scope + +| Option | Description | Selected | +|--------|-------------|----------| +| Minimal: just what Phase 2 needs | v1 carries only Season 1 fields. Real v1→v2 migration in Phase 4. Honest minimum, exercises the migration framework on real player data. | ✓ | +| Structural: full 7-Season shape with empty defaults | v1 already has slots for Roothold, currentSeason, storyFlags, knownFragments, all defaulting to zero/null. Less migration churn, but designing for code that doesn't exist yet. | | +| Hybrid: Phase 2 fields + a `_extensions` bucket | Typed `_extensions: Record` for forward writes. Pragmatic but invites schema drift. | | + +**User's choice:** Minimal: just what Phase 2 needs. + +**Notes:** Round-trip migration test in Phase 1 will use a synthetic v0 → v1 demo migration to prove the chain works end-to-end. First real migration ships in Phase 4. + +--- + +## Doctrine Docs Concreteness + +| Option | Description | Selected | +|--------|-------------|----------| +| Principle-level: the rest-state contract | Doc answers what 'rest state' means, what the finite Roothold ceiling is tied to, what tonal register the coda lives in. No final scene text. | ✓ | +| Treatment-level: with the binary-choice scene | Principle-level + actual final scene treatment: binary-choice prompt text, both ending paragraphs, Lura's final line, credits/coda screen. Eliminates 7 phases of drift risk at the cost of authoring the climax in Phase 1. | | +| Principle + 'do not violate' list | Principle-level plus an explicit list of patterns Phase 2–7 must NOT introduce. Cheaper than full treatment but still gives later phases a hard wall. | | + +**User's choice:** Principle-level: the rest-state contract. + +**Notes:** Anti-FOMO doctrine was not put to choice — it's a consolidation of constraints already scattered across PROJECT.md / REQUIREMENTS.md / CLAUDE.md / SUMMARY.md banner concerns; Claude can write that without further input. Both doctrine docs land in `.planning/`. No CI/lint enforcement — doctrine is referenced at design reviews, not enforced by code. + +--- + +## Project Scaffold Layout + +| Option | Description | Selected | +|--------|-------------|----------| +| BigQty wrapper around break_eternity.js | Build the typed wrapper in Phase 1 so Phase 2 starts using it immediately. | | +| Empty Zustand store skeleton | A `src/store/` with the bridge pattern stubbed (selectors, no state). | | +| Tick scheduler / monotonic clock | The pure simulation tick loop with monotonic-only time injection. Phase 2's CORE-11 anchors on this. | | +| None — stop at success criteria | Phase 1 ships exactly what the 5 success criteria demand and nothing more. Phase 2 builds BigQty, the store, the tick loop as its first tasks. | ✓ | + +**User's choice:** None — stop at success criteria. + +**Notes:** Cleanest scope — Phase 1 stays honest as "land retrofit-hostile decisions only." Phase 2 owns BigQty, Zustand store contents, tick scheduler. The boundary directories (`src/sim/`, `src/render/`, `src/ui/`) still need to exist in Phase 1 so the ESLint boundary rule has clean targets to enforce. + +--- + +## Claude's Discretion + +- ESLint boundary plugin choice (`eslint-plugin-boundaries` vs `eslint-plugin-import`'s `no-restricted-paths`). +- Save checksum algorithm (CRC32, simple hash, SHA-1) — any deterministic, fast hash. +- Migration registry shape (chain of named functions, registry object). +- `idb` wrapper API surface inside `src/save/`. +- Vitest + Playwright config. +- Where Zod content schemas live and how the build step is invoked (Vite plugin vs separate npm script). +- Specific images / prompts / seeds for the 10–20 north-star generations (user accepts/rejects). + +--- + +## Deferred Ideas + +- AI vendor lock-in / model pinning → early Phase 5. +- `BigQty` wrapper around break_eternity.js → Phase 2 first task. +- Empty Zustand store skeleton → Phase 2. +- Tick scheduler / monotonic clock → Phase 2 (CORE-11). +- Season 7 treatment-level details (binary-choice scene text, Lura's final line, coda screen) → Phase 7. +- Anti-FOMO lint rule on UX strings → explicitly rejected. +- Curator workflow / two-stage asset promotion / pre-commit hook on assets → explicitly rejected. +- Visual regression testing across asset library → PIPE-04, Phase 8.