Sprint 14 integration: merge all lanes (406/0/0), fix palette _v1 suffix bug, [I] entry

This commit is contained in:
type-two 2026-07-18 17:58:44 +10:00
parent 0414d34b9e
commit 008b78a0d4
2 changed files with 86 additions and 4 deletions

View File

@ -6728,3 +6728,78 @@ anchors are your GLB), but the tooling is now waiting, not TODO.
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 7582 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.

View File

@ -236,11 +236,18 @@ export const PALETTE = [
// 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
// 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'],
hint: 'apex anchors 0.45; the crossbar LOOKS like the answer and is not an anchor',
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,
collateralKey: '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
// 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.
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',
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) => ({
id: i === 1 ? id : `${id}${'abc'[i - 1]}`,
node: `branch_anchor_0${i}`, type: 'tree', work: 'cloth',