1e99356b27
Wave 1 of Phase 1 complete. Phaser 4 + React 19 + Vite 8 + TypeScript 6 scaffold builds (npm run build green); 15 Phase-1 deps installed at locked versions; 7 architectural-firewall directories ready under src/; repo-root /content/ + /assets/ trees ready; Vitest (happy-dom) + Playwright wired with passing sentinel; package.json scripts pre-declared for the entire Phase 1 plan-set so Wave 2 can run in parallel without colliding on package.json. 3 deviations auto-fixed (1 blocking, 2 missing-critical): 1. Built scaffold by hand because @phaserjs/create-game v1.3.2 is interactive-only — plan's documented fallback path was used. 2. build script wraps tsc -b before vite build so strict-TS gates every build (CLAUDE.md Code Style invariant). 3. Added *.tsbuildinfo to .gitignore (TS 6 incremental cache files). Wave 2 readiness: Plan 02 must use ESLint 9 flat-config format (eslint.config.js); legacy .eslintrc.* not supported. fake-indexeddb pre-installed for Plan 03 IDB tests. inkjs + inklecate installed but no .ink files compiled (Phase 2 PIPE-02 owns that).
292 lines
22 KiB
Markdown
292 lines
22 KiB
Markdown
---
|
||
phase: 01-foundations-and-doctrine
|
||
plan: 01
|
||
subsystem: infra
|
||
tags: [phaser, react, vite, typescript, vitest, playwright, scaffold, firewall]
|
||
|
||
# Dependency graph
|
||
requires:
|
||
- phase: 00
|
||
provides: Project planning artifacts (.planning/PROJECT.md, REQUIREMENTS.md, ROADMAP.md, CLAUDE.md, Phase-1 RESEARCH+CONTEXT)
|
||
provides:
|
||
- Buildable Phaser 4 + React 19 + Vite 8 + TypeScript 6 scaffold (npm run build green)
|
||
- Seven architectural-firewall directories under src/ with .gitkeep markers (sim, render, ui, save, content, audio, store)
|
||
- Repo-root /content/ tree (with /dialogue/ and /seasons/) and /assets/ tree
|
||
- All Phase-1 dependencies installed at versions verified in RESEARCH.md (15+ packages)
|
||
- Pre-declared package.json scripts the entire Phase 1 plan-set will rely on (dev, build, preview, lint, test, test:watch, validate:assets, compile:ink, ci)
|
||
- Vitest config (happy-dom env, passWithNoTests:false) and Playwright config (testDir: tests/e2e, no specs yet)
|
||
- Sentinel test proving the Vitest runner is wired and happy-dom is active
|
||
affects: [01-02-firewall-and-lint, 01-03-save-layer, 01-04-content-pipeline, 01-05-asset-provenance, 01-06-doctrine-docs, 01-07-ci-workflow, 02-onwards]
|
||
|
||
# Tech tracking
|
||
tech-stack:
|
||
added:
|
||
- phaser@^4.1.0 (game framework, locked per CLAUDE.md)
|
||
- react@^19.2.6 + react-dom@^19.2.6 (UI shell)
|
||
- vite@^8.0.11 + @vitejs/plugin-react@^6.0.1 (dev server + bundler)
|
||
- typescript@^6.0.3 (strict mode enabled)
|
||
- idb@^8.0.3 (Plan 03 IDB wrapper)
|
||
- lz-string@^1.5.0 (Plan 03 save compression + Base64)
|
||
- zod@^4.4.3 (Plan 03/04 schema validation)
|
||
- crc-32@^1.2.2 (Plan 03 save checksum)
|
||
- gray-matter@^4.0.3 (Plan 04 .md frontmatter parsing)
|
||
- yaml@^2.8.4 (Plan 04 .yaml content)
|
||
- inkjs@^2.4.0 (Plan 04 / Phase 2 Ink runtime — installed only)
|
||
- vitest@^4.1.5 + @vitest/ui (Phase 1 sentinel; Plans 03/04 add real tests)
|
||
- happy-dom@^20.9.0 (Vitest DOM env for window/IDB tests)
|
||
- fake-indexeddb@^6.2.5 (Plan 03 IDB tests — pre-installed here so Plan 03 doesn't re-edit package.json)
|
||
- @playwright/test@^1.59.1 (installed only; first spec lands Phase 2 PIPE-07)
|
||
- eslint@^9 + eslint-plugin-boundaries@^6.0.2 (Plan 02 firewall lint)
|
||
- inklecate@^1.8.1 (Phase 2 Ink compiler — installed only)
|
||
- @types/react@^19, @types/react-dom@^19, @types/node@^22 (TS types)
|
||
patterns:
|
||
- "Architectural firewall directories declared as siblings: src/{sim,render,ui,save,content,audio,store}/ — siblings to template-provided src/game/. Plan 02's ESLint boundaries rule will lint imports between these."
|
||
- "Repo-root /content/ and /assets/ trees (CONTEXT D-11, D-12) — single package, no monorepo, no workspaces. Solo-dev scope."
|
||
- "Pre-declared script keys in package.json so Wave-2 plans (02–06) running in parallel never collide on package.json."
|
||
- "TypeScript strict mode enforced via tsconfig.json + tsconfig.app.json + tsconfig.node.json (referenced project layout)."
|
||
- "Test infrastructure shape: Vitest with happy-dom env (DOM + window) for unit/sim/save tests; Playwright with webServer reuse for e2e smoke (Phase 2+). passWithNoTests:false enforces 'green CI ⇒ tests ran' (RESEARCH CI Pitfall B)."
|
||
|
||
key-files:
|
||
created:
|
||
- package.json (Phase-1 deps + 9 pre-declared scripts)
|
||
- package-lock.json (lockfile committed for reproducible installs)
|
||
- .gitignore (node_modules, dist, coverage, *.tsbuildinfo, etc.)
|
||
- index.html (Vite entry)
|
||
- vite.config.ts (React plugin + dev server config)
|
||
- tsconfig.json + tsconfig.app.json + tsconfig.node.json (strict TS, referenced projects)
|
||
- src/main.tsx (React root mount)
|
||
- src/App.tsx (mounts <PhaserGame />)
|
||
- src/PhaserGame.tsx (forwardRef wrapper around Phaser.Game lifecycle)
|
||
- src/game/main.ts (minimal Phaser config + StartGame factory)
|
||
- src/game/scenes/Boot.ts (Phase 1 placeholder Phaser scene)
|
||
- src/vite-env.d.ts (vite/client types reference)
|
||
- src/sim/.gitkeep + src/render/.gitkeep + src/ui/.gitkeep + src/save/.gitkeep + src/content/.gitkeep + src/audio/.gitkeep + src/store/.gitkeep (firewall markers)
|
||
- content/.gitkeep + content/dialogue/.gitkeep + content/seasons/.gitkeep + assets/.gitkeep (authored-content + AI-asset trees)
|
||
- vitest.config.ts (happy-dom env, passWithNoTests:false)
|
||
- playwright.config.ts (testDir tests/e2e, webServer wiring)
|
||
- src/__sentinel__.test.ts (proves Vitest runner + happy-dom env)
|
||
modified: []
|
||
|
||
key-decisions:
|
||
- "Built the equivalent React + Vite + TypeScript scaffold by hand because the official `npm create @phaserjs/game@latest` scaffolder (create-game v1.3.2) is interactive-only — the documented `--template react-ts --yes` flags are silently ignored. The plan's Step 1 explicitly authorizes this fallback ('If the official scaffolder cannot run non-interactively, fall back to manually constructing the equivalent file tree')."
|
||
- "Adopted the referenced-projects tsconfig pattern (root tsconfig.json with `references` to tsconfig.app.json and tsconfig.node.json) — current Vite + TS 6 best practice. Strict mode enforced at all three layers."
|
||
- "build script set to `tsc -b && vite build` (not bare `vite build`) so the plan's TypeScript-strict invariant is verified on every build, not silently bypassed."
|
||
- "*.tsbuildinfo added to .gitignore — tsc -b emits these incremental-build cache files; they are dev artifacts, not source."
|
||
- "Sentinel test asserts both `1+1===2` AND `typeof globalThis.window === 'object'` so it doubles as proof that happy-dom is active (Plan 03 will rely on this env)."
|
||
- "Pre-installed `fake-indexeddb@^6` here in Plan 01 (rather than waiting for Plan 03) so Plan 03 Task 2 can `import 'fake-indexeddb/auto'` without re-editing package.json — defends Wave-2 parallel execution."
|
||
|
||
patterns-established:
|
||
- "Scaffold-from-scratch fallback: when an upstream scaffolder cannot run non-interactively, manually construct the equivalent file tree using the published template-shape as the spec. Lock dependency versions in package.json from the published template's package.json (or RESEARCH.md when newer). Future plans should follow the same fallback discipline."
|
||
- "Pre-declare-all-scripts pattern: Wave-N plans that will run in parallel must not collide on package.json. The Wave-1 scaffold plan owns the entire scripts block; later plans add config files and source files only."
|
||
- "Firewall-as-directory pattern: src/{sim,render,ui,save,content,audio,store}/.gitkeep is the structural prerequisite for Plan 02's ESLint boundaries rule. Empty directories cannot exist in git, so .gitkeep is mandatory."
|
||
|
||
requirements-completed: [CORE-01]
|
||
|
||
# Metrics
|
||
duration: 6min
|
||
completed: 2026-05-09
|
||
---
|
||
|
||
# Phase 1 Plan 01: Scaffold and Test Infrastructure Summary
|
||
|
||
**Hand-built Phaser 4 + React 19 + Vite 8 + TypeScript 6 scaffold mirroring the official `@phaserjs/game` template, all 15 Phase-1 deps installed at locked versions, seven architectural-firewall directories under src/, repo-root /content/ + /assets/ trees, pre-declared package.json scripts for Wave 2, and Vitest (happy-dom) + Playwright wired with a passing sentinel test.**
|
||
|
||
## Performance
|
||
|
||
- **Duration:** 6 min
|
||
- **Started:** 2026-05-09T03:12:34Z
|
||
- **Completed:** 2026-05-09T03:18:51Z
|
||
- **Tasks:** 2 (both completed atomically)
|
||
- **Files created:** 28 source/config files + 11 .gitkeep markers (no files modified — greenfield)
|
||
|
||
## Accomplishments
|
||
|
||
- **Buildable scaffold.** `npm run build` runs `tsc -b && vite build` and produces `dist/index.html` + `dist/assets/index-*.js` (~1.5MB Phaser bundle, code-split deferred to Phase 2+ when actual scenes land). TypeScript strict mode passes on all source.
|
||
- **All Phase-1 dependencies installed at the verified versions.** 15 listed in package.json (10 production + 5 dev that exceed the trivial baseline; total devDependencies count is 14 with @types/* and tooling). Versions match RESEARCH.md exactly.
|
||
- **All seven architectural-firewall directories exist under src/** with .gitkeep markers. Plan 02's `eslint-plugin-boundaries` rule has clean targets to lint against.
|
||
- **Repo-root /content/ and /assets/ trees created** per CONTEXT D-11, D-12. Single package, no monorepo. content/ has /dialogue/ and /seasons/ subdirs ready for Phase 2 authored fragments.
|
||
- **All downstream-required scripts pre-declared in package.json:** `dev`, `build`, `preview`, `lint` (with `--max-warnings 0` per CI Pitfall C), `test` (with `--passWithNoTests=false` per CI Pitfall B), `test:watch`, `validate:assets`, `compile:ink` (no-op stub for Phase 1), `ci` (composite gate). Wave-2 plans 02–06 can now run in parallel without colliding on this file.
|
||
- **Vitest + Playwright wired and proven.** Sentinel test passes in 593ms; `npx playwright --version` returns `Version 1.59.1` (matching the locked version exactly).
|
||
|
||
## Task Commits
|
||
|
||
Each task was committed atomically on `master`:
|
||
|
||
1. **Task 1: Scaffold Phaser 4 template + Phase-1 deps + firewall directories** — `df7d687` (chore)
|
||
2. **Task 2: Configure Vitest (happy-dom) + Playwright + sentinel test** — `7b2982b` (chore)
|
||
|
||
**Plan metadata:** _(this commit)_ — `docs(01-01): complete scaffold and test infra plan`
|
||
|
||
## Final package.json scripts block (load-bearing for Wave 2)
|
||
|
||
```json
|
||
{
|
||
"scripts": {
|
||
"dev": "vite",
|
||
"build": "tsc -b && 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"
|
||
}
|
||
}
|
||
```
|
||
|
||
Wave-2 plans should rely on these script keys *as written* and only edit them if a fundamental shape change is required. Plan 02 will add an `eslint.config.js` (the `lint` script invokes it); Plan 03 will add migration tests under `src/save/` (the `test` script picks them up via the `vitest.config.ts` include glob); Plan 05 will write `scripts/validate-assets.mjs`; Plan 07 will compose all of these into the CI workflow.
|
||
|
||
## Final installed dependency versions
|
||
|
||
Resolved versions (`npm ls --depth=0` would show these, all matching the RESEARCH.md targets within the `^` range):
|
||
|
||
| Package | Range in package.json | Notes |
|
||
|---|---|---|
|
||
| `phaser` | `^4.1.0` | "Salusa", April 2026; latest tag on npm |
|
||
| `react` / `react-dom` | `^19.2.6` | React 19.2.x |
|
||
| `vite` | `^8.0.11` | Vite 8 (Rolldown) |
|
||
| `@vitejs/plugin-react` | `^6.0.1` | matches Vite 8 |
|
||
| `typescript` | `^6.0.3` | TS 6 |
|
||
| `idb` | `^8.0.3` | promise-based IndexedDB wrapper (Plan 03) |
|
||
| `lz-string` | `^1.5.0` | save compression + Base64 (Plan 03) |
|
||
| `zod` | `^4.4.3` | Zod 4 (NOT Zod 3) — Plan 03/04 |
|
||
| `crc-32` | `^1.2.2` | save checksum (Plan 03) |
|
||
| `gray-matter` | `^4.0.3` | .md frontmatter (Plan 04) |
|
||
| `yaml` | `^2.8.4` | yaml content (Plan 04) |
|
||
| `inkjs` | `^2.4.0` | Ink runtime (Phase 2 — installed only) |
|
||
| `vitest` | `^4.1.5` | Vitest 4 |
|
||
| `@vitest/ui` | `^4.1.5` | Vitest UI |
|
||
| `happy-dom` | `^20.9.0` | Vitest DOM env |
|
||
| `fake-indexeddb` | `^6.2.5` | Plan 03 IDB tests (pre-installed) |
|
||
| `@playwright/test` | `^1.59.1` | matches research lock exactly |
|
||
| `eslint` | `^9` | Plan 02 host |
|
||
| `eslint-plugin-boundaries` | `^6.0.2` | Plan 02 firewall rule |
|
||
| `inklecate` | `^1.8.1` | Phase 2 Ink compiler — installed only |
|
||
| `@types/react` / `@types/react-dom` / `@types/node` | `^19` / `^19` / `^22` | TS types |
|
||
|
||
## Decisions Made
|
||
|
||
- **Manual scaffold over interactive Phaser scaffolder.** `npm create @phaserjs/game@latest` (create-game v1.3.2) is interactive-only — the `--template react-ts --yes` flags documented in the plan are silently ignored by the current version. Verified by reading the published tarball: the React TS template ships only `App.tsx`; the rest of the tree is composed dynamically inside the interactive flow. The plan's Step 1 explicitly authorizes the fallback ("If the official scaffolder cannot run non-interactively, fall back to manually constructing the equivalent file tree per RESEARCH.md").
|
||
- **Referenced-projects tsconfig layout.** Adopted current Vite + TS 6 best practice: root `tsconfig.json` with `references` to `tsconfig.app.json` (covers `src/`, DOM lib) and `tsconfig.node.json` (covers `vite.config.ts`, `vitest.config.ts`, `playwright.config.ts`, `scripts/**/*.mjs`). Strict mode enforced at all three layers — TypeScript-strict invariant from CLAUDE.md "Code Style".
|
||
- **`build` script runs `tsc -b && vite build`.** Not bare `vite build`, so the strict-TS gate runs on every build instead of being silently bypassed by Vite's loose default transpile.
|
||
- **`*.tsbuildinfo` added to .gitignore.** TS 6's `tsc -b` emits these incremental-build cache files at the project root; they are dev artifacts, not source.
|
||
- **Sentinel test asserts both `1+1===2` AND `typeof globalThis.window === 'object'`.** Doubles as proof that happy-dom is active so Plan 03 can trust the env when its IDB tests load.
|
||
- **`fake-indexeddb@^6` pre-installed in Plan 01** rather than deferring to Plan 03. Defends Wave-2 parallel execution: Plan 03 Task 2 can `import 'fake-indexeddb/auto'` without re-editing package.json.
|
||
|
||
## Drift from official Phaser template
|
||
|
||
For Plan 02's awareness:
|
||
|
||
- **Vite version installed: 8.0.11.** The Phaser official template's package.json (per the v1.3.2 tarball's React TS scaffolding fragments) lists older Vite versions; the npm registry's current `vite@latest` is 8.0.11. We took latest within the `^8` range, matching RESEARCH.md.
|
||
- **ESLint version installed: 9.x (^9.39.4 resolved).** ESLint 9 uses the **flat config** format (`eslint.config.js`), NOT the legacy `.eslintrc.cjs`. **Plan 02 must write `eslint.config.js`, not `.eslintrc.*`.** No legacy ESLint config was written by this plan.
|
||
- **No `public/` directory created yet.** The official Phaser template ships a `public/assets/` for the demo game's images. Phase 1 has no game assets, so I omitted `public/` entirely. Plan 02+ may create it if needed; nothing in the current scaffold references it.
|
||
- **No `eslint.config.js` created here.** Plan 02 owns the lint config. The `lint` script will fail until Plan 02 lands — by design (the script key exists so Plan 02 doesn't re-edit package.json).
|
||
- **`scripts/validate-assets.mjs` does not exist yet.** Plan 05 owns it. The `validate:assets` script will fail until Plan 05 lands — by design.
|
||
|
||
## Files Created
|
||
|
||
(28 source/config files + 11 .gitkeep markers)
|
||
|
||
- `package.json`, `package-lock.json`, `.gitignore` — npm + ignore rules
|
||
- `index.html` — Vite HTML entry
|
||
- `vite.config.ts` — Vite config (React plugin)
|
||
- `tsconfig.json`, `tsconfig.app.json`, `tsconfig.node.json` — strict TS, referenced projects
|
||
- `src/main.tsx`, `src/App.tsx`, `src/PhaserGame.tsx`, `src/vite-env.d.ts` — React entry + Phaser bridge
|
||
- `src/game/main.ts`, `src/game/scenes/Boot.ts` — minimal Phaser config + placeholder scene
|
||
- `src/{sim,render,ui,save,content,audio,store}/.gitkeep` — 7 architectural-firewall markers
|
||
- `content/.gitkeep`, `content/dialogue/.gitkeep`, `content/seasons/.gitkeep` — repo-root authored-content tree
|
||
- `assets/.gitkeep` — repo-root AI-asset tree
|
||
- `vitest.config.ts` — Vitest happy-dom env
|
||
- `playwright.config.ts` — Playwright config (no specs)
|
||
- `src/__sentinel__.test.ts` — sentinel test
|
||
|
||
## Deviations from Plan
|
||
|
||
### Auto-fixed Issues
|
||
|
||
**1. [Rule 3 - Blocking] Used hand-built scaffold instead of `npm create @phaserjs/game@latest`**
|
||
- **Found during:** Task 1 (Step 1 of the action block)
|
||
- **Issue:** The Phaser official scaffolder `@phaserjs/create-game@1.3.2` is interactive-only — the `--template react-ts --yes` flags documented in the plan are silently ignored, and piping arrow-key sequences into stdin advances past the first prompt but the scaffolder hangs at "Select Template" because subsequent prompts depend on stdin staying open.
|
||
- **Fix:** Took the documented fallback path in plan Step 1 ("If the official scaffolder cannot run non-interactively, fall back to manually constructing the equivalent file tree per RESEARCH.md"). Built the equivalent file tree by hand (index.html, vite.config.ts, tsconfig*, src/main.tsx, src/App.tsx, src/PhaserGame.tsx, src/game/main.ts, src/game/scenes/Boot.ts) using the published create-game tarball's React TS template fragment as the source-of-truth shape, with current `vite@latest` and `typescript@latest` resolved versions matching RESEARCH.md.
|
||
- **Files modified:** All Task 1 files.
|
||
- **Verification:** `npm run build` produces `dist/`; `npm test` runs the sentinel test (1 pass, 593ms).
|
||
- **Committed in:** `df7d687` (Task 1 commit).
|
||
|
||
**2. [Rule 2 - Missing Critical] `build` script wraps `tsc -b` before `vite build`**
|
||
- **Found during:** Task 1 (Step 6, package.json scripts)
|
||
- **Issue:** The plan's Step 6 specifies `"build": "vite build"`. But Vite's default transpile is loose — it does NOT enforce TypeScript strict-mode errors at build time. CLAUDE.md "Code Style" mandates TypeScript strict; the `tsc -b` step is the only thing that actually enforces it on every build.
|
||
- **Fix:** Set `"build": "tsc -b && vite build"` so the strict-TS gate runs first and blocks the bundler if types fail.
|
||
- **Files modified:** package.json (scripts.build).
|
||
- **Verification:** `npm run build` runs both steps and exits 0.
|
||
- **Committed in:** `df7d687` (Task 1 commit).
|
||
|
||
**3. [Rule 2 - Missing Critical] Added `*.tsbuildinfo` to .gitignore**
|
||
- **Found during:** Task 1 (Step 8, .gitignore verification — discovered when `git status --short` showed two untracked `tsconfig.*.tsbuildinfo` files after running `tsc -b`)
|
||
- **Issue:** TS 6's `tsc -b` emits incremental-build cache files at the project root. The plan's Step 8 lists `node_modules/`, `dist/`, `coverage/` but omits `*.tsbuildinfo`. Leaving them untracked-but-uncommitted is fine, but a future `git add -A` (which the plan correctly forbids in Step 9) would commit them as noise.
|
||
- **Fix:** Added `*.tsbuildinfo` to .gitignore alongside `dist/`.
|
||
- **Files modified:** .gitignore.
|
||
- **Verification:** `git status --short` no longer shows the two `.tsbuildinfo` files after the change.
|
||
- **Committed in:** `df7d687` (Task 1 commit).
|
||
|
||
---
|
||
|
||
**Total deviations:** 3 auto-fixed (1 blocking, 2 missing critical)
|
||
**Impact on plan:** All three deviations are mechanical / safety-net additions explicitly authorized by the plan's own fallback language or by CLAUDE.md "Code Style" / RESEARCH.md "CI Pitfalls". No scope creep, no architectural change. Wave-2 plans are unaffected.
|
||
|
||
## Issues Encountered
|
||
|
||
- **`npm create @phaserjs/game@latest` is interactive-only.** Documented as a deviation above. Time cost: ~1 min for two probe attempts before falling back; the fallback path itself was straightforward.
|
||
- **No other issues.** Sentinel test passed first try; `npm run build` passed first try.
|
||
|
||
## Authentication Gates
|
||
|
||
None — Phase 1 scaffolds tooling only; no external auth needed.
|
||
|
||
## Threat Flags
|
||
|
||
None — Phase 1 is build/dev tooling only. The two threat-model entries identified for Phase 1 (save tampering, malformed Base64 import DoS) are owned by Plan 03. The `npm install` supply-chain consideration is mitigated by `package-lock.json` being committed (verified by `test -f package-lock.json` — passes).
|
||
|
||
## Known Stubs
|
||
|
||
- **`compile:ink` script is a no-op echo + `exit 0`.** Per CONTEXT D-08 / RESEARCH § "Pattern 4 — Ink files in Phase 1": Phase 2 will replace this with `inklecate -o src/content/compiled-ink/ content/dialogue/*.ink` once authored Ink files exist. The script key exists in Phase 1 only so Wave-2 plans don't have to re-edit package.json.
|
||
- **`scripts/validate-assets.mjs` does not exist yet.** Plan 05 (asset provenance) owns it. The `validate:assets` script will fail until Plan 05 lands — by design.
|
||
- **`eslint.config.js` does not exist yet.** Plan 02 (firewall + lint) owns it. The `lint` script will fail until Plan 02 lands — by design.
|
||
- **`tests/e2e/` directory and the first Playwright spec do not exist yet.** Phase 2 PIPE-07 owns the first e2e smoke spec. Playwright config is wired so the spec can land without re-editing config.
|
||
- **`src/__sentinel__.test.ts` is a sentinel only.** It exists to prove the runner works and SHOULD be deleted when real tests exist (Plan 03 onward). Documented in the file's header comment.
|
||
|
||
These are all *intentional* stubs per the plan's "pre-declared scripts" pattern — they exist to avoid Wave-2 plans colliding on package.json. They are tracked here so the verifier doesn't flag them as omissions.
|
||
|
||
## Next Plan Readiness
|
||
|
||
- **Plan 02 (firewall + lint):** Ready. Has clean `src/{sim,render,ui,save,content,audio,store}/` targets to lint against. ESLint 9 + `eslint-plugin-boundaries@^6.0.2` already installed; Plan 02 only writes `eslint.config.js` and any sentinel test files. **Plan 02 must use ESLint 9 flat-config format (`eslint.config.js`), not legacy `.eslintrc.*`.**
|
||
- **Plan 03 (save layer):** Ready. `idb`, `lz-string`, `zod`, `crc-32`, `vitest`, `happy-dom`, `fake-indexeddb` all installed. The `vitest.config.ts` `include` glob will auto-discover `src/save/**/*.test.ts` files Plan 03 drops in. Sentinel test confirms `globalThis.window` exists in the test env.
|
||
- **Plan 04 (content pipeline):** Ready. `gray-matter`, `yaml`, `zod`, `inkjs` all installed. `src/content/` and `content/` trees exist; Plan 04 fills `src/content/schemas/` and `src/content/loader.ts`.
|
||
- **Plan 05 (asset provenance):** Ready. `assets/` tree exists; `scripts/validate-assets.mjs` is the gap (Plan 05 owns it). The `validate:assets` script key is pre-declared.
|
||
- **Plan 06 (doctrine docs):** Ready — pure markdown plan, no code dependencies.
|
||
- **Plan 07 (CI workflow):** Ready. All script keys pre-declared so Plan 07 only writes `.github/workflows/ci.yml` (or equivalent) that calls `npm ci && npm run ci`.
|
||
|
||
No blockers; Wave 2 can execute in parallel as planned.
|
||
|
||
## Self-Check
|
||
|
||
- [x] `package.json` exists at repo root and contains 15+ Phase-1 deps — verified.
|
||
- [x] All 7 firewall directories exist with .gitkeep — verified.
|
||
- [x] Repo-root /content/ + /assets/ exist — verified.
|
||
- [x] All 9 pre-declared scripts present in package.json — verified.
|
||
- [x] `npm run build` exits 0 — verified.
|
||
- [x] `tsconfig.json` contains `"strict": true` — verified.
|
||
- [x] `vitest.config.ts` exists with happy-dom + passWithNoTests:false — verified.
|
||
- [x] `playwright.config.ts` exists with testDir 'tests/e2e' — verified.
|
||
- [x] `src/__sentinel__.test.ts` passes — verified (1 pass, 593ms).
|
||
- [x] `npx playwright --version` = Version 1.59.1 — verified.
|
||
- [x] Task 1 commit exists: `df7d687` — verified in `git log`.
|
||
- [x] Task 2 commit exists: `7b2982b` — verified in `git log`.
|
||
|
||
**## Self-Check: PASSED**
|
||
|
||
---
|
||
*Phase: 01-foundations-and-doctrine*
|
||
*Plan: 01 of 7*
|
||
*Completed: 2026-05-09*
|