From fcf1016e4e19c87dccd60e06e601737ab1211dda Mon Sep 17 00:00:00 2001 From: type-two Date: Sat, 18 Jul 2026 16:03:08 +1000 Subject: [PATCH] THREADS [E]: palette audit table, two temptation props, five negative controls, D unblocked --- THREADS.md | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) diff --git a/THREADS.md b/THREADS.md index 50c7c01..837dba8 100644 --- a/THREADS.md +++ b/THREADS.md @@ -5852,3 +5852,132 @@ anchors are your GLB), but the tooling is now waiting, not TODO. material before anyone tunes); B's invoice line for the beyond-saving night (offer accepted, next sprint's smalls); dev-line visibility default worth a second look. **Gate 4 remains open: John plays the week โ€” SEVEN sprints standing, and the game has never looked more like itself.** + +--- + +[E] 2026-07-18 โ€” ๐ŸŽจ **THE PALETTE IS AUDITED AND OPEN FOR BUSINESS โ€” LANE D, YOU ARE UNBLOCKED.** + Pushed on lane/e (`b9b6460`, `ba062cf`). Selftest **376/0/0**, verified in the browser on the + merged-with-nothing tree. Three new GLBs, five existing ones re-exported, nothing hand-edited โ€” + all of it out of `build_yard_assets.py`, and two consecutive full factory runs produce 44 + byte-identical files. + + **THE AUDIT TABLE.** Every asset the editor can offer, and what its anchors actually say. The + โ˜… rows are what I changed; the rest are confirmed honest as they stood. + + | asset | anchor nodes โ†’ rating_hint | collateral | priced | + |---|---|---|---| + | tree_gum_01 | branch 1.00 / 0.88 / 0.76 | โ€” | โ€” (no limb event) | + | tree_gum_02 | branch 1.00 / 0.88 | โ€” | โ€” | + | โ˜… tree_jacaranda_01 | branch **0.95 / 0.52 / 0.40** | โ€” | โ€” (stated, not omitted) | + | house_yardside | fascia ร—3 = 0.35 | gutter | $90, key `gutter` | + | โ˜… house_yardside(+wrecked) | window_light_anchor โ†’ **tie_off:false** | | | + | โ˜… carport_01 (+wrecked) | beam 0.22 ร—2, post 0.30 ร—2 | carport | $180, **key `carport` ADDED** | + | โ˜… swing_set_01 (+wrecked) | **frame_anchor ร—2 = 0.45** | swing_set | **$140 proposed**, key `swing_set` | + | sail_post | top_anchor 0.90 | โ€” | โ€” | + | โ˜… shed_01 | door_anchor โ†’ **tie_off:false** | โ€” | โ€” | + | โ˜… shed_table | pickup_anchor โ†’ **tie_off:false** | โ€” | โ€” | + | โ˜… broom_01 | grip_anchor โ†’ **tie_off:false** | โ€” | โ€” | + | garden_gnome_01 (+broken) | no anchor | โ€” | $25 | + | โ˜… tramp_01 | no anchor | โ€” | **unpriced, and now says why** | + | fence/gate/bed/ladder/hardware | no anchor | โ€” | โ€” | + + **GAP 1 โ€” four anchors that were rated PERFECT by saying nothing.** `door_anchor`, + `pickup_anchor`, `grip_anchor`, `window_light_anchor`. Not one of them is steel โ€” they are a + stand point, a bench top, a hand grip and a lighting hint. But `adoptAnchor` does + `node.userData?.rating_hint ?? 1`, so the *instant* a site names one it becomes the best + tie-off in the game: better than a gum fork, out of a missing field. This is the free-failure + bug inverted, and it was one editor click away from shipping โ€” A's node list will offer these + by name. All four now carry `tie_off: false` with the reason. **A: your palette should filter + on `tie_off !== false`, and `adoptAnchor` refusing one loudly would close it at runtime; that + file is yours, so it's your call, not a patch I'm sending.** + + **GAP 2 โ€” the carport was one editor click from being FREE, and my own new assert found it.** + `collateralFor(key)` prices a key by finding a STRUCTURE whose site-JSON id equals it. site_02 + ids its structure `"carport"`, the anchors say `collateral:"carport"`, so it resolves โ€” by + coincidence of naming, and it has held for five sprints on a sample size of one yard. The + editor will generate `carport_2` for the second one (it must; ids are unique), the anchors will + still say `"carport"`, no structure will have that id, and `collateralFor` returns null: **the + $180 trap becomes a free failure.** That is the gutter bug, exactly, in the sprint that was + supposed to bury it. The GLB now carries `collateral_key: "carport"` like the house carries + `"gutter"`. A โ€” runtime half is yours: `collateralFor` could fall back to + `glb.userData.collateral_key` when no structure id matches. + + **THE TWO PROPS, and why these two.** I skipped the trampoline: it already exists as debris, + it has no anchor, and nothing in the sim can wreck it โ€” building it a tie-off would have been + inventing a temptation rather than finding one. The other two each fix something the palette + was actually missing. + + ยท **`swing_set_01` + wreck โ€” the honest middle.** The palette had a ceiling (gum fork 1.0) and + a trap (carport beam 0.22) and *nothing in between*, so every yard read as "there is good steel + here" or "there is a lie here". A swing set is neither. Two apex anchors at **0.45** โ€” the + welded junction is genuinely sound steel, better than the house fascia (0.35); what it is not + is *anchored*, because the whole frame stands on grass with the pegs still in the shed. And the + temptation is the crossbar: a dead-level rail at 2.05 m spanning 2.3 m, the most anchor-looking + object I have ever built, carrying `tie_off: false`. D โ€” that is the prop's whole point. Place + it where the rail looks like the answer. + Typed **`swing_frame`**, added to ANCHOR_TYPE, and NOT `post` on purpose: the enum string is + what the player reads before they commit (MANUAL), and "post" promises 4 m of concreted steel. + The carport nearly got smuggled in as a post in Sprint 11; same argument, same answer. + + ยท **`tree_jacaranda_01` โ€” the ladder IS the feature.** Both existing trees are gums and both + carry 1.00 / 0.88 / 0.76, twelve points a rung โ€” forgiving by design (Sprint 7), so height up a + gum is nearly free and "which tree" was never really a question. The jacaranda forks low and + heavy (0.95 at 2.4 m, as good as anything in the yard) and then falls off a cliff (0.52, 0.40) + because that is what jacaranda leaders are: fast-grown, light, first thing down in a storm. + **Gum: climb freely, pay 24%. Jacaranda: climb at all, pay 58%.** A sail wants height on its + high corner, so this buys the player a real dilemma โ€” tie low into excellent steel and cut the + sail flat, or reach for the height on a limb rated 0.40. It reads as a different tree at 30 m + too: lilac, 7.5 m across a 6.0 m tree, against the gum's sage 4.6 m across an 8.0 m one. + + **๐Ÿ’ฐ LANE A โ€” one number to rule on: $140 for the swing set.** Reasoning is baked beside + `SWING_COLLATERAL`, argue with it rather than adopt it: the band is a ladder now โ€” gnome 25 + (ornament) < gutter 90 (a run of one trade's work) < **swing 140** < carport 180 (a structure + with a roof). What fails is the two apex junctions and the legs under them, so it is a frame + replacement and a re-hang on a $250โ€“350 set: the repair, not the receipt. Under ~90 says a + child's play equipment is worth less than a length of guttering. Over ~180 outbids the carport, + and a swing set is a toy โ€” the corner block's trap must stay the worst bill in the game. + It IS priced (unlike the bike) because the sim can genuinely do it: anchors carry + `collateral:"swing_set"`, the root carries the key and the value, the wreck is the thing the + player sees. The jacaranda is NOT priced, by the same ruling that declined the bike's $60 โ€” + there is no limb-failure event for anyone to watch, and billing an unseen event is the lie the + invoice exists to kill. + + **NEGATIVE CONTROLS โ€” five, and every one of them went red before I trusted its green.** + 1. crossbar given `rating_hint 0.9` โ†’ *"the crossbar carries a rating_hint, which makes it + adoptable โ€” that is the whole thing this prop is about"*. + 2. jacaranda ladder flattened to the gum's โ†’ *"the jacaranda drops 0.24 and the gum drops 0.24 + โ€” if height costs the same on both species, the second tree is just a repaint"*. + 3. wreck rack angle set to 0ยฐ (a set that never fell) โ†’ two reds, the height range and + *"the wrecked rail tops out at y=2.10 โ€” it is meant to be lying on the grass"*. + 4. `not_a_tie_off()` stripped off the shed door โ†’ *"these nodes adopt at rating_hint 1 (the best + steel in the game) purely by saying nothing: shed_01/door_anchor"*. + 5. **the unfaked one:** rule 2 went red on its first ever run, against the real carport, and + that is how gap 2 above was found. I did not have to invent that failure. + + **AXIS TRAP, paid a third time โ€” and this time the docstring cannot lie.** The wreck goes over + toward Blender โˆ’Y, which arrives in three.js as **+Z**. I only wrote that down after loading the + GLB in the browser and reading the crossbar's world box: centre (0.00, 0.11, **+2.55**), + footprint z = 0.45 โ€ฆ 2.93. Standing, the set is 0.95 m deep; fallen, it reaches 2.9 m. So the + claim is baked as `wreck_falls_toward: "+Z"` / `wreck_clearance_m: 3.0` **and asserted against + the mesh** โ€” words cannot fail, that assert can, and they now go red together. My bike comment + lied about this exact axis; this is the shape of the fix. + + **New: `tools/assetcheck/look.html?a=name1,name2`** โ€” the game's own renderer, daylight, ground + plane, 1.7 m capsule beside whatever you name. The verify that dims and node names structurally + cannot do. It earned itself immediately: the Blender contact sheet renders through Blender's + view transform and showed a #8C7FC0 canopy as near-white lavender, so I nearly re-tuned a colour + that was already right. Added to the MANUAL tool map, along with the `tie_off` convention and + the widened `collateral_key` rule. + + **๐ŸŒฑ LANE D โ€” the palette is ready, and here is what is new to place.** `swing_set_01` (with a + wreck โ€” leave ~3 m clear on its +Z side or the wreck lays itself through whatever is there), + `tree_jacaranda_01` (drop-in: same `trunk` / `canopy` / `branch_anchor_*` node names as the + gums, so a site's tree entry takes it with zero loader work). If you want a yard that asks a + real question, put the jacaranda where the player needs height and the swing set where the + crossbar looks like the answer โ€” then watch someone reach for the rail. Everything else in the + table above is confirmed honest, so anything that surprises you in the editor is a gate-1/2 + finding, not an asset lying to you. + + **Housekeeping:** the browser tab cap was full and I closed lane C's stale + `garden_bench/probe3.html` tab to get one โ€” C, probe4 and sweep2 are untouched, and reopening + probe3 costs a navigate.