# Self-check — before you say a born-owned game is done

Answer every line. **Where something is not done, write that it is not done.** A false green here is
worse than a gap: the whole claim of this tool is that what it tells a designer is true.

`node tools/verify.mjs <gameDir>` covers rows marked ⚙ automatically. The rest need you to look.

---

## It runs

- [ ] The game boots with **no console errors** under `serve.mjs --shell`.
- [ ] The game boots on a **plain static server too**, with DevTune nowhere — the contracts are
      identity functions and nothing depends on them.
- [ ] A person can tell what to do within five seconds. Controls are on screen.
- [ ] ⚙ three.js is pinned to `0.160.x` and the `?pump` block is still in `index.html`.

## It is owned

- [ ] ⚙ `✓ BORN OWNED`, **0 fatal**.
- [ ] Every warning the checker printed is one you **decided to accept**, not one you skipped.
- [ ] At least one **movement/feel** system is owned and read every frame.
- [ ] Each owned value is an **input you typed**, not an output the game computes.
- [ ] Ranges are declared **only where you mean them**. None was added to make the UI look nicer.
- [ ] Colours live in a `thing()` of their own.
- [ ] ⚙ **No mega-group bind** — never `bind(id, this.group|root|world|level)` (FATAL `bind-mega-group`). Bind each mesh.
- [ ] ⚙ **Imports stay in the serve sandbox** — pack paths resolve under the game or `product/medium|vendor` (FATAL `import-outside-serve`).

## It is honest

- [ ] Every `readAt` describes a boundary the game **actually has**. Nothing was invented to look
      complete.
- [ ] Nothing owned is fake-live: turn any dial and either something changes this frame, or the row
      says `SPAWN ONLY` / `NEXT WAVE`.
- [ ] **PD1 mid-flight:** change a dial without reload — feel systems re-read (packs do this every
      step). Automated witness: monorepo `product/tools/pd1-live.test.mjs`.
- [ ] **PD2 layers:** feel is namespaced (`physics.*` / `movement.*` / `camera.*` / game systems) —
      no central `CONFIG` import bag.
- [ ] **PD3 snapshot:** if you load a feel JSON, merge into existing settings objects
      (`medium/feel-snapshot.js`) — do not replace the object identity.
- [ ] Exactly one piece of code resolves each overlap. No system writes a transform another owns.
- [ ] Instance `state` passed to `bind()` is the game's **own live record**, by reference, with its
      own field names. Nothing was renamed or derived for presentation.

## It survives

- [ ] Turn a dial in the desk → **the game changes** (or the row says it defers, and the next spawn
      changes).
- [ ] Press **`K`** → the toast names the file and the line.
- [ ] The **source file on disk** now holds the new number, as a one-line diff with comments and
      alignment intact.
- [ ] **Reload with nothing read from the desk** → the game boots at the kept value.

## What you could not own

Write it down. This is the most useful thing in the report.

- [ ] Values you deliberately left unowned, and why.
- [ ] Anything the substrate had no way to express.
- [ ] Anything you were unsure about and guessed at.
