Round 2 orders, all seven. - data/CANON-DELTA.md: ledger of every invention beyond the codex, with the rationale and the arithmetic behind the numbers. - colour + flavor on all 21 machines (kills UI's hardcoded lookup and RENDER's black-on-black); desaturated industrial per style guide §8. - heat: software decoder 45->55 gen at 0.0025/tick (throttles 9.3s, scrams 13.3s) so it's a burst generator, not a better ASIC; a pinch on the splicer. - bufferCap 240 = 10s of the reference chain's one-decoder-down deficit. - commission queue reordered into a ramp + 3 standing orders, incl. THE CORRECTION BUYBACK (the sellout loop: anchors clean THE SCREEN). - container line (moov-shard/offset-ribbon/sync-key) unblocks the hex splicer; bloom grades 1-5. bloom-concentrate kept — LANE-SCREEN hardcodes it. - validator 28 -> 36 tests, covering every v2 field; FORWARD_CANON pruned. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
155 lines
8.3 KiB
Markdown
155 lines
8.3 KiB
Markdown
# 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.
|