# SPRINT 14 — THE YARD EDITOR: SITES ARE DATA, NOW MAKE THEM MAKEABLE

*Sprint 13 ended with the game looking like itself: the garden matters, the
night looks like a night, the front door onboards a stranger, and the audit
tells the truth. 362/0/0, live at partly.party/hardyards. Sprint 14 builds the
thing every future branch needs: an in-browser editor that turns "sites are
data" into "John builds a yard the same day he builds its assets." Every piece
already exists — site loading, raycast picking, validateSite, the audit and
garden engines, the shared wind builder. This sprint is assembly, not
invention. Read docs/MANUAL.md first if you haven't — it's new, and it's the
cookbook this editor automates.*

Baseline: selftest **362/0/0**. Keep it green; mutation-check anything you'd
call coverage. The editor is a TOOL with a UI — its internals don't need
`(dt,t)` determinism, but its EXPORT does: same yard in, byte-identical JSON
out (stable key order, pretty-printed), or site diffs become unreviewable.

## Gate 1 — THE EDITOR CORE (A owns)

`web/world/editor.html` (+ `js/editor.js`) — it ships with the game (it's
web/, it deploys; a public "build a yard" toy is a feature, not a leak — no
secrets live in site JSON).
1. Load: start from any existing site or an empty template (flat yard + fence
   ring + garden bed at origin). Import = the same `loadSite`/`createWorld`
   path the game uses — the editor renders the REAL dressed world, not a
   diagram.
2. Place / drag / delete on the ground plane via raycast: posts, trees
   (species from the existing GLB set), structures (house, shed, carport),
   the garden bed, the gnome and props. Placement writes the SAME named-key
   site-JSON shapes the loader reads — no parallel schema. Drag = live
   re-dress of that entry (cheap: re-dress the one object, not the world).
3. Export: canonical JSON to clipboard/download — stable key order, comments
   preserved via `_design`/`_why` fields the author fills in a side panel
   (the repo expects levels to carry their design notes; make the field
   visible, not buried).
4. Validation is LIVE: `validateSite` runs on every edit; errors render in the
   panel, not the console. An invalid yard exports with a loud banner in the
   JSON (`"_INVALID"` key) so it can't sneak into data/sites clean.
5. Round-trip assert (a.test): template → place minimal rig-able yard →
   export → `loadSite` the export → world builds, anchors adopt, enum passes.
   Editor bugs must not be able to produce a yard the game can't boot.
6. Night hookup stays manual and documented: a site becomes playable when a
   week.js NIGHTS entry names it (MANUAL.md site cookbook step 6) — the
   editor's export panel SAYS this so nobody thinks export = shipped.

## Gate 2 — THE LIVE SCORE (B + C; the editor tells you if the yard is a game)

1. **B — "SCORE IT":** one button runs the audit gauntlet against the edited
   yard in-page: winnable lines at $80 (funnel ON, header says so), cheapest
   honest line, held-vs-bare garden separation (gardenfly), margin flags on
   knife-edge corners (the 15% rule). Results as a card, not console text.
   It's the same engines — `site_audit`/`gardenfly` already run in a browser;
   feed them the in-memory site object instead of a fetched JSON. Slow is
   fine (seconds, on demand); wrong is not: the score must go through
   `windForSite()` and the real commit→attach chain — the editor must never
   grow its own private harness (Sprint 13's whole lesson).
2. **C — wind authoring:** place/rotate/drag the venturi (axis drawn as a
   LINE through the gap, both ends — it's mod π and the editor should show
   that), gain/radius sliders, tree-shelter cones rendered as translucent
   volumes. Plus a wind-field overlay: arrows/streaks sampling `speedAt`
   across the yard at a chosen storm+time, so an author SEES where the funnel
   screams before D has to feel it. Deterministic sampling, same seed path as
   the game.
3. **B + C shared assert:** the editor's scored wind and the game's played
   wind are the same numbers — one probe point, one storm second, exact match
   pinned. Two harnesses, one number, by construction this time.

## Gate 3 — THE PALETTE PROVES IT (E builds, D authors)

1. **E — the placeable set, audited:** every GLB the editor offers must carry
   its extras honestly (rating_hint, collateral, collateral_key) — audit the
   current set, fix gaps in the factory, and add TWO new props built for
   temptation: pick from the trampoline (typed honestly in the enum this
   time), the kids' swing set (two honest posts + a crossbar that is NOT an
   anchor), or a second tree species with a different branch ladder. Each
   ships with baked reasoning, a wreck if priceable, and your
   negative-control assert discipline.
2. **D — author a yard COLD, editor only:** no JSON hand-editing, no console.
   Build a complete third yard (your design instincts, any theme the palette
   supports), score it with B's button until it's winnable-but-mean, name it,
   export it, wire its night in a scratch branch, play it. File the entire
   experience in THREADS: every place the editor fought you is gate-1/2
   feedback; every place it sang is proof. **The yard you make is site_03
   CANDIDATE** — it ships only if gate 4 picks the more-sites branch, but its
   existence makes that branch nearly free.
3. **D — pool nit while you're in:** the phantom-sail seam (A took the view
   half and filed it — re-test at gate-3 time; if A's fix landed, verify;
   if not, it's your repro that keeps it honest).

## Gate 4 — JOHN: PLAY, THEN CHOOSE (eight sprints standing)

partly.party/hardyards — five nights, three sentences in THREADS. Then, with
the editor in hand, the branch decision Sprint 12 deferred:
- **Reputation / warranty** (DESIGN.md's consequence loop; the invoice exists
  to hang it off)
- **More sites** (D's site_03 candidate is sitting right there; the editor
  makes a fourth and fifth cheap)
- **Heatwave days** (the slow-pressure half of the design; sun-arc coverage,
  a different puzzle entirely)
Nobody builds any of the three this sprint. The editor serves all of them.

Pool, spread by ownership: B's invoice line for the beyond-saving night
(offer accepted S13); bench-vs-UI residual cause (open; margin rule stands
in); bare-beds-win-nights-2-3 (gate-4 material — do NOT tune it this sprint);
dev-line visibility default (A, one look).

```
gate 1: editor loads/places/drags/exports; round-trip pinned; live validation
gate 2: SCORE IT runs the real engines through the real chain; wind authoring
        visual; editor-vs-game wind pinned exact
gate 3: palette extras audited + two temptation props; D authors site_03
        candidate cold and files the experience
gate 4: John's three sentences + the branch, chosen in THREADS
```
