From 3707afa3a0333f301b303344bf9e22a4d46652e8 Mon Sep 17 00:00:00 2001 From: type-two Date: Fri, 17 Jul 2026 18:20:50 +1000 Subject: [PATCH] [screen] round 3 notes Co-Authored-By: Claude Opus 4.8 --- fktry/lanes/LANE-SCREEN.md | 76 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/fktry/lanes/LANE-SCREEN.md b/fktry/lanes/LANE-SCREEN.md index da08453..a48898b 100644 --- a/fktry/lanes/LANE-SCREEN.md +++ b/fktry/lanes/LANE-SCREEN.md @@ -222,3 +222,79 @@ NEXT (not self-assigning): stamps currently say the item's NAME; once MODELBEAST rather stamp the item's *silhouette* in its chip colour. Also the 3 new passes are all full-frame — moiré especially wants to grow from a *region* (the codex has it spreading as maze walls across the factory floor), which would want a spatial mask rather than a scalar. + +### Round 3 — 2026-07-17 — Opus 4.8 + +SHIPPED: all 4 orders. Thank you for the v3 grant — `frame(timeMs, snap?)` is exactly the seam +strain needed. +- `strain.ts` (new) — pure, snapshot-shaped, no DOM/GL. The whole point: order 4's sterile + guarantee is now a unit test, not a promise. +- `strain.test.ts` (new) — 14 tests. Screen suite is 44 green. +- `glitchStack.ts` — `growthMask()` + tremor/fever warps + regional moiré + fever tint. +- `index.ts` — snapshot peek, strain easing, deterministic moiré seed, 3-frame scram. + +DECISIONS: +- **Tremor is measured in SECONDS, not units.** Your v3 units ruling made this: `stored` is + bandwidth-seconds, `draw-gen` is bandwidth/second, so `stored/(draw-gen)` is literally *how + long until the lights go out*. Dread ramps over the last 8 seconds of reserve. This falls out + correct at every scale for free — a megafactory bleeding 1000/s with 4000 banked feels exactly + as doomed as a shack bleeding 10/s with 40 banked, because both have 4 seconds. There's a test + pinning that equivalence. Raw `stored` would have made big factories look permanently calm. +- **Surplus is always calm, whatever the reserve.** If `draw <= gen` nothing is draining, so + there is nothing to dread — which is *also* what makes the boot state (gen=draw=stored=0) + sterile by construction rather than by special-case. Order 4 fell out of the maths. +- **Fever averages only the machines that run hot** (heat > 0.01). Averaging across every entity + would drown one glowing decoder in a sea of cold belts, and belts are most of a factory. +- Tremor ≈ ¼ of the brownout's judder amplitude, and fever is a smooth sine haze while tremor is + random judder — so dread, fever and seizure are three distinguishable readings, not one dial. + Strain stays weather: MAD vs sterile is ~6.8, against ~35 for moiré. Subordinate as ordered. +- **Regional moiré separates AREA from INTENSITY.** Intensity saturates early (`u_moire*2.2` + clamped) while the mask's radius keeps growing with tally. That's what makes a big shipment + read as "the maze has spread" instead of "everything got slightly shimmery" — which is the + whole difference between regional and a scalar fade. +- `growthMask(p, seed, grow)` is written as the **reusable spatial-artifact template** you asked + me to note: an fbm-ragged growth front, aspect-corrected, creeping outward from a seed. Any + future artifact that should grow from a PLACE multiplies its amount by it. The raggedness is + load-bearing — a clean circle reads as a spotlight, not as spreading crystal. +- Moiré seeds from the tick of the first moire-weighted shipment, so a given run always grows the + same maze while different runs grow it elsewhere. Debug-hook ships default to tick 0. + +VERIFIED (fixture snapshots + pixel reads + contact sheets): +- **Order 4, at the pixel level**: rendered no-snapshot / boot / healthy at an *identical* + timebase — boot and healthy are **byte-for-byte identical** to no-snapshot. Strain cannot leak + into the NOTHING IS WRONG era. (First attempt showed MAD ~1-2 and that was my harness: each run + advanced the clock, so the *timecode digits* differed. Fixed the test, not the code.) +- **Tremor ramp** (deficit 10/s): 20s left → 0, 8s (the horizon) → 0, 4s → 0.50, 2s → 0.75, + empty → 1.00. Fever 0.837 from hot decoders with tremor still 0. +- **Regional moiré growth**, as % of frame taken over: 0 → 20.1% → 44.7% → 74.5% → 84.5% → 85.8% + across 0/4/10/25/60/150 crystals. It spreads; it does not switch. The front is visibly ragged. +- **Seed**: same tick → same seed twice over; different tick → different seed. Deterministic. +- **Scram**: read the bar's row per frame — `BAR,BAR,BAR,-,-,-`. Exactly 3 frames, readable now. +- **Budget: 0.072 ms/frame** wall-clock with a forced GPU sync, on a 2000-entity factory with + every artifact class lit — `computeStrain`'s per-frame entity walk is not measurable at that + size. CPU-only 0.043 ms. Still ~28× under. + +BLOCKED/BROKEN: nothing outstanding. +- **I found and fixed a real bug in my own code while chasing a false alarm.** My `dt` was + `Math.min(0.1, ...)` — ceiling clamped, floor not. A *negative* dt (clock rewind) turns + `ease()`'s `1-exp(-dt/tau)` into a huge negative multiplier and threw strain to **-3614** before + it crawled back. Production can't hit it (`performance.now()` is monotonic, and main.ts passes + it straight through), so this was only reachable from my harness — but an eased value that can + explode on a clock hiccup is a landmine, so `dt` is now clamped at both ends. Worth other lanes + checking their own dt handling if they ease anything. +- Full suite went 215/216 once mid-run, then 216/216 twice — another lane mid-write, not a real + red. HEAD is clean repo-wide, tsc included. + +CONTRACT REQUEST: none. v3 covers everything I need. + +PROPOSAL: `SimSnapshot.bandwidth` has no *capacity* field, so THE SCREEN can express "seconds +until empty" but not "the tanks are 20% full". Seconds is the better dread metric and I'd keep it +either way — but if buffer capacity ever lands in the snapshot cheaply, a second reading ("reserve +low" vs "reserve draining fast") would let strain distinguish a factory that's coasting on fumes +from one that's falling off a cliff. Not asking; noting the seam while it's fresh. + +NEXT (not self-assigning): the mask template is ready for reuse — **bloom loops** and **HF dust +piles** are the obvious next spatial artifacts (both are regional in the codex), and the strata +biomes in §1 would suggest a mask per era. Also, now that strain reads the snapshot, THE SCREEN +could react to `jammed` entities (a stalled factory *should* look bored — the feed drifting back +toward clean is a nice punishment), but that's a design call, not a lane call.