# CANON-DELTA — everything in `data/` that isn't in the codex yet LANE-DATA owns this file. `../../docs/FKTRY_LORE.md` is canon; this is the ledger of where the data has run ahead of it. The orchestrator absorbs these into the lore doc in one pass later. Until then, **this is the single place canon-drift is allowed to live**. Rule for adding an entry: the codex was silent, I invented in its voice, and I wrote down *why it is consistent with the codex* — not just what I did. If a future lore pass disagrees, the codex wins and the data changes. --- ## Canonized in round 1 (orchestrator: "CANONIZED", round 2 review) | Thing | Kind | Why it fits | |---|---|---| | `press-anchor-slab` | recipe (dct-press) | The press run backwards is an IDCT, and an IDCT *is* a complete picture. §4 already runs the field loom and the telecine puller in reverse, so reversibility is established machine behaviour. This is where I-frames come from. | | `color-plate` | item | §4 demosaicer literally outputs "a smooth colour sheet"; it needed an id. | | `v-hold-roll` | item | §1 Broadcast Shelf has "v-hold faults that make whole regions periodically roll upward". Bottling one gives the ANALOG PACK's "combing + v-hold roll + static" triptych three real ingredients. | | `artifact-bottler` | machine | §2 calls the science packs "a bottled artifact triptych" but names no bottling plant. Something has to hold the bottle. | | `lane-splitter` | machine | The contract has `kind: 'splitter'` and belts need routing, but §4 only ever calls the DEMUXER "the first splitter" — which is a refinery, not a junction. | ## Added in round 2 ### The container line (unblocks `stream-hex-splicing`) §2 names the CONTAINER PACK's contents ("moov shard + offset ribbon + sync key") and §7 names the moov brain's parts, but nothing said where they come from. The chain now mirrors what the parts actually *are* in a real container: | Thing | Kind | Why it fits | |---|---|---| | `moov-shard` | item | The index, not the payload. | | `offset-ribbon` | item | The stco map — a ribbon of byte offsets. | | `sync-key` | item | The stss table lists which frames are keyframes, i.e. I-frames. | | `demux-container` | recipe (demuxer) | The demuxer is the machine that separates index from payload. 8 ore → 2 shards: the index is a rounding error next to the mdat, which is the joke and also the truth. | | `spool-offset-ribbon` | recipe (gop-assembler) | The assembler is the only machine that knows where each frame starts, because it put them there. | | `cut-sync-key` | recipe (artifact-bottler) | Cut from an anchor slab, because stss is a list of anchors. | | `bottle-container-pack` | recipe | Assembles the §2 triptych. | Chicken-and-egg check: §4 says the hex splicer "Requires CONTAINER PACK research", so the container line deliberately does **not** route through the splicer. It is demuxer → assembler → bottler, all machines you already own. ### The bloom line §3 sells bloom "by intensity grade; grade-5 bloom visibly tries to escape its canister in one direction" — five grades, one item each, `bloom-grade-1..5`. - `bloom-concentrate` is **kept** and redefined as the raw, ungraded draw-off from a loop (`tap-bloom`). It was not deleted because LANE-SCREEN hardcodes it in `src/screen/corruptionMap.ts:54` and its test — deleting it would have broken another lane's suite mid-round. Grading now consumes it. - The recipe id `bloom-grade-3` survives from round 1 but now produces the *item* `bloom-grade-3`, so the id finally means what it says. `tap-bloom` is the renamed round-1 `bloom-grade-3` recipe. **Deprecation notice:** no recipe id was retired, but `bloom-grade-3` changed its inputs/outputs entirely. Nothing outside `data/` referenced it (checked: only my own `tech.json`). - Escalation is in delta wafers, not exotic inputs — a grade-5 canister is 2 raw bloom + 18 wafers of compounding, which is §4's "contents compound each lap" priced honestly. --- ## The numbers, and the arithmetic behind them ### The reference M1 chain (measured, not guessed) Computed from `data/*.json` against the machine list in SIM's `meltChain()` (`src/sim/sim.test.ts`), with the two recipes that test hand-dials applied: ``` idle draw (every machine's powerDraw) 57 /s + active recipe draw at full tilt 39 /s = peak draw 96 /s - compression paid back (quantize -6, 4:2:2 -4, 4:2:0 -8) 18 /s = net peak demand 78 /s ``` **Unit assumption — SIM please confirm:** I read `gen`/`draw` as bandwidth units **per second**, not per tick (the codex's pylon meter reads kbps, §2 BANDWIDTH). This only matters now that `bufferCap` exists, because a stored quantity = rate × time. If SIM integrates per *tick*, every buffer number below is 30× too small and I'll retune. ### `bufferCap: 240` on the buffer tank Order was "roughly 10 seconds of typical M1-chain deficit". Typical deficit ≠ total blackout — it's the chain running with one generator down: ``` reference chain, peak draw 96 /s plant: 2 software decoders (55 each) 110 /s → comfortable one decoder scrams: supply = 55 + 18 (compression) = 73 /s deficit = 96 - 73 23 /s × 10 s 230 bufferCap 240 (one tank ≈ one decoder's cooldown) ``` That is the intended M2 sentence: **a buffer tank is what makes software decoders survivable.** The tank rides out exactly one scram. Two decoders scramming in sync drains it and you brown out — which is the lesson. ### `heatPerTick: 0.0025` on the software decoder, `powerGen` 45 → 55 Heat is 0..1, throttling >0.7 and scramming at 1 (contract). From cold, running flat out: ``` throttle (0.7) at 280 ticks = 9.3 s scram (1.0) at 400 ticks = 13.3 s ``` So a software decoder **cannot** run continuously. That's deliberate and it is the codex: §4 gives it "burst gen", "doubles throughput on demand", "throttles theatrically". It is a burst generator that needs downtime, not a better ASIC. The trade, per 2×2 footprint: | | gen | duty | effective | failure mode | |---|---|---|---|---| | DECODE ASIC | 20 /s | 100% | **20 /s** | none, forever | | SOFTWARE DECODER | 55 /s | ~50% | **~27 /s** | brownout, on its own schedule | ~37% more average power for a supply that drops out on a timer you don't control. That's a real choice rather than a strictly-better button. **And it answers the order's question directly** ("does anyone dare run two side by side"): two identical decoders placed together heat in lockstep and therefore scram in lockstep, turning a 50% duty cycle into a 100% blackout every ~13 s. Two decoders are only safe if something staggers them or a tank covers the gap. Daring to run two is precisely the M2 lesson. **Assumption SIM owns — cooling.** The ~50% duty above assumes cooling of about `0.0025`/tick while scrammed or idle (symmetric with the heat-up, so ~400 ticks cold). There is no cooling model in the contract and no cooler machine in `data/`. If SIM picks a different rate, tell me the number in NOTES and I'll retune `heatPerTick` — the shape I'm aiming at is *throttle in ~10 s, full cycle ~25 s*. If SIM implements no cooling at all, `heatPerTick` is a fuse, not a mechanic, and every software decoder is a one-shot: say so and I'll drop it to 0 until a cooler exists. ### `heat: 0.05` on `splice-offsets` Per craft, at 45 ticks each: 20 consecutive crafts = 900 ticks = 30 s to scram. §4 says the splicer "Requires ... a steady buffer feed or it splices *itself*" — a splicer you leave running unattended stops itself, which is the pinch the order asked for. --- ## Open / deferred - **No cooler machine exists.** §2 HEAT says heat is "Vented by ASIC coolers" — that's a machine the codex names but never specifies. Candidate for round 3; until then, heat is only survivable via duty cycling. - `cinema-pack`, `mosquito-swarm`, `gibbs-wraith` remain forward canon (no recipe). The validator's FORWARD_CANON allowlist is the enforcement, and it now has a companion test asserting nothing sits on the list once it *is* producible. - Dials-as-recipes (quantizer Q, subsampler grades, GOP cadence) stays, per round-2 review. - The reel and broadcast era tech nodes don't exist yet; tech is disc + stream only.