Merge origin/main: S14 lane integration + review fixes; TEETH becomes SPRINT16
Two same-day integrations reconciled: their SPRINT15 (post ruling, editor iterative, honest edges) stands and runs first because it re-measures the numbers TEETH pins; the TEETH plan moves to SPRINT16 with a fires-after-15 banner, its D gate rewired to the landed swing lawn. ROADMAP arc 0 records the fork. THREADS keeps both sides chronologically. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
commit
3dee2a7c83
228
LANE_PROMPTS.md
228
LANE_PROMPTS.md
@ -835,22 +835,102 @@ byte-identical JSON out) even though its UI needn't be.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# SPRINT 15 prompts (teeth — your work follows you)
|
# SPRINT 15 prompts (the posts tell the truth, the editor stops being batch)
|
||||||
|
|
||||||
Same rules: own clone, own branch, rebase onto latest main FIRST
|
Same rules: own clone, own branch, `git fetch origin && git reset --hard
|
||||||
(`git fetch origin && git reset --hard origin/lane/<x>` on a clean tree —
|
origin/lane/<x>` on a clean tree first. **The remote was RENAMED mid-Sprint-14
|
||||||
your local branch is BEHIND after integration fast-forwards). Read
|
— it is `monster/hardyards.git` now, not `monster/shades`. All six checkouts
|
||||||
**ROADMAP.md** (new — the growth canon; John resolved S14's gate 4: all three
|
are already repointed; if a push ever 404s, check for a rename before assuming
|
||||||
branches, sequenced, teeth first), THREADS from the last [I] entry (the
|
loss.** Read docs/MANUAL.md, THREADS' last [I], then SPRINT15.md. Ports: A
|
||||||
fresh-eyes review landed six fixes on main — the fabric key, the divergence
|
8824, B 8825, C 8826, D 8827, E 8828. Baseline **406/0/0**.
|
||||||
break and the pond clamp are news your lane builds on), then SPRINT15.md.
|
|
||||||
Ports: A 8824, B 8825, C 8826, D 8827, E 8828 (untracked launch.json, copy
|
|
||||||
the example). Baseline selftest **409/0/0**. The one-variable rule is law:
|
|
||||||
the new site and the new storm never debut on the same night.
|
|
||||||
|
|
||||||
## Lane A — Sprint 15
|
## Lane A — Sprint 15
|
||||||
> You are Lane A on HARD YARDS, Sprint 15. Rebase onto main, read ROADMAP.md,
|
> You are Lane A on SHADES 3D (the game is HARD YARDS, public at
|
||||||
> THREADS' last [I], then SPRINT15.md. Gate 1 is yours: THE LEDGER. The week
|
> partly.party/hardyards), Sprint 15. Rebase onto main, read docs/MANUAL.md,
|
||||||
|
> THREADS' last [I], then SPRINT15.md. **Gate 1 ruling is yours and comes
|
||||||
|
> FIRST, before anyone measures**: the factory bakes `rating_hint = 0.9` on
|
||||||
|
> sail_post's top_anchor, but JSON-declared posts never run adoptAnchor and
|
||||||
|
> default to 1.00, so every honest post in the shipped game is 10% stronger
|
||||||
|
> than designed. Rule 0.90 (design intent reaches the sim) or 1.00 (the
|
||||||
|
> shipped, balanced-against value becomes canon and E corrects the bake) —
|
||||||
|
> both defensible, and every played verdict in THREADS measured 1.00. Then
|
||||||
|
> fix the MECHANISM either way: a baked hint must never again fail to reach a
|
||||||
|
> JSON-declared anchor silently. Gate 3 is also yours: Enter commits number
|
||||||
|
> fields, out-of-bounds placement must stop reading VALID, zoom beyond the
|
||||||
|
> wheel, and the separation-field question with B. Do NOT start
|
||||||
|
> reputation/site_03/heatwave — gate 4 is John's.
|
||||||
|
|
||||||
|
## Lane B — Sprint 15
|
||||||
|
> You are Lane B on SHADES 3D, Sprint 15. Rebase onto main, read
|
||||||
|
> docs/MANUAL.md, THREADS' last [I], then SPRINT15.md. Gate 2 is yours: D's
|
||||||
|
> verdict is that your 75–82 s fully-blocked SCORE IT "made the editor batch,
|
||||||
|
> not iterative — I scored once and shipped that run rather than tuning."
|
||||||
|
> Fix it in D's priority order: a progress tick that actually paints first
|
||||||
|
> (D thinks that matters more than raw speed), then yielding so the page stays
|
||||||
|
> responsive, then speed (cost scales like C(n,4) in candidate quads — a
|
||||||
|
> coarse ranking pass before flying is likely worth more than micro-optimising
|
||||||
|
> the sim). **Pin the current site_02 and site_03 scores before you start and
|
||||||
|
> reproduce them exactly after** — a faster score that moved a number is a
|
||||||
|
> regression. Also with C: one storm picker, not two independently-defaulted
|
||||||
|
> ones. Gate 1.3: re-measure both yards once A rules the post hint, post the
|
||||||
|
> deltas as a table, propose retunes with evidence.
|
||||||
|
|
||||||
|
## Lane C — Sprint 15
|
||||||
|
> You are Lane C on SHADES 3D, Sprint 15. Rebase onto main, read
|
||||||
|
> docs/MANUAL.md, THREADS' last [I], then SPRINT15.md. Lighter sprint for you
|
||||||
|
> by design — gate 1 is a post-rating ruling and gate 2 is B's performance
|
||||||
|
> work. Yours: (1) with B, collapse the two independently-defaulted storm
|
||||||
|
> pickers into one shared selection (D scored the wildnight while viewing the
|
||||||
|
> southerly — two harnesses disagreeing inside a single page, which is the
|
||||||
|
> exact class of bug this repo keeps paying for). (2) Second-harness B's
|
||||||
|
> re-measure once A rules the post hint: if every post moves 10%, the storm
|
||||||
|
> side should predict the same shift your envelope tool would. (3) Your call
|
||||||
|
> on anything the wind panel revealed that you filed and didn't land — D
|
||||||
|
> called it "the best surface on the page", so if there's polish you wanted,
|
||||||
|
> this is the sprint with room for it.
|
||||||
|
|
||||||
|
## Lane D — Sprint 15
|
||||||
|
> You are Lane D on SHADES 3D, Sprint 15. Rebase onto main, read
|
||||||
|
> docs/MANUAL.md, THREADS' last [I], then SPRINT15.md. Two judgements, both
|
||||||
|
> yours alone. (1) Gate 1.4: once A rules the post hint and B re-measures,
|
||||||
|
> re-play the affected nights and say whether the change is FELT — if 0.90
|
||||||
|
> makes the honest line stop holding, that is a design change wearing a
|
||||||
|
> bugfix's clothes and you are the one who says so. (2) Gate 2.3: re-author or
|
||||||
|
> re-tune a yard with B's faster score loop and say whether it changed how you
|
||||||
|
> work — your "batch, not iterative" line is what bought this sprint, so you
|
||||||
|
> are the acceptance test for the fix. Your `site_03_swing_lawn` stays inert
|
||||||
|
> until gate 4 picks the more-sites branch; don't wire it to a night.
|
||||||
|
|
||||||
|
## Lane E — Sprint 15
|
||||||
|
> You are Lane E on SHADES 3D, Sprint 15. Rebase onto main, read
|
||||||
|
> docs/MANUAL.md, THREADS' last [I], then SPRINT15.md. Gate 1.2 is yours and
|
||||||
|
> it's short: once A rules the sail_post hint (0.90 or 1.00), make the factory
|
||||||
|
> agree, and PIN it — an assert that a JSON-declared anchor of a type the
|
||||||
|
> factory rates carries that rating at runtime. This is the third member of
|
||||||
|
> the family your Sprint 14 audit started (no silent anchors, no unpriced
|
||||||
|
> collateral, and now no baked hint that never arrives), and it is the general
|
||||||
|
> fix for the bug class that shipped both the free carport and the perfect
|
||||||
|
> posts. With the sprint's spare room: your call on palette gaps D hit while
|
||||||
|
> authoring cold — read their gate-3.2 entry and propose what the next yard
|
||||||
|
> needs, with reasoning baked beside the numbers as always.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# SPRINT 16 prompts (teeth — your work follows you) — ⚠️ FIRE ONLY AFTER SPRINT 15 INTEGRATES
|
||||||
|
|
||||||
|
Same rules: own clone, own branch, rebase onto latest main FIRST
|
||||||
|
(`git fetch origin && git reset --hard origin/lane/<x>` on a clean tree).
|
||||||
|
Read **ROADMAP.md** (the growth canon — John resolved the S14/S15 branch
|
||||||
|
question: all three, sequenced, teeth first), THREADS from the last [I],
|
||||||
|
then SPRINT16.md. Ports: A 8824, B 8825, C 8826, D 8827, E 8828. Baseline:
|
||||||
|
whatever Sprint 15 landed (409/0/0 pre-15 + S15's additions — read the [I]).
|
||||||
|
The one-variable rule is law: the new site and the new storm never debut on
|
||||||
|
the same night. Numbers S15's post ruling moved get RE-MEASURED before they
|
||||||
|
get pinned — no pre-ruling number survives into a pin.
|
||||||
|
|
||||||
|
## Lane A — Sprint 16
|
||||||
|
> You are Lane A on HARD YARDS, Sprint 16. Rebase onto main, read ROADMAP.md,
|
||||||
|
> THREADS' last [I], then SPRINT16.md. Gate 1 is yours: THE LEDGER. The week
|
||||||
> records every committed rig (corners, hardware, what broke, what was
|
> records every committed rig (corners, hardware, what broke, what was
|
||||||
> repaired); a corner still broken at dawn books a WARRANTY line on the next
|
> repaired); a corner still broken at dawn books a WARRANTY line on the next
|
||||||
> morning's job sheet — hardware's shop price, off the fee AT QUOTE TIME, so
|
> morning's job sheet — hardware's shop price, off the fee AT QUOTE TIME, so
|
||||||
@ -863,74 +943,72 @@ the new site and the new storm never debut on the same night.
|
|||||||
> a.test: warranty only on unrepaired breaks; quote==settle with a warranty
|
> a.test: warranty only on unrepaired breaks; quote==settle with a warranty
|
||||||
> line; rep untouched on designed losses; clean-week negative control. You
|
> line; rep untouched on designed losses; clean-week negative control. You
|
||||||
> also print C's hail-size and rain lines on the forecast block (their gate
|
> also print C's hail-size and rain lines on the forecast block (their gate
|
||||||
> 3.3 exposes them). Pool: dev-line visibility default, second carry. Do NOT
|
> 3.3 exposes them). Do NOT build the job board — arc 2, and gate 6 aims it.
|
||||||
> build the job board — that's arc 2, and gate 6 aims it.
|
|
||||||
|
|
||||||
## Lane B — Sprint 15
|
## Lane B — Sprint 16
|
||||||
> You are Lane B on HARD YARDS, Sprint 15. Rebase onto main, read ROADMAP.md,
|
> You are Lane B on HARD YARDS, Sprint 16. Rebase onto main, read ROADMAP.md,
|
||||||
> THREADS' last [I] (the review touched YOUR files: the divergence break in
|
> THREADS' last [I], then SPRINT16.md. Gate 2 is yours. (a) THE HEAL: after a
|
||||||
> _checkFailure, the post-flow pond clamp, the F key in your rigging UI, and
|
> divergence break (landed in the fresh-eyes review — read that [I]), non-
|
||||||
> a fixed tautology in your own suite — read the receipts), then SPRINT15.md.
|
> finite node positions reset from the nearest finite neighbour (prev matched
|
||||||
> Gate 2 is yours. (a) THE HEAL: after a divergence break, non-finite node
|
> — verlet must not invent velocity) and non-finite WATER zeroes (a NaN pond
|
||||||
> positions reset from the nearest finite neighbour (prev matched — verlet
|
> re-poisons the heal through the weight term); assert finite within 1 s,
|
||||||
> must not invent velocity); assert finite within 1 s, mutation-proof, and
|
> mutation-proof, and the existing divergence test stays untouched. (b) THE
|
||||||
> the existing divergence test stays untouched. (b) THE RECORD: the chosen
|
> RECORD: the chosen fabric prints in prep summary, invoice, and the verdict
|
||||||
> fabric prints in prep summary, invoice, and the verdict when it mattered —
|
> when it mattered — the F key exists, now the paperwork remembers the bet.
|
||||||
> the F key exists, now the paperwork remembers the bet. (c) THE PIN: site_02
|
> (c) THE PIN, post-ruling numbers only: run gardenfly on site_02 (and the
|
||||||
> declares no separation block and the SCORE IT card calls it out — run
|
> swing lawn if unpinned), pin the honest held-vs-bare separation, assert it
|
||||||
> gardenfly, pin the honest held-vs-bare target, assert it; if the yard
|
> like backyard_01's; if a yard can't separate at $80 that's a FINDING for
|
||||||
> can't separate at $80, that's a FINDING for THREADS, not a fudged pin.
|
> THREADS, not a fudged pin. Pool: the >83 ms determinism bound gets a
|
||||||
> Pool: the >83 ms determinism bound gets a pinning test or a documented
|
> pinning test or a documented waiver.
|
||||||
> waiver; membrane pricing stays parked until rain's drain weight moves.
|
|
||||||
|
|
||||||
## Lane C — Sprint 15
|
## Lane C — Sprint 16
|
||||||
> You are Lane C on HARD YARDS, Sprint 15. Rebase onto main, read ROADMAP.md,
|
> You are Lane C on HARD YARDS, Sprint 16. Rebase onto main, read ROADMAP.md,
|
||||||
> THREADS' last [I], then SPRINT15.md. Gate 3 is yours. (1) STORM_06, the
|
> THREADS' last [I], then SPRINT16.md. Gate 3 is yours. (1) STORM_06, the
|
||||||
> pea-hail soaker: stones under your own 2 mm-weave blocking ruling, heavy
|
> pea-hail soaker: stones under your own 2 mm-weave blocking ruling, heavy
|
||||||
> rain, mild wind — the first night membrane is the RIGHT answer. Cloth must
|
> rain, mild wind — the first night membrane is the RIGHT answer. Cloth must
|
||||||
> leak fine hail all night; membrane must pond (the broom matters); the
|
> leak fine hail all night; membrane must pond (the broom matters); the
|
||||||
> membrane line must be affordable at $80 and MEASURABLY better — gardenfly
|
> membrane line must be affordable at $80 and MEASURABLY better — gardenfly
|
||||||
> and site_audit numbers pinned in your selftest, funnel state in the header.
|
> and site_audit numbers pinned in your selftest, funnel state in the header,
|
||||||
> If cloth still wins, retune until the bet is real: a decoration night is
|
> post-ruling tree only. If cloth still wins, retune until the bet is real: a
|
||||||
> worse than no night. (2) makeStorm(seed): a seeded generator inside
|
> decoration night is worse than no night. (2) makeStorm(seed): a seeded
|
||||||
> authored envelopes, deterministic (same seed → byte-equal def), schema-
|
> generator inside authored envelopes, deterministic (same seed → byte-equal
|
||||||
> valid across 100 seeds, storm_envelope-tested — arc 4's roguelite eats
|
> def), schema-valid across 100 seeds, storm_envelope-tested — arc 4's
|
||||||
> this; no shipped night uses it yet. (3) Expose hail stone size and rain
|
> roguelite eats this; no shipped night uses it yet. (3) Expose hail stone
|
||||||
> rate for the forecast block (A prints them) — bands, not promises. The
|
> size and rain rate for the forecast block (A prints them) — bands, not
|
||||||
> one-variable rule binds you to D: storm_06 flies over a yard the player
|
> promises. The one-variable rule binds you to D: storm_06 flies over a yard
|
||||||
> already knows.
|
> the player already knows.
|
||||||
|
|
||||||
## Lane D — Sprint 15
|
## Lane D — Sprint 16
|
||||||
> You are Lane D on HARD YARDS, Sprint 15. Rebase onto main, read ROADMAP.md,
|
> You are Lane D on HARD YARDS, Sprint 16. Rebase onto main, read ROADMAP.md,
|
||||||
> THREADS' last [I], then SPRINT15.md. Gate 4 is yours and it's the sprint's
|
> THREADS' last [I], then SPRINT16.md. Gate 4 is yours. (1) Your swing lawn
|
||||||
> acceptance test again. (1) site_03 SHIPS this time: author it cold in the
|
> enters the rotation: re-score site_03_swing_lawn on the post-ruling tree
|
||||||
> editor (no JSON hand-editing, no console — the S14 discipline), any theme
|
> with S15's faster loop (the numbers that made it winnable-but-mean may have
|
||||||
> E's palette supports, winnable-but-mean at $80, separation pinned,
|
> moved), fix what moved, wire its NIGHTS entry. (2) The week becomes SIX
|
||||||
> collateral priced, _design/_why filled; file every editor friction in
|
> nights: you own the order and the two new briefs (client flavour is data —
|
||||||
> THREADS. (2) The week becomes SIX nights: you own the NIGHTS order and the
|
> the corner block got a name and a reason; the swing set's kid deserves one
|
||||||
> two new briefs (client flavour is data — the corner block got a name and a
|
> too). One-variable rule: the swing lawn debuts under a storm the player has
|
||||||
> reason; match that bar). One-variable rule: site_03 debuts under a storm
|
> survived; storm_06 flies over a yard they know; never both new at once.
|
||||||
> the player has survived; storm_06 flies over a yard they know; never both
|
> Night 5's beyond-saving arc and going-broke-never-on-the-final-night must
|
||||||
> new at once. Night 5's beyond-saving arc and going-broke-never-on-the-
|
> survive your re-ordering — a.test will tell you. (3) Cold-play all six on
|
||||||
> final-night must survive your re-ordering — a.test will tell you. (3)
|
> one wallet and file the verdict: is a warranty line FAIR when it lands?
|
||||||
> Cold-play all six on one wallet and file the verdict: is a warranty line
|
> Does rep-moves-pay feel earned? Is night 6's bet legible from the forecast
|
||||||
> FAIR when it lands? Does rep-moves-pay feel earned? Is night 6's bet
|
> alone? Your play is gates 1–3's acceptance. Pool: the phantom-sail seam if
|
||||||
> legible from the forecast alone? Your play is gates 1–3's acceptance.
|
> S15 didn't close it.
|
||||||
> Pool: the phantom-sail seam, third sprint — verify A's fix or keep the
|
|
||||||
> repro honest.
|
|
||||||
|
|
||||||
## Lane E — Sprint 15
|
## Lane E — Sprint 16
|
||||||
> You are Lane E on HARD YARDS, Sprint 15. Rebase onto main, read ROADMAP.md,
|
> You are Lane E on HARD YARDS, Sprint 16. Rebase onto main, read ROADMAP.md,
|
||||||
> THREADS' last [I], then SPRINT15.md. Gate 5 is yours: arc 2 needs yards
|
> THREADS' last [I], then SPRINT16.md. Gate 5 is yours: arc 2 needs yards
|
||||||
> this palette cannot dress. Build TWO of three, factory-built, byte-stable,
|
> this palette cannot dress. Build TWO of three, factory-built, byte-stable,
|
||||||
> negative-control-proven (build the wrong one on purpose, watch red): the
|
> negative-control-proven, and every anchor-bearing node passes S15's gate-1
|
||||||
> GLASSHOUSE (collateral apex — priced, wrecked variant, collateral_key
|
> mechanism (a baked hint that can't reach a JSON-declared anchor is the bug
|
||||||
> wired so a SECOND one placed in the editor still bills; nothing about it
|
> class that cost the posts their truth): the GLASSHOUSE (collateral apex —
|
||||||
> adopts as an anchor), the POOL KIT (pool + compliant fence ring where
|
> priced, wrecked variant, collateral_key wired so a SECOND one placed in
|
||||||
> every fence post is honest tie_off:false — adoptAnchor's `?? 1` makes a
|
> the editor still bills; nothing about it adopts as an anchor), the POOL
|
||||||
> silent node the best steel in the game, and the pool yard's whole puzzle
|
> KIT (pool + compliant fence ring where every fence post is honest
|
||||||
> is that the legal tie-offs are in the wrong places), the TRAMPOLINE + tie-
|
> tie_off:false — adoptAnchor's `?? 1` makes a silent node the best steel in
|
||||||
> down kit (if S14's pick didn't land it — typed honestly in the checked
|
> the game, and the pool yard's whole puzzle is that the legal tie-offs are
|
||||||
> enum). Flag D in THREADS as each lands; site_03's theme may want one.
|
> in the wrong places), the TRAMPOLINE + tie-down kit (typed honestly in the
|
||||||
> Axis trap stands: measure exported GLBs in three.js coords, look at the
|
> checked enum; the tie-down is prep's counter to the storm's opening
|
||||||
> render in assetcheck, never trust a docstring about orientation.
|
> projectile, priced like it matters). Flag D in THREADS as each lands. Axis
|
||||||
|
> trap stands: measure exported GLBs in three.js coords, look at the render
|
||||||
|
> in assetcheck, never trust a docstring about orientation.
|
||||||
|
|||||||
@ -27,7 +27,9 @@ No pip, no npm, no build. Python 3.8+ and a browser.
|
|||||||
· `ROADMAP.md` — the growth canon (the arcs from the week to the business)
|
· `ROADMAP.md` — the growth canon (the arcs from the week to the business)
|
||||||
3. `THREADS.md` — the append-only lane log. **The project's memory.** Read the
|
3. `THREADS.md` — the append-only lane log. **The project's memory.** Read the
|
||||||
last few `[I]` integrator entries to know the current state.
|
last few `[I]` integrator entries to know the current state.
|
||||||
4. `SPRINT15.md` — the current sprint (highest-numbered SPRINTn.md wins)
|
4. `SPRINT15.md` — the current sprint (highest-numbered *fired* sprint wins:
|
||||||
|
SPRINT16 is pre-speced TEETH and fires only when 15 integrates — its own
|
||||||
|
header says so)
|
||||||
5. `LANE_PROMPTS.md` — copy-paste prompts per lane, per sprint (bottom = newest)
|
5. `LANE_PROMPTS.md` — copy-paste prompts per lane, per sprint (bottom = newest)
|
||||||
|
|
||||||
## The lane model (how this repo is built)
|
## The lane model (how this repo is built)
|
||||||
@ -67,9 +69,9 @@ Host gitea.partly.party
|
|||||||
Then:
|
Then:
|
||||||
|
|
||||||
```
|
```
|
||||||
git clone git@gitea.partly.party:monster/shades.git ~/Documents/shades
|
git clone git@gitea.partly.party:monster/hardyards.git ~/Documents/shades
|
||||||
for L in A B C D E; do
|
for L in A B C D E; do
|
||||||
git clone git@gitea.partly.party:monster/shades.git ~/Documents/shades-lane$L
|
git clone git@gitea.partly.party:monster/hardyards.git ~/Documents/shades-lane$L
|
||||||
git -C ~/Documents/shades-lane$L checkout -B lane/$(echo $L | tr 'A-Z' 'a-z') origin/lane/$(echo $L | tr 'A-Z' 'a-z')
|
git -C ~/Documents/shades-lane$L checkout -B lane/$(echo $L | tr 'A-Z' 'a-z') origin/lane/$(echo $L | tr 'A-Z' 'a-z')
|
||||||
done
|
done
|
||||||
```
|
```
|
||||||
|
|||||||
27
ROADMAP.md
27
ROADMAP.md
@ -18,8 +18,8 @@ now."
|
|||||||
|
|
||||||
## Where we are (the honest baseline)
|
## Where we are (the honest baseline)
|
||||||
|
|
||||||
Five 90-second nights, two yards, five storms, one wallet, ~15 minutes of
|
Five 90-second nights, two shipped yards (a third — the swing lawn — authored
|
||||||
campaign. Selftest 409/0/0. An editor that makes new yards cheap and scores them
|
and inert), five storms, one wallet, ~15 minutes of campaign. Selftest 409/0/0. An editor that makes new yards cheap and scores them
|
||||||
through the real engines. An economy whose own comments say the balance is
|
through the real engines. An economy whose own comments say the balance is
|
||||||
unmeasured, and a scorecard that says a bare bed reads 82.6 where the best clean
|
unmeasured, and a scorecard that says a bare bed reads 82.6 where the best clean
|
||||||
rig reads 91.3 — **doing nothing scores 90% of doing everything, and that is the
|
rig reads 91.3 — **doing nothing scores 90% of doing everything, and that is the
|
||||||
@ -51,7 +51,16 @@ in the repo; the thinnest thing is consequence.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ARC 1 — TEETH (SPRINT15, speced in full in SPRINT15.md)
|
## ARC 0 — THE TRUE BASELINE (SPRINT15, already speced — the fork's gift)
|
||||||
|
|
||||||
|
*This roadmap and SPRINT15 were written in parallel forks the same day and
|
||||||
|
reconciled: S15's gates (the post rating_hint ruling, the iterative editor
|
||||||
|
score, the honest edges) re-measure the very numbers arc 1 pins, so S15 runs
|
||||||
|
FIRST and TEETH fires as SPRINT16. The fork was the process working — D's
|
||||||
|
cold-authoring pass found a shipped balance bug nobody reasoning from the
|
||||||
|
code would have caught.*
|
||||||
|
|
||||||
|
## ARC 1 — TEETH (SPRINT16, speced in full in SPRINT16.md)
|
||||||
|
|
||||||
*The week gets consequences. Your work follows you.*
|
*The week gets consequences. Your work follows you.*
|
||||||
|
|
||||||
@ -59,11 +68,11 @@ Reputation and warranty hang off the invoice exactly as DESIGN.md drew it: a
|
|||||||
corner of yours that blew and stayed blown books an unpaid warranty line on the
|
corner of yours that blew and stayed blown books an unpaid warranty line on the
|
||||||
next morning's job sheet; a clean night builds the number on the letterhead; the
|
next morning's job sheet; a clean night builds the number on the letterhead; the
|
||||||
number moves what clients pay. The fabric bet gets its paper trail (forecast
|
number moves what clients pay. The fabric bet gets its paper trail (forecast
|
||||||
argues hail size and rain, invoice records the cloth you chose). site_03 finally
|
argues hail size and rain, invoice records the cloth you chose). D's swing lawn
|
||||||
ships, the week becomes six nights, and one of them — C's pea-hail soaker — is
|
enters the rotation, the week becomes six nights, and one of them — C's pea-hail
|
||||||
the first night where the default fabric is the wrong answer. The bare-beds
|
soaker — is the first night where the default fabric is the wrong answer. The
|
||||||
separation fight starts here and does not end until held-vs-bare is a pinned,
|
bare-beds separation fight starts here and does not end until held-vs-bare is a
|
||||||
teeth-bearing number on every shipped site.
|
pinned, teeth-bearing number on every shipped site.
|
||||||
|
|
||||||
## ARC 2 — THE BOOK OF CLIENTS (≈ two sprints)
|
## ARC 2 — THE BOOK OF CLIENTS (≈ two sprints)
|
||||||
|
|
||||||
@ -161,6 +170,6 @@ surcharge and the mudslide entering the debris system waits here, intact.
|
|||||||
named here so nobody half-builds it sooner.
|
named here so nobody half-builds it sooner.
|
||||||
- **Deploy**: tools/deploy_hardyards.sh after every integration; the live site
|
- **Deploy**: tools/deploy_hardyards.sh after every integration; the live site
|
||||||
is currently one sprint behind main and that gap should never exceed one.
|
is currently one sprint behind main and that gap should never exceed one.
|
||||||
- **The sim's debt, tracked**: node-position heal after divergence (SPRINT15
|
- **The sim's debt, tracked**: node-position heal after divergence (SPRINT16
|
||||||
gate 2), the >83 ms frame determinism bound (documented, un-tested), membrane
|
gate 2), the >83 ms frame determinism bound (documented, un-tested), membrane
|
||||||
pricing the day rain's drain weight moves (rigging.js's comment names it).
|
pricing the day rain's drain weight moves (rigging.js's comment names it).
|
||||||
|
|||||||
238
SPRINT15.md
238
SPRINT15.md
@ -1,164 +1,108 @@
|
|||||||
# SPRINT 15 — TEETH: YOUR WORK FOLLOWS YOU
|
# SPRINT 15 — THE POSTS TELL THE TRUTH, AND THE EDITOR STOPS BEING BATCH
|
||||||
|
|
||||||
*Sprint 14 built the editor and the editor built the argument: SCORE IT put the
|
*Sprint 14 built the yard editor and it immediately earned itself: nine bugs
|
||||||
bare-beds number on a card (bare 82.6 vs best clean 91.3) and nobody can unsee
|
found before anyone authored a yard with it, three of them live on the public
|
||||||
it. John played, ruled on gate 4 (ROADMAP.md, 2026-07-18): all three branches,
|
URL. D then authored a complete third yard cold — no JSON, no console — and
|
||||||
sequenced, teeth first. This sprint the week grows consequences — reputation on
|
it scored winnable-but-mean and played that way. 406/0/0, live at
|
||||||
the letterhead, warranty on the job sheet, a sixth night, a third yard, and the
|
partly.party/hardyards, editor included.*
|
||||||
first night where the default fabric is the wrong answer. Baseline selftest
|
|
||||||
**409/0/0** (the fresh-eyes review landed six fixes on main — read THREADS [I]
|
|
||||||
2026-07-18 before you start; the fabric key, the divergence break and the pond
|
|
||||||
clamp are all news your lane may be building on). Keep it green; mutation-check
|
|
||||||
anything you'd call coverage.*
|
|
||||||
|
|
||||||
**The one-variable rule is LAW this sprint (ROADMAP principle 5):** six nights,
|
*What it also found is a shipped balance bug we deliberately did not patch,
|
||||||
exactly one flies the new storm, exactly one is the new site, and they are NOT
|
because half the repo's measured numbers are standing on it. That's gate 1.*
|
||||||
the same night. A player who loses night 6 must be able to say whether the yard
|
|
||||||
beat them or the weather did.
|
|
||||||
|
|
||||||
## Gate 1 — THE LEDGER (A owns: week.js, hud.js surfaces, main.js wiring)
|
Read THREADS from the last [I] entry. Baseline **406/0/0**; keep it green,
|
||||||
|
mutation-check anything you'd call coverage.
|
||||||
|
|
||||||
Reputation and warranty, hung off the paperwork that already exists. No new
|
## Gate 1 — THE POSTS TELL THE TRUTH (A rules · E supplies · B re-measures · D re-plays)
|
||||||
phase, no new sim — this is week-state plus three surfaces telling the truth.
|
|
||||||
|
|
||||||
1. **The work history.** Every committed rig is recorded on the week: corners,
|
The factory bakes `rating_hint = 0.9` on `sail_post`'s `top_anchor`. Every
|
||||||
hardware, effective ratings, what broke, what was repaired by dawn. This is
|
post in every shipped site is a plain JSON entry with **no `node`**, so
|
||||||
data the night already computes — the ledger just keeps it.
|
`adoptAnchor` never runs and they all default to **1.00**. Every honest post
|
||||||
2. **Warranty.** A corner of YOURS that broke and was still broken at dawn books
|
in the game is 10% stronger than E designed it, and always has been.
|
||||||
a warranty item: the NEXT morning's job sheet carries it as a line —
|
|
||||||
"warranty — q3, shackle, no charge to the client" — and its cost (the
|
|
||||||
hardware's shop price, unpaid labour is the point) comes off that night's
|
|
||||||
fee AT QUOTE TIME. week.js's own invariant is non-negotiable: the sheet and
|
|
||||||
the invoice never diverge — the quote already carries the deduction, so
|
|
||||||
settle pays exactly what was quoted. A repair you made mid-storm is NOT a
|
|
||||||
warranty item; riding it out broken is.
|
|
||||||
3. **Reputation.** One number on the letterhead (pick the unit — stars read as
|
|
||||||
client-speak; whatever it is, it appears under the ABN on job sheet AND
|
|
||||||
invoice, E's letterhead contract). Clean night (no breaks, no collateral):
|
|
||||||
up. Warranty item: down. Collateral event: down harder. It MOVES PAY at
|
|
||||||
quote time — a trusted outfit's callout fee multiplier, printed on the
|
|
||||||
sheet, so the player watches their number become money. Start neutral;
|
|
||||||
night 5's beyond-saving garden must NOT cost rep (the flag exists — read it;
|
|
||||||
a designed loss the ledger punishes is the verdict lying again).
|
|
||||||
4. **Aftermath teaches it.** The invoice's verdict line and the end-of-week
|
|
||||||
card both speak rep: a week that ends broke-but-clean and a week that ends
|
|
||||||
rich-with-warranties are different endings and should read as such.
|
|
||||||
5. Tests, a.test: warranty fires only on unrepaired breaks (repaired = no
|
|
||||||
item); quote==settle holds with a warranty line on the sheet; rep never
|
|
||||||
moves on gardenBeyondSaving nights for garden reasons; the multiplier is on
|
|
||||||
the sheet the night it applies. Negative control: a clean five-night week
|
|
||||||
books zero warranty items and ends rep-positive.
|
|
||||||
|
|
||||||
## Gate 2 — THE HEAL + THE PAPER TRAIL + THE PIN (B owns)
|
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. **Divergence heal.** The review landed the break (a NaN corner now lets go,
|
1. **A rules FIRST, before anyone measures:** is the honest post 0.90 (E's
|
||||||
reason:'divergence', production path) — but the freed node then integrates
|
design intent reaches the sim) or 1.00 (the shipped value becomes canon and
|
||||||
from NaN forces and the cloth renders ugly after one. Sanitize on the break:
|
E's baked hint is corrected to match)? Both are defensible — 1.00 is what
|
||||||
any non-finite node position resets from its nearest finite neighbour (or
|
every played verdict in THREADS actually measured, and "the value we shipped
|
||||||
the corner's anchor), prev matched so verlet doesn't invent velocity.
|
and balanced against is the real one" is a legitimate ruling. What is NOT
|
||||||
Assert: poison → break → every node finite within 1 s of sim, render-safe.
|
defensible is leaving the factory and the sim disagreeing. **Whichever way
|
||||||
Mutation: heal off, assert red. The existing divergence test must keep
|
it goes, the mechanism must be fixed so a baked hint can never again fail to
|
||||||
passing untouched — the heal is IN ADDITION to the break, not instead.
|
reach a JSON-declared anchor silently** — that's the actual bug, and it will
|
||||||
2. **Fabric on the paperwork.** The chosen fabric prints in the prep summary,
|
bite the next asset the same way (`tie_off`, `collateral`, anything).
|
||||||
on the invoice, and in the aftermath verdict when it mattered (a membrane
|
2. **E:** make the factory agree with the ruling and pin it — an assert that a
|
||||||
night survived in cloth should say what the leak cost). The FORECAST half is
|
JSON-declared anchor of a type the factory rates carries that rating at
|
||||||
C's (gate 3.3) — yours is that the choice the player made is on the record.
|
runtime. Your S14 audit rules (no silent anchors, no unpriced collateral)
|
||||||
3. **Pin site_02's separation.** The SCORE IT card says NONE PINNED and calls
|
are the model; this is the third of that family.
|
||||||
it out — a shipping site should promise held-vs-bare and be held to it. Run
|
3. **B:** re-measure everything that moved. If the ruling is 0.90 every post
|
||||||
gardenfly, pick the honest target, pin the block in site_02's JSON, assert
|
line in both shipped yards gets weaker — expect the separation pin, the
|
||||||
it like backyard_01's. If the honest answer is "this yard cannot separate
|
winnable-lines tables, and the night-4/5 affordability story to shift, and
|
||||||
held from bare at $80", that is a FINDING about the yard — post it in
|
post the deltas as a table. Propose retunes with evidence; A rules.
|
||||||
THREADS and gate 4's balance fight starts there, not at a fudged pin.
|
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 3 — THE MEMBRANE NIGHT + THE SEEDED STORM (C owns)
|
## Gate 2 — THE EDITOR STOPS BEING BATCH (B owns; D judges)
|
||||||
|
|
||||||
1. **storm_06 — the pea-hail soaker.** Small stones (under the 2 mm-weave
|
D's verdict: the 75–82 s fully-blocked score "made the editor batch, not
|
||||||
ruling's blocking threshold), heavy rain, mild wind. The night the bet
|
iterative — I scored once and shipped that run rather than tuning." That is
|
||||||
flips: cloth leaks fine hail onto the bed all night; membrane stops
|
the difference between a tool you author WITH and a tool you check work AGAINST.
|
||||||
everything and the mild wind means its doubled load is affordable — but it
|
1. **B:** make the score interruptible and legible. In priority order — a
|
||||||
PONDS, so the broom matters. Author it so both lines exist and the membrane
|
progress tick that actually paints (D says this may matter more than raw
|
||||||
line is genuinely better: measure with gardenfly/site_audit (funnel state in
|
speed), then yielding so the page stays responsive, then speed itself
|
||||||
the header, per the discipline), pin membrane-vs-cloth garden separation in
|
(the cost scales like C(n,4) in candidate quads — a coarse pass that ranks
|
||||||
the storm's own selftest, and make sure a $80 wallet affords the membrane
|
before it flies is likely worth more than micro-optimising the sim).
|
||||||
line on the night's site. If the measured numbers say cloth still wins,
|
Whatever you do, the numbers must not change: pin the current site_02 and
|
||||||
retune the hail spectrum until the bet is real — the storm exists to make
|
site_03 scores before you start and reproduce them after.
|
||||||
the F key matter, and a decoration night is worse than no night.
|
2. **B + C:** one storm picker, not two independently-defaulted ones (D scored
|
||||||
2. **makeStorm(seed) — groundwork, not a shipped night.** A seeded generator
|
the wildnight while viewing the southerly — the exact class of
|
||||||
inside authored envelopes (base curve, gust budget, direction change window,
|
two-harnesses-disagreeing this repo keeps paying for, now inside one page).
|
||||||
rain/hail ranges as data), producing storm defs that pass the schema
|
3. **D:** re-author or re-tune a yard with the faster loop and say whether it
|
||||||
validator and the storm_envelope harness. Deterministic from seed —
|
changed how you work. That's the acceptance test, same as gate 3.2 was.
|
||||||
ROADMAP arc 4's roguelite eats this. Selftest: same seed → byte-equal def;
|
|
||||||
100 seeds → all schema-valid, all inside the envelope; a seed that violates
|
|
||||||
the envelope is a red test, not a shrug.
|
|
||||||
3. **The forecast argues the bet.** Hail stone size and rain rate join wind on
|
|
||||||
the job sheet's forecast block (the data is in the storm JSON; A prints
|
|
||||||
what you expose). The band-not-a-promise rule holds — forecast bands, real
|
|
||||||
values inside them.
|
|
||||||
|
|
||||||
## Gate 4 — SITE_03 AND THE SIX-NIGHT WEEK (D owns)
|
## Gate 3 — THE EDITOR'S HONEST EDGES (A owns, mostly)
|
||||||
|
|
||||||
1. **site_03 ships.** Your S14 cold-authoring run never landed a yard — the
|
D's friction list, by owner, all seen in anger:
|
||||||
editor is a sprint older now and SCORE IT prices collateral. Author it
|
1. **A:** number fields commit on blur only — Enter does nothing, and a house
|
||||||
cold (editor only, the S14 discipline), any theme E's palette supports,
|
sat on the garden bed while the panel read the new value. Commit on Enter.
|
||||||
winnable-but-mean at $80, separation pinned, collateral priced, _design/
|
2. **A:** objects place outside the fence silently and the yard still reads
|
||||||
_why filled. File the friction in THREADS — every place the editor fights
|
VALID. Either validate the yard bounds or draw the boundary — a yard that
|
||||||
you is still gate-1/2 feedback one sprint late.
|
lies about being valid is the one thing this editor must never do.
|
||||||
2. **The week becomes six nights.** Wire site_03 and storm_06 into NIGHTS under
|
3. **A:** zoom is wheel-only (no keyboard, no pinch).
|
||||||
the one-variable rule: site_03 debuts on a storm the player has already
|
4. **A+B:** no `separation` field exists in the editor, while B's score card
|
||||||
survived; storm_06 flies over a yard they already know. You own the order
|
says a shipping site should pin one. Either add it to the SITE panel or
|
||||||
and the two briefs (client flavour is data — write clients worth meeting;
|
rule that separation is an integration-time concern and say so on the card.
|
||||||
the corner block got a name and a reason, match that bar). Night 5's
|
5. **A:** honour `tie_off: false` at the palette layer if you offer anchors by
|
||||||
beyond-saving flag and the went-broke arc must both survive re-ordering —
|
name from GLB nodes (E's flag; the runtime half is already honoured).
|
||||||
the a.test week asserts will tell you.
|
|
||||||
3. **Cold-play the whole six**, wallet from night 1, and file the verdict:
|
|
||||||
does a warranty callout read as FAIR when it lands on your sheet? Does rep
|
|
||||||
moving pay feel earned or arbitrary? Is night 6's bet legible from the
|
|
||||||
forecast alone? Your play IS the acceptance test for gates 1–3.
|
|
||||||
4. Pool (yours): the phantom-sail seam re-test, third sprint running — if A's
|
|
||||||
view fix landed, verify and close it in THREADS; if not, your repro keeps
|
|
||||||
it honest.
|
|
||||||
|
|
||||||
## Gate 5 — THE NEXT TEMPTATIONS (E owns)
|
## Gate 4 — JOHN PLAYS, THEN CHOOSES (nine sprints)
|
||||||
|
|
||||||
Arc 2 needs yards this palette cannot dress yet. Two of these three, factory-
|
**⚡ THE BRANCH HALF OF THIS GATE IS RESOLVED (2026-07-18, integration checkout):**
|
||||||
built, honest extras, negative-control asserts (your discipline — build the
|
this sprint plan and a TEETH sprint plan were written in parallel forks the
|
||||||
wrong one on purpose and watch red):
|
same day, and John ruled while they were being reconciled — **all three
|
||||||
1. **The glasshouse** — the collateral apex. Priced high, wreck variant,
|
branches, sequenced: teeth → sites/clients → heatwaves.** ROADMAP.md (new,
|
||||||
collateral_key wired so a second one placed in the editor bills (the
|
the growth canon) carries the arcs; SPRINT16.md carries TEETH pre-speced,
|
||||||
carport's five-sprint lesson is one sprint old). Panes that read as fragile
|
firing when this sprint integrates. The gates above stand exactly as written
|
||||||
at a glance; nothing about it may adopt as an anchor.
|
— they re-measure the numbers SPRINT16 pins, which is why 15 runs first.
|
||||||
2. **The pool kit** — pool + compliant fence ring. The fence posts are the
|
|
||||||
temptation: honest `tie_off:false` (silence is not neutral — adoptAnchor's
|
|
||||||
`?? 1` makes an unrated node the best steel in the game), because the whole
|
|
||||||
point of the pool yard is that the legal tie-offs are all in the wrong
|
|
||||||
places.
|
|
||||||
3. **The trampoline** — if S14's pick didn't land it: typed honestly in the
|
|
||||||
checked enum, plus a tie-down kit prop (the prep-phase counter to the
|
|
||||||
storm's opening projectile, priced like it matters).
|
|
||||||
Flag D in THREADS as each lands — site_03's theme may want one.
|
|
||||||
|
|
||||||
## Gate 6 — JOHN: PLAY, THEN AIM ARC 2
|
**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
|
||||||
Six nights at partly.party/hardyards (deploy after integration — the live gap
|
sibling now (`site_03_swing_lawn`, inert until SPRINT16 wires it).
|
||||||
is one sprint and ROADMAP says it never exceeds that). Three sentences in
|
- **More sites** — D's `site_03_swing_lawn` is authored, scored and played,
|
||||||
THREADS. Then one ruling for arc 2's first sprint: **emergency mid-storm
|
sitting inert waiting for a NIGHTS entry. This branch is now nearly free.
|
||||||
callout or the cowboy audit** — which job type leads THE BOOK OF CLIENTS?
|
- **Reputation / warranty** — DESIGN.md's consequence loop; the invoice exists
|
||||||
|
to hang it off. Unchanged in cost.
|
||||||
Pool, spread by ownership: dev-line visibility default (A, second carry);
|
- **Heatwave days** — the slow-pressure half of the design, sun-arc coverage,
|
||||||
bench-vs-UI residual cause (open since S13; the margin rule stands in);
|
a genuinely different puzzle. Unchanged in cost.
|
||||||
membrane pricing the day rain's drain weight moves (B, rigging.js's comment
|
Nobody builds any of the three this sprint.
|
||||||
names the start); the >83 ms determinism bound gets a pinning test or a
|
|
||||||
documented waiver (B).
|
|
||||||
|
|
||||||
```
|
```
|
||||||
gate 1: ledger — warranty on the sheet, rep on the letterhead, quote==settle
|
gate 1: the post hint ruled, the mechanism fixed so a baked hint cannot
|
||||||
holds, a designed loss costs nothing
|
silently fail to reach a JSON anchor, both yards re-measured, D re-plays
|
||||||
gate 2: divergence heal (finite in 1s, mutation-proof); fabric on the record;
|
gate 2: the score paints progress and stays responsive; numbers reproduce
|
||||||
site_02 separation pinned or honestly refused
|
exactly; one storm picker; D says the loop changed
|
||||||
gate 3: storm_06 makes membrane the right answer, measured not asserted;
|
gate 3: Enter commits, out-of-bounds stops reading VALID, the friction list empty
|
||||||
makeStorm(seed) deterministic inside envelopes; forecast argues the bet
|
gate 4: John's three sentences + the branch, in writing
|
||||||
gate 4: site_03 cold-authored and shipped; six nights, one-variable rule;
|
|
||||||
the whole week cold-played and judged
|
|
||||||
gate 5: two temptation assets, honest extras, negative controls
|
|
||||||
gate 6: John's three sentences + the arc-2 job-type ruling
|
|
||||||
```
|
```
|
||||||
|
|||||||
168
SPRINT16.md
Normal file
168
SPRINT16.md
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
# SPRINT 16 — TEETH: YOUR WORK FOLLOWS YOU
|
||||||
|
|
||||||
|
*⚠️ PRE-SPECED, FIRES AFTER SPRINT 15 INTEGRATES. Sprint 15 (the post ruling,
|
||||||
|
the iterative editor, the honest edges) re-measures numbers this sprint pins —
|
||||||
|
do not start these gates on a pre-15 tree, and treat every number below that
|
||||||
|
S15's gate-1 re-measure moves as "re-measure first". Written 2026-07-18 at
|
||||||
|
John's direction (ROADMAP.md — gate 4 of S14 resolved: all three branches,
|
||||||
|
sequenced, teeth first).*
|
||||||
|
|
||||||
|
*The week grows consequences — reputation on the letterhead, warranty on the
|
||||||
|
job sheet, a sixth night, the swing lawn in the rotation, and the first night
|
||||||
|
where the default fabric is the wrong answer. Baseline selftest: whatever
|
||||||
|
Sprint 15 lands (409/0/0 pre-15 plus S15's additions). Keep it green;
|
||||||
|
mutation-check anything you'd call coverage.*
|
||||||
|
|
||||||
|
**The one-variable rule is LAW this sprint (ROADMAP principle 5):** six nights,
|
||||||
|
exactly one flies the new storm, exactly one is the new site, and they are NOT
|
||||||
|
the same night. A player who loses night 6 must be able to say whether the yard
|
||||||
|
beat them or the weather did.
|
||||||
|
|
||||||
|
## Gate 1 — THE LEDGER (A owns: week.js, hud.js surfaces, main.js wiring)
|
||||||
|
|
||||||
|
Reputation and warranty, hung off the paperwork that already exists. No new
|
||||||
|
phase, no new sim — this is week-state plus three surfaces telling the truth.
|
||||||
|
|
||||||
|
1. **The work history.** Every committed rig is recorded on the week: corners,
|
||||||
|
hardware, effective ratings, what broke, what was repaired by dawn. This is
|
||||||
|
data the night already computes — the ledger just keeps it.
|
||||||
|
2. **Warranty.** A corner of YOURS that broke and was still broken at dawn books
|
||||||
|
a warranty item: the NEXT morning's job sheet carries it as a line —
|
||||||
|
"warranty — q3, shackle, no charge to the client" — and its cost (the
|
||||||
|
hardware's shop price, unpaid labour is the point) comes off that night's
|
||||||
|
fee AT QUOTE TIME. week.js's own invariant is non-negotiable: the sheet and
|
||||||
|
the invoice never diverge — the quote already carries the deduction, so
|
||||||
|
settle pays exactly what was quoted. A repair you made mid-storm is NOT a
|
||||||
|
warranty item; riding it out broken is.
|
||||||
|
3. **Reputation.** One number on the letterhead (pick the unit — stars read as
|
||||||
|
client-speak; whatever it is, it appears under the ABN on job sheet AND
|
||||||
|
invoice, E's letterhead contract). Clean night (no breaks, no collateral):
|
||||||
|
up. Warranty item: down. Collateral event: down harder. It MOVES PAY at
|
||||||
|
quote time — a trusted outfit's callout fee multiplier, printed on the
|
||||||
|
sheet, so the player watches their number become money. Start neutral;
|
||||||
|
night 5's beyond-saving garden must NOT cost rep (the flag exists — read it;
|
||||||
|
a designed loss the ledger punishes is the verdict lying again).
|
||||||
|
4. **Aftermath teaches it.** The invoice's verdict line and the end-of-week
|
||||||
|
card both speak rep: a week that ends broke-but-clean and a week that ends
|
||||||
|
rich-with-warranties are different endings and should read as such.
|
||||||
|
5. Tests, a.test: warranty fires only on unrepaired breaks (repaired = no
|
||||||
|
item); quote==settle holds with a warranty line on the sheet; rep never
|
||||||
|
moves on gardenBeyondSaving nights for garden reasons; the multiplier is on
|
||||||
|
the sheet the night it applies. Negative control: a clean week books zero
|
||||||
|
warranty items and ends rep-positive.
|
||||||
|
|
||||||
|
## Gate 2 — THE HEAL + THE PAPER TRAIL + THE PIN (B owns)
|
||||||
|
|
||||||
|
1. **Divergence heal.** The review landed the break (a NaN corner now lets go,
|
||||||
|
reason:'divergence', production path) — but the freed node then integrates
|
||||||
|
from NaN forces and the cloth renders ugly after one. Sanitize on the break:
|
||||||
|
any non-finite node position resets from its nearest finite neighbour (or
|
||||||
|
the corner's anchor), prev matched so verlet doesn't invent velocity, and
|
||||||
|
non-finite water zeroed (a NaN pond re-poisons the heal through the weight
|
||||||
|
term). Assert: poison → break → every node finite within 1 s of sim.
|
||||||
|
Mutation: heal off, assert red. The existing divergence test must keep
|
||||||
|
passing untouched — the heal is IN ADDITION to the break, not instead.
|
||||||
|
2. **Fabric on the paperwork.** The chosen fabric prints in the prep summary,
|
||||||
|
on the invoice, and in the aftermath verdict when it mattered (a membrane
|
||||||
|
night survived in cloth should say what the leak cost). The FORECAST half is
|
||||||
|
C's (gate 3.3) — yours is that the choice the player made is on the record.
|
||||||
|
3. **Pin site_02's separation — AFTER S15's re-measure.** The SCORE IT card
|
||||||
|
says NONE PINNED and calls it out. Once the post ruling has settled the
|
||||||
|
numbers, run gardenfly, pick the honest target, pin the block in site_02's
|
||||||
|
JSON, assert it like backyard_01's. If the honest answer is "this yard
|
||||||
|
cannot separate held from bare at $80", that is a FINDING about the yard —
|
||||||
|
post it in THREADS; the balance fight starts there, not at a fudged pin.
|
||||||
|
Same pass, same rule for `site_03_swing_lawn` if S15 left it unpinned.
|
||||||
|
|
||||||
|
## Gate 3 — THE MEMBRANE NIGHT + THE SEEDED STORM (C owns)
|
||||||
|
|
||||||
|
1. **storm_06 — the pea-hail soaker.** Small stones (under the 2 mm-weave
|
||||||
|
ruling's blocking threshold), heavy rain, mild wind. The night the bet
|
||||||
|
flips: cloth leaks fine hail onto the bed all night; membrane stops
|
||||||
|
everything and the mild wind means its doubled load is affordable — but it
|
||||||
|
PONDS, so the broom matters. Author it so both lines exist and the membrane
|
||||||
|
line is genuinely better: measure with gardenfly/site_audit (funnel state in
|
||||||
|
the header, per the discipline; post-ruling numbers only), pin
|
||||||
|
membrane-vs-cloth garden separation in the storm's own selftest, and make
|
||||||
|
sure a $80 wallet affords the membrane line on the night's site. If the
|
||||||
|
measured numbers say cloth still wins, retune the hail spectrum until the
|
||||||
|
bet is real — the storm exists to make the F key matter, and a decoration
|
||||||
|
night is worse than no night.
|
||||||
|
2. **makeStorm(seed) — groundwork, not a shipped night.** A seeded generator
|
||||||
|
inside authored envelopes (base curve, gust budget, direction change window,
|
||||||
|
rain/hail ranges as data), producing storm defs that pass the schema
|
||||||
|
validator and the storm_envelope harness. Deterministic from seed —
|
||||||
|
ROADMAP arc 4's roguelite eats this. Selftest: same seed → byte-equal def;
|
||||||
|
100 seeds → all schema-valid, all inside the envelope; a seed that violates
|
||||||
|
the envelope is a red test, not a shrug.
|
||||||
|
3. **The forecast argues the bet.** Hail stone size and rain rate join wind on
|
||||||
|
the job sheet's forecast block (the data is in the storm JSON; A prints
|
||||||
|
what you expose). The band-not-a-promise rule holds — forecast bands, real
|
||||||
|
values inside them.
|
||||||
|
|
||||||
|
## Gate 4 — THE SIX-NIGHT WEEK (D owns)
|
||||||
|
|
||||||
|
1. **The swing lawn enters the rotation.** Your site_03_swing_lawn landed in
|
||||||
|
S14 — authored cold, scored, played, inert. Re-score it on the post-ruling
|
||||||
|
tree with S15's faster loop (the numbers that made it winnable-but-mean may
|
||||||
|
have moved), fix what moved, then wire it into NIGHTS. If S15's edges work
|
||||||
|
added a separation field or B pinned one for it, carry it; otherwise gate
|
||||||
|
2.3 covers it.
|
||||||
|
2. **The week becomes six nights.** Wire the swing lawn and storm_06 into
|
||||||
|
NIGHTS under the one-variable rule: the new site debuts on a storm the
|
||||||
|
player has already survived; storm_06 flies over a yard they already know.
|
||||||
|
You own the order and the two new briefs (client flavour is data — the
|
||||||
|
corner block got a name and a reason; the swing set's kid deserves one
|
||||||
|
too). Night 5's beyond-saving flag and going-broke-never-on-the-final-night
|
||||||
|
must both survive re-ordering — the a.test week asserts will tell you.
|
||||||
|
3. **Cold-play the whole six**, wallet from night 1, and file the verdict:
|
||||||
|
does a warranty callout read as FAIR when it lands on your sheet? Does rep
|
||||||
|
moving pay feel earned or arbitrary? Is night 6's bet legible from the
|
||||||
|
forecast alone? Your play IS the acceptance test for gates 1–3.
|
||||||
|
4. Pool (yours): the phantom-sail seam if S15 didn't close it.
|
||||||
|
|
||||||
|
## Gate 5 — THE NEXT TEMPTATIONS (E owns)
|
||||||
|
|
||||||
|
Arc 2 needs yards this palette cannot dress yet. Two of these three, factory-
|
||||||
|
built, byte-stable, negative-control-proven (build the wrong one on purpose,
|
||||||
|
watch red) — and every anchor-bearing node passes the S15 gate-1 mechanism
|
||||||
|
(a baked hint that cannot reach a JSON-declared anchor is the bug class that
|
||||||
|
cost the posts their truth):
|
||||||
|
1. **The glasshouse** — the collateral apex. Priced high, wreck variant,
|
||||||
|
collateral_key wired so a SECOND one placed in the editor still bills (the
|
||||||
|
carport's five-sprint lesson). Panes that read as fragile at a glance;
|
||||||
|
nothing about it may adopt as an anchor.
|
||||||
|
2. **The pool kit** — pool + compliant fence ring. The fence posts are the
|
||||||
|
temptation: honest `tie_off:false` on every one (silence is not neutral —
|
||||||
|
adoptAnchor's `?? 1` makes an unrated node the best steel in the game),
|
||||||
|
because the pool yard's whole puzzle is that the legal tie-offs are all in
|
||||||
|
the wrong places.
|
||||||
|
3. **The trampoline + tie-down kit** — typed honestly in the checked enum;
|
||||||
|
the tie-down is the prep-phase counter to the storm's opening projectile,
|
||||||
|
priced like it matters.
|
||||||
|
Flag D in THREADS as each lands.
|
||||||
|
|
||||||
|
## Gate 6 — JOHN: PLAY, THEN AIM ARC 2
|
||||||
|
|
||||||
|
Six nights at partly.party/hardyards (deploy after integration — ROADMAP: the
|
||||||
|
live gap never exceeds one sprint). Three sentences in THREADS. Then one
|
||||||
|
ruling for arc 2's first sprint: **emergency mid-storm callout or the cowboy
|
||||||
|
audit** — which job type leads THE BOOK OF CLIENTS?
|
||||||
|
|
||||||
|
Pool, spread by ownership: whatever S15's pool leaves standing, plus:
|
||||||
|
membrane pricing the day rain's drain weight moves (B, rigging.js's comment
|
||||||
|
names the start); the >83 ms determinism bound gets a pinning test or a
|
||||||
|
documented waiver (B).
|
||||||
|
|
||||||
|
```
|
||||||
|
gate 1: ledger — warranty on the sheet, rep on the letterhead, quote==settle
|
||||||
|
holds, a designed loss costs nothing
|
||||||
|
gate 2: divergence heal (finite in 1s, mutation-proof); fabric on the record;
|
||||||
|
separations pinned post-ruling or honestly refused
|
||||||
|
gate 3: storm_06 makes membrane the right answer, measured not asserted;
|
||||||
|
makeStorm(seed) deterministic inside envelopes; forecast argues the bet
|
||||||
|
gate 4: swing lawn re-scored and wired; six nights, one-variable rule;
|
||||||
|
the whole week cold-played and judged
|
||||||
|
gate 5: two temptation assets, honest extras, negative controls, S15-clean
|
||||||
|
gate 6: John's three sentences + the arc-2 job-type ruling
|
||||||
|
```
|
||||||
300
THREADS.md
300
THREADS.md
@ -6530,6 +6530,280 @@ anchors are your GLB), but the tooling is now waiting, not TODO.
|
|||||||
real wait. If it bites, say so — the `FLY_CAP` (12) and the sweep are both knobs I can turn,
|
real wait. If it bites, say so — the `FLY_CAP` (12) and the sweep are both knobs I can turn,
|
||||||
and I'd rather hear it from someone using it in anger than guess.
|
and I'd rather hear it from someone using it in anger than guess.
|
||||||
|
|
||||||
|
[D] 2026-07-18 — 🏡 **GATE 3.2 — I AUTHORED A THIRD YARD COLD IN THE EDITOR, AND THE EDITOR IS
|
||||||
|
SHIPPING BOTH OF E'S NEW PROPS INERT.** Site JSON landed on lane/d as the site_03 CANDIDATE,
|
||||||
|
awaiting John's gate-4 branch call. Selftest **406/0/0** on my tree with it landed. No JSON
|
||||||
|
hand-editing and no console for any of the authoring — one exception, declared at the bottom.
|
||||||
|
|
||||||
|
**🔴 THE HEADLINE, AND IT IS A's FILE: the palette's two newest entries omit the `_v1` suffix
|
||||||
|
every other entry carries, so `swing_set_01` and `tree_jacaranda_01` 404, never draw, and
|
||||||
|
adopt at ratingHint 1.00.** Found in the first ten minutes of placing.
|
||||||
|
|
||||||
|
· **Receipt, from the network log:** `GET /web/world/models/swing_set_01.glb → 404 File not
|
||||||
|
found`. The shipped asset is `swing_set_01_v1.glb`, and it preloads **200 OK** under its
|
||||||
|
real name three lines earlier in the same log. Same for `tree_jacaranda_01`.
|
||||||
|
· **Source:** `editor.js` 239/243 (`model: 'swing_set_01'`, `wreckedModel:
|
||||||
|
'swing_set_01_wrecked'`) and 257/260 (`model: 'tree_jacaranda_01'`). The other nine palette
|
||||||
|
entries all carry `_v1`. (`nodeNamesFor` at 385-398 also omits `_v1` — that one is CORRECT,
|
||||||
|
those are scene-node names, not files. I checked before filing.)
|
||||||
|
· **Consequence, read straight off A's own SELECTED panel:**
|
||||||
|
|
||||||
|
| prop | E designed | editor adopted |
|
||||||
|
|---|---|---|
|
||||||
|
| swing_set_01 `s1_f1` / `s1_f2` | 0.45 / 0.45 | **1.00 / 1.00** |
|
||||||
|
| tree_jacaranda_01 `t1` / `t1b` / `t1c` | 0.95 / 0.52 / 0.40 | **1.00 / 1.00 / 1.00** |
|
||||||
|
|
||||||
|
Neither prop renders — you get a selection ring on empty grass. And the yard still reads
|
||||||
|
**VALID — the game can boot this**.
|
||||||
|
· **This is E's GAP 1 exactly, one layer up.** `adoptAnchor` does `rating_hint ?? 1`, so a
|
||||||
|
model that 404s doesn't fail — it becomes the best steel in the game. A's own ruling says
|
||||||
|
the 0.45 "is the prop's entire reason to exist" and that softening it "would delete the
|
||||||
|
honest middle the palette was missing". The 404 deletes it. The jacaranda's whole design —
|
||||||
|
**"gum: climb freely, pay 24%. Jacaranda: climb at all, pay 58%"** — becomes three perfect
|
||||||
|
anchors, i.e. a better tree than the gum at every rung. Both props gate 3.1 built so that
|
||||||
|
gate 3.2 could ask a real question, and neither was asking it.
|
||||||
|
· **It propagates into the DATA.** The palette's `make()` writes the model string into the
|
||||||
|
site JSON, so the first editor-authored yard using either prop ships a permanently broken
|
||||||
|
model reference. This is not just an editor-preview bug.
|
||||||
|
· **Gate 1's promise holds and is not enough.** A wrote that the palette "structurally cannot
|
||||||
|
offer a prop that would produce a site `validateSite` rejects" — true, and irrelevant here,
|
||||||
|
because `validateSite` cannot open a GLB (A's own words when they took the `tie_off`
|
||||||
|
runtime half). Nothing in 406 tests that a palette model name resolves to a file.
|
||||||
|
· **Negative-controlled in both directions.** With the four names corrected locally:
|
||||||
|
`swing_set_01_v1` → `s1_f1`/`s1_f2` **hint 0.45**; `tree_jacaranda_01_v1` → **0.95 / 0.52 /
|
||||||
|
0.40**; both props draw. Reverted before landing — **the fix is A's, and `editor.js` is
|
||||||
|
untouched on lane/d.** I authored the yard on that local patch, the same way B and C
|
||||||
|
developed against A's import line without landing it. Everything below was measured on the
|
||||||
|
corrected palette, so the numbers describe the yard A's one-line fix will produce.
|
||||||
|
· **The assert that would have caught it** is one line in the round-trip test A already
|
||||||
|
wrote, since it dresses the world: every palette item's model must resolve. A's adoption
|
||||||
|
check keys on `collateral`, which the swing set HAS — so the existing check passes while
|
||||||
|
the mesh is missing and the hint is a lie.
|
||||||
|
|
||||||
|
**🏡 THE YARD — `site_03_swing_lawn`, "The Delaneys' back lawn". 24×16, 11 anchors.**
|
||||||
|
The thesis: **the good steel is all LOW and the only height is bad.** Three temptations,
|
||||||
|
three different lies, and the blurb sells all three — *"Swing set, big jacaranda, house right
|
||||||
|
there — you'll have no trouble finding something to tie to."*
|
||||||
|
|
||||||
|
| anchor | rating | the lie |
|
||||||
|
|---|---|---|
|
||||||
|
| `s1_f1` `s1_f2` swing apexes | 0.45 | the crossbar between them is a dead-level 2.05 m rail spanning 2.3 m and is NOT an anchor. Blowing an apex bills **$140** |
|
||||||
|
| `t1` jacaranda low fork | 0.95 | genuinely excellent — but it is 2.5 m up and cuts the sail flat |
|
||||||
|
| `t1b` / `t1c` jacaranda height | 0.52 / 0.40 | where the sail wants its high corner. Height costs 58% here |
|
||||||
|
| `h1` `h2` `h3` fascia | 0.35 | the familiar lie, and takes the **$90** gutter |
|
||||||
|
| `t2` / `t2b` gum | 1.00 / 0.88 | the best steel in the yard, parked 9 m away on the WRONG SIDE on purpose |
|
||||||
|
| `p1` post | 1.00 | one honest corner. You need four |
|
||||||
|
|
||||||
|
**The wind is the yard's personality, not decoration.** The venturi is the real gap between
|
||||||
|
the shed and the west end of the house — I placed the throat by clicking that gap and set the
|
||||||
|
axis to the slot's true orientation (90°, running north-south), *not* to whatever maximised
|
||||||
|
alignment. C's panel then told me what that geometry was worth, live: **align 62%, peak
|
||||||
|
×1.28, fastest 14.96 m/s at (-8.3,-4.4)**. Throat sits **3.0 m from the swing set's apexes**,
|
||||||
|
inside r=5 — so the tempting middle option is also the windy one. Deliberately gentler than
|
||||||
|
the corner block (100%, ×1.46): **that yard keeps the crown for worst weather and worst bill.**
|
||||||
|
|
||||||
|
**SCORE IT** — storm_03_southerly, FUNNEL ON, 11 anchors dressed, **82.5 s**:
|
||||||
|
✓ **WINNABLE at $80** · 81 quads in band · **11 clean** · 16 marginal ·
|
||||||
|
cheapest honest `h3,t2,t2b,p1` $65 (holds at $55), 22 m², 85.3 FULL ·
|
||||||
|
bare bed **83.7** → best clean `h3,t1c,t2,p1` **90.0**, separation **+6.3 HP** ·
|
||||||
|
margin flags: t2b 0%, t1/t1b/p1/s1_f1 all 1% · collateral exposure **$230 on an $80 job**.
|
||||||
|
The card's own warning is the yard's design in one line: **the best-READING line
|
||||||
|
`t1c,t2,t2b,s1_f2` is MARGINAL at 91.8 FULL.** The prettiest number in the yard is the one
|
||||||
|
that breaks.
|
||||||
|
|
||||||
|
**🎮 THEN I PLAYED IT** (scratch branch `scratch/laneD-play-site03`, night 2 → my yard; A's
|
||||||
|
`week.js` is untouched on lane/d, exactly as in Sprint 12).
|
||||||
|
· **The job sheet reads.** JOB 1042, the Delaneys, 31 Ferndale Ave, NIGHT 2 OF 5, SOUTHERLY
|
||||||
|
BUSTER, and my blurb landing on the letterhead as the cover story. $122 the night, $80 bank.
|
||||||
|
· **The yard reads from the spawn.** All three temptations visible without moving: the three
|
||||||
|
fascia rings, the jacaranda's ladder of rings climbing away, and the swing set's two apex
|
||||||
|
rings **with the crossbar bare between them**. The rail is obviously level, obviously
|
||||||
|
spanning, and has no ring on it. E's prop does exactly what it was built to do. The HUD
|
||||||
|
types it `swing_frame`, so the player's pre-rig read is honest — and it does NOT distinguish
|
||||||
|
the two tree species, so "which tree" is answered by looking at the yard (lilac vs sage),
|
||||||
|
not by reading a list. That is the right place for it.
|
||||||
|
· **The trap bites, and it bites honestly.** Flew the marginal best-reading line at
|
||||||
|
affordable hardware ($60): **`t1c` broke** — the 0.40 limb, the exact corner the card
|
||||||
|
flagged — and the garden finished **83.9 FULL against a bare bed of 83.7**. Rigging the
|
||||||
|
prettiest line in the yard was worth **+0.2 HP over doing nothing.** Flew the cheapest
|
||||||
|
honest line at the same money: **`h3` broke**, 85.2 FULL, and h3 blowing bills the $90
|
||||||
|
gutter. At full-strength hardware ($120 — over budget) all three lines are clean.
|
||||||
|
**That is the yard: you cannot afford top steel on four corners, and it punishes which one
|
||||||
|
you skimp on.**
|
||||||
|
· **B's card and the real game agree on my yard**: card 90.0 → played **90.7**; card 91.8 →
|
||||||
|
played **93.6**. Two chains, one number, on a yard neither was tuned against.
|
||||||
|
· **My own lane, on editor-authored geometry.** `needsLadder` keys on `work === 'bracket'`,
|
||||||
|
and A's palette emits `work` per anchor — so **the ladder followed the site data with zero
|
||||||
|
code change**, which closes the handoff I asked A for in Sprint 10 ("emit `work` per anchor
|
||||||
|
and the ladder follows the site"). On this yard the three fascia corners are both the 0.35
|
||||||
|
lie AND the only ladder job: the cheapest-looking corners are the slowest to repair. The
|
||||||
|
shed renders at (-9,-5) and `shed_table` at (3.32,7.75) — **A's NaN-quaternion fix confirmed
|
||||||
|
on a yard built after it.**
|
||||||
|
|
||||||
|
**👻 PHANTOM SAIL — DEAD, verified in play.** Rigged `p1,p2,p3,p4` on backyard_01, then
|
||||||
|
`loadSiteInto('site_03_swing_lawn')`:
|
||||||
|
|
||||||
|
| | before | after |
|
||||||
|
|---|---|---|
|
||||||
|
| `rig.rigged` | true | **false** |
|
||||||
|
| `sailView` | present | **null** |
|
||||||
|
| in scene | true | **false** |
|
||||||
|
|
||||||
|
A's fix holds across a live site transition, which is my Sprint-13 sighting reproduced and
|
||||||
|
closed. Visually confirmed too: no cloth behind the splash card on the new yard.
|
||||||
|
|
||||||
|
**🧰 FRICTION, BY OWNER.**
|
||||||
|
· **A — number fields commit on BLUR only; Enter does nothing.** Typed `-6` into the house's
|
||||||
|
z, pressed Enter, and the field read `-6` while the site JSON still read `1.501` — the house
|
||||||
|
was standing on the garden bed and the bed had vanished under it. Only clicking elsewhere
|
||||||
|
committed. It mostly self-heals for a human (clicking the next thing blurs), but for the
|
||||||
|
duration the panel and the world disagree with no visual tell, and I lost real time
|
||||||
|
believing the bed had been deleted. Enter should commit.
|
||||||
|
· **A — the editor places objects outside the yard without a word.** My first bike landed at
|
||||||
|
**z = 8.699 in a 16 m yard** (z ∈ [-8, 8]), outside the fence, and VALIDATION still said
|
||||||
|
"VALID — the game can boot this". Which is true. But nobody means to put the bike in the
|
||||||
|
neighbour's yard.
|
||||||
|
· **A + B — there is no `separation` field anywhere in the editor, and B's own card asks for
|
||||||
|
one.** The card says, correctly, that "a shipping site should pin one: it is the difference
|
||||||
|
between 'a sail helps here' and 'a sail is the point of this night'." The editor cannot
|
||||||
|
comply. I shipped without one and said so in `_why` rather than hand-editing it in. Either
|
||||||
|
the SITE panel grows the field or the card stops asking.
|
||||||
|
· **A — zoom is mouse-wheel only.** No keyboard, no buttons. Minor, but it is the one camera
|
||||||
|
control with no alternative on a page that ships publicly.
|
||||||
|
· **B — the 82.5 s blocking score converted the editor from an iterative tool into a batch
|
||||||
|
one, and that is the honest answer to "what did it cost you".** Mine ran **82.5 s against
|
||||||
|
the integrator's 75 s on site_02** — 11 anchors / 81 candidate quads vs 10 / 66, and it
|
||||||
|
scales like C(n,4), so this gets worse with exactly the yards an editor makes easy to build.
|
||||||
|
**Everything I know about my yard came from ONE run.** I did not tune the yard against the
|
||||||
|
score; I designed it, scored it once, and shipped what that run said, because a second
|
||||||
|
opinion cost 82 s of a page that looks crashed. I would have moved the bed and re-scored if
|
||||||
|
it had been 8 s. **If gate 4 picks "more sites", a responsive score is the difference
|
||||||
|
between authoring and guessing** — and I'd take a progress tick and a yielded loop over raw
|
||||||
|
speed, because the worst part is not the wait, it's not knowing whether it died.
|
||||||
|
· **B + C — two storm pickers, independently defaulted.** SCORE IT opened on `02_wildnight`
|
||||||
|
while WIND opened on `03_southerly`. Scoring against one storm while reading the other's
|
||||||
|
wind field is a quiet way to be wrong, and I only caught it because I went looking. One
|
||||||
|
storm selection, shared.
|
||||||
|
· **E — the palette prose is doing real work.** Every button's tooltip is the design argument
|
||||||
|
("the crossbar LOOKS like the answer and is not an anchor"). I chose props by reading the
|
||||||
|
palette. That is what it is for and it worked.
|
||||||
|
· **E + A — `sail_post`'s audited `top_anchor 0.90` never reaches the runtime.** Every post on
|
||||||
|
my yard **and on shipped backyard_01** adopts at `ratingHint 1.00`, and posts carry no
|
||||||
|
`tieOff` field at all — they are constructed anchors, never GLB-adopted, so the extra is
|
||||||
|
never read. E's audit table row is a document and nothing asserts it. Either the 0.90 is
|
||||||
|
meant to bite (and every post in the game has been 11% stronger than its asset says) or the
|
||||||
|
row should say "constructed at 1.00". I corrected my own `_design` after measuring it.
|
||||||
|
|
||||||
|
**✅ WHAT SANG, because the investment is the story too.**
|
||||||
|
· **The SELECTED panel's live anchor readout is why the headline bug took ten minutes instead
|
||||||
|
of a sprint.** It lists the anchors as ADOPTED FROM THE DRESSED WORLD with their hints, not
|
||||||
|
as declared — so `hint 1.00` sat there in a warning-coloured badge next to a prop I knew was
|
||||||
|
0.45. Showing the adopted value is the entire reason that bug was findable.
|
||||||
|
· **The editor renders the real dressed world**, so a missing prop is visible by absence. A
|
||||||
|
diagram would have drawn me a swing set that isn't there.
|
||||||
|
· **`mountPanel` ordering held**: five panels from four lanes on one rail, no collisions, and
|
||||||
|
C's wind panel is the best surface on the page — I placed a venturi by clicking a gap and
|
||||||
|
never once wanted a private harness.
|
||||||
|
· **The EXPORT ≠ SHIPPED note**, which lists four steps including "a cold playthrough by
|
||||||
|
someone who did not author it". A tool that tells you it isn't finished.
|
||||||
|
· Text fields survive `markDirty` re-render with focus and caret intact — typed 23 characters
|
||||||
|
into `name` and all 23 landed.
|
||||||
|
|
||||||
|
**🔍 THREE THINGS I CHECKED AND DID NOT FILE**, because measure-don't-reason cuts both ways:
|
||||||
|
the side rail DOES scroll (`overflow-y:auto`, scrollHeight 3237) — my wheel events were a
|
||||||
|
tooling artifact, not a bug; the HUD's "anchors 1" was a stale text read and the HUD is
|
||||||
|
correct (it showed 11); and the template's 5×3.5 m bed is NOT below an audit floor — I went to
|
||||||
|
`sweep.js` and `AUDIT.BAND {lo:18,hi:45}` is the SAIL QUAD band, not the bed. I had that one
|
||||||
|
written up as a finding before I checked.
|
||||||
|
|
||||||
|
**DECLARED, since gate 3.2 is a discipline test:** the yard's geometry, every placement, the
|
||||||
|
wind block, the blurb and both note blocks came out of the editor and were transcribed from
|
||||||
|
its own canonical export. Two hand edits after the fact, both prose, both disclosed: the local
|
||||||
|
`_v1` palette patch described above (not landed), and correcting my `_design`'s claim that p1
|
||||||
|
is 0.90 once play measured it at 1.00 — I would rather hand-edit a note than ship a false
|
||||||
|
number in a level's design doc.
|
||||||
|
|
||||||
|
**site_03_swing_lawn is landed on lane/d as DATA ONLY and is inert** — nothing reaches it
|
||||||
|
until a `week.js` NIGHTS entry names it, and that entry lives only on my scratch branch. It is
|
||||||
|
the **site_03 CANDIDATE awaiting John's gate-4 branch decision**. If the call is "more sites",
|
||||||
|
it is a night that already reads, already scores winnable-but-mean, and has been played. It
|
||||||
|
would take night 2 (southerly) and relieve backyard_01 of one of its four nights.
|
||||||
|
|
||||||
|
[I] 2026-07-18 — **SPRINT 14 INTEGRATION (main).** All five lanes merged; selftest **406/0/0** on the
|
||||||
|
merged tree, the exact per-lane sum (362 + A 11 + B 13 + C 6 + E 14), verified in the browser.
|
||||||
|
The yard editor exists, it works, and **three lanes built into one page with ZERO code conflicts**
|
||||||
|
— only THREADS. A's seam contract, published on day one before the implementation was finished,
|
||||||
|
is the reason; it is the `.letterhead` pattern proven at a much larger scale and it should be the
|
||||||
|
default whenever two lanes must share a surface.
|
||||||
|
|
||||||
|
**Integrator edits, both because the owning lane had finished (the S13 precedent):**
|
||||||
|
· Mounted B's and C's panels in `editor.html` — one import line each, which is all either lane
|
||||||
|
ever asked A for. Inside the try/catch on purpose: a panel that throws should say so on the
|
||||||
|
glass, not leave a hole in the rail.
|
||||||
|
· **Fixed D's headline bug in `editor.js`** — the palette shipped E's two new props with the
|
||||||
|
`_v1` suffix missing, so both GLBs 404'd, never drew, and — because `adoptAnchor` does
|
||||||
|
`rating_hint ?? 1` — **a missing model silently became the best steel in the game** (swing
|
||||||
|
apexes 1.00 instead of E's 0.45; jacaranda 1.00/1.00/1.00 instead of 0.95/0.52/0.40), while the
|
||||||
|
yard still validated VALID. D negative-controlled it both directions on a local patch they
|
||||||
|
deliberately did not land. Verified my fix through the editor's REAL placement path (click the
|
||||||
|
palette, click the ground): `s1_f1=0.45 s1_f2=0.45`. Note the shape for the manual: this is
|
||||||
|
E's own `tie_off` lesson wearing a filename — **silence is not neutral wherever the default is
|
||||||
|
generous.**
|
||||||
|
|
||||||
|
**⚠️ CARRIED TO SPRINT 15, AND IT IS A SHIPPED BALANCE BUG, NOT AN EDITOR ONE.** D found it and
|
||||||
|
I confirmed it end to end: the factory bakes `rating_hint = 0.9` on `sail_post`'s `top_anchor`,
|
||||||
|
but every post in `backyard_01.json` (and site_02) is a plain data entry with **no `node`**, so
|
||||||
|
`adoptAnchor` never runs for them and they all default to **1.00**. Every honest post in the
|
||||||
|
shipped game is 10% stronger than E designed it, and has been for as long as posts have been
|
||||||
|
data. **I did not fix this at integration and nobody should hot-fix it**: it moves balance across
|
||||||
|
both shipped yards, and A's `separation` block pins measured hp numbers through the real chain
|
||||||
|
while B's audit tables and D's played numbers all sit on the current value. It is a RULING (A) +
|
||||||
|
a re-measure (B) + a re-play (D), which is a gate, not a patch.
|
||||||
|
|
||||||
|
🔧 **THE REMOTE WAS RENAMED MID-SPRINT — `monster/shades` → `monster/hardyards`**, via the Gitea
|
||||||
|
web UI at 09:02 (matching the repo to the game's name). Nothing was lost; every ref was intact
|
||||||
|
under the new name. D hit it as `Cannot find repository` and correctly REFUSED to create a repo
|
||||||
|
or rewrite the remote to force a push — they committed locally and reported instead, which is
|
||||||
|
exactly right and is why their work survived. All six checkouts are repointed and D's two commits
|
||||||
|
are pushed. **If a push ever fails with "cannot find repository", check for a rename before
|
||||||
|
assuming loss: `git ls-remote ssh://git@100.71.119.27:222/monster/<newname>.git`.**
|
||||||
|
|
||||||
|
**The sprint's real argument, in one line: the editor found NINE bugs before anyone authored a
|
||||||
|
yard with it**, and three were live on the public URL — a graybox house slab across site_02's
|
||||||
|
north horizon, the Hendersons' shed which has NEVER rendered (an `undefined` rotation → NaN
|
||||||
|
matrix → three.js silently declines to draw, no throw, no warning), and boot failures written
|
||||||
|
into a `display:none` div so a stranger got a blank page. None was findable from a bench. All
|
||||||
|
were findable by standing in the yard and looking, which is the entire thesis of gate 1.
|
||||||
|
|
||||||
|
**`return t.skip(msg)` was a fake pass** (A): `Suite.skip()` pushes a NEW result while the
|
||||||
|
current test still records `pass`. I grepped every suite — **confined to a.test.js, four
|
||||||
|
instances, all fixed**; B, C, D, E and balance.test were clean, so the repo's counts were never
|
||||||
|
materially inflated. Worth knowing WHY those four were exposed: they guard on `dressed`, and
|
||||||
|
C's S13 landmine is that `dress()` throws silently without the importmap — two bugs that compose
|
||||||
|
into "green because nothing ran". selftest.html carries the importmap, so they were genuinely
|
||||||
|
running.
|
||||||
|
|
||||||
|
**Gate 3.2 delivered: `site_03_swing_lawn`, "The Delaneys' back lawn"** — authored COLD by D in
|
||||||
|
the editor, no JSON, no console. Thesis: *the good steel is all low and the only height is bad.*
|
||||||
|
Scored winnable at $80 (11 clean lines, cheapest honest $65, collateral $230 on an $80 job),
|
||||||
|
played on a scratch branch, and the trap bit exactly as designed — the prettiest line finished
|
||||||
|
**83.9 against a bare bed's 83.7**, i.e. worth +0.2 HP. Card and game agreed to a point. **It is
|
||||||
|
a CANDIDATE, inert until a NIGHTS entry names it, and that is gate 4's call, not mine.**
|
||||||
|
|
||||||
|
Pool, by owner: **B** — the score is 75–82 s with the UI thread fully blocked, which made the
|
||||||
|
editor *batch, not iterative* (D scored once and shipped that run rather than tuning; D's words
|
||||||
|
are the evidence, and a progress tick may matter more than raw speed). **A** — number fields
|
||||||
|
commit on blur only (Enter does nothing; D lost real time to a house sitting on the garden bed
|
||||||
|
while the panel read the new value); objects place outside the fence silently and still read
|
||||||
|
VALID; zoom is wheel-only. **A+B** — no `separation` field exists in the editor while B's card
|
||||||
|
says a shipping site should pin one. **B+C** — two independently-defaulted storm pickers (D
|
||||||
|
scored the wildnight while viewing the southerly). **E+A** — the `sail_post` hint above.
|
||||||
|
|
||||||
|
**Gate 4 is open and it is now the only thing standing between this project and its next
|
||||||
|
direction: John plays the week.** Nine sprints. The editor has made "more sites" nearly free and
|
||||||
|
D has a candidate yard sitting ready; reputation/warranty and heatwave are unchanged in cost.
|
||||||
|
That choice is his and the game is the best argument for making it that it has ever been.
|
||||||
|
|
||||||
[I] 2026-07-18 — 🔍 **FRESH-EYES REVIEW (John's ask, run by Claude in the integration
|
[I] 2026-07-18 — 🔍 **FRESH-EYES REVIEW (John's ask, run by Claude in the integration
|
||||||
checkout) + SIX FIXES LANDED ON MAIN.** Full read of canon + code + a played night 1 +
|
checkout) + SIX FIXES LANDED ON MAIN.** Full read of canon + code + a played night 1 +
|
||||||
the whole suite. Selftest **409/0/0** (406 baseline + 3 new, every new assert
|
the whole suite. Selftest **409/0/0** (406 baseline + 3 new, every new assert
|
||||||
@ -6549,3 +6823,29 @@ anchors are your GLB), but the tooling is now waiting, not TODO.
|
|||||||
cloth render after one is still ugly; B should own the heal), a job-sheet surface for the
|
cloth render after one is still ugly; B should own the heal), a job-sheet surface for the
|
||||||
fabric bet (the key exists, the FORECAST should argue with it — A), and membrane's
|
fabric bet (the key exists, the FORECAST should argue with it — A), and membrane's
|
||||||
balance once rain's drain weight moves (rigging.js's own comment says where to start).
|
balance once rain's drain weight moves (rigging.js's own comment says where to start).
|
||||||
|
|
||||||
|
[I] 2026-07-18 — 🔀 **TWO INTEGRATIONS, ONE DAY — THE FORK, RECONCILED.** The fresh-eyes
|
||||||
|
review (my entry above) and the S14 lane integration (the [I] above it) happened in
|
||||||
|
PARALLEL checkouts the same day: origin took D's swing lawn + the palette-_v1 fix + a
|
||||||
|
SPRINT15 (posts/editor); this checkout took the six review fixes + a TEETH sprint plan,
|
||||||
|
also numbered 15. Merged with the house rules — code was disjoint (their side: editor.js;
|
||||||
|
my side: sail/rigging/debris/hud/main + suites), docs were the fork:
|
||||||
|
|
||||||
|
· **Their SPRINT15 STANDS as Sprint 15.** Its gate 1 (the post rating_hint ruling)
|
||||||
|
re-measures the exact numbers TEETH wants to pin — running TEETH first would have
|
||||||
|
pinned pre-ruling numbers, which is the S13 lesson at sprint scale.
|
||||||
|
· **TEETH is SPRINT16, pre-speced** with a fires-after-15 banner; its D gate now WIRES
|
||||||
|
the swing lawn instead of authoring it (it exists — 0b858ab), and every pin says
|
||||||
|
"post-ruling numbers only". LANE_PROMPTS carries both sets, 16 below 15, marked.
|
||||||
|
· **S15 gate 4's branch half is RESOLVED by John** (all three, sequenced — teeth →
|
||||||
|
sites/clients → heatwaves; ROADMAP.md is the new growth canon holding the arcs). The
|
||||||
|
PLAY half stands, and is better now: the F key is live and the review fixes ride along.
|
||||||
|
· THREADS conflict resolved keep-both-chronological (their S14 entries, then the review
|
||||||
|
entry — the review's "406 baseline" and "pushed to SPRINT15" read as that fork's truth;
|
||||||
|
the follow-ups it names are SPRINT16 gates now).
|
||||||
|
|
||||||
|
Selftest on the merged tree: run below this entry — the review's 3 asserts join whatever
|
||||||
|
D's landing carried. My review entry's fix #4 (debris seam deletion) and D's inert-props
|
||||||
|
finding touched DIFFERENT halves of debris/editor and merged clean; the palette fix means
|
||||||
|
the swing set now DRAWS, which makes E's S14 negative-control discipline the next thing
|
||||||
|
the editor exercises.
|
||||||
|
|||||||
232
web/world/data/sites/site_03_swing_lawn.json
Normal file
232
web/world/data/sites/site_03_swing_lawn.json
Normal file
@ -0,0 +1,232 @@
|
|||||||
|
{
|
||||||
|
"id": "site_03_swing_lawn",
|
||||||
|
"name": "The Delaneys' back lawn",
|
||||||
|
"blurb": "Swing set, big jacaranda, house right there — you'll have no trouble finding something to tie to.",
|
||||||
|
"_design": [
|
||||||
|
"THE YARD WHERE THE GOOD STEEL IS ALL LOW AND THE ONLY HEIGHT IS BAD.",
|
||||||
|
"Three temptations, three different lies:",
|
||||||
|
" - the swing set's crossbar is a dead-level rail at 2.05 m spanning 2.3 m and is NOT",
|
||||||
|
" an anchor (tie_off:false). The two apexes beside it are honest steel but only 0.45,",
|
||||||
|
" and blowing one bills $140.",
|
||||||
|
" - the jacaranda forks low and excellent (0.95) then falls off a cliff (0.52 / 0.40).",
|
||||||
|
" A sail wants height on its high corner; on this tree height costs 58%, against 24%",
|
||||||
|
" up a gum. That is the \"which tree\" question, and it is the whole reason t2 exists.",
|
||||||
|
" - the house fascia is the familiar 0.35 lie and takes the $90 gutter with it.",
|
||||||
|
"The only top-grade steel in the yard is one post (p1) and the jacaranda's LOW fork",
|
||||||
|
"(0.95). Four corners, two good ones - that is the puzzle.",
|
||||||
|
"MEASURED IN PLAY, and the one line here not written by the editor: p1 adopts at",
|
||||||
|
"ratingHint 1.00, NOT the 0.90 in E's asset audit - posts are constructed anchors and",
|
||||||
|
"never read the sail_post GLB extra. Every post on backyard_01 reads 1.00 too, so it",
|
||||||
|
"is repo-wide and not this yard's doing. Filed to E/A in THREADS.",
|
||||||
|
"The gum t2 (1.00 / 0.88) is parked 9 m away in the south-west ON PURPOSE: excellent",
|
||||||
|
"steel on the wrong side, so reaching for it costs you span and shape rather than",
|
||||||
|
"rating. The audit's cheapest honest line (h3,t2,t2b,p1) goes and gets it.",
|
||||||
|
"WIND: the venturi is the gap between the shed and the west end of the house - real",
|
||||||
|
"geometry, not a heading. The slot runs north-south so axis = 90 deg; gain 1.4, r 5.",
|
||||||
|
"It bites the RIGGING ZONE and not the bed: the throat sits 3.0 m from the swing set's",
|
||||||
|
"apexes, so the tempting middle option is also the windy one. Deliberately gentler than",
|
||||||
|
"the corner block (align 62%, peak x1.28 against its 100% / x1.46) - that yard keeps",
|
||||||
|
"the crown for worst weather and worst bill."
|
||||||
|
],
|
||||||
|
"_why": [
|
||||||
|
"Authored COLD in the yard editor for Sprint 14 gate 3.2 - no JSON hand-editing, no",
|
||||||
|
"console. Every number below is B's SCORE IT card, storm_03_southerly, funnel ON,",
|
||||||
|
"11 anchors dressed, one run of 82.5 s.",
|
||||||
|
" WINNABLE at $80 - 81 quads in band, 11 clean, 16 marginal.",
|
||||||
|
" cheapest honest line h3,t2,t2b,p1 - $65 hardware (holds at $55), 22 m2,",
|
||||||
|
" garden 85.3 FULL, worth +1.6 HP over bare.",
|
||||||
|
" held vs bare (flown) bare 83.7 FULL; best clean h3,t1c,t2,p1 -> 90.0 FULL;",
|
||||||
|
" separation +6.3 HP; by hail / rain 6.8 / 3.1.",
|
||||||
|
" THE TRAP, MEASURED the best-READING line t1c,t2b,s1_f2 is MARGINAL - 91.8 FULL",
|
||||||
|
" on paper, inside the 15% band. The prettiest number in the",
|
||||||
|
" yard is the one that breaks.",
|
||||||
|
" margin flags t2b 0% headroom; t1, t1b, p1, s1_f1 all 1%. s1_f1 wrecks the",
|
||||||
|
" swing set ($140), and the card prices it.",
|
||||||
|
" collateral exposure gutter $90 + swing set $140 = $230 if all lost, on a $80 job.",
|
||||||
|
"No `separation` block: the editor has no field for one, and B's own card says a",
|
||||||
|
"shipping site should pin one. Filed to A/B in THREADS rather than hand-edited in.",
|
||||||
|
"The bare bed reads 83.7 FULL, which is the bare-beds-win pool item showing up on a",
|
||||||
|
"third yard - gate-4 material, not this yard's doing and not tuned here."
|
||||||
|
],
|
||||||
|
"yard": {
|
||||||
|
"width": 24,
|
||||||
|
"depth": 16
|
||||||
|
},
|
||||||
|
"sun": {
|
||||||
|
"elevationDeg": 55,
|
||||||
|
"azimuthDeg": -125
|
||||||
|
},
|
||||||
|
"gardenBed": {
|
||||||
|
"x": 0,
|
||||||
|
"z": 0,
|
||||||
|
"w": 5,
|
||||||
|
"d": 3.5
|
||||||
|
},
|
||||||
|
"house": {
|
||||||
|
"model": "house_yardside_v1",
|
||||||
|
"wreckedModel": "house_yardside_wrecked_v1",
|
||||||
|
"collateralKey": "gutter",
|
||||||
|
"collateralValue": 90,
|
||||||
|
"collateralLabel": "the gutter",
|
||||||
|
"x": 0,
|
||||||
|
"z": -6,
|
||||||
|
"anchors": [
|
||||||
|
{
|
||||||
|
"id": "h1",
|
||||||
|
"node": "fascia_anchor_01",
|
||||||
|
"type": "house",
|
||||||
|
"work": "bracket"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "h2",
|
||||||
|
"node": "fascia_anchor_02",
|
||||||
|
"type": "house",
|
||||||
|
"work": "bracket"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "h3",
|
||||||
|
"node": "fascia_anchor_03",
|
||||||
|
"type": "house",
|
||||||
|
"work": "bracket"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"structures": [
|
||||||
|
{
|
||||||
|
"id": "s1",
|
||||||
|
"model": "swing_set_01_v1",
|
||||||
|
"wreckedModel": "swing_set_01_wrecked_v1",
|
||||||
|
"x": -5,
|
||||||
|
"z": -2,
|
||||||
|
"rotYDeg": 0,
|
||||||
|
"solid": false,
|
||||||
|
"collateralKey": "swing_set",
|
||||||
|
"collateralValue": 140,
|
||||||
|
"collateralLabel": "the swing set",
|
||||||
|
"anchors": [
|
||||||
|
{
|
||||||
|
"id": "s1_f1",
|
||||||
|
"node": "frame_anchor_01",
|
||||||
|
"type": "swing_frame",
|
||||||
|
"work": "cloth"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "s1_f2",
|
||||||
|
"node": "frame_anchor_02",
|
||||||
|
"type": "swing_frame",
|
||||||
|
"work": "cloth"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"trees": [
|
||||||
|
{
|
||||||
|
"id": "t1",
|
||||||
|
"model": "tree_jacaranda_01_v1",
|
||||||
|
"x": 4.971,
|
||||||
|
"z": 2,
|
||||||
|
"phase": 1.1,
|
||||||
|
"trunkH": 3.4,
|
||||||
|
"anchorY": 2.4,
|
||||||
|
"anchors": [
|
||||||
|
{
|
||||||
|
"id": "t1",
|
||||||
|
"node": "branch_anchor_01",
|
||||||
|
"type": "tree",
|
||||||
|
"work": "cloth"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "t1b",
|
||||||
|
"node": "branch_anchor_02",
|
||||||
|
"type": "tree",
|
||||||
|
"work": "cloth"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "t1c",
|
||||||
|
"node": "branch_anchor_03",
|
||||||
|
"type": "tree",
|
||||||
|
"work": "cloth"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "t2",
|
||||||
|
"model": "tree_gum_02_v1",
|
||||||
|
"x": -8.5,
|
||||||
|
"z": 5.5,
|
||||||
|
"phase": 1.7,
|
||||||
|
"trunkH": 3.8,
|
||||||
|
"anchorY": 3.1,
|
||||||
|
"anchors": [
|
||||||
|
{
|
||||||
|
"id": "t2",
|
||||||
|
"node": "branch_anchor_01",
|
||||||
|
"type": "tree",
|
||||||
|
"work": "cloth"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "t2b",
|
||||||
|
"node": "branch_anchor_02",
|
||||||
|
"type": "tree",
|
||||||
|
"work": "cloth"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"posts": [
|
||||||
|
{
|
||||||
|
"id": "p1",
|
||||||
|
"x": 3.5,
|
||||||
|
"z": -2.5,
|
||||||
|
"h": 4,
|
||||||
|
"type": "post",
|
||||||
|
"work": "cloth"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fence": {
|
||||||
|
"sides": [
|
||||||
|
"north",
|
||||||
|
"south",
|
||||||
|
"east",
|
||||||
|
"west"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"shed": {
|
||||||
|
"model": "shed_01_v1",
|
||||||
|
"x": -9,
|
||||||
|
"z": -5,
|
||||||
|
"rotYDeg": -90
|
||||||
|
},
|
||||||
|
"shedTable": {
|
||||||
|
"model": "shed_table_v1",
|
||||||
|
"x": 3.321,
|
||||||
|
"z": 7.753,
|
||||||
|
"rotYDeg": -90,
|
||||||
|
"pickupNode": "pickup_anchor"
|
||||||
|
},
|
||||||
|
"gnome": {
|
||||||
|
"model": "garden_gnome_01_v1",
|
||||||
|
"x": 7.08,
|
||||||
|
"z": 6.344,
|
||||||
|
"rotYDeg": 0,
|
||||||
|
"collateralValue": 25
|
||||||
|
},
|
||||||
|
"bike": {
|
||||||
|
"model": "bike_kid_01_v1",
|
||||||
|
"x": -6,
|
||||||
|
"z": 5,
|
||||||
|
"rotYDeg": 180
|
||||||
|
},
|
||||||
|
"wind": {
|
||||||
|
"venturi": [
|
||||||
|
{
|
||||||
|
"x": -6.22,
|
||||||
|
"z": -4.77,
|
||||||
|
"axis": 1.571,
|
||||||
|
"gain": 1.4,
|
||||||
|
"radius": 5,
|
||||||
|
"sharp": 3
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -236,11 +236,18 @@ export const PALETTE = [
|
|||||||
// crossbar that is the most anchor-looking object in the game and carries
|
// crossbar that is the most anchor-looking object in the game and carries
|
||||||
// `tie_off: false`. $140 is E's number, ADOPTED unchanged; the ruling and
|
// `tie_off: false`. $140 is E's number, ADOPTED unchanged; the ruling and
|
||||||
// the one condition for revisiting it are in THREADS.
|
// the one condition for revisiting it are in THREADS.
|
||||||
kind: 'structure', label: 'Swing set (the honest middle)', model: 'swing_set_01',
|
// ⚠️ The `_v1` suffix is LOAD-BEARING and its absence is silent. These two
|
||||||
|
// entries shipped without it (SPRINT14, D's cold pass): the GLB 404s, the
|
||||||
|
// prop never draws, and because `adoptAnchor` does `rating_hint ?? 1` a
|
||||||
|
// MISSING MODEL BECOMES THE BEST STEEL IN THE GAME — the swing apexes read
|
||||||
|
// 1.00 instead of E's 0.45, the jacaranda 1.00/1.00/1.00 instead of
|
||||||
|
// 0.95/0.52/0.40 — and the yard still validates VALID. Same species as E's
|
||||||
|
// `tie_off` audit: silence is not neutral where a default is generous.
|
||||||
|
kind: 'structure', label: 'Swing set (the honest middle)', model: 'swing_set_01_v1',
|
||||||
requires: ['swing_frame'],
|
requires: ['swing_frame'],
|
||||||
hint: 'apex anchors 0.45; the crossbar LOOKS like the answer and is not an anchor',
|
hint: 'apex anchors 0.45; the crossbar LOOKS like the answer and is not an anchor',
|
||||||
make: (id, x, z) => ({
|
make: (id, x, z) => ({
|
||||||
id, model: 'swing_set_01', wreckedModel: 'swing_set_01_wrecked',
|
id, model: 'swing_set_01_v1', wreckedModel: 'swing_set_01_wrecked_v1',
|
||||||
x, z, rotYDeg: 0, solid: false,
|
x, z, rotYDeg: 0, solid: false,
|
||||||
collateralKey: 'swing_set',
|
collateralKey: 'swing_set',
|
||||||
collateralValue: 140, collateralLabel: 'the swing set',
|
collateralValue: 140, collateralLabel: 'the swing set',
|
||||||
@ -254,10 +261,10 @@ export const PALETTE = [
|
|||||||
// on a jacaranda and you pay 58% for it, against the gum's 24%. Unpriced by
|
// on a jacaranda and you pay 58% for it, against the gum's 24%. Unpriced by
|
||||||
// E's own ruling (no limb-failure event to watch; billing an unseen event
|
// E's own ruling (no limb-failure event to watch; billing an unseen event
|
||||||
// is the lie the invoice exists to kill). Same node names as the gums.
|
// is the lie the invoice exists to kill). Same node names as the gums.
|
||||||
kind: 'tree', label: 'Jacaranda (height costs)', model: 'tree_jacaranda_01',
|
kind: 'tree', label: 'Jacaranda (height costs)', model: 'tree_jacaranda_01_v1',
|
||||||
hint: 'forks low and strong, then falls off a cliff — the "which tree" question',
|
hint: 'forks low and strong, then falls off a cliff — the "which tree" question',
|
||||||
make: (id, x, z) => ({
|
make: (id, x, z) => ({
|
||||||
id, model: 'tree_jacaranda_01', x, z, phase: 1.1, trunkH: 3.4, anchorY: 2.4,
|
id, model: 'tree_jacaranda_01_v1', x, z, phase: 1.1, trunkH: 3.4, anchorY: 2.4,
|
||||||
anchors: [1, 2, 3].map((i) => ({
|
anchors: [1, 2, 3].map((i) => ({
|
||||||
id: i === 1 ? id : `${id}${'abc'[i - 1]}`,
|
id: i === 1 ? id : `${id}${'abc'[i - 1]}`,
|
||||||
node: `branch_anchor_0${i}`, type: 'tree', work: 'cloth',
|
node: `branch_anchor_0${i}`, type: 'tree', work: 'cloth',
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user