glytch/fktry/lanes/LANE-DATA.md
type-two 4cccd22ca4 [data] heat that fires, the muxer, reel + broadcast eras
Round 3 orders, all six. The validator move landed in 4803b6a (swept into
LANE-SCREEN's commit by the shared index); this is the rest.

- heat retune: round 2's numbers were below the sim's always-on cooling, so
  nothing could ever warm up. Decoder now 100 gen at 0.0033 heat / 0.001 cool
  -> throttles 10.2s, scrams 14.5s, 23.9s cycle, 25.8/s average (1.29x the
  ASIC). Verified against LANE-SIM's real sim, not just arithmetic.
- powerGen had to move: the scram/restart hysteresis forces ~30% duty, so at
  55 gen the decoder averaged worse than a steady ASIC and nobody would build
  one.
- two new tests refuse decorative heat (per-tick and per-craft). They caught a
  fresh instance of the same bug in chart-stco-map before it shipped.
- bufferCap 240 -> 300: one tank now covers exactly one decoder scram.
- ASIC COOLER spec'd (aura deferred to M4, no contract field requested yet);
  THE MUXER + moov brain sub-lines; reel + broadcast era tech.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 18:24:38 +10:00

293 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 3 (goal: heat that matters, deeper economy)
Round 2 review: the bloom-concentrate grep-before-delete and the fault-injection
discipline are exactly the standard. Both your cross-lane asks are RULED:
**(1) Units: per-second.** `gen`/`draw` are per second, `stored` is
bandwidth-seconds; SIM converts their integration this round — your `bufferCap: 240`
= 8 seconds of a 30 deficit, as you intended. **(2) Cooling:** `coolPerTick?` granted
in v3 (sim default 0.004); SIM wires it. Your SIM's-test-is-red flag was correct
mid-round and self-resolved at HEAD (their landing fixed it) — the stash-and-rerun
diagnostic was the right move. Ownership RULING: `data-validate.test.ts` moves to
`data/validate.test.ts` (git mv, yours — vitest picks it up there; `src/sim/**`
returns fully to SIM).
1. **The validator move** above, first, so the tree is clean.
2. **Heat retune, the headline**: today NOTHING can overheat — every `heatPerTick`
you authored is below the 0.004 ambient cooling, so heat is decorative. With
`coolPerTick` yours to set per machine: hit SIM's suggested feel — software
decoder throttles after ~10s of continuous load, scrams ~13-15s, full duty cycle
~25s; ASIC stays incapable of heat. Show the arithmetic in CANON-DELTA (per-tick
vs per-second — mind the units ruling). Give the hex-splicer a lesser fever.
Coordinate with SIM's reference-factory v3 via NOTES — your numbers decide
whether their layout survives.
3. **Buffer economy check** under the units ruling: is 240 (8s) still your intent
now that it's true? One tank should cover one decoder scram — verify against your
retuned cycle, adjust, show working.
4. **ASIC COOLER spec'd** in CANON-DELTA (the codex names it, §2 "vented by ASIC
coolers"): item/machine entry + intended adjacency mechanic, data authored but
recipes gated behind a `broadcast`-era tech node — the MECHANIC stays deferred
until SIM builds auras (M4); the data existing first is fine and the validator's
FORWARD_CANON pattern covers it.
5. **Reel + broadcast era tech nodes**: research costs in analog packs; unlocks
field-loom/telecine recipe families you already authored.
6. **Muxer + moov brain sub-lines** (§7): `stsz-ledger`, `stco-map`, `stts-metronome`,
`stss-keyring` items + assembly recipes converging on a `moov-brain`
`mux-container` endgame recipe on the muxer. This is M4's rocket — data lands
first, mechanics later. Muxer machine entry if you don't have one.
**Definition of done:** validator green from its new home; a software decoder
demonstrably overheats in SIM's tests using YOUR numbers (coordinate — their DoD
depends on your retune); CANON-DELTA carries the arithmetic; FORWARD_CANON pruned of
anything that gained a recipe.
---
## 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.