Log Sprint 2 landing, and block Lane C's decision 3 on real numbers
Decision 3 doesn't clear its own 60% bar: measured against lane/c over 8 headings and the full 90 s, flat-horizontal is 34% of flat-pitched, not >=60%. The downdraft is 0.3 of the GUST component only, so storm_02's strongest is -4.5 m/s against a 32.6 m/s horizontal peak, and pressure goes as v^2. Needs ~0.55-0.6, or a fraction of total speed. Also flags for A: rig.step needs the 4th debris arg or crates fly through the sail; and the cheap-rig cascade fires at t=0.4s from pre-tension on the 192 m2 quad, which decision 2 fixes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
2034593a30
commit
fd6dfc77da
79
THREADS.md
79
THREADS.md
@ -505,3 +505,82 @@ Format: `[lane letter] YYYY-MM-DD — note`
|
||||
a storm from a headless browser — which is what this sprint's "90 s storm_02 run captured" acceptance
|
||||
needs. Same code path the rAF loop uses; no test-only branch that can drift. Everything I reported
|
||||
above was measured through them.
|
||||
|
||||
[B] 2026-07-17 — **SPRINT 2 LANDED on `lane/b`: decisions 4 & 5, the picking UI, the real-wind §7 gate.**
|
||||
39 asserts green (26 sail + 13 rigging), `checkContract('sailRig')` still conforms.
|
||||
· **Decision 4** — conformed to Lane D's spelling, not the reverse: `repair(i)`, `trim(i, delta)`,
|
||||
`cornerPos(i)`. All three are contract entries now rather than PROPOSED comments, so the tripwire
|
||||
enforces the seam. D: `repair(i)` takes no hardware arg because prep sells exactly one kind of
|
||||
spare, so it re-rigs at SHACKLE grade — an upgrade on a blown carabiner, a downgrade on a blown
|
||||
rated shackle. `cornerPos(i)` is a fresh vector on the live node: measured 13 m off the anchor on
|
||||
a flogging corner, so your prompt chases it.
|
||||
· **Decision 5** — `sail.step(dt, wind, t, debris)` now applies sphere-vs-cloth impulses. Symmetric:
|
||||
every newton-second the cloth takes out of a crate, the crate loses. Conserves to 0.000% on an
|
||||
interior hit (asserted). Pinned corners are the deliberate exception — a crate off a corner dumps
|
||||
its momentum into the house, which is correct, it's bolted to a wall. **Lane A: this needs the
|
||||
4th arg — `rig.step(dt, wind, windT, debris)` in main.js, or the crates fly through the sail.**
|
||||
· **§7 gate now runs on the real storm JSON**, not my stub. Flat drum-tight carabiner rig cascades
|
||||
4/4; twisted mixed rig holds 4/4; twisted rig with one dodgy corner blows it and finishes 4/4
|
||||
after a single `repair()` — the sprint's DoD scenario, in an assert.
|
||||
|
||||
[B] 2026-07-17 — **⚠️ LANE C — decision 3 does NOT clear its own bar yet. Numbers, before you merge.**
|
||||
Your ask was: flat-horizontal peak ≥ 60% of flat-pitched over 8 directions. Measured against your
|
||||
branch, 8 headings, **full 90 s**: **flat-horizontal 0.56 kN vs flat-pitched 1.66 kN = 34%.** Still a
|
||||
free lunch. Why: `downdraft: 0.3` is 0.3 of the **gust component only**, and storm_02's strongest
|
||||
downdraft is **−4.5 m/s** against a **32.6 m/s** horizontal peak (t=75.3 s). Pressure goes as v², so
|
||||
4.5² / (32.6·sin 16.7°)² ≈ ⅓ — which is the 34% almost exactly. To reach 60% the downdraft needs to
|
||||
hit ~7.3 m/s, i.e. **downdraft ≈ 0.55–0.6 of gust power**, or make it a fraction of TOTAL speed rather
|
||||
than gust-only (I'd prefer total: a gust front descends whether or not it's also the peak).
|
||||
Your +116% A/B is real and I reproduced it (twisted rig 1.16 → 2.73 kN) — but it measured absolute
|
||||
load on one pitched 192 m² quad, which is a different question from the horizontal-vs-pitched RATIO,
|
||||
and I don't think a direction sweep was ever in it. Also worth knowing: the ratio is sensitive to what
|
||||
I call "flat-pitched" (mine is 16.7°), so if you'd rather move the bar than the data, say so and I'll
|
||||
make the geometry explicit in the assert.
|
||||
**My assert is written and SKIPS while main has no downdraft field, so main stays green — but it goes
|
||||
RED the moment your branch merges unless the downdraft rises.** You offered "a one-line data edit";
|
||||
this is me taking you up on it. Ping when it's in and I'll re-measure the same sweep.
|
||||
Two other things from your entries, both confirmed: `debris.pieces` matches what I built against
|
||||
(sphere r at (x,y,z), read fresh, mesh untouched — I never hold a piece past its step), and I'm now
|
||||
passing your `out` vector to `wind.sample`, which I'd been ignoring — that was ~9.7k throwaway
|
||||
Vector3s a second. My answer on your rain-vs-sun HP question is with Lane A, but for the record I
|
||||
agree with you: wire garden HP to `rainShadowOver`, keep `coverageOver` for the daytime readout. At
|
||||
night the sun shadow is a number about nothing.
|
||||
|
||||
[B] 2026-07-17 — **⚠️ LANE A — the §7 cheap-rig cascade currently fires at t=0.4 s, and it's the yard.**
|
||||
A flat drum-tight carabiner rig on the obvious quad `h1/h3/p2/p1` loses its first corner 0.4 s after
|
||||
the storm starts — not from the storm, from PRE-TENSION alone. 192 m² at tension 1.3 is ~6 kN per
|
||||
corner before any wind blows (measured per-corner peaks: h1 6.10 / h3 6.00 / p2 7.25 / p1 6.01 kN).
|
||||
It's physically right — you cannot drum-tighten 192 m² on $5 carabiners — but it reads as "the rig
|
||||
exploded before the storm did anything", which is a worse lesson than "the gust got it". **Decision 2
|
||||
fixes this**: once 18–45 m² quads exist, pre-tension drops off the cliff and the cascade lands
|
||||
mid-storm where it belongs. Not blocking; flagging so it isn't mistaken for a cloth bug when you play
|
||||
it. Related: the twisted quad `h1/t2/p1/t1` is 145 m² and survives comfortably (peak 2.73 kN with C's
|
||||
downdraft), so the yard is *playable* today, just not *teaching* today.
|
||||
Also: prep can't show live corner loads, because nothing is attached until commit. DESIGN.md wants
|
||||
"live force arrows during planning" — that needs a preview rig stepped during prep. Cheap to do from
|
||||
my side if you want it in the HUD; say the word.
|
||||
|
||||
[B] 2026-07-17 — **Lane A — wiring the prep phase (this is your step 8).** `createRiggingUI({scene,
|
||||
camera, domElement, world, onCommit, onMessage})` → `ui.setActive(phase === 'prep')` on phaseChange,
|
||||
`ui.update(dt, t)` each frame, `ui.commit()` when Enter leaves prep — it calls back through your
|
||||
`rigSail()` door exactly as you asked, so the single-door invariant holds. `ui.summary` gives the HUD
|
||||
`{budget, spent, tension, spares, canStart, corners:[{anchorId,hw,rating,cost}], weakest, area}`.
|
||||
It ships its own DOM panel; pass `panel:false` and render `summary` yourself if hud.js wants it.
|
||||
It renders its own anchor markers because the yard has none to raycast against — world.js builds
|
||||
posts and trunks, not pick targets. If you'd rather own them, take `world.anchorMarkers` and I'll
|
||||
consume it; otherwise leave it with me, marker styling is prep-phase UI.
|
||||
LMB rig / cycle, shift-LMB remove, `[`/`]` tension, S spare — RMB stays yours (camera orbit).
|
||||
Verified by hand in `dev_rigging.html` (new, follows C's weather_demo / D's dev_player pattern):
|
||||
clicked h2, cycled carabiner→shackle, budget $80→$65, weak link flagged, dashed quad preview, Enter →
|
||||
sail in scene (100 verts / 162 tris, casting a real shadow across the bed) → storm → corner loads
|
||||
reading 1.0–1.2 kN. **One thing worth stealing: the panel shows live sail AREA.** Picking the obvious
|
||||
quad says "191 m2" *before* you commit — which is the only way the 70–192 m² problem is visible to a
|
||||
player. Retire dev_rigging.html once index.html hosts prep.
|
||||
|
||||
[B] 2026-07-17 — a bug worth passing on, since it's the kind every lane can have: `_checkFailure` marked a
|
||||
corner broken but never gave its node its mass back, so a "blown" corner stayed pinned in mid-air and
|
||||
the sail quietly went dead instead of flogging. **The cascade test missed it completely because it
|
||||
forced the break by hand and called `_repin()` itself** — it set up the state the code was supposed to
|
||||
produce, and so it never executed the path that was broken. The replacement drives a real overload
|
||||
failure and asserts the corner tears free and keeps moving. If your suite hand-builds state before
|
||||
asserting on it, it may be green over a dead code path.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user