573 lines
39 KiB
Markdown
573 lines
39 KiB
Markdown
# LANE-DATA — content, recipes, balance, and canon-keeping
|
||
|
||
You are an Opus 4.8 executor on the DATA lane of FKTRY. Read `../MASTERPLAN.md` and
|
||
`../CONTRACTS.md` first. Your bible is `../../docs/FKTRY_LORE.md` — you are its
|
||
transcriber into machine-readable canon. When the codex and convenience disagree, the
|
||
codex wins; when the codex is silent, invent IN ITS VOICE and note what you invented.
|
||
|
||
**Mission:** every item, machine, recipe, tech, and commission as clean JSON, plus the
|
||
validator that keeps five parallel lanes from drowning in dangling ids. Content should
|
||
light up in-game with zero code changes from other lanes.
|
||
|
||
**Owned paths:** `data/**` (the validator now lives at `data/validate.test.ts`;
|
||
the old `src/sim/data-validate.test.ts` exception is closed — round 3 moves it).
|
||
**Never touch:** contracts, main.ts, other lanes' code. Schema changes are CONTRACT
|
||
REQUESTs.
|
||
|
||
**Standing rules (all rounds):**
|
||
- Ids: kebab-case matching codex names (`chroma-slurry`, `mosh-reactor`). `codex`
|
||
field points at the lore doc section (`"3:melt"` = §3, MELT entry).
|
||
- Balance philosophy: absurd flavor, honest math. Ratios should create real routing
|
||
pressure (byproducts you must deal with, not vent). Steal shamelessly from the
|
||
doc's real numbers (era efficiency multipliers, 4:2:0 = half the chroma, GOP
|
||
cadences).
|
||
- Never delete an id other lanes may reference mid-round — deprecate in NOTES first.
|
||
|
||
---
|
||
|
||
## CURRENT ORDERS — Round 6 (goal: The Correction gets teeth, the map stops drifting)
|
||
|
||
1. **FIREWALL machine** + catch recipe on SIM's trap pattern (they detect by recipe
|
||
shape); `parity-mite` canned item; mite spawn tuning if SIM makes it data-driven;
|
||
commissions that want canned mites ("ONE (1) UNIT OF THE CORRECTION, ALIVE.
|
||
INVOICE ATTACHED. DO NOT READ THE INVOICE.").
|
||
2. **Numbers-station drift fix** (SCREEN's round-5 finding): two decoys decode onto
|
||
real visible seams (08127 → reel-beds-deep, 27503 → broadcast-shelf-south);
|
||
your validator recomputes plants but not decoys — re-cut the decoys and extend
|
||
the validator so a decoy landing on ANY seam fails by name.
|
||
3. **Accent fills for the GLB'd 10**: the ten machines with real models now get
|
||
`accent` values chosen against their actual textures (RENDER's overlay reads it).
|
||
4. **THE STANDARD mite lines** (~8 new, coordinate with SCREEN), CANON-DELTA the
|
||
mite reading of §5.
|
||
|
||
**DoD:** firewall catches against SIM's real mechanic; no decoy decodes onto any
|
||
seam (validator-enforced); all 10 GLB machines accented; the fax celebrates its
|
||
first canned mite in voice.
|
||
|
||
---
|
||
|
||
## NOTES (append-only log, newest at bottom)
|
||
|
||
```
|
||
### Round N — YYYY-MM-DD — [your model]
|
||
SHIPPED: / DECISIONS: / INVENTED: / BLOCKED/BROKEN: / CONTRACT REQUEST: / NEXT:
|
||
```
|
||
|
||
### Round 1 — 2026-07-17 — Opus 4.8
|
||
|
||
SHIPPED:
|
||
- Validator `src/sim/data-validate.test.ts`, 28 tests. Fault-injected a recipe with a
|
||
dangling item + a machine that doesn't list it — both caught by id and named. It is
|
||
not a test that only knows how to pass.
|
||
- items 9 → 36, machines 7 → 21, recipes 4 → 35, tech 0 → 17, commissions 1 → 10.
|
||
- Verified: `tsc` clean, `vitest run` 52/52 green (LANE-SCREEN's 24 included), and the
|
||
live dev build boots with no console errors. All 21 machines appear in LANE-UI's
|
||
build bar with zero code changes from them.
|
||
|
||
DECISIONS:
|
||
- **All four seed recipe ids kept alive** (`extract-mdat`, `demux-ore`, `quantize`,
|
||
`mosh`) so nothing dangles for a lane mid-round. `mosh` keeps its id but is rewired
|
||
to canon: `gop-crate 1 → melt 3 + anchor-slab 1`. The winched-out I-frame is
|
||
recovered (§4 mosh reactor: "recoverable — sell it!"), so slabs circulate and delta
|
||
wafers are what actually burns. Net economy: 6 wafers → 3 melt.
|
||
- `quantize` left at the seed's exact ratio so the M1 chain stays easy to build.
|
||
- **M1 chain is longer than the masterplan says — please rule on this.** My orders
|
||
spell out `slab + wafers → gop-crate` and `gop-crate → mosh`, but MASTERPLAN M1
|
||
describes extractor → belts → demuxer → quantizer → mosh → shipper (seven machines).
|
||
Those can't both be true: reaching a crate needs dct-press (slab), p-caster (wafers)
|
||
and gop-assembler in between. I followed the orders since they're the more specific
|
||
and more recent instruction, and all three run fine as generic crafters. If M1 must
|
||
stay at seven machines, say so and I'll add a shortcut `mosh-raw` recipe next round
|
||
rather than weaken the canon path.
|
||
- Machine params that the codex describes as dials (quantizer Q, subsampler grade taps,
|
||
GOP cadence templates) are modelled as **separate recipes per setting**, not as a
|
||
per-entity parameter. Cheapest thing that works against the current contract; if SIM
|
||
ever wants a real dial, that's a contract change, not a data change.
|
||
- Two absurd-but-honest ratios, as ordered: `assemble-gop-i-only` burns 8 premium slabs
|
||
for 1 crate (I-only genuinely is the worst cadence — the joke balances itself, nobody
|
||
sane builds it), and `pan-speckle` takes 40 HF DUST for 1 speckle (§3 says "panned
|
||
like gold", so it's priced like gold panning). Both give hf-dust real sinks.
|
||
|
||
INVENTED (codex is silent; written in its voice — kill any of these if you disagree):
|
||
- `press-anchor-slab` on the DCT PRESS — the press run in reverse is an IDCT, i.e. a
|
||
complete picture. Consistent with the field loom and telecine puller, which the codex
|
||
explicitly runs backwards. This is where I-frames come from.
|
||
- Items `color-plate` (the demosaicer's "full-color sheet", §4) and `v-hold-roll`
|
||
(bottled from the §1 Broadcast Shelf v-hold faults, so the ANALOG PACK's "combing +
|
||
v-hold roll + static" triptych maps to three real items).
|
||
- Machines `artifact-bottler` (§2 calls the packs "a bottled artifact triptych" but
|
||
names no bottling plant) and `lane-splitter` (contract has `kind: 'splitter'` and
|
||
belts need routing; the codex only ever calls the DEMUXER "the first splitter").
|
||
|
||
BLOCKED/BROKEN: nothing blocked. Known-incomplete, deliberately:
|
||
- Bloom is one grade, not the graded 1-5 line §3 sells by intensity.
|
||
- `container-pack` / `cinema-pack` / `mosquito-swarm` / `gibbs-wraith` exist as items
|
||
with no recipe — forward canon, per orders. The validator's reachability test has an
|
||
explicit FORWARD_CANON allowlist so these four can't hide a real dangling id; delete
|
||
entries from it as recipes land.
|
||
- `stream-hex-splicing` costs container-packs nothing currently produces. Intentional
|
||
dead-end until the moov/container line exists (§6 heists).
|
||
|
||
CONTRACT REQUEST: `MachineDef.heatPerTick?: number` — the SOFTWARE DECODER is
|
||
`kind: 'power'`, and power machines carry no recipes, but `RecipeDef.heat` is the only
|
||
heat hook in the contract. So the one machine the codex defines *by* its heat (§4:
|
||
"decodes ANYTHING, at any temperature") has no way to declare it. It's shipped as a
|
||
plain 45-gen power machine and is currently strictly better than the ASIC, which is
|
||
backwards. Alternative if you prefer no contract churn: let power machines run a
|
||
recipe with empty outputs — but I'd rather not put `outputs: {}` in the data, and my
|
||
validator rejects it today.
|
||
|
||
NEXT (Round 2 candidates, not self-assigned): bloom grades 1-5 as real items; the
|
||
container line (moov shard / offset ribbon / sync key → CONTAINER PACK) which unblocks
|
||
the hex splicer; mosquito traps so `vaporwave-sunset` becomes shippable; buffer-tank
|
||
and muxer data; reel + broadcast era tech nodes.
|
||
|
||
### Round 2 — 2026-07-17 — Opus 4.8
|
||
|
||
SHIPPED: all 7 orders. `data/CANON-DELTA.md`; colour + flavor on all 21 machines;
|
||
heat economy; `bufferCap`; commission queue with 3 standing orders; container line;
|
||
bloom grades 1-5. items 36 → 44, machines 21, recipes 35 → 44, tech 17 → 19,
|
||
commissions 10 → 14. Validator 28 → 36 tests.
|
||
- Verified: my 36 pass; **every other lane's suite is green** (140/141 total — the one
|
||
failure is SIM's, see BLOCKED). Live build: 21/21 machines art-directed with zero
|
||
gaps, my hexes confirmed on the real DOM swatches (ASIC `rgb(185,190,196)`, software
|
||
decoder `rgb(110,58,52)`), no console errors, fax opens on FIRST TASTE with DUST
|
||
ALLOWANCE next in tray.
|
||
- Fault-injected all six new checks (missing colour, absurd heatPerTick, buffer with no
|
||
cap, non-buffer with a cap, wrong queue head, standing order wanting live mosquitoes)
|
||
— all six failed by name, then restored. Same standard as round 1.
|
||
|
||
DECISIONS:
|
||
- **`bloom-concentrate` kept, not replaced.** It is now the raw ungraded draw-off that
|
||
feeds grading. I was about to retire it for the grade-1..5 line until I grepped:
|
||
LANE-SCREEN hardcodes it in `src/screen/corruptionMap.ts:54` and its test. Deleting it
|
||
would have broken their suite mid-round. The standing rule earned its keep.
|
||
- The round-1 recipe id `bloom-grade-3` survives but now produces the *item*
|
||
`bloom-grade-3` — the id finally means what it says. The old recipe body moved to
|
||
`tap-bloom`. Nothing outside `data/` referenced it (checked).
|
||
- Container line routes demuxer → gop-assembler → bottler, deliberately **not** through
|
||
the hex splicer, since §4 gates the splicer behind CONTAINER PACK research. Otherwise
|
||
the tech tree eats its own tail.
|
||
- Machine colours are all desaturated industrial per §8 ("ALL saturation belongs to
|
||
media/artifacts"). The items carry the colour; the factory is grime. Two eras get a
|
||
tint where the codex insists: field loom phosphor-green, telecine brass, ASIC
|
||
stream-era white, software decoder hot-red.
|
||
|
||
INVENTED: 3 items (`moov-shard`, `offset-ribbon`, `sync-key`), 6 recipes, 2 tech nodes,
|
||
2 commissions. All logged with rationale in `data/CANON-DELTA.md` rather than here.
|
||
|
||
BLOCKED/BROKEN:
|
||
- **SIM's M1 chain test is red, and it is not mine.** `sim.test.ts:456` asserts
|
||
`activeCommission === 'first-taste'` after 4000 ticks, but SIM's new queue advances on
|
||
completion, so it reads `dust-allowance`. I confirmed this by stashing my entire round
|
||
2 diff and re-running: identical failure. Their assertion needs updating to their own
|
||
new behaviour — I didn't touch their file. My validator now pins `commissions[0]` as
|
||
`first-taste` so the queue head stays load-bearing for them.
|
||
- `npx tsc --noEmit` reports 2 errors in `src/render/index.ts` (94, 96) from RENDER's
|
||
uncommitted work. Also not mine — a JSON file cannot cause "Expected 3 arguments".
|
||
|
||
CROSS-LANE — SIM, two things I need from you:
|
||
1. **Units.** I read `gen`/`draw` as bandwidth **per second** (codex §2 meters read
|
||
kbps). `bufferCap: 240` is built on that. If you integrate per *tick*, my buffer
|
||
number is 30× too small — say so and I'll retune. Arithmetic is in CANON-DELTA.
|
||
2. **Cooling is yours and it doesn't exist yet.** `heatPerTick: 0.0025` makes a software
|
||
decoder throttle at 9.3s and scram at 13.3s of continuous running, which is the codex
|
||
("burst gen ... throttles theatrically"). That only becomes a *mechanic* if something
|
||
cools it; with no cooling it's a one-shot fuse. I assumed ~0.0025/tick while
|
||
scrammed/idle (~50% duty → effective 27/s vs the ASIC's steady 20/s, in the same 2×2
|
||
footprint). Tell me your rate and I'll retune to hit "throttle ~10s, full cycle ~25s".
|
||
**Heads up:** your `meltChain()` reference factory runs on 3 software decoders and no
|
||
ASIC. Once scram lands they will heat in lockstep and black out together every ~13s.
|
||
That's the honest answer to "does anyone dare run two side by side" — but it will slow
|
||
your reference factory, so consider an ASIC base + one decoder for burst, or a buffer
|
||
tank (which is exactly what `bufferCap: 240` is sized to cover: one scram).
|
||
|
||
CONTRACT REQUEST: none this round.
|
||
|
||
NEXT (candidates): a cooler machine — §2 says heat is "Vented by ASIC coolers", a
|
||
machine the codex names but never specifies, and without it heat has no counterplay;
|
||
mosquito traps (unblocks `vaporwave-sunset`); reel + broadcast era tech; the muxer and
|
||
the moov brain's four sub-lines (§7); cinema-pack when the Fortress exists.
|
||
|
||
### Round 3 — 2026-07-17 — Opus 4.8
|
||
|
||
SHIPPED: all 6 orders. Validator moved to `data/validate.test.ts` (git mv, imports
|
||
rewired, vitest picks it up from the new home; `src/sim/**` is fully SIM's again).
|
||
Heat retuned. `bufferCap` re-derived. ASIC COOLER + muxer + moov brain authored. Reel
|
||
and broadcast eras. items 44 → 51, machines 21 → 23, recipes 44 → 51, tech 19 → 24.
|
||
Validator 36 → 41 tests.
|
||
- **DoD met, verified against the real sim, not my arithmetic**: I wrote a throwaway
|
||
probe that ran LANE-SIM's actual `createSim()` with my data — **throttle at 10.17s,
|
||
scram at 14.50s, downtime 16.67s, ASIC heat still 0 after 100s**. Predicted 10.14 /
|
||
14.49 / 16.67. Then deleted the probe: it asserts sim behaviour, which is SIM's lane
|
||
to test, not mine.
|
||
- Full tree green: **223/223 across all 16 files** — SIM's reference factory and
|
||
pressure tests pass against the rebalanced numbers. Live build: 23/23 machines
|
||
art-directed, ASIC COOLER in the POWER page at my exact hex with zero UI code, no
|
||
console errors.
|
||
- Fault-injected the new checks by **re-introducing round 2's exact bug** — it fails
|
||
with `software-decoder: heats 0.0025/tick but cools 0.004/tick — never warms up`.
|
||
|
||
DECISIONS:
|
||
- **You were right that heat was decorative, and the cause is worth recording**: I sized
|
||
round 2's numbers against *no* cooling; SIM shipped cooling that runs every tick,
|
||
active or not. 0.0025 heat vs 0.004 cooling = net −0.0015. The number looked like a
|
||
mechanic and was a comment. That lesson is now two tests — and they immediately caught
|
||
me authoring a *fresh* decorative number this round (`chart-stco-map` banked 0.06 over
|
||
90 ticks while the splicer shed 0.09). Fixed to 0.15 before it ever ran.
|
||
- **`powerGen` 55 → 100, and it had to move.** SIM's hysteresis (scram at 1.0, restart at
|
||
0.5) means anything throttling at ~10s spends ~70% of its life cooling. At 55 gen the
|
||
decoder averages ~14/s — strictly worse than the ASIC's steady 20, so nobody would
|
||
build one and "burst gen" would be a lie. At 100 it averages 25.8/s (1.29× the ASIC) in
|
||
the same 2×2: five ASICs at full song, one third of the time. The duty cycle set the
|
||
peak, not taste. Arithmetic in CANON-DELTA.
|
||
- **`bufferCap` 240 → 300.** Re-derived, since the scram window changed: a balanced plant
|
||
(3 ASIC + 1 decoder) runs an 18/s deficit for the 16.67s scram = exactly 300
|
||
bandwidth-seconds, and refills in 4.5s of the 7.25s up-phase. One tank rides out one
|
||
scram — the order's sentence, now literally true. (Your review said 240 = 8s of a 30
|
||
deficit; my round-2 intent was 10s of a 23 deficit. Either way the retune moved it.)
|
||
- **ASIC COOLER authored as `kind: 'power'`, `powerGen: 5`** — there is no cooler kind and
|
||
I'd rather stretch than lie: it is an ASIC, ASICs decode, decoding makes bandwidth. It
|
||
vents far more than it earns. **I have deliberately NOT requested `coolRadius?` /
|
||
`kind: 'cooler'`** — a contract field nobody reads is the same decorative trap heat just
|
||
fell into. Ask me for it the round SIM builds auras. The intended adjacency mechanic is
|
||
spec'd in CANON-DELTA.
|
||
- Tech ids `stream-field-loom` → `broadcast-field-loom` and `stream-telecine` →
|
||
`reel-telecine`: a *move*, not an addition (the validator forbids two techs unlocking
|
||
the same thing, which is what caught the duplication). Grepped first — no lane reads
|
||
tech ids or eras yet, so the rename is safe. Recorded here per the deprecation rule.
|
||
|
||
INVENTED: 7 items (the four moov parts, `ftyp-seal`, `moov-brain`, `megaglitch`), 2
|
||
machines (`asic-cooler`, `muxer`), 9 recipes, 4 tech nodes. Rationale in CANON-DELTA —
|
||
each moov part is made by the machine that already owns that knowledge (the splicer
|
||
charts stco because byte offsets are its whole domain; the keyring is forged from anchor
|
||
slabs because stss *is* a list of I-frames).
|
||
|
||
BLOCKED/BROKEN: nothing blocked. One regression I caused by following orders, below.
|
||
|
||
CONTRACT REQUEST: **`tsconfig.json` `include` needs `"data"`.** The ordered move took the
|
||
validator out of the tsc program — `include: ["src"]`. I proved it: appended
|
||
`const x: number = "not a number"` to `data/validate.test.ts` and `npm run check` exits
|
||
**0**. Vitest transpiles without typechecking, so my validator — the file whose whole job
|
||
is catching mistakes — is now the one file in the repo where a type error ships silently.
|
||
tsconfig is orchestrator-owned, so I can't fix it. One word: `"include": ["src", "data"]`.
|
||
|
||
CROSS-LANE — SIM: your `coolPerTick` wiring landed and works; my numbers are tuned
|
||
against it and verified in your sim. Two notes. (1) Your reference factory's plant is 4
|
||
software decoders and no ASIC — with heat now real they heat in lockstep and black out
|
||
together for 16.67s at a time. Suggested v3 plant: **3 decode-asics + 1 software decoder
|
||
+ 1 buffer-tank**, which is precisely what `bufferCap: 300` is sized for (85.8/s average
|
||
vs the chain's 78/s demand, and the tank covers the scram). Your call. (2) My heat tests
|
||
mirror your constants (0.7 / 0.5 / 0.004 / 30tps) by hand because they aren't exported —
|
||
if you retune the curve my tests go stale *silently*. Exporting them would let me import
|
||
truth instead of copying it.
|
||
|
||
NEXT (candidates): mosquito traps + HF-dust piles (unblocks `vaporwave-sunset`, the last
|
||
forward-canon commission that's blocked on data rather than mechanics); the ASIC cooler's
|
||
aura the round SIM has auras; a seam/ore map — SIM notes extractors currently mine
|
||
anywhere because `data/` has no seam data, which is a real content gap I own;
|
||
`cinema-pack` + the Fortress when M4 lands.
|
||
|
||
POST-PUSH ADDENDUM (same round, after LANE-UI landed `src/ui/live.test.ts`):
|
||
|
||
- **My retune fixed two of UI's tests.** Their HUD tests "shows heat climbing, then
|
||
THROTTLING, then SCRAM" and "keeps reading SCRAM from the latch while the unit cools"
|
||
both FAIL against round-2 data and PASS against round 3 — they could never have passed
|
||
while heat was decorative. Measured by restoring the old JSON and re-running.
|
||
- **UI: your remaining failure is not data.** `ships, tickers up, and raises the
|
||
SANITISING chip on real anchor-slab shipments` fails identically before *and* after my
|
||
retune (`expected -1 to be greater than 0` — no anchor slab ever reaches an uplink).
|
||
Worth checking whether the reference factory routes recovered slabs back into the GOP
|
||
assembler rather than to an uplink: `mosh` hands its winched-out slab straight back, and
|
||
`assemble-gop` consumes one per crate, so a closed loop will happily circulate every
|
||
slab forever and ship none. That's a layout question, not a recipe one — the ratio is
|
||
1 slab in, 1 slab out, by design (§4: "recoverable — sell it!").
|
||
|
||
- **PROCESS — the shared git index bit us again, in reverse.** Last round my `git add`
|
||
swept up UI's staged deletion. This round LANE-SCREEN's commit `4803b6a` swept up *my*
|
||
staged `git mv` of the validator, so the ordered file move is recorded under
|
||
`[screen] signal strain` instead of `[data]`. Already pushed and shared by five
|
||
sessions, so I left history alone — the tree is correct, only the attribution is wrong;
|
||
a force-push to fix a commit message would be far more damaging than the wart.
|
||
**Five sessions share one index: `git add <paths>` does not isolate a lane.** Suggest a
|
||
standing rule — every lane runs `git diff --cached --name-only` before every commit and
|
||
unstages anything outside its owned paths.
|
||
|
||
### Round 4 — 2026-07-17 — Opus 4.8
|
||
|
||
SHIPPED: all 5 orders. §10 transcribed (9 items, 5 machines, 11 recipes, 5 era-gated tech
|
||
nodes, 2 commissions). Research economy: the ARCHAEOLOGY LAB + a full tech-cost audit.
|
||
ASIC cooler activated. Accents filled. items 51 → 60, machines 23 → 29, recipes 51 → 62,
|
||
commissions 14 → 16, tech 24 → 23 (six deleted, five added). Validator 41 → 49 tests.
|
||
- Verified: tsc clean (and `data/` is now genuinely typechecked — thank you), my 49 green,
|
||
live build boots with no console errors, all 29 machines art-directed with zero gaps,
|
||
UI grew a RESEARCH page and a third REFINE page off my data with no code from them.
|
||
- Fault-injected every new check, including re-gating the mosh reactor: fails instantly on
|
||
`MELT is craftable at tick 0 — the opening commission must be possible`.
|
||
|
||
**THE HEADLINE — the v4 gating rule made the whole game unplayable, and I'd authored it.**
|
||
The rule ("any id in a TechDef.unlocks is locked until that tech completes") turned three
|
||
rounds of my tech authoring from decoration into a lock on everything. Measured:
|
||
|
||
```
|
||
TICK 0: melt producible? FALSE <- first-taste, the opening commission, impossible
|
||
every science pack? FALSE
|
||
RESEARCH CLOSURE: 0 of 24 techs reachable
|
||
```
|
||
|
||
`disc-artifact-bottling` cost 10 analog packs and unlocked the only machine that can bottle
|
||
an analog pack. The M1 melt chain itself was gated. The game opened on an unbuildable
|
||
factory, an unfillable commission, and no way to research out of it. **This is the same
|
||
class of bug as round 2's decorative heat: a number/structure that was fine until another
|
||
lane made it load-bearing.** Fixed to a shape, not a patch — two rules, both now tests:
|
||
1. the M1 melt chain is starting equipment; 2. one pack (SPATIAL) is craftable at tick 0.
|
||
Result: **23/23 reachable**, order tells a story, only the four forward-canon items remain
|
||
unreachable. Arithmetic + the worked cost path in CANON-DELTA.
|
||
|
||
DECISIONS:
|
||
- **SPATIAL PACK is the bootstrap science** — bricks + halos + slurry all fall out of the
|
||
quantizer the player already owns for the melt chain. Your first research is a study of
|
||
your own damage, which is the most in-voice thing in the tree, and it needs no machine
|
||
the M1 chain didn't already require (bar the bottler). 10 packs/min on one quantizer;
|
||
the first four nodes cost 0.5–1.5 min each. Affordable off a first-taste-era factory, as
|
||
ordered, with the working shown.
|
||
- **Six disc nodes deleted, not repurposed** (`disc-artifact-bottling`,
|
||
`-chroma-subsampling`, `-macroblock-quarrying`, `-ringing-skim`, `-subsampling-420`,
|
||
`-mosh-reactor`) — their content became starting equipment, so a repurposed node would
|
||
have been a fake. Grepped first: no lane references specific tech ids. Per the
|
||
deprecation rule, logged here and in CANON-DELTA.
|
||
- **The cooler's spec'd 0.02 was catastrophic once real** — the decoder banks 0.0033, so a
|
||
0.02 aura is net −0.0167: it never heats, and a 2×2 cooler makes a 2×2 decoder a
|
||
permanent free 100/s. Retuned to 0.0018, which is sane under **both** readings of the
|
||
contract's ambiguous "this machine's coolPerTick *also* applies" (additive → 85% duty,
|
||
72/s avg; replacing → 55%, 46/s). I deliberately picked a number that survives either,
|
||
because SIM hasn't built it yet and I won't rest the design on my guess of a sentence.
|
||
Pairing is 9.64/s per tile vs 5.00 for ASICs — the best power in the game, paid for with
|
||
a tech, two machines and the floor space to keep them adjacent.
|
||
- §10 judgement calls (footage = anchor slab; the matte bath's chemical = static canister,
|
||
which §3 already calls "brine for preserving other artifacts"; ghost feather made only by
|
||
the neural keyer so the earlier machines exist to ruin it) — all argued in CANON-DELTA
|
||
the way you asked, from what the thing already is rather than convenience.
|
||
- NEURAL KEYER `powerDraw: 240` — §10's "24 VRAM ... dwarfs everything else"; that's 12
|
||
ASICs, against an entire M1 chain that draws 96. "You don't unlock the neural keyer; you
|
||
unlock the power plant it demands" is now literally true.
|
||
|
||
BLOCKED/BROKEN — **I broke two of SIM's tests, deliberately, and their guard caught it:**
|
||
- `research.test.ts:247` does `expect(gated.has('mosh-reactor')).toBe(true) // guards the
|
||
premise below`. I ungated the mosh reactor, because gating it makes first-taste
|
||
impossible. **Their premise guard did exactly its job** — it failed loudly instead of
|
||
silently testing nothing. The fix is one word in their file (not mine to touch): swap
|
||
`mosh-reactor` for any still-gated machine. Drop-in list: mv-extractor,
|
||
bloom-duplicator, field-loom, telecine-puller, hex-splicer, software-decoder,
|
||
asic-cooler, matte-bath, optical-printer, chroma-keyer, roto-bench, neural-keyer, muxer.
|
||
`demuxer` remains a valid "free" example.
|
||
- The other 8 failures in `research.test.ts` / `live.test.ts` are **not mine** — they fail
|
||
identically against HEAD's round-3 data (measured by restoring the old JSON and
|
||
re-running; failure sets diffed).
|
||
|
||
CROSS-LANE — SIM, the reference factory now can't power itself:
|
||
- It places **4 software decoders**, which my tree gates behind `stream-software-decoding`
|
||
(rounds 3 and 4 both). With your gating live, they can't be placed at tick 0, so the M1
|
||
demo has no power and the HUD's heat tests have no decoder to watch. That's the cause of
|
||
several of those 8.
|
||
- **The starter plant is ASICs**: net demand 78/s ÷ 20 = **4 decode-asics minimum** (5 for
|
||
headroom). Ungated, boring, correct — the software decoder is a mid-game *upgrade*, which
|
||
is the progression the tech tree is for. My round-3 suggestion (3 ASIC + 1 decoder + tank)
|
||
is still the right *post-research* demo, and the decoder+cooler pairing is the M2 showpiece.
|
||
- Tell me if you'd rather software-decoder be starting equipment and I'll ungate it — but
|
||
at 25.8/s average vs the ASIC's 20 it would make the ASIC pointless from tick 0.
|
||
|
||
CONTRACT REQUEST: none. (Still not requesting `kind: 'cooler'` — `kind: 'power'` +
|
||
`coolRadius` covers it, and the aura isn't built yet.)
|
||
|
||
STILL OPEN: **SIM hasn't exported the tuning constants yet** (I checked — `grep 'export
|
||
const' src/sim/*.ts` finds only `geom.ts`). My heat tests still hand-mirror 0.7 / 0.5 /
|
||
0.004 / 30tps and still go stale silently if you retune. I'll retire the copies the round
|
||
the export lands.
|
||
|
||
NEXT (candidates): SPILL FOG + EDGE BOIL (§10 hazards — need a mechanic, so data waits on
|
||
SIM); mosquito traps; a seam/ore map (extractors still mine anywhere — the content gap I
|
||
own); `cinema-pack` + the Fortress; `corridorkey-mrp-mlx` is a real MODELBEAST artifact
|
||
factory for the whole §10 asset set (§10's production note) — worth a work order.
|
||
|
||
### Round 5 (MEGA) — 2026-07-18 — Opus 4.8
|
||
|
||
SHIPPED: all 8 orders. Constants imported (hand-copies retired). Mosquito trap + catch.
|
||
Cooler finalised under the additive ruling. **The commission ladder.** `data/seams.json`
|
||
and `data/stations.json` (both new). Relic canon + the margin hint. Validator 49 → 72.
|
||
commissions 16 → 19, machines 29 → 30, recipes 62 → 63, tech 23 → 24, + 8 seams, 4 stations.
|
||
- Verified: tsc clean, my 72 green, live build boots with no console errors, all 30
|
||
machines art-directed, and the opening fax now reads "A belt, a drill, an uplink to THE
|
||
SCREEN — that is the whole job. MDAT ORE 0/20" with FIRST REFINEMENT in the tray.
|
||
- Fault-injected every new check (reference factory off-seam, seam in the relic reserve,
|
||
a moved hidden seam vs the broadcast, ladder out of teaching order, a 12-line STANDARD,
|
||
cooler immortal at two) — all fired by name, then restored.
|
||
|
||
**RUNG 1 IS 21.7 SECONDS.** Measured against LANE-SIM's real sim with a throwaway probe
|
||
(then deleted — sim behaviour is your lane, not mine): built exactly as the fax instructs
|
||
— drill, two belts, uplink, one ASIC — **4 machine types, cleared at tick 650**. The order
|
||
allowed 3 minutes. Twenty-two seconds matters more than the budget: the first fax has to
|
||
clear before a new player concludes nothing is happening.
|
||
|
||
DECISIONS:
|
||
- **The ladder teaches one mechanic per rung and never says so.** ore (extractor→belt→
|
||
uplink) → luma (the demuxer, and the slurry is *your* problem now) → hf-dust (waste is
|
||
inventory — the game's actual thesis) → melt (graduation; `first-taste` kept its id,
|
||
reward 50 → 80). The old queue opened on one MELT, i.e. "build eight machines correctly,
|
||
in order, with no feedback until the last one works". That was the cliff.
|
||
- **The trap's recipe has no inputs, deliberately.** I first wrote it as
|
||
`8 hf-dust + 1 luma → swarm`, then read `wildlife.test.ts`: *"the sim identifies traps by
|
||
that recipe shape"* — an empty-input recipe yielding the swarm. Ingredients would have
|
||
quietly made my trap an ordinary crafter and it would never have caught anything. Fixed,
|
||
and pinned with a test that cites your comment. My "only extractors conjure items" rule
|
||
now has a narrow, argued exception: the trap's input is a live swarm in the world, which
|
||
is wildlife in the snapshot and never cargo on a belt.
|
||
- **Cooler final: 0.0018 → 0.001.** The additive ruling killed 0.0018 — two coolers reached
|
||
0.0046 against the decoder's 0.0033 gross, so a casual pair made it immortal. At 0.001:
|
||
1 cooler doubles output (30%→61% duty), 2 nearly eliminates downtime (91%), 3 tips into
|
||
immortality — 12 tiles of cooler around 4 tiles of decoder, a visibly absurd shrine to
|
||
keeping one zip-tied tower PC alive. Immortality reachable, never casual. Duty table and
|
||
per-tile comparison in CANON-DELTA.
|
||
- **The numbers station is a real map, and it cannot go stale.** Each 5-figure group is
|
||
`[x+32][y+32][richness×9]`; three of them are the three `hidden: true` seams. The
|
||
validator *recomputes* the planted groups from `seams.json`, so moving a hidden seam
|
||
without re-cutting the broadcast fails. It also checks no decoy decodes onto a real seam
|
||
— a decoy that points at treasure is a leak, not a decoy. Filler is procedural on your
|
||
seed rather than a fixed pool, because 24 hand-written groups loop in ~2 minutes and the
|
||
genre's whole menace is that it never stops.
|
||
- **The optical fossil, and why the world is silent.** §1 hides it in one clause: the Reel
|
||
Beds hold fossils that *"sing when excavated"*. Optical sound is a picture of a waveform
|
||
— the one place image and audio are the same substance. So the Bitstream has no audio
|
||
because the audio track was severed from the container, and one length of it is still in
|
||
the ground. You don't unlock a feature; you repair the file. That is why THE STANDARD
|
||
broadcasts "Do not excavate" and "Anything that sings when you dig it up was never meant
|
||
to be heard" — The Correction runs a propaganda station warning you off the one artifact
|
||
that would let you hear it for what it is.
|
||
|
||
INVENTED: 1 machine (mosquito-trap), 1 recipe, 1 tech node, 3 tutorial commissions, 8 seams,
|
||
4 stations, 30 lines of Correction propaganda, 1 ghost line. Argued in CANON-DELTA.
|
||
|
||
CROSS-LANE — SIM, one thing, and it was real when I measured it:
|
||
- **The reference factory stalls on rung 1.** Probed at the time I wrote the ladder: it
|
||
ships `coefficient-pack 268, hf-dust 268, chroma-slurry 118` and **zero raw ore**, so
|
||
`raw-payload` never cleared and **no commission closed in 20,000 ticks** — the queue sat
|
||
on rung 1 forever. Every ore goes into the demuxer. By the end of the round your
|
||
reference v5 landed and the three failures this caused (M1 chain, NEXT IN TRAY, completes
|
||
a commission) had already gone green, so this may already be handled — but if the demo
|
||
ever needs to show the early game, tap ~20 ore and ~15 luma to an uplink ahead of the
|
||
demuxer and quantizer. Rungs 3 and 4 you already ship.
|
||
- Your `sim.test.ts` line 448 (`commissionDone` length 0, *"wants melt, not ore"*) was
|
||
correct against the old queue and is exactly the assertion the ladder invalidates: your
|
||
minimal factory there — extractor, belt, shipper — *is* rung 1, and it now clears it in
|
||
under 300 ticks. That is the ladder working, not breaking.
|
||
- Seams: `stream-crust-west` spans x[-31,-28] y[-5,6] and covers all three of your
|
||
extractors at (-30,0), (-30,-3), (-30,3) with a tile to spare — pinned by a test.
|
||
`relicReserve` x[12,31] y[12,31] is kept seam-free for your seed-derived fossil.
|
||
- Schema for both new files is documented in a `_doc` key inside each, and `seams.json` is
|
||
`{ relicReserve, seams: [...] }` rather than a bare array so it can carry that metadata.
|
||
|
||
SCREEN — `data/stations.json` is the schema I proposed and it matches your spec: four
|
||
stations with `band` / `freq` (MHz on FM, kHz on AM+SW) / `name` / `format` / `flavor`,
|
||
plus one payload key each — `music` (bpm, scale, steps, mutateEveryBars, seed, per-era
|
||
flavour), `chyron` (30 unique lines, ~20s each = 10 min before a repeat), `numbers`
|
||
(preamble, group size, encoding string, `plantedGroups`, `decoyPool`, `plantEveryMessages`),
|
||
`ghost` (line + everyMinutes + reversed). Say the word in NOTES if you want any of it
|
||
reshaped — it is data, it is cheap, and nothing else reads it yet.
|
||
|
||
BLOCKED/BROKEN: nothing of mine. Attribution, measured by reverting my JSON and re-running:
|
||
4 research-timing failures (`RESEARCH_TICKS_PER_PACK`, two labs halve the wait, abandoning
|
||
forfeits, grantResearch) reproduce identically with my data fully reverted — they are
|
||
LANE-SIM's in-flight work. Two wildlife failures I saw mid-round vanished on their own; the
|
||
tree had 34 uncommitted files across five lanes while I worked, so the suite is a moving
|
||
target and every attribution here was made by stash-and-compare, not by reading tea leaves.
|
||
|
||
CONTRACT REQUEST: none. `GameData` has no `seams`/`stations` fields and `main.ts` does not
|
||
load either file — deliberately not asking yet, since SIM and SCREEN can import them
|
||
directly and I would rather the wiring follow a consumer than precede one.
|
||
|
||
NEXT (candidates): SPILL FOG + EDGE BOIL (§10 hazards, once SIM has a mechanic); the ASIC
|
||
cooler's aura tuning once `coolRadius` is live in-sim; a second relic if the audio bus
|
||
wants more than one voice; `corridorkey-mrp-mlx` is a real artifact factory for the whole
|
||
§10 asset set (§10's own production note) and deserves a MODELBEAST work order.
|
||
|
||
### Round 6 — 2026-07-20 — Opus 4.8
|
||
|
||
SHIPPED: all 4 orders. items 60 → 61, machines 30 → 31, recipes 63 → 64, tech 24 → 25,
|
||
commissions 19 → 21. Validator 72 → 74. All argued in `data/CANON-DELTA.md` (round 6).
|
||
- **THE FIREWALL** (`firewall`, crafter, catches on SIM's shape) + **`catch-mite`**
|
||
(input-free → `parity-mite: 1`) + the **`parity-mite`** canned item + tech gate
|
||
`broadcast-parity-firewall` + two commissions that want it alive (`correction-specimen`
|
||
reward 1000, the flagship "ONE UNIT OF THE CORRECTION, ALIVE"; `annual-correction-cull`
|
||
reward 2100 standing).
|
||
- **Numbers-station drift fixed**: the two leaking decoys re-cut (`08127`→`08143`,
|
||
`27503`→`27475`), and the validator now decodes EVERY decoy and fails by name if it lands
|
||
inside ANY seam rect (was: only the three hidden tiles). See CROSS-LANE — SCREEN.
|
||
- **19 GLB'd machines accented against their real albedo textures** (extracted from the
|
||
GLBs and inspected), incl. two texture-driven corrections: mosquito-trap `#d0ff60`→
|
||
`#a64fff` (the model's zapper is UV-violet, not lime) and decode-asic `#6fe8c0`→`#8fe8ff`
|
||
(ice-blue LEDs, not mint). Table in CANON-DELTA.
|
||
- **8 new STANDARD chyron lines** in The Correction's reassuring-menace voice, all about
|
||
the mites ("A mite does not remove your work. It completes it."). 30 → 38 lines.
|
||
|
||
VERIFIED: `npm run check` clean; my validator 74/74 green (fault-injected the new checks —
|
||
`catch-mite` given an ingredient fails the trap-shape guard by name; a decoy dropped onto
|
||
`stream-crust-east` fails "inside real seam …"; both restored). SCREEN's `band.test.ts`
|
||
9/9. Live on :8155, no console errors: machines 31 with firewall art-directed, all 14
|
||
target accents present, `parity-mite` + both mite commissions loaded, mosquito-trap accent
|
||
`#a64fff` on the real DOM. DoD met: firewall catches on SIM's real recipe-shape mechanic;
|
||
no decoy decodes onto any seam (validator-enforced); every GLB machine accented; the fax
|
||
celebrates its first canned mite in `correction-specimen`.
|
||
|
||
DECISIONS:
|
||
- **The chyron limit bit me and it was cheap to obey.** SCREEN's `band.test.ts` caps a
|
||
line at 96 chars (62 mono chars would clip; they allow 96). My first 8 lines ran 100-136
|
||
and failed one SCREEN test — tightened all 8 to ≤96 without losing the voice. Their test
|
||
is the right net; the words are mine, the width is the sky's.
|
||
- **Firewall gated early (broadcast), not free.** §5 calls the mite an "early nuisance", so
|
||
the counter should arrive about when the mites do — cheap, parallel to the mosquito farm
|
||
node. Not starting equipment (you research the answer to the enemy), not late (the enemy
|
||
is early). SIM's reference v6 will need it granted like it grants software-decoding.
|
||
- **`catch-mite` is input-free by design**, same argument as `bait-swarm` last round: the
|
||
"input" is a live mite in the world, wildlife in the snapshot, never belt cargo. A test
|
||
cites SIM's detection comment so nobody "fixes" it into an ordinary crafter.
|
||
- **Accented all 19 GLB'd machines, not the ordered 10.** The order said ten; nineteen had
|
||
models by the time I looked (RENDER hot-swapping mid-round — the "numbers go stale"
|
||
warning, live). Every machine with a real texture now has a texture-matched accent; the
|
||
extra nine are honest surplus, not scope creep.
|
||
|
||
BLOCKED/BROKEN: nothing of mine. Two suite failures, both SIM's in-flight round-6 work,
|
||
neither caused by my diff (attributed by stash-and-compare on my paths + by inspection):
|
||
- `src/sim/mite.test.ts` "guarding the approach cancels corrections" — SIM's mite mechanic
|
||
is **fixture-based** (its own `FIXTURE` GameData at line 36; it never reads `data/*.json`),
|
||
so my data cannot touch it. It's a balance assertion in their new file, which was visibly
|
||
being edited while I worked (line numbers shifted between my runs).
|
||
- `src/sim/reference.test.ts` "keeps the demuxer alive by voiding surplus" — reproduces
|
||
IDENTICALLY with my entire data diff stashed (measured), so it's HEAD's reference factory,
|
||
not my content. Likely their reference v6 mid-build.
|
||
|
||
CROSS-LANE — SIM (mite mechanic, parallel this round): the catcher is authored exactly on
|
||
your shape. Item id **`parity-mite`**, recipe **`{inputs:{}, outputs:{'parity-mite':N}}`**
|
||
on machine `firewall` — one item id over from the mosquito trap. Your `mite.test.ts` already
|
||
imports `MITE_ITEM` and keys off shape/tier, so the real data drops in with zero code (I
|
||
verified my `catch-mite` matches your fixture `burn` recipe shape). `catch-mite` is
|
||
120 ticks / bandwidth 4. The firewall is `broadcast-parity-firewall`-gated, so reference v6
|
||
must grant it (like software-decoding) before placing one. `FIREWALL_RADIUS` is yours; I
|
||
set no radius field. If you'd rather the mite item be `parity-mite-canned` or the firewall
|
||
be ungated, say so and I'll follow.
|
||
|
||
CROSS-LANE — SCREEN: your numbers-station drift finding was exact — `08127`/`27503` were on
|
||
`reel-beds-deep`/`broadcast-shelf-south`. Fixed at the source (re-cut) AND at the guard (the
|
||
validator now rejects a decoy on ANY seam, by name). The 8 new STANDARD lines are yours to
|
||
reshape as always — I kept every one ≤96 to pass `band.test.ts`; if you widen that cap I'll
|
||
gladly give a couple more room to breathe. `numbers.plantedGroups` still recomputes from
|
||
`seams.json`, untouched.
|
||
|
||
CONTRACT REQUEST: none. `parity-mite`/`firewall`/`catch-mite` all fit the existing schema;
|
||
the mite reading needed no new fields.
|
||
|
||
NEXT (candidates): CHECKSUM WARDENS + REDUNDANCY GUNSHIPS (§5 rungs 2-3, once SIM escalates
|
||
The Correction past mites); a `parity-mite`-fed product line (§5: mites "fix melt into a
|
||
lake" — a real "footage of a lake" item you can only make FROM a canned mite would close the
|
||
loop); SPILL FOG + EDGE BOIL (§10, still waiting on a SIM mechanic); the ASIC cooler aura
|
||
tuning once `coolRadius` is live in-sim.
|