HardYards/web/world/js/tests
type-two 8ec01028f9 Lane E, Sprint 11: client juice — job sheet, invoice, and the kid's bike
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.
2026-07-17 17:39:58 +10:00
..
a.test.js The second site: corner block loads from JSON; night 3 moves to it 2026-07-17 16:05:06 +10:00
b.test.js Align sail lane to contracts.js; free blown corners so they flog 2026-07-16 21:55:37 +10:00
balance.test.js Prove the porosity->gardenHailExposure leak end-to-end (answer C's seam) 2026-07-17 15:55:11 +10:00
c.test.js Ship forecast uncertainty to the card (carried twice — now visible) 2026-07-17 13:10:53 +10:00
d.test.js Land needsLadder on the work field, measured against E's real carport 2026-07-17 15:28:47 +10:00
e.test.js Lane E, Sprint 11: client juice — job sheet, invoice, and the kid's bike 2026-07-17 17:39:58 +10:00
run-node.mjs Add wind field, storm timelines and weather selftest 2026-07-16 21:38:12 +10:00
weather.selftest.js Add validateSiteWind — the site JSON's wind block fails loud (SPRINT10) 2026-07-17 15:30:00 +10:00