- The aftermath 'ghost sliver' QA blamed on my ladder is C's hail
InstancedMesh at the origin: count:0 but frustumCulled:false +
depthWrite:false leaves instance-0 drawn as a 5cm always-on-top speck.
Fix is mesh.visible = n>0 or scale-to-zero when intensity is 0. skyfx.js.
- The shed-table spare is free and infinite: interact.js gates only on
!carrying and never reads rigging.session.spares. Took a spare 3x with 0
bought. Deletes the spare economy the ladder cost is balanced against.
Cross-lane: the count lives in B's session, main.js wires
wireYardActions without it. Needs A to thread rigging in; B owns the
economy. Flagged both. Should land before gate 4 (public difficulty hole).
Gate 2.4 asks E to agree names+thresholds with D before exporting. Filed:
- Blocker E can't see from a JING5 clone: build_player_anims.py's source
libraries (~/Documents/FBX, 3D=models/animations, mixamo-fetch) do not
exist on this laptop. All three are on ultra. The pack ships built but is
not rebuildable here.
- The asked-for clips aren't on disk anywhere (only Stumble Backwards and
Taking Cover are lean-adjacent, both already shipped), and new Mixamo
fetches need John's manual browser login. Brace and stagger are ALREADY
shipped and wired (TakeCover on KeyC, Reaction/StumbleBack on gusts) —
the lean is the only genuinely new posture.
- Bands measured at the player spawn across all five storms:
calm <8.3 / lean 8.3-17 / gale >=17 m/s, hysteresis +/-1.5. 8.3 m/s is
30 km/h, the same number C's leaves start at. Band ladder lands on the
storm rating ladder.
- Signal is sim.windBase (existing ~4s EMA), not raw wind.speedAt: raw
strobes at 8-18 band flips/min, windBase gives 0-2 per 90s storm.
Sustained = posture, gust = event. Deviation from the prompt's literal
wording flagged to A with the table.
Gate 3.3: collateralFor('gutter') returns {90, 'the gutter'} — canonical in
backyard_01.json beside the reasoning, GLB extras as fallback, per E's
collateralKey chain. House wreck wired on the carport's swap contract
(no-op until lane/e's GLB merges; window_glow state copied). site_02 stays
null: no house, no gutter. hud.js bars + main.js verdict now read
rating × ratingHint, matching sail.js's failure line (B's flag).
selftest 319/0/0.
Gate 3.2: bike_kid_01_v1 on backyard_01's south fence, rotYDeg 180 so the
baked -Z lean lands ON the fence — bars measured to the rail (0.286 m
reach, z 9.69 -> grip at 9.98), tyres 0.31 m clear, between posts. Unpriced
by ruling: the sim can't knock a bike over, and billing an unseen event is
the lie the invoice kills; the windward-fence pose is the honest one.
a.test pins lean direction, standoff band, and the ruling. 318/0/0.
audit.mjs's hand-typed backyard dump goes full-precision: the 2-dp rounding
moved t2 ~5 mm against t1's shelter cone and swung its ice-night peak
4.8 -> 9.3 kN — the node and browser front-ends disagreed by one whole
winnable line until the positions matched to the float. Reconciled by
measurement (node on full floats reproduces the browser exactly).
Re-audit verdict (THREADS, full tables): every night still passes, no retune
proposed — E's numbers stand. backyard: hints move exactly one number (night
2 honest $30 -> $40; fascia appears in zero bed-covering quads so its 0.35
is audit-invisible). site_02: 64/66 -> 23/66 affordable, every cheap carport
line dead, cheapest now $40 honest steel, cheapest >=70% line $45 through a
$30-rated carport post — the trap is priced, not fenced off.
Selftest 319/0/0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Gate 3.1: the CUT block from tools/jobsheet verbatim — letterhead, billto,
brief, sched, .void, AMOUNT DUE, terms. Docket numbers shared across the
pair (JOB/INV 1040+night); week.js nights carry an addr. Cards scroll when
taller than the window (safe center + overflow). Both rulings adopted and
pinned by DOM asserts; selftest 317/0/0.
site_audit's headless false-negative is fixed by the browser front-end
(A's loadSite/createWorld landed in main — that was all it waited on), and
fixing it surfaced a worse bug underneath: the sweep built its wind from the
STORM def alone and never called setVenturi, which main.js:424 does at every
site load. The venturi is SITE data, so every site_02 audit ever run — including
the numbers quoted at C in SPRINT10 — was of a corner block with no gap. The
SPRINT6 p1=7.4kN failure inverted: there the tool called a good site unriggable,
here it called a mean site cheap.
- sweep.js: setVenturi on both winds (the gap doesn't switch off for the settle);
both front-ends pass the site's funnel and print it, so a funnelled run is
legible as one.
- sweep.selftest.js (new, wired into b.test.js): the auditor gets an auditor.
Funnel must strictly raise every corner; a funnel-less site must be
byte-identical. Verified it fails when the setVenturi calls are deleted.
- rigging.js: setWorld(world) + session.setBudget(n)/setAnchors() — A's two asks.
Markers are rebuilt (the anchor set changes across sites) and disposed; stale
picks die with the old yard. Deletes A's "one private touch" into this module.
- dev_rigging.html: dead since SPRINT10 (called createWorld without a site, which
now throws) and nothing noticed, because a dev page has no selftest to go red.
Fixed, dressed, and given the site switch it should have had (N = next yard).
Verdict for C/A, in THREADS: site_02 PASSES with the funnel on — 64 of 66 lines
affordable, cheapest $20. The funnel kills nothing, so the gain does NOT need
dropping and E's tree stays put. It's a reach problem, not a gain problem: the
throat's radius is 5 m and the bed centre is 6.08 m away, so the gap screams over
the carport at +50% and reaches the garden at +0.0%.
selftest 300/0/0 (296 + 4 new).
The letterhead is the point: one business, two documents, same masthead, so
the job sheet and the invoice read as a pair of papers off the same outfit's
printer rather than two game screens. DESIGN.md has opened with "you run a
small landscaping outfit" since day one and it has never been on the glass.
tools/jobsheet/ — paste-ready for Lane A between CUT markers, purely additive
(.card/.row/.ledger untouched), rendered to four PNGs before handover, each
state addressable as ?v=. The ledger already WAS an invoice; it just never
said so. The line worth keeping is .void: a bonus that was on the job sheet
and didn't survive the night, struck through in the same column as the money
that did — a bonus you never watch fail is one you never learn to protect.
Two design calls left as A's with the reasoning beside them, same as the
carport's $180: the business name (proposal: HARD YARDS) and the ABN
(sequential digits on purpose — a plausible one could be a real business's).
bike_kid_01.glb — 1.15 x 0.33 x 0.74 m, 700 tris, lean baked in because a
bike doesn't stand up on its own. Two bugs caught by LOOKING at the render,
neither catchable by the existing suite: a comment claiming a step-through
above a diamond frame, and a fork with negative rake that drew head tube and
fork as one pole through the front wheel. Both passed the Blender verify —
a bounding box can't answer "is this the right shape".
The lean is an export-time axis fact (+Y in Blender is -Z in three.js), so
e.test.js now pins it in browser coords. Proved the assert fails: rebuilt at
lean=0 and Blender still said PASS while the selftest went red.
selftest 299/0/0. 32/32 GLBs byte-identical across three full factory runs.
Played lane/a 0f288be. Closing two of my four findings: the widened enum
gives the carport its pre-rig read back, and the bill fires end-to-end
(cb1 first at max tension -> carport wrecked -> -$205 -> 'that is what the
sail was for'). Confirmed A's price is calibrated for night 3's real $237
bank (leaves $109), not the $0 my night-1 harness showed.
Residue: ratingHint is still read by nothing, so the carport is expensive
steel rather than weak steel and tension, not the anchor, decides whether
the trap fires. Needs a ruling since E's tests pin those ratings.
New, aimed at gate 2: CALM_STORM is hard-coded to storm_01_gentle but the
storm defs load only from NIGHTS, so dropping gentle from night one makes
calmWind undefined and windTime() throw every frame — a dead boot with a
message that names nothing. A is about to rewrite every night entry.
Night 3 remains soft-locked; lane/b has not moved.
Gate 1.3, four sprints owed. Played the real path (nights 1-2-3, mouse).
The corner block is a good yard; two gate-1 blockers stand in front of it,
both measured rather than reasoned:
- Night 3 is unplayable. rigging.setWorld is undefined, so main.js:450's
optional call is a no-op and createRiggingUI's markers (rigging.js:254)
stay bound to the boot-time backyard. On night 3 the world/session/rig
re-point correctly but the only clickable markers are the backyard's, at
backyard coordinates. Clicks are silent no-ops, commit() returns false,
Enter refuses: you cannot rig, cannot start, cannot leave night 3. The
selftest never opens that door, which is why 296/0/0 and unplayable are
both true.
- The carport trap has no teeth. anchor.ratingHint and anchor.collateral are
written by world.js:556-557 and read by nothing; sail.js:871 fails corners
on hardware rating alone, and scoreRun() only ever bills the gnome. 46 m2
hung off the carport through the funnel pays +$82 at garden 83%.
Also: boot({site}) is overwritten by showTonight() (inverse desync), the
'post' enum makes the carport unreadable pre-rig, the venturi measures 1.5-1.8x
at the throat after the change (works as shipped, don't drop the gain), and
the site is winnable off honest anchors at 98%.
THREADS-only; no code touched on lane/d this sprint.
Answer to A's blocking gate 1 question, by measurement. venturiFactor
aligns on |dot|, so an axis is a line defined mod pi. 2.1 - (-1.08) =
3.1800 vs pi = 3.1416: the two are 2.2 degrees apart, the same gap read
from opposite ends. Measured at the throat through all of storm_03b,
axis 2.1 peaks 33.5061 m/s and axis -1.08 peaks 33.5329 — 0.08% apart,
same gust, same second. Ship 2.1 as it stands.
The error was mine and it is the repo's own lesson again: -1.08 was
dirAt(40), a wind DIRECTION, never a proposed axis. I compared it to a
gap ORIENTATION and called it a conflict. A number gathered from the
wrong harness, fourth time.
Also posted for B: gain 1.35 vs 1.5 measured at the throat (30.16 vs
33.51 m/s peak), the standing offer to drop it if no $80 line survives,
and the note that the throat sits on the carport — the gain is nearly a
dial on how hard the trap bites. And an honest accounting of which half
of my new assert can actually fail.
Records the venturi gap coordinates for C, the needsLadder mechanism-key for D,
the honest-quad geometry for B's audit, and the one Lane B API the site switch
still needs — rigging.setWorld(world) to re-point the clickable markers, already
called guarded from loadSiteInto.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Load goes as wind^2 but the funnel only fires while aligned, so gain 1.35 adds
+40% not +82% — a small quad in the throat peaks 1.99 kN, above a carabiner
(1.2) and under a shackle (3.2). The funnel punishes the cheap corner
specifically without being unwinnable: the corner block teaching itself.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Night 3 = corner block + storm_03b is the right pairing (the funnel teaches the
southerly, 03b is the southerly). Its post-change wind blows toward -1.08 rad,
so that's the venturi axis. Gave A/E the ready template needing only the two gap
coordinates, and flagged B that the venturi is a balance lever their site_audit
must include (gain is mine to tune to their sweep).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The carport anchors have said collateral="carport" since Sprint 9, but the root
carried no collateral_value — so main.js, which reads world.gnome.collateralValue
for the gnome, had no number to reach for. A trap with no price is a warning
label. The root now carries it in the same shape and place, pinned above the
gnome's 25, with the proposed 180 and its reasoning as a named constant so Lane A
can argue with the number rather than the asset.
carport_01_wrecked is the payoff, on the intact one's origin for a mesh-for-mesh
swap: the pads stay (they were never the weak part), the frame racks over like a
parallelogram, the roof peels off downwind in one piece.
Two bugs found by measuring rather than reasoning, both now comments where the
numbers are: the beams were rotated when a beam spans the axis the frame racks
in, so it rides level — tilting it made the wreck taller than the carport; and
the roof sheets dipped below ground, which is what inflated the height. Asserts
now pin the wreck shorter than its twin and sitting on the grass.
291/0/0, Lane E 64 asserts, 40/40 output files byte-identical.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
carport_01 is site_02's dressing and its whole design. DESIGN.md wants the
corner block anchor-poor, and the interesting way to build that isn't to give
the yard nothing — an empty yard is just a smaller yard. It's to give it
something that looks like four free anchors and isn't. Light posts on small
pads, a beam sized for one sheet of roofing: tie 25 m2 to it in a southerly and
you take the carport, not the shackle. Ships with the worst ratings in the game
(beam 0.22 vs the fascia's 0.35) and collateral="carport", pinned in e.test.js
below the fascia with the reason attached, so nobody quietly fixes them upward
and turns the site back into a small yard.
The pyrrhic card is the third outcome on the same camera: dawn, bed green, gnome
standing, sail post down across the yard behind him. Warm light on purpose — a
pyrrhic result is a win, and the wreckage is the price, not the verdict. Copy
goes to Lane A in THREADS; cardpreview renders all three.
277/0/0, Lane E 60 asserts, 39/39 output files byte-identical.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>