From f7a22eabb8ef63631093affdac36c9a5be878845 Mon Sep 17 00:00:00 2001 From: type-two Date: Mon, 20 Jul 2026 20:48:34 +1000 Subject: [PATCH] =?UTF-8?q?Lane=20B=20S16:=20ponding=20fabric-blindness=20?= =?UTF-8?q?RULED=20a=20known=20simplification=20=E2=80=94=20the=20comments?= =?UTF-8?q?=20stop=20lying?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit C's gate-3 finding, answered in the file it names: _applyPonding never reads porosity, so cloth and membrane pond identically while setFabric's comment and the cloth blurb promised shedding. Ruled, not silently fixed: every pinned cloth number (backyard separation, the section-7 gates, C's storm_06 pins, the S15 zero-delta lattice) was measured under fabric-blind ponding, and a pond- physics change mid-TEETH moves them all against the one-variable law. The fix (porosity-scaled intake + through-weave leak) wants its own gate with a full gauntlet re-measure; C's soaker is its test case. setFabric's comment carries the ruling, _applyPonding carries the warning, the cloth blurb drops 'sheds water' (a player-facing claim the sim doesn't cash). Co-Authored-By: Claude Opus 4.8 --- web/world/js/rigging.js | 6 +++++- web/world/js/sail.js | 25 +++++++++++++++++++++---- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/web/world/js/rigging.js b/web/world/js/rigging.js index f7da5c3..bdcde17 100644 --- a/web/world/js/rigging.js +++ b/web/world/js/rigging.js @@ -46,7 +46,11 @@ export const DEFAULT_TENSION = 1.0; * weight, membrane earns a price and this comment is the place to start. */ export const FABRIC = [ - { id: 'cloth', name: 'shade cloth', porosity: 0.30, cost: 0, blurb: 'wind blows through — half the load, sheds water, leaks the finest hail' }, + // Blurb honesty (SPRINT16): "sheds water" deleted — C measured that ponding + // is fabric-blind (_applyPonding never reads porosity; both cloths pond + // identically), and a player-facing claim the sim doesn't cash is the worst + // kind. Ruled a known simplification in sail.js setFabric's comment. + { id: 'cloth', name: 'shade cloth', porosity: 0.30, cost: 0, blurb: 'wind blows through — half the load, leaks the finest hail' }, { id: 'membrane', name: 'waterproof membrane', porosity: 0, cost: 0, blurb: 'stops rain and every stone — full wind load, and it ponds' }, ]; export const DEFAULT_FABRIC = FABRIC[0]; diff --git a/web/world/js/sail.js b/web/world/js/sail.js index 075f971..e5a9b54 100644 --- a/web/world/js/sail.js +++ b/web/world/js/sail.js @@ -529,6 +529,11 @@ export class SailRig { /** * Rain lands, runs downhill, and pools where it can't get out. Called after * the wind pass (which fills _nodeFlat / _nodeArea). + * + * ⚠ FABRIC-BLIND, on purpose and on the record (SPRINT16, C's finding): + * nothing below reads `this.porosity`, so an open weave ponds exactly like a + * membrane. Ruled a known simplification — see setFabric's comment for the + * ruling and the re-measure bill a real through-weave leak would incur. * @param {number} mmPerHour wind.rainMmPerHour(t) — REAL-world rate, Lane C's data */ _applyPonding(mmPerHour, dt) { @@ -1105,10 +1110,22 @@ export class SailRig { } /** - * What the sail is made of. Porosity scales the wind pressure term and, since - * rain lands on the horizontal projection of a face, an open weave sheds the - * water it can't hold — so a porous cloth also ponds far less. Set BEFORE - * attach(); RiggingSession.commit() does that. + * What the sail is made of. Porosity scales the wind pressure term — and, as + * of SPRINT16, that is ALL it scales. The previous version of this comment + * claimed an open weave "sheds the water it can't hold — so a porous cloth + * also ponds far less", and C's gate-3 measurement caught the cheque the sim + * doesn't cash: _applyPonding never reads porosity, so cloth and membrane + * pond IDENTICALLY (the $75 soaker ring's q2 gap, 3.24 vs 3.32 kN, is wind + * term only). RULED a known simplification rather than silently fixed + * ([B] THREADS 2026-07-20): every pinned cloth number in the repo — the + * backyard separation block, the §7 gates, C's storm_06 pins, the S15 + * zero-delta lattice — was measured under fabric-blind ponding, and a pond- + * physics change mid-TEETH would move all of them against the sprint's own + * one-variable law. The fix (porosity-scaled intake + through-weave leak) + * is real, wants its own gate with a full gauntlet re-measure, and C's + * soaker is its ready-made test case; rigging.js's membrane-pricing comment + * is the same conversation. Set BEFORE attach(); RiggingSession.commit() + * does that. * @param {{porosity:number}|number} f a FABRIC entry or a raw porosity */ setFabric(f) {