Files
josh 39563f6934 docs(01): plan phase 1 — 7 plans across 3 waves, verified after 1 revision
Wave 1: Plan 01 (scaffold + test infra)
Wave 2: Plans 02 (eslint firewall), 03 (save layer), 04 (content pipeline),
        05 (asset provenance — autonomous:false human-curate checkpoint),
        06 (doctrine docs)
Wave 3: Plan 07 (CI workflow)

All 16 Phase-1 REQ-IDs covered. Plan-checker found 4 blockers + 6 warnings
on first pass; revision iteration 1 landed all 10 fixes; iteration 2
returned VERIFICATION PASSED. Two orchestrator judgment calls during
revision: (1) implement CORE-04 localStorage fallback in Phase 1 (the
literal requirement and ROADMAP success criterion #2 both call for it),
(2) reclassify STRY-09 as vacuously satisfied in Phase 1.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 23:09:08 -04:00

18 KiB
Raw Permalink Blame History

phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
phase plan type wave depends_on files_modified autonomous requirements must_haves
01 01 execute 1
package.json
package-lock.json
tsconfig.json
vite.config.ts
vitest.config.ts
playwright.config.ts
src/sim/.gitkeep
src/render/.gitkeep
src/ui/.gitkeep
src/save/.gitkeep
src/content/.gitkeep
src/audio/.gitkeep
src/store/.gitkeep
content/.gitkeep
content/dialogue/.gitkeep
content/seasons/.gitkeep
assets/.gitkeep
.gitignore
true
CORE-01
truths artifacts key_links
Game scaffold builds without errors via `npm run build`
Phaser 4 + React 19 + Vite + TypeScript template is installed and runnable via `npm run dev`
All seven firewall directories (sim, render, ui, save, content, audio, store) exist under src/
All Phase-1 dependencies (idb, lz-string, zod, crc-32, gray-matter, yaml, inkjs, eslint-plugin-boundaries, vitest, @playwright/test, happy-dom, fake-indexeddb, inklecate) are installed at the verified versions
package.json declares all scripts that downstream plans will rely on (lint, test, validate:assets, compile:ink, ci) — stubs allowed
Vitest can find and run a sentinel test that asserts `1+1===2`
path provides contains
package.json Phase-1 dependencies + scripts (dev, build, lint, test, validate:assets, compile:ink, ci) "vitest"
path provides contains
vitest.config.ts Vitest config with happy-dom env (for IndexedDB shim used by save tests) happy-dom
path provides
playwright.config.ts Playwright config (installed only — no specs in Phase 1)
path provides
src/sim/.gitkeep Firewall directory marker for Plan 02 ESLint boundaries rule
path provides
src/save/.gitkeep Save layer directory (Plan 03 fills with implementation)
path provides
content/.gitkeep Repo-root content directory per CONTEXT D-11
path provides
assets/.gitkeep Repo-root assets directory per CONTEXT D-12
from to via pattern
package.json Plan 02, 03, 04, 05, 06 Pre-declared scripts (lint, test, validate:assets, compile:ink) so later plans only fill behaviour, never re-edit script keys "scripts":\s*{[^}]*"validate:assets"
Bootstrap the Phaser 4 + React 19 + Vite + TypeScript scaffold via the official `npm create @phaserjs/game@latest` template, install every Phase-1 dependency at the versions locked in RESEARCH.md, restructure `src/` to expose the seven architectural-firewall directories as siblings to the template-provided `src/game/`, create the repo-root `/content/` and `/assets/` trees, and ship a minimal Vitest + Playwright config plus a sentinel test that proves the test runner works. This plan is the structural prerequisite for every Wave-2 plan: it owns `package.json` scripts wholesale so later parallel plans never touch `package.json`.

Purpose: Without this scaffold there is no project. Without exposing the seven firewall directories Plan 02's ESLint boundaries rule has nothing to lint against. Without the pre-declared scripts and Vitest config Plans 03, 04, 05, 06 cannot run their tests in parallel without colliding on package.json.

Output: A buildable, runnable Phaser 4 scaffold with the firewall directory skeleton, all Phase-1 deps installed, and the test infrastructure ready for Wave 2 to drop test files into.

<execution_context> @$HOME/.claude/get-shit-done/workflows/execute-plan.md @$HOME/.claude/get-shit-done/templates/summary.md </execution_context>

@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/01-foundations-and-doctrine/01-CONTEXT.md @.planning/phases/01-foundations-and-doctrine/01-RESEARCH.md @CLAUDE.md Task 1: Scaffold Phaser 4 official template + restructure src/ + install Phase-1 deps package.json, package-lock.json, tsconfig.json, .gitignore, src/sim/.gitkeep, src/render/.gitkeep, src/ui/.gitkeep, src/save/.gitkeep, src/content/.gitkeep, src/audio/.gitkeep, src/store/.gitkeep, content/.gitkeep, content/dialogue/.gitkeep, content/seasons/.gitkeep, assets/.gitkeep - .planning/phases/01-foundations-and-doctrine/01-CONTEXT.md (D-10, D-11, D-12 — scaffold layout, repo-root /content/ and /assets/, single package) - .planning/phases/01-foundations-and-doctrine/01-RESEARCH.md § "Standard Stack" (verified versions table) and § "Recommended Project Structure" - CLAUDE.md "Stack" section (locked versions) Run the official Phaser 4 template scaffold and merge it into the current repo (which already contains `.git/`, `.planning/`, `.claude/`, and `CLAUDE.md`). The repo cwd is `c:\Users\josh1\Documents\Code\TheLastGarden\` and must remain so — do not nest the template in a subdirectory.
**Step 1 — Bootstrap into a temp dir, then copy in:**
```bash
# Run from a parent directory or temp location
cd "$TMPDIR" || cd /tmp
npm create @phaserjs/game@latest tlg-template -- --template react-ts --yes 2>&1 | tail -20
# If --template/--yes flags are not supported by create-game, run interactively and choose:
#   "React + Vite + TypeScript"
# Then copy everything except .git into the repo root:
cp -r tlg-template/{src,public,*.json,*.ts,*.html,*.md,.eslintrc*,.gitignore,vite.config.*} c:/Users/josh1/Documents/Code/TheLastGarden/ 2>&1 || true
rm -rf tlg-template
```
If the template does not provide non-interactive flags, scaffold interactively in a temp dir and then copy.

**Step 2 — Install Phase-1 production deps (versions per RESEARCH.md verified 2026-05-08):**
```bash
cd c:/Users/josh1/Documents/Code/TheLastGarden
npm install idb@^8.0.3 lz-string@^1.5.0 zod@^4.4.3 crc-32@^1.2.2 gray-matter@^4.0.3 yaml@^2.8.4 inkjs@^2.4.0
```

**Step 3 — Install Phase-1 dev deps (note: `fake-indexeddb` is required by Plan 03's IDB tests — happy-dom does not ship IndexedDB; install it here in Plan 01 so Plan 03 Task 2 can `import 'fake-indexeddb/auto'` without re-running install):**
```bash
npm install -D vitest@^4.1.5 @vitest/ui happy-dom fake-indexeddb@^6 @playwright/test@^1.59.1 eslint-plugin-boundaries@^6.0.2 inklecate@^1.8.1
```

**Step 4 — Create the seven firewall directories with .gitkeep markers (per RESEARCH Open Question #3, .gitkeep is the recommendation):**
```bash
mkdir -p src/sim src/render src/ui src/save src/content src/audio src/store
touch src/sim/.gitkeep src/render/.gitkeep src/ui/.gitkeep src/save/.gitkeep src/content/.gitkeep src/audio/.gitkeep src/store/.gitkeep
```

**Step 5 — Create the repo-root /content/ and /assets/ trees (per CONTEXT D-11, D-12):**
```bash
mkdir -p content/dialogue content/seasons assets
touch content/.gitkeep content/dialogue/.gitkeep content/seasons/.gitkeep assets/.gitkeep
```

**Step 6 — Edit `package.json` to add ALL scripts that downstream plans need.** Use the Edit tool to set the `scripts` block to include exactly these keys (preserve any template-provided `dev`/`build`/`preview` entries; add the rest):
```json
{
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview",
    "lint": "eslint . --max-warnings 0",
    "test": "vitest run --passWithNoTests=false",
    "test:watch": "vitest",
    "validate:assets": "node scripts/validate-assets.mjs",
    "compile:ink": "echo \"[compile:ink] no .ink files yet — Phase 2 will populate /content/dialogue/\" && exit 0",
    "ci": "npm run lint && npm run test && npm run validate:assets && npm run build"
  }
}
```
Per CONTEXT D-08 RESEARCH § "Pattern 4 — Ink files in Phase 1", `compile:ink` is a no-op stub in Phase 1; Phase 2 will replace it with `inklecate -o src/content/compiled-ink/ content/dialogue/*.ink`.

Per RESEARCH § "Common Pitfalls (CI / Tooling Specific)" CI Pitfall B, the test script MUST include `--passWithNoTests=false`; CI Pitfall C: lint MUST include `--max-warnings 0`.

**Step 7 — Verify `tsconfig.json` has `"strict": true`.** The template should provide it; if not, add it under `compilerOptions`. Per CLAUDE.md "Code Style", TypeScript strict is mandatory.

**Step 8 — Verify `.gitignore` contains `node_modules/`, `dist/`, `coverage/`.** Add if missing.

**Step 9 — Commit with message `chore(01-01): scaffold Phaser 4 template + Phase-1 deps + firewall directories`.** Stage only the files this task touched; do NOT `git add -A` (the repo also has `.planning/` files from upstream that are tracked separately).
npm run build && test -d src/sim && test -d src/render && test -d src/ui && test -d src/save && test -d src/content && test -d src/audio && test -d src/store && test -d content && test -d assets && node -e "const p=require('./package.json'); for (const k of ['dev','build','lint','test','validate:assets','compile:ink','ci']) if (!p.scripts[k]) { console.error('missing script: '+k); process.exit(1); } console.log('all scripts present')" - `package.json` exists at repo root and contains `"phaser"`, `"react"`, `"react-dom"`, `"vite"`, `"typescript"`, `"idb"`, `"lz-string"`, `"zod"`, `"crc-32"`, `"gray-matter"`, `"yaml"`, `"inkjs"`, `"vitest"`, `"@playwright/test"`, `"eslint-plugin-boundaries"`, `"happy-dom"`, `"fake-indexeddb"`, `"inklecate"` somewhere in dependencies or devDependencies — verify with `grep -E '"(phaser|idb|lz-string|zod|crc-32|gray-matter|yaml|inkjs|vitest|eslint-plugin-boundaries|happy-dom|fake-indexeddb|inklecate)"' package.json | wc -l` returns at least 13. - All 7 firewall directories exist as directories: `test -d src/sim && test -d src/render && test -d src/ui && test -d src/save && test -d src/content && test -d src/audio && test -d src/store` exits 0. - All 7 firewall directories contain `.gitkeep`: `for d in sim render ui save content audio store; do test -f src/$d/.gitkeep || exit 1; done`. - Repo-root `/content/` and `/assets/` exist: `test -d content && test -d content/dialogue && test -d content/seasons && test -d assets`. - `package.json` scripts block contains ALL of: `dev`, `build`, `preview`, `lint`, `test`, `test:watch`, `validate:assets`, `compile:ink`, `ci` — verify with `node -e "const p=require('./package.json'); ['dev','build','preview','lint','test','test:watch','validate:assets','compile:ink','ci'].forEach(k=>{ if(!p.scripts[k]) throw new Error('missing '+k); })"` exits 0. - `npm run build` exits 0 and produces a `dist/` directory. - `tsconfig.json` contains `"strict": true` — verify with `grep -q '"strict"\\s*:\\s*true' tsconfig.json`. - The template's existing `src/main.tsx`, `src/App.tsx`, `src/PhaserGame.tsx` are preserved (untouched) — verify with `test -f src/main.tsx && test -f src/App.tsx`. Phaser 4 template scaffolded into the repo root, all Phase-1 deps installed at the verified versions (including `fake-indexeddb@^6` for Plan 03's IDB tests), all 7 firewall directories created with `.gitkeep`, repo-root `/content/` and `/assets/` trees created, `package.json` has all downstream-required scripts pre-declared, `npm run build` succeeds, commit landed. Task 2: Configure Vitest (happy-dom) + Playwright (install only) + sentinel test vitest.config.ts, playwright.config.ts, src/__sentinel__.test.ts - .planning/phases/01-foundations-and-doctrine/01-RESEARCH.md § "Validation Architecture" (Vitest framework table; happy-dom for IndexedDB shim) and § "Wave 0 Gaps" (the test stub list) - .planning/phases/01-foundations-and-doctrine/01-VALIDATION.md § "Test Infrastructure" - package.json (verify vitest + happy-dom + @playwright/test installed by Task 1) Wave 0 deliverable per RESEARCH § Validation Architecture: stand up Vitest + Playwright config so Wave 2 plans can drop `*.test.ts` files into `src/save/`, `src/content/`, `scripts/` and have them auto-discovered.
**Step 1 — Create `vitest.config.ts`** with happy-dom environment (so `src/save/db.test.ts` in Plan 03 can use `idb` against the happy-dom IndexedDB shim — RESEARCH explicitly calls for this). Use the Write tool with this exact content:
```typescript
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    environment: 'happy-dom',
    include: ['src/**/*.test.ts', 'scripts/**/*.test.ts'],
    passWithNoTests: false,
    globals: false,
  },
});
```

**Step 2 — Create `playwright.config.ts`** with an empty `testDir` pointing at a not-yet-existing `tests/e2e/` directory. Phase 1 installs Playwright but ships no specs (per RESEARCH Standard Stack and CONTEXT — first spec is Phase 2 PIPE-07). Use Write tool:
```typescript
import { defineConfig } from '@playwright/test';

export default defineConfig({
  testDir: 'tests/e2e',
  // Phase 1: no specs yet. First spec lands in Phase 2 (PIPE-07).
  // This config exists so Plan 01 proves Playwright is installed and configured.
  use: { baseURL: 'http://localhost:5173' },
  webServer: {
    command: 'npm run dev',
    url: 'http://localhost:5173',
    reuseExistingServer: true,
    timeout: 30_000,
  },
});
```

**Step 3 — Create a sentinel Vitest test** at `src/__sentinel__.test.ts` that proves the runner works end-to-end. This test will be deleted in Phase 2 (or earlier) once real tests exist; it exists in Phase 1 only to prove `npm test` is wired correctly so Wave 2 plans can rely on it. Use Write tool:
```typescript
import { describe, it, expect } from 'vitest';

describe('phase-1 test infrastructure sentinel', () => {
  it('vitest is wired and the happy-dom environment is active', () => {
    expect(1 + 1).toBe(2);
    // happy-dom provides `window` in the test env, which save tests will rely on
    // for IndexedDB. Assert it exists so Plan 03 can trust the env.
    expect(typeof globalThis.window).toBe('object');
  });
});
```

**Step 4 — Verify the test runs:** `npm test` should produce a green run with exactly 1 test passing.

**Step 5 — Verify Playwright is wired:** `npx playwright --version` should print a version string starting with `1.59`.

**Step 6 — Commit `chore(01-01): wire Vitest (happy-dom) and Playwright config + sentinel test`.**
npm test && npx playwright --version - `vitest.config.ts` exists at repo root and contains `happy-dom` and `passWithNoTests: false` — verify with `grep -q "environment: 'happy-dom'" vitest.config.ts && grep -q "passWithNoTests: false" vitest.config.ts`. - `playwright.config.ts` exists at repo root and references `testDir: 'tests/e2e'` — verify with `grep -q "testDir: 'tests/e2e'" playwright.config.ts`. - `src/__sentinel__.test.ts` exists and contains a passing test — verify with `npm test 2>&1 | grep -E '✓|passed' | head -5`. - `npm test` exits 0 with at least 1 test passing. - `npx playwright --version` prints a version string matching `^Version 1\\.59\\.`. - The sentinel test asserts both `1+1===2` AND that `window` exists (proving happy-dom is active) — verify with `grep -q "globalThis.window" src/__sentinel__.test.ts`. Vitest configured with happy-dom env and `passWithNoTests:false`; Playwright config installed (no specs); sentinel test passes proving the runner works; `npm test` returns green; commit landed.

<threat_model> No security-relevant code in this plan; this is scaffold + dev-tooling configuration only. The two threat-model entries identified for Phase 1 (save tampering, malformed Base64 import DoS) are addressed by Plan 03. The npm install supply-chain consideration is mitigated by package-lock.json being committed — verified by test -f package-lock.json in acceptance. </threat_model>

- `npm run build` succeeds (smoke test for CORE-01). - `npm test` runs and the sentinel test passes (smoke test for the test infrastructure). - All seven firewall directories exist (structural prerequisite for Plan 02). - `package.json` has every script downstream plans require — `lint`, `test`, `validate:assets`, `compile:ink`, `ci` — so Plans 0206 only need to add config files and source files, not edit `package.json`.

<success_criteria>

  • Phaser 4 + React 19 + Vite + TS scaffold builds and runs.
  • src/{sim,render,ui,save,content,audio,store}/ exist with .gitkeep.
  • Repo-root /content/ and /assets/ exist.
  • All Phase-1 dependencies installed at versions verified in RESEARCH.md (including fake-indexeddb@^6 for Plan 03 IDB tests).
  • Vitest + Playwright configured; sentinel test passes; npm test is green.
  • package.json scripts pre-declared for the entire plan set: dev, build, preview, lint, test, validate:assets, compile:ink, ci. </success_criteria>
After completion, create `.planning/phases/01-foundations-and-doctrine/01-01-SUMMARY.md` documenting: - Final dependency versions installed (may differ slightly from RESEARCH if `npm install` resolved a newer patch). - The exact `package.json` `scripts` block as written (so Wave-2 executors can verify their assumptions). - Any drift from the template (e.g., did the template ship Vite 6, 7, or 8? did it ship a legacy `.eslintrc.cjs` or already-flat `eslint.config.js`?) — this drift is critical context for Plan 02. - Sentinel test command and current pass status.