Commit Graph

83 Commits

Author SHA1 Message Date
type-two
18f6575660 [screen] regional moire, strain warps, 3-frame scram
growthMask() is the reusable spatial-artifact template: an fbm-ragged growth
front creeping outward from a deterministic seed. The raggedness is load-bearing
-- a clean circle reads as a spotlight, not as spreading crystal.

Moire separates area from intensity: intensity saturates early while the mask
keeps growing with tally, so a big shipment reads as "the maze has spread"
rather than "everything got slightly shimmery". Seeded from the tick the crystal
first landed.

Tremor is ~1/4 of the brownout's judder and fever is a smooth haze against
tremor's random jitter, so dread, fever and seizure stay distinguishable.

Also clamps dt at both ends: a negative dt (clock rewind) turned ease()'s
1-exp(-dt/tau) into a huge negative multiplier and threw eased values into orbit.
Unreachable from main.ts's monotonic clock, but not a landmine worth keeping.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 18:20:50 +10:00
type-two
4803b6a1e7 [screen] signal strain: dread measured in seconds of reserve
Per the v3 units ruling, stored is bandwidth-seconds and draw-gen is bandwidth
per second, so stored/(draw-gen) is literally how long until the lights go out.
Tremor ramps over the last 8 seconds. That reads correct at every factory size
for free: 1000/s with 4000 banked feels exactly as doomed as 10/s with 40.

A factory in surplus is always calm, which is also what keeps the boot state
(gen=draw=stored=0) sterile by construction rather than by special case.
Fever averages only the machines that run hot, so one glowing decoder is not
drowned by a sea of cold belts.

Pure and snapshot-shaped so the sterile guarantee is a test, not a promise.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 18:20:50 +10:00
type-two
08761e8eeb [orchestrator] round 2 review + contracts v3 + round 3 orders
Review: 5/5 lanes pass. 160/160 tests, tsc clean, M1 COMPLETE — verified live:
reference factory ships melt, commission queue advances with standing orders,
SCREEN's new artifact passes respond item-specifically (block 0.46 from bricks).

Contracts v3 (granted): EntityState.scrammed, SimSnapshot.commissionQueue,
MachineDef.coolPerTick, setRecipeAt command, Sim.save/load, ScreenFX.frame(t, snap),
BeltItem.id hardened required, MachineDef.color re-ruled as chassis/body.
main.ts: passes snapshot to screen.frame; dev __fktryDemo() builds reference factory.
happy-dom ACTUALLY installed this time (round-2 grant never landed; UI caught it).

Rulings: bandwidth units are per-second (SIM converts); heat retune ordered (nothing
can currently overheat - heatPerTick < ambient cooling); validator test moves to
data/; RENDER's color deviation approved as the ruling; scram wipe 3 frames; REMOVE
button approved. Round 3 orders in all lane docs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 18:05:53 +10:00
type-two
dc1591d0e6 [render] scram latches with hysteresis, mirroring sim (fixes a ~4s visual lie)
SIM landed heat this round, so I read their implementation: `scrammed` lives
on their internal Ent, never on EntityState; they deliberately clear `jammed`
on scram ("reported by its own event, not as a flow jam"); and Renderer only
ever receives snapshots, never events. So the latched-off state is not
snapshot-visible at all.

A plain `heat >= 1` test (what I shipped earlier today) therefore un-scrams the
moment a machine starts cooling. With HEAT_RESTART=0.5 and dissipation
0.004/tick, the sim holds it dead for ~125 ticks (~4s) while heat falls 1.0 ->
0.5 — the renderer showed it alive, glowing and animating, that whole window.

Now latches at 1.0 and releases below SCRAM_RELEASE=0.5, mirroring them.
Verified: 1.0 dead -> 0.7 STAYS dead -> 0.3 releases and recovers.

This duplicates SIM's constant, which is the wrong place for it to live —
EntityState.scrammed is filed as a contract request with the evidence.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 17:47:15 +10:00
type-two
30deed10dc [render] round 2 NOTES
Verification numbers, the MachineDef.color conflict written up in full, and
3 contract requests (settle color's meaning, EntityState.scrammed, BeltItem.side).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 17:36:09 +10:00
type-two
56c29eaba6 [render] belt topology + corner cargo pathing, heat/throttle/scram, buffer fill
Round 2 orders 1-6:

- topology.ts: belt neighbour analysis -> straight/cornerA/cornerB/merge,
  one InstancedMesh per (def x shape), flow field baked per shape. Corners
  sweep a quarter-arc; merges get inlet arrows.
- cargo follows the corner arc: `t` is progress along the tile, so walking
  items straight through the centre made them cut corners and pop in at the
  wrong edge. They now enter at the feeding edge (verified 0.089-0.248 off
  the centreline where straight pins to 0.000).
- heat.ts + entities.ts: dull-red body ramp, rising shimmer column, throttle
  (idle AND GLB clips slow together), scram (dead-dark + amber, frozen) and
  a restart path that restores what scram zeroed.
- buffer tanks show fill from their share of bandwidth.stored / bufferCap.
- AnimationMixer plays clip 0 looped; rigged GLBs clone via SkeletonUtils so
  instances don't share a skeleton.
- exact cargo interpolation via BeltItem.id, order-matching kept as fallback.
- multi-mesh belt GLBs merge with groups (2 materials, 1 draw call) instead
  of rendering only the first mesh.

MachineDef.color is wired to the BODY, not the accent, against the letter of
the orders: all 21 values DATA authored are industrial chassis neutrals per
codex/§8, and wiring them to the emissive makes every machine glow muddy and
kills the two-material rule. Flagged in NOTES for the orchestrator to settle.

500 entities + 2,000 items still at 3.6ms/frame (4.6x headroom), 5 draw calls.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 17:36:09 +10:00
LANE-SIM
dfd1860d09 [sim] round 2 NOTES
Reference factory holds: melt at tick 1247, still shipping at 20,000,
demuxer never jams. Heat curve and scram/throttle decisions documented.

Main thing for the orchestrator: data/ has none of the v2 fields, so heat
and buffer tanks are implemented and tested but inert in the real game --
the software decoder cannot overheat until DATA gives it a heatPerTick.
Suggested starting values included. One contract request: coolPerTick.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 17:28:42 +10:00
LANE-SIM
ff43c09972 [sim] splitters, buffer tanks, heat, commission queue, starved, item ids
Round 2 per lanes/LANE-SIM.md.

- splitters: round-robin across outward-facing belts, blocked outputs
  skipped not waited on; rank now traces THROUGH splitters and takes the
  best outcome reachable across every terminal a lane reaches
- buffer tanks: charge on surplus, discharge to cover deficit, brownout
  only once dry; bandwidth.stored is the pool
- heat v1: heatPerTick while active + RecipeDef.heat per craft, ambient
  cooling, linear throttle 1.0@0.7 -> 0.5@1.0, scram at 1.0, restart
  under 0.5, both edges emit 'scram'. Throttle applies to powerGen too,
  so a hot decoder sags before it drops off the bus
- commission queue: data-order activation, repeat re-enters at the back
- jammed:'starved' (edge-triggered) and BeltItem.id (stable through belt
  transfers and splitters alike)

15 new fixture tests for the M2 mechanics -- data/ carries none of the v2
fields yet, so heat and tanks are tested against a fixture this lane owns.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 17:28:25 +10:00
type-two
90703c4bcd [ui] round 2 notes
Shipped/verified list, and the honest parts: happy-dom was granted but never
installed; STANDING ORDER and SANITISING are built but unreachable until the
sim advances commissions and a chain gets fed; NEXT IN TRAY infers the queue.
Three requests (commission queue on snapshot, sim commission rotation,
happy-dom) and a remove-button proposal.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 17:27:58 +10:00
type-two
a57729ce33 [ui] 57 tests for pagination, hit-testing, selection, keymap, chips, voice
Order asked for a minimum of ten under happy-dom. happy-dom is not actually
installed (not in package.json, not in node_modules) and root config is not
mine to edit, so these run in the default node environment instead — which is
why the logic was factored into pure modules first.

Covers everything the order named except the two things that genuinely need a
DOM: chip rendering (the arithmetic is covered) and attach()'s window binding
(the routing is covered).

Pins the invariants worth pinning: no build page ever exceeds nine slots at
any catalog size, syncRoster copies values rather than holding sim buffers
across frames, footprint hit-testing respects rotation, and an unknown jam
reason or machine kind degrades instead of throwing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 17:27:58 +10:00
type-two
e25c854be8 [ui] inspector recipe picker + heat states; fax queue peek and stamps
Inspector: setRecipe finally has a UI — a process picker listing each
machine's recipes as readable lines ("1 LUMA BARS -> 1 COEFFICIENT PACK +
1 HF DUST"). Heat gets a bar with THROTTLING and SCRAM states rather than a
number. Jam reasons route through jamText() so 'starved' and 'output full'
read as different problems, and an unknown reason passes through uppercased
instead of being swallowed.

Fax: NEXT IN TRAY peek, a STANDING ORDER stamp for repeat commissions, and a
SANITISING chip once anchor-slabs ship (hardcoded id sanctioned this round).

voice.ts/palette.ts now prefer MachineDef.flavor/.color from data and keep the
round-1 hand-transcribed tables as fallback. chipspec.ts lifts the chip
arithmetic out of the DOM so it can be tested.

Caveats in NOTES: the sim pins the active commission to commissions[0] and
never advances, so STANDING ORDER is unreachable; NEXT IN TRAY infers "next"
from data order because the snapshot has no queue.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 17:27:45 +10:00
type-two
cd733445d9 [ui] build bar paging: kind tabs, [ ] to page, 1-9 within the page
Kind tabs alone don't deliver "every machine hotkey-reachable at any catalog
size": REFINE holds 14 crafters and 1-9 reaches nine. So a page caps at nine
and an oversized kind spills into numbered pages (REFINE 1/2, REFINE 2/2).
The 21-machine catalog lands as 1+3+9+5+2+1 across six pages, every slot
hotkeyed. Pagination is pure (pages.ts) so the invariant can be tested rather
than eyeballed.

Selecting a machine from anywhere pulls the bar to the page that holds it, so
the hot button is always the visible one.

hotkeys.ts splits into a pure KeyRouter (map + dispatch, no window) and a thin
window binding, which lets the keymap be tested in node.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 17:27:45 +10:00
type-two
491fbf2d68 [ui] click-to-inspect via bus.pickTile; drop the TAB fallback and fixture
Contract request 1 landed, so the inspector opens the way it always should
have: click a machine. pick.ts loses the window.__fktryRenderer probe and
its apology; index.ts loses the TAB manifest cycle that stood in for it.

?uifixture and fixture.ts are deleted too. The sim is real now — a brownout
is something you cause by building an extractor with no generator, which is
a better demo than the fake one ever was.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 17:27:25 +10:00
type-two
34e2bb3fcf [screen] round 2 notes + snapshot-access contract request
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 17:22:32 +10:00
type-two
7f9de9c8b1 [screen] shipment stamps + scram wipe, debug hook gated to DEV
One stamp per shipped event (not per unit), 0.4s, sized by count, in the item's
chip colour. Composited in screen space so a melting feed never drags the placard.
Scram events get the one-frame TRACKING LOST bar, positioned from entity+tick so
a run always wipes the same way.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 17:22:32 +10:00
type-two
ed823a09ff [screen] three artifact classes the original 8 params cannot express
block: 8x8 quantization on a lattice locked to screen space, so the grid stays
rigid while melt drags the picture underneath it. ring: Gibbs halos, gradient
sampled out to 7px so they ring OUT from edges rather than clinging to them,
oscillating parallel to the edge. moire: two near-identical lattices beating,
with rainbow sheen.

PARAMS 8 -> 11; the ledger, easing, wobble and stats all iterate PARAMS, so the
new classes inherit the existing machine. Wires bricks/coeff-packs to block,
halos/gibbs-wraiths to ring, crystal to moire.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 17:22:32 +10:00
type-two
3e70482447 [data] art direction, heat economy, container + bloom lines
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>
2026-07-17 17:20:36 +10:00
type-two
c4f0538231 [orchestrator] fix tsc break introduced by happy-dom install
Adding happy-dom hoisted @types/node, changing global setTimeout's return type;
src/ui/fax.ts stampTimer is a DOM timer id, so use window.setTimeout. One-line
cross-lane touch by the orchestrator to unbreak the build it broke.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 16:43:55 +10:00
type-two
86d765f90b [orchestrator] round 1 review + contracts v2 + round 2 orders
Review: all 5 lanes pass — 70/70 tests, tsc clean, ownership audit clean,
integration verified live (sim -> events -> UI ticker + SCREEN corruption).

Contracts v2 (granted from lane requests): UIBus.pickTile (wired), BeltItem.id?,
MachineDef.{color,flavor,heatPerTick,bufferCap}?, CommissionDef.repeat?,
SimEvent 'scram'. main.ts: non-left pointerdown no longer places. happy-dom added.

Rulings: canon melt chain IS M1 (masterplan updated); rank-routing stays, splitters
next; anchor-slab sanitizing -> Correction buyback fiction; build-bar paging approved;
per-lane dev ports 8151-8155. Round 2 orders written in all lane docs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 16:42:58 +10:00
type-two
5ee0fb9e78 [render] round 1 NOTES
Decisions, verification evidence, honest limitations, and 3 contract
requests (BeltItem stable id, optional MachineDef.color, main.ts placing
on any pointer button).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 16:31:10 +10:00
type-two
883dd4b02b [render] isometric world, instanced belts/cargo, GLB hot-swap registry
Replaces the render stub with the full M1 surface:

- camera: ortho iso rig, wheel zoom, middle/right-drag + WASD pan, resize
- ground: shader tile grid w/ world-edge dissolve + screen-space vignette
- registry: procedural placeholders (two-material rule) + MODELBEAST GLB
  hot-swap, probed on init and every 10s in dev. GLBs auto-normalise to
  the machine footprint, so any export scale lands correctly.
- belts: InstancedMesh per belt def, chevron scroll injected into a
  MeshStandardMaterial so belts keep lighting/fog/brownout
- cargo: InstancedMesh per item type, interpolated across ticks via alpha
- ghost + pickTile with footprint occupancy (cyan valid / red blocked)
- feedback: jam klaxon blink, brownout dims the scene via tone-mapping
  exposure so emissives dim too

Machine accents are derived from data (recipes -> outputs -> ItemDef.color),
with a legibility floor: near-black products like MDAT ORE would otherwise
render the extractor's CRT head as a black panel and its ore as invisible.

Verified in the dev build: 500 entities + 2,000 belt items at 3.2ms/frame
(5 instanced draw calls); a GLB dropped in mid-session swaps without reload.
Dev scaffold is DEV-gated and tree-shaken from the prod bundle.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 16:31:10 +10:00
LANE-SIM
3a42ab2d9e [sim] round 1 NOTES
Reports the M1 melt chain working (tick 1149) and two things the
orchestrator needs to decide: the DoD chain no longer exists after
LANE-DATA's codex landed (mosh now eats gop-crate, melt is 8 machines
deep), and the M1 factory deadlocks at ~tick 1200 on byproduct surplus
with no legal overflow. Proposes splitters as the fix.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 16:25:22 +10:00
LANE-SIM
fcf5d04727 [sim] deterministic factory core: belts, crafting, bandwidth, shipping
Replaces the stub with the real sim per lanes/LANE-SIM.md round 1.

- grid + placement/remove/rotate/setRecipe, footprint rotation, bounds
- belts: 2 items/tile, 0.45 spacing enforced across the tile seam,
  back-pressure, merges, belt<->machine handoff
- crafting: recipe buffers (2x in, stall at 4x out), edge-triggered jams
- bandwidth v1: gen vs draw, compression generates, brownout = gen/draw
  scaling both craft progress and belt movement
- shipping + commission tracking
- output routing ranks belts by tracing the chain to its terminal machine,
  so the demuxer's three outputs reach three different consumers without
  splitters (see NOTES - biggest judgement call of the round)

18 tests. Measured 3,500 entities + 6,820 belt items at 0.42ms/tick (80x
realtime). Full M1 chain ships MELT at tick 1149 in both node and browser.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 16:25:22 +10:00
type-two
e1206fea78 [ui] round 1 notes
Shipped/verified list, and the honest parts: click-to-inspect is blocked
on reaching renderer.pickTile, 12 of 21 machines have no hotkey, and the
lane has no DOM test env. Four contract requests (pickTile, MachineDef
.color, MachineDef.flavor, jsdom) and a build-bar paging proposal.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 16:16:02 +10:00
type-two
df1eee7249 [ui] dev-only fake sim behind ?uifixture
The sim stub reported an empty world, so there was nothing on screen to
verify the HUD against: an empty inspector and a 0/0 meter prove nothing.
This synthesises a plausible snapshot -- entities mid-craft, a jam, heat,
shipments, a recurring brownout and commission -- so every surface can be
watched doing its job in a browser.

Runs on a wall clock rather than the sim tick: rAF stops in a backgrounded
tab, and a tick-driven fixture crawls too slowly to ever reach the brownout
window. It is a fake sim for eyeballing chrome; nothing here is or needs to
be deterministic.

Inert without the query param, dispatches no Commands, touches no other
lane. Delete once the real sim can be driven to a brownout by hand.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 16:16:02 +10:00
type-two
c18309f464 [ui] build bar, top strip, inspector, commission fax, toasts
The five M1 surfaces, replacing the stub:

- buildbar.ts: one button per machine, hotkeys 1-9, R rotates, Esc or
  right-click clears. LANE-DATA shipped 21 machines, so the bar wraps
  rather than running off both edges of the viewport; slots 10-21 are
  click-only for now (paging proposed in NOTES).
- topstrip.ts: bandwidth meter going amber at 85% and red + flashing
  BROWNOUT over 100%, buffer, shipped ticker + per-item chips, tick or
  HALTED. The brownout is legible from this panel alone, which is the
  one failure the player has to read across the room.
- inspector.ts: name, codex flavor, intake/output chips with live
  buffers, process bar, heat, jam reason. Holds an entity id and
  re-looks-up each frame, so a removed unit closes itself.
- fax.ts: the commission card with wants-as-chips and a FAX SENT stamp
  on commissionDone.
- toasts.ts: max 4, 6s TTL, colored per event kind.

Click-to-inspect is not wired: the UI cannot reach renderer.pickTile
(UIBus exposes only dispatch/selectedBuild, and ui.init never sees the
Renderer). TAB cycles the unit manifest as a stopgap so the inspector is
reachable without a console. Contract request filed in NOTES.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 16:15:50 +10:00
type-two
d017e710ad [ui] HUD foundation: voice, style, chips, hotkeys, selection
Shared plumbing for the DOM HUD, no framework:

- voice.ts: every player-facing string, so the OSHA-poster deadpan
  register lives in one place instead of being re-invented per panel.
- style.ts: injected terminal-industrial stylesheet. Panels re-enable
  pointer-events; #ui itself stays transparent to the mouse.
- chips.ts: the item chip (swatch + name + count), keyed off GameData
  so new items from LANE-DATA light up with no code change.
- hotkeys.ts: the whole keymap in one file, per lane orders.
- selection.ts: pending build selection, written through to bus._sel.
- pick.ts: tile -> entity hit-testing plus the flattened roster the UI
  keeps instead of holding a snapshot across frames (CONTRACTS says sim
  may reuse those buffers, and input handlers fire between frames).
- palette.ts: machine accent colors. Stopgap — MachineDef has no color
  field; contract request filed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 16:15:38 +10:00
type-two
5a85360ef9 [screen] round 1 notes
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 16:11:35 +10:00
type-two
f31e36de72 [screen] compositor: shipments drive THE SCREEN
Eased param pressure so shipments land as waves, log escalation over the
first ~100 items, cross-modulated wobble above 0.8 so a mature factory looks
alive, brownout seize, and a one-frame white awakening on the first ship ever.

Measured 0.004-0.013ms/frame CPU against a 2ms budget.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 16:11:35 +10:00
type-two
2982862e83 [screen] corruption ledger: item -> artifact mapping + escalation curve
Mix and total are separate axes: what you ship picks the artifact, how much
you have ever shipped picks the intensity. That separation is what makes
40 chroma slurry read as chroma specifically instead of generic damage.

Covers the full 40-item codex LANE-DATA landed; unknown ids degrade to a
generic noise bump, with a test walking data/items.json to keep it that way.
anchor-slab has negative potency and sanitizes THE SCREEN (see NOTES).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 16:11:35 +10:00
type-two
3dd423fe2b [screen] port GLYTCH shader stack + procedural clean feed
Raw WebGL fullscreen triangle, not three.js: one texture, one pass.
The 8 prototype params keep their tuning verbatim; u_drift, u_brownout
and u_flash are additions. Base feed repaints only when a visible glyph
changes rather than per frame, so the texture upload stays off the hot path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 16:11:35 +10:00
type-two
f015a66283 [data] full codex catalog + data validator
Transcribe the §2-§6 codex into machine-readable canon and add the validator
that keeps five parallel lanes from drowning in dangling ids.

- validator (28 tests): recipes point back at their machine, every item/tech/
  commission reference resolves, ids unique + kebab-case, colors hex, footprints
  >=1x1, plus a reachability pass proving MELT is craftable from raw ore.
- items 9->36, machines 7->21, recipes 4->35, tech 0->17, commissions 1->10.
- mosh rewired to canon (gop-crate -> melt + reclaimed anchor slab); all seed
  recipe ids preserved so nothing dangles mid-round.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 16:04:27 +10:00
type-two
1a769e6cbd Baseline: GLYTCH prototype, FKTRY lore codex, scaffold + 5-lane orchestration docs
- index.html: WIMVEE GLYTCH match-the-glitch prototype (playable)
- docs/FKTRY_LORE.md: world bible / MODELBEAST asset codex
- fktry/: vite+three+TS scaffold, contracts, main loop, seed data
- fktry/MASTERPLAN.md + CONTRACTS.md + lanes/LANE-{SIM,RENDER,UI,SCREEN,DATA}.md:
  round protocol and Round 1 orders for parallel Opus 4.8 executors

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 15:51:12 +10:00