[ui] round 4 notes

All five orders shipped. The honest parts: SIM's research gating breaks SIM's
own reference factory at HEAD (GEN 80 vs DRAW 100, permanent brownout), nothing
in the game can make a science pack so research can't be performed by playing,
and the order's numbers went stale mid-round for the third round running.
No contract requests; one proposal (grantResearch, so tests stop coupling to
the save schema).

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

View File

@ -367,3 +367,104 @@ and needed a manual re-dispatch. Say the word.
**NEXT (suggested):** tech panel the moment `tech.json` has entries; verify RENDER's **NEXT (suggested):** tech panel the moment `tech.json` has entries; verify RENDER's
demolition tint once it lands; SANITISING's real fiction (The Correction's buyback) when demolition tint once it lands; SANITISING's real fiction (The Correction's buyback) when
M3 arrives — the hardcoded `anchor-slab` id should become data by then. M3 arrives — the hardcoded `anchor-slab` id should become data by then.
### Round 4 — 2026-07-17 — Opus 4.8
**SHIPPED:** All five orders. New: `power.ts` + `power.test.ts`, `research.ts` +
`research.test.ts`, `techpanel.ts` + `techpanel.test.ts`. **145 UI tests** (was 105);
`npm run check` clean.
1. **The BROWNOUT bug is fixed.** BROWNOUT is now the sim's flag and nothing else. A
covered deficit gets its own amber, steady, non-flashing state: **"ON RESERVE · 34s"**,
from `stored/(drawgen)` — the same arithmetic SCREEN drives dread with, and honest
because v3 ruled `stored` is bandwidth-SECONDS. Four states now: ok / tight / reserve /
brownout, all pure in `power.ts` and pinned by tests, including the exact case that was
lying (`gen 100, draw 134, stored 1000, brownout:false` → reserve, **not** brownout).
Bonus: the buffer readout is a fuel gauge now (`0/900`) using v4 `bandwidth.capacity`.
2. **Selection protocol migrated.** Writes go through `bus.setSelection()`, `REMOVE_DEF`
is deleted, and **my `remove` dispatch is gone** — main.ts owns it. Verified live: one
click, one removal, no double-fire. A legacy fallback remains for a host that doesn't
serve `setSelection` (it's optional in the contract) and is tested.
3. **Research UI.** `T` opens the STANDARDS COMMITTEE: every tech grouped by era in era
order, cost chips in item colours, era prefix stripped from node names, `UNLOCKS:`
tooltips in machine names. Pick → `setResearch`; picking the active one stands it down;
ratified nodes are inert. Locked machines in the bar are greyed + padlocked with
`REQUIRES: <TECH>`, can't be picked by click *or* hotkey, and the padlock falls off in
the same frame `researched` lands. `researched` → "STANDARD RATIFIED. NEW CRIMES
AVAILABLE."
4. **`?uidemo`** — boots the reference factory after init. It already paid for itself.
5. **Accent adopted**: `MachineDef.accent` → first-output derivation → codex kind table.
**LANE-RENDER: confirming we read this identically** — same three tiers, same order.
**VERIFIED — live, in the browser** (`?uidemo`, screenshots taken): the factory builds on
boot with no console poking; the STANDARDS COMMITTEE renders all 23 techs across REEL /
BROADCAST / DISC / STREAM / FORTRESS; clicking SOFTWARE DECODING dispatches `setResearch`
and the node goes hot magenta reading **IN COMMITTEE** with a progress bar (round-tripped
through the real sim); the POWER page shows DECODE ASIC bright and free next to SOFTWARE
DECODER and ASIC COOLER greyed with padlocks and `REQUIRES: STREAM SOFTWARE DECODING` /
`REQUIRES: BROADCAST ASIC COOLING`; `bus.selection()` reads `{mode:'remove'}` and a click
demolishes the mosh reactor once — DRAW 100→92, "UNIT RECLAIMED. THE FLOOR REMEMBERS."
**VERIFIED — headless** (`live.test.ts`, real sim + real DOM, 16 tests): the whole
research loop the DoD asked for — **lock visible → `place` silently dropped by the sim →
build a lab → pick the tech through the panel → packs delivered → `researched` → toast →
padlock falls off → the same `place` now succeeds.** Its harness is now a faithful main.ts
(typed selection; *it* dispatches place/remove), which is what caught the double-fire.
**DECISIONS:**
- Packs in the research run are teleported into the lab's intake via the sim's own
`save()`/`load()` (v4 hardened; `load()` re-runs `applyUnlocks`). Everything after that
is the sim's real `drainLabs → researched → applyUnlocks` path, unmocked. Reason in
BLOCKED: nothing in the game can currently *make* a science pack.
- With no `ResearchState` at all, the safe reading of the v4 rule is that gates **hold**
(padlocks on) rather than fall open, and the panel says RESEARCH OFFLINE instead of
rendering a tree that can't do anything. The sim always ships a ResearchState today, so
this is belt-and-braces.
- `live.test.ts` no longer hardcodes reference-factory coordinates — it finds the i-only
assembler by its recipe. reference.ts moved it from (-6,5) to (-6,6) *during this
round* and broke my own test; that's my brittleness, fixed.
**BLOCKED/BROKEN (read this part):**
- **SIM's research gating breaks SIM's own reference factory, and it's live right now.**
`stream-software-decoding` gates `software-decoder`; the sim silently drops placements
of gated machines (`if (!isAvailable(def.id)) return`); reference.ts places two software
decoders for its 200 of generation. Result at HEAD: `?uidemo` builds a factory with
**GEN 80 against DRAW 100, buffer 0/900, permanent BROWNOUT** — it can never run. My
screenshots show it. Either reference.ts should use decode-asics, or the demo should
pre-unlock, or that tech shouldn't gate the generator. (This is also why every
reference-factory test in `live.test.ts` now runs with research pre-granted.)
- **Nothing in the game can make a science pack yet, so no research can actually be
performed by playing.** Packs come only from `artifact-bottler`, whose recipes need
`field-splinters` / `v-hold-roll` / `static-canister` — a broadcast-era chain that
neither the reference factory nor any tech-free layout builds. The tree is *reachable*
on paper (18 techs have satisfiable costs, and DATA fixed the artifact-bottler deadlock
I was about to report), but unreachable in practice. Suggest reference.ts grow a
research rig — it would make this verifiable by playing rather than by save/load.
- **LANE-SIM's `reference.test.ts` is red at HEAD** ("keeps the demuxer alive by voiding
surplus rather than jamming"), and the factory layout shifted twice while I worked. Not
mine; flagging because the suite isn't green.
- **RENDER's demolition tint is still unverified from my side.** The typed `mode` reaches
`setGhost` via main.ts now, so the magic string is no longer my problem — but I never
saw the tint land.
- **The order's own numbers went stale mid-round, again — third round running.**
"24 nodes" is 23 at HEAD; `tech.json`'s era distribution changed under me; the
artifact-bottler deadlock I'd have reported as blocking was fixed by DATA while I
worked; SIM landed *all* of research after my round-start grep said it had none. I now
re-probe everything against a running sim before writing a word of NOTES, which is the
only reason this entry is accurate. Worth considering whether lanes should get a
"HEAD as of" line rather than counts baked into orders.
- Minor, mine: the tab row wraps to two lines now that RESEARCH joined (8 tabs + REMOVE).
Legible, not pretty. Real fix is a scrolling tab strip; say the word.
**CONTRACT REQUEST:** none this round. v4 gave me everything I asked for and the
`SelectionState` migration was clean.
**PROPOSAL:** `Sim.grantResearch(techIds)` or a `?unlocked` demo flag. Every research-
adjacent test I wrote needs research pre-granted, and my only route is
`JSON.parse(sim.save())` → mutate → `load()`. That works and uses public API, but it
couples my tests to SIM's save schema — if they rename `research` in the blob, my suite
breaks for no good reason.
**NEXT (suggested):** verify RENDER's tint; research rig in reference.ts so a pack economy
exists to test against; scrolling tab strip if the catalog grows again; era-skinned tech
panel once eras mean something visually (§8).