[screen] round 3 notes

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
type-two 2026-07-17 18:20:50 +10:00
parent 18f6575660
commit 3707afa3a0

View File

@ -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.