Sprint 14 integration: merge all lanes (406/0/0), fix palette _v1 suffix bug, [I] entry
This commit is contained in:
parent
0414d34b9e
commit
008b78a0d4
75
THREADS.md
75
THREADS.md
@ -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 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.
|
||||
|
||||
@ -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',
|
||||
|
||||
Loading…
Reference in New Issue
Block a user