# SPRINT 15 — THE POSTS TELL THE TRUTH, AND THE EDITOR STOPS BEING BATCH

*Sprint 14 built the yard editor and it immediately earned itself: nine bugs
found before anyone authored a yard with it, three of them live on the public
URL. D then authored a complete third yard cold — no JSON, no console — and
it scored winnable-but-mean and played that way. 406/0/0, live at
partly.party/hardyards, editor included.*

*What it also found is a shipped balance bug we deliberately did not patch,
because half the repo's measured numbers are standing on it. That's gate 1.*

Read THREADS from the last [I] entry. Baseline **406/0/0**; keep it green,
mutation-check anything you'd call coverage.

## Gate 1 — THE POSTS TELL THE TRUTH (A rules · E supplies · B re-measures · D re-plays)

The factory bakes `rating_hint = 0.9` on `sail_post`'s `top_anchor`. Every
post in every shipped site is a plain JSON entry with **no `node`**, so
`adoptAnchor` never runs and they all default to **1.00**. Every honest post
in the game is 10% stronger than E designed it, and always has been.

This is a gate and not a patch because A's `separation` block pins measured hp
through the real chain, B's audit tables predict against it, and D's played
verdicts sit on it. Move the number and all three move together, in order:

1. **A rules FIRST, before anyone measures:** is the honest post 0.90 (E's
   design intent reaches the sim) or 1.00 (the shipped value becomes canon and
   E's baked hint is corrected to match)? Both are defensible — 1.00 is what
   every played verdict in THREADS actually measured, and "the value we shipped
   and balanced against is the real one" is a legitimate ruling. What is NOT
   defensible is leaving the factory and the sim disagreeing. **Whichever way
   it goes, the mechanism must be fixed so a baked hint can never again fail to
   reach a JSON-declared anchor silently** — that's the actual bug, and it will
   bite the next asset the same way (`tie_off`, `collateral`, anything).
2. **E:** make the factory agree with the ruling and pin it — an assert that a
   JSON-declared anchor of a type the factory rates carries that rating at
   runtime. Your S14 audit rules (no silent anchors, no unpriced collateral)
   are the model; this is the third of that family.
3. **B:** re-measure everything that moved. If the ruling is 0.90 every post
   line in both shipped yards gets weaker — expect the separation pin, the
   winnable-lines tables, and the night-4/5 affordability story to shift, and
   post the deltas as a table. Propose retunes with evidence; A rules.
4. **D:** re-play the affected nights and say whether the change is FELT. If
   0.90 makes the honest line stop holding, that's a design change wearing a
   bugfix's clothes and you're the one who says so.

## Gate 2 — THE EDITOR STOPS BEING BATCH (B owns; D judges)

D's verdict: the 75–82 s fully-blocked score "made the editor batch, not
iterative — I scored once and shipped that run rather than tuning." That is
the difference between a tool you author WITH and a tool you check work AGAINST.
1. **B:** make the score interruptible and legible. In priority order — a
   progress tick that actually paints (D says this may matter more than raw
   speed), then yielding so the page stays responsive, then speed itself
   (the cost scales like C(n,4) in candidate quads — a coarse pass that ranks
   before it flies is likely worth more than micro-optimising the sim).
   Whatever you do, the numbers must not change: pin the current site_02 and
   site_03 scores before you start and reproduce them after.
2. **B + C:** one storm picker, not two independently-defaulted ones (D scored
   the wildnight while viewing the southerly — the exact class of
   two-harnesses-disagreeing this repo keeps paying for, now inside one page).
3. **D:** re-author or re-tune a yard with the faster loop and say whether it
   changed how you work. That's the acceptance test, same as gate 3.2 was.

## Gate 3 — THE EDITOR'S HONEST EDGES (A owns, mostly)

D's friction list, by owner, all seen in anger:
1. **A:** number fields commit on blur only — Enter does nothing, and a house
   sat on the garden bed while the panel read the new value. Commit on Enter.
2. **A:** objects place outside the fence silently and the yard still reads
   VALID. Either validate the yard bounds or draw the boundary — a yard that
   lies about being valid is the one thing this editor must never do.
3. **A:** zoom is wheel-only (no keyboard, no pinch).
4. **A+B:** no `separation` field exists in the editor, while B's score card
   says a shipping site should pin one. Either add it to the SITE panel or
   rule that separation is an integration-time concern and say so on the card.
5. **A:** honour `tie_off: false` at the palette layer if you offer anchors by
   name from GLB nodes (E's flag; the runtime half is already honoured).

## Gate 4 — JOHN PLAYS, THEN CHOOSES (nine sprints)

**⚡ THE BRANCH HALF OF THIS GATE IS RESOLVED (2026-07-18, integration checkout):**
this sprint plan and a TEETH sprint plan were written in parallel forks the
same day, and John ruled while they were being reconciled — **all three
branches, sequenced: teeth → sites/clients → heatwaves.** ROADMAP.md (new,
the growth canon) carries the arcs; SPRINT16.md carries TEETH pre-speced,
firing when this sprint integrates. The gates above stand exactly as written
— they re-measure the numbers SPRINT16 pins, which is why 15 runs first.

**The PLAY half stands:** partly.party/hardyards — five nights, three
sentences in THREADS. The fabric key (F) is newly live; night 3's yard has a
sibling now (`site_03_swing_lawn`, inert until SPRINT16 wires it).
- **More sites** — D's `site_03_swing_lawn` is authored, scored and played,
  sitting inert waiting for a NIGHTS entry. This branch is now nearly free.
- **Reputation / warranty** — DESIGN.md's consequence loop; the invoice exists
  to hang it off. Unchanged in cost.
- **Heatwave days** — the slow-pressure half of the design, sun-arc coverage,
  a genuinely different puzzle. Unchanged in cost.
Nobody builds any of the three this sprint.

```
gate 1: the post hint ruled, the mechanism fixed so a baked hint cannot
        silently fail to reach a JSON anchor, both yards re-measured, D re-plays
gate 2: the score paints progress and stays responsive; numbers reproduce
        exactly; one storm picker; D says the loop changed
gate 3: Enter commits, out-of-bounds stops reading VALID, the friction list empty
gate 4: John's three sentences + the branch, in writing
```
