sustained to ${peak.toFixed(0)} m/s (${kmh(peak).toFixed(0)} km/h)
- · gusts to ~${kmh(gustPeak).toFixed(0)} km/h
rain ${rainPeak >= 0.8 ? 'heavy' : rainPeak >= 0.4 ? 'steady' : 'light'}${
- hail ? ' · hail forecast' : ''}
+
${(f.name ?? key).replace(/_/g, ' ').toUpperCase()}${night ? ' · NIGHT' : ''}
+
${f.wind}
+
${f.rain}${hail ? ' · hail forecast' : ''}
${change ? `· change at ${change.t}s` : '· no change forecast'}
+ ${f.confidence ? `
${f.confidence}
` : ''}
in the bank$${wk.bank}
${hail
diff --git a/web/world/js/tests/balance.test.js b/web/world/js/tests/balance.test.js
index ad6e074..73c2215 100644
--- a/web/world/js/tests/balance.test.js
+++ b/web/world/js/tests/balance.test.js
@@ -315,50 +315,10 @@ export default async function run(t) {
// measurement, not the verdict.
t.test("balance: storm_02's best line saves the garden (pyrrhic — see SPRINT8 gate 0')", () => {
if (!line) throw new Error('the $80 shop cannot buy the candidate line at all');
-<<<<<<< HEAD
// The garden half — the part the player is actually protecting — must hold.
if (line.hp < 50) {
throw new Error(`the wild night's best $${line.spent} line let the garden die: hp=${line.hp} ` +
`(need >=50). This is a real balance regression, not the pyrrhic-win question.`);
-=======
- // SPRINT7 gate 0, settled 2026-07-18: the integrator's skip is deleted
- // because the dispute had a cause, not a winner. This suite built skyfx
- // WITHOUT a camera, and skyfx.step() opens `if (!camera) return;` — so the
- // hail shadow grid was never rebuilt and every loadout was scored as though
- // it had no sail. That is why this line read hp 36: 36 IS the bare-bed
- // number. With a camera it reads what Lane A measured. Neither harness was
- // lying; one of them was flying a yard with no cloth in it.
- if (!WIN(line.hp, line.lost)) {
- // SPRINT8 gate 0' — CLOSED, and this suite was RIGHT. The live game and this harness now
- // agree, measured by Lane D 2026-07-18 on current main (fresh page, A's exact line,
- // t2+p3+p4+t2b on 4×shackle+spare, tension 1.0):
- // live game → hp 58, 2 lost [t2,t2b], t2 peak 4.55 kN
- // this suite → hp 58, 2 lost [t2,t2b], t2 peak 4.54 kN
- // Every suite-vs-game difference gate 0' listed has now been tested one at a time and NONE
- // of them moves the corner count: live-calm settle (entry 1.94→0.40 kN, verdict unchanged),
- // live tree sway (t2 4.33→4.55, verdict unchanged), walked repair timing (unchanged).
- // Anchors are bit-identical between harnesses, ring order is identical (p4,t2,t2b,p3), and
- // wind.sample() at t2 is identical to 2 dp (36.49 m/s @ t=75.9).
- //
- // RETRACTED, on the record: Lane D's "the settle flips 2 lost → 1" (SPRINT7). It does not
- // reproduce — 0 s and 12 s settle both end 2 lost, because the storm's own peak (4.54 kN at
- // t=75.9) dwarfs the attach transient. The settle is a real fidelity fix and NOT the
- // corner-count cause. A's hp 58 reproduces exactly; A's "1 lost" reproduces in neither
- // harness.
- //
- // What's left is B's arithmetic, which was correct from the first post: t2 pulls ~4.5 kN and
- // a shackle is rated 3.2 kN. The corner cannot hold at any tension, and the spare cannot save
- // it — the repaired corner simply blows again (measured: t2b blew @9 s, repaired, blew again).
- // So this is no longer an engineering question. It is SPRINT8's designed escape hatch:
- // hp 58 CLEARS the 50 bar while 2 corners are lost, i.e. the player saves the garden and
- // loses the sail — DESIGN.md's own story — and the win rule (`hp>=50 && lost<2`) calls it a
- // loss. Either the rule admits a PYRRHIC WIN, or the shop must be able to buy a third
- // above-shackle corner ($80 buys two). That is a design call, not a harness bug. See THREADS.
- throw new Error(
- `no winnable line: ${COVER_QUAD.join(',')} on 4×shackle+spare ($${line.spent}) ended ` +
- `hp=${line.hp}, lost=${line.lost}/4 (need hp>=50, lost<2). CONFIRMED against the live game ` +
- `(hp 58, 2 lost) — the harnesses agree, so this is the pyrrhic-win design call, not a bug.`);
->>>>>>> origin/lane/d
}
const pyrrhic = line.lost >= 2;
return `$${line.spent} on ${COVER_QUAD.join(',')} -> garden hp ${line.hp}` +