HardYards/web/world/js/tests
m3ultra 942709d2e9 Site-proof the ladder ahead of site_02, and test the real rule not a copy
SPRINT9 §Lane D: "play site_02 cold and log where the verbs break (the ladder
assumes fascia height; the carport may not have one)". site_02 isn't landed yet,
so I audited the verb against it instead of waiting.

The seam is real but it isn't height — it's that `needsLadder` is spelled
`type === 'house'`, and contracts.js types anchors as a closed enum
('house'|'tree'|'post') that E's carport doesn't fit. The failure mode is what
makes it worth fixing now: if needsLadder says false, interact's canReach returns
TRUE UNCONDITIONALLY, so the player re-rigs a 2.6 m bracket standing on the grass
and the mechanic silently stops existing. Same disease as StumbleBack's dead
threshold and the camera-less shadow grid — a rule keyed on the wrong thing,
failing open with no error.

A pure height test is NOT the fix: posts (3.95 m) and tree limbs (5.05 m) are
higher than the fascia and need no ladder, because you work the CLOTH there and
the bracket here. So needsLadder now reads data first —
`anchor.worksAtBracket` — exactly like anchor.ratingHint already does from the
GLB's userData, and falls back to site_01's type. Nothing on site_01 carries the
flag, so it's a no-op there (asserted). Lane A/E: set it in the site JSON and the
ladder follows the site with no code change.

Also made ladder.js headless-importable (lazy GLTFLoader, same as broom.js),
because d.test.js was testing fakeLadder's hand-copied duplicate of needsLadder
rather than the rule itself — a rule the suite re-implements is one it cannot
catch drifting. Verified the ladder's GLB still loads in the browser.

62 Lane D asserts headless, 275/0/0 in the browser.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 14:32:06 +10:00
..
a.test.js The week: five nights, one wallet, and an ending that tells the truth 2026-07-17 13:13:44 +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 Gate 0' guard: redesign it to measure SHAPE, and prove it fires 2026-07-17 14:25:08 +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 Site-proof the ladder ahead of site_02, and test the real rule not a copy 2026-07-17 14:32:06 +10:00
e.test.js Sweep and taper the tree limbs; pin the anchors that ride them 2026-07-17 11:25:03 +10:00
run-node.mjs Add wind field, storm timelines and weather selftest 2026-07-16 21:38:12 +10:00
weather.selftest.js Land hailBlockFor(size, porosity) — the honest fabric-hail rule for B 2026-07-17 11:30:37 +10:00