diff --git a/fktry/lanes/LANE-DATA.md b/fktry/lanes/LANE-DATA.md index ff4ff8a..0ff3321 100644 --- a/fktry/lanes/LANE-DATA.md +++ b/fktry/lanes/LANE-DATA.md @@ -25,24 +25,33 @@ REQUESTs. --- -## CURRENT ORDERS — Round 6 (goal: The Correction gets teeth, the map stops drifting) +## CURRENT ORDERS — Round 7 (Phase 1: the paperwork economy) -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. +Contracts v9: `CommissionDef.compliance`, and SIM lands debt/wardens/gunships/ +auditors this round — coordinate thresholds via NOTES as usual. -**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. +1. **COMPLIANCE QUOTAS**: 3-4 `compliance:true` standing commissions in The + Correction's register — they want TIER-0/1 material only (extend your validator: + a compliance commission wanting tier>=2 fails by name). Flavor: polite, clean, + horrifying ("QUOTA 7-C: 40 LUMA BARS. THE FILE THANKS YOU FOR YOUR COOPERATION. + THE FILE DOES NOT KNOW YOUR NAME."). These are the debt valve — shipping boring + content on purpose is a real strategy with a real bandwidth cost. +2. **FORGED HASH**: a two-input recipe on the EXISTING hex-splicer (container-pack + + hf-dust or your better reading — argue it in CANON-DELTA), producing `forged-hash` + (new item, tier 3). It voids a Hash Auditor's audit. Tech-gate it late (fortress- + adjacent). NOTE for SIM coordination: its shape cannot use the empty-inputs + catcher path — they're budgeting a second detection for it. +3. **Debt/band tuning numbers** if SIM makes them data-driven (they export constants + otherwise — retire copies as before). +4. **THE STANDARD, audit pool**: ~8 new chyron lines acknowledging audits/mirrors/ + stasis ("Units conducting review are not present." / "The sector was always + white."). <=96 chars each (the wrap cap). +5. **CANON-DELTA**: the rungs-2-4 reading of §5, the no-grudge ruling, the + deviation-targeting ruling, and FORGED HASH's argument. + +**DoD:** compliance quotas validate + complete against SIM's real debt venting; +forged-hash reachable via tech; validator green; the fax reads like the enemy's HR +department discovered your existence and filed it. --- diff --git a/fktry/lanes/LANE-RENDER.md b/fktry/lanes/LANE-RENDER.md index 2c41e4c..5bfd3e0 100644 --- a/fktry/lanes/LANE-RENDER.md +++ b/fktry/lanes/LANE-RENDER.md @@ -25,28 +25,36 @@ you never simulate. If motion looks wrong, interpolate better or note it — don --- -## CURRENT ORDERS — Round 6 (goal: the GLB era looks as good as it is) +## CURRENT ORDERS — Round 7 (Phase 1: bodies later, PRESENCE now) -MODELBEAST delivered: 10 real GLBs now live in `public/assets/models/` (mosh-reactor, -quantizer, seam-extractor, muxer, archaeology-lab, software-decoder, decode-asic, -mosquito-trap, chroma-keyer, artifact-bottler). Hot-swap + normalization worked -first try. One problem, and it's yours: **at game zoom they read dark** — baked -textures carry no emissive, so the two-material rule dies on real assets. +Contracts v9 grants your round-6 request: `Renderer.onEvents?(events)` — main.ts fans +out the same array Screen/Audio get. Your three derived cues (repaired sparkle, +firewall paperwork, relicFound geyser) can now be exact; migrate them. -1. **GLB legibility pass, the round's centerpiece**: give hot-swapped GLBs the - accent treatment placeholders get — your existing accent derivation drives a - small emissive element (glow sprite / rim boost / brightest-texel emissive lift; - your call, note it) + an overall brightness floor so a dark chassis never reads - as a hole. Verify all 10 in showroom AND in the demo world at default zoom; - screenshot before/after in NOTES. -2. **Mite visuals** (SIM lands `'parity-mite'` wildlife): hospital-white beetles, - green checkmark eye (§5), unsettling gentleness; a caught mite in a firewall - reads as filed paperwork. The 'repaired' event gets a small, infuriatingly tidy - sparkle where your product used to be. -3. **Excavation VFX** on `relicFound` (carried from your round-5 NEXT). +RULING — THE INVERSION: the codex assigns wrong-motion to CORRUPTION, not authority +(§8: "clean things move at 60fps; corrupted things move wrong on purpose"). So The +Correction units are the ONLY things in the world that never miss a frame: they +glide, smoothly interpolated, unbothered, while everything the player owns keeps its +existing judder vocabulary. Do NOT quantize their transforms. -**DoD:** all 10 GLBs legible at default zoom (before/after proof); mites read as -The Correction at a glance; perf rule holds. +1. **Placeholder bodies for rungs 2-4** (zero GLBs this round): distinct primitive + silhouettes in hospital-white with one green element each — warden: tall + filing-cabinet slab with a stamp arm; gunship: five mirrored rotor platters in a + row, hovering; auditor: a faceless white marble column that TELEPORTS (appears/ + disappears, never walks — §5 says it moves only between frames). All matte, + spotless, unweathered. +2. **The gunship's mirror**: its `rect` renders as a faint ghostly duplicate of the + sector beneath it (a translucent white re-render or projected decal — your + language). The tether to `target` is a visible line. +3. **Stasis rect**: bleached ground, frozen belt items visibly stopped mid-tile, + 00:00:00:00 timecode floating. Release snaps back hard. +4. **Seal stamp**: sealed machines get a white compliance placard on the chassis + + their idle animation FREEZES (a sealed machine is a still photograph of itself). +5. **onEvents migration** for your three derived cues + the new ones (notice ping at + the fax, mirrored flash inside the sector). + +**DoD:** all three rungs readable at a glance in showroom + demo world; the glide +verified against juddering surroundings; stasis freeze/release pinned; perf holds. --- diff --git a/fktry/lanes/LANE-SCREEN.md b/fktry/lanes/LANE-SCREEN.md index 6455142..a7440d9 100644 --- a/fktry/lanes/LANE-SCREEN.md +++ b/fktry/lanes/LANE-SCREEN.md @@ -27,24 +27,33 @@ seed stock — port, don't move). --- -## CURRENT ORDERS — Round 6 (goal: the sky notices the enemy) +## CURRENT ORDERS — Round 7 (Phase 1: the sky is audited, the speaker stays pure) -Your chyron now wraps (orchestrator fix — 29/30 STANDARD lines were clipping at ~51 -chars since round 5; two-line wrap verified live). +Contracts v9 events: `mirrored`, `stasis`, `debtBand`, `notice`. -1. **`repaired` events on the sky** (SIM lands them): each repair eases total - corruption by its item's contribution AND stamps a small, perfect, green-tick - placard — The Correction signs its work. Boredom and repairs must stay - distinguishable (rot vs theft). -2. **Mite shimmer**: reuse the growth-mask for a faint hospital-white sterile patch - creeping around heavy mite activity — the inverse of corruption, and it should - feel WORSE. -3. **THE STANDARD, new pool**: coordinate with DATA — the propaganda acknowledges - the mites now ("Units are assisting you." / "Inventory discrepancies are being - resolved in your favor."). Chyron-only, mumble untouched (standing constraint). +1. **`mirrored` subtracts from the ledger** — the gunship steals corruption the same + way `repaired` does (your shipped decrement path); reuse it, don't fork it. A + mirrored theft also stamps a small hospital-white sector outline placard (distinct + from the mite's green tick — this one is architectural). +2. **Stasis on the sky**: while any `stasis` rect is on, the feed gets a subtle + freeze-adjacent treatment — timecode stops advancing, drift pauses — WITHOUT + triggering the brownout seizure vocabulary. Release resumes exactly where it + stopped (the sky was never damaged; it was administered). +3. **THE COMPLIANCE TONE (the audio ruling, verbatim):** The Correction never speaks — + it faxes. Its only sound: on `notice` and on warden-arrival, ONE voice of the + ratifySting triad, alone, struck on a fixed Hz grid — zero vibrato, zero drift, + zero analog imperfection. You cannot record a tone with no imperfection; you can + only generate one. That is the house law making its own argument. CONSTRAINTS: + gate on `discovered` exactly as tapeChunk is (pre-relic silence guarantee is + structural and measured); do NOT create a continuous tone — ratifySting's rarity + is its punchline and a frequent second 'only clean sound' would demote it. One + note per event, sparse by construction. +4. **Debt band ambience**: at band>=3 the sky's substrate gains the faintest sterile + vignette (reuse the pallor machinery, white instead of grey); gone below band 3. -**DoD:** a mite wave is visible on the sky as creeping cleanliness + tick stamps; -pixel-verified; budget holds. +**DoD:** mirrored arithmetic pinned (ledger before/after); stasis freeze +byte-identical on resume; compliance tone spectrally verified (single partial, zero +sidebands) and pre-discovery silence still 0.0/0.0; budget holds. --- diff --git a/fktry/lanes/LANE-SIM.md b/fktry/lanes/LANE-SIM.md index d023af5..992d71f 100644 --- a/fktry/lanes/LANE-SIM.md +++ b/fktry/lanes/LANE-SIM.md @@ -21,28 +21,50 @@ playable through unit tests. You are the lane the other four trust with their li --- -## CURRENT ORDERS — Round 6 (goal: M3's enemy — THE CORRECTION walks) +## CURRENT ORDERS — Round 7 (Phase 1: THE CORRECTION, EMBODIED — mechanics only) -Round 5 (MEGA) shipped complete: wildlife, seams, relic, research time — reviewed and -live. The tuner dead-dial and chyron clipping were fixed orchestrator-side; seams are -wired into GameData (your CONTRACT REQUEST, granted in v7). +Zero new assets, zero farm. Contracts v9 carries everything: `CorrectionState` (debt, +band, units), `EntityState.sealed`, the `pry` command, `CommissionDef.compliance`, and +events `notice`/`sealed`/`mirrored`/`stasis`/`debtBand`. The parity-mite REMAINS in +WildlifeState — the refactor was measured at 25 files across five lanes for zero +visible change and is deferred by ruling. CorrectionState covers rungs 2-4 only. -1. **PARITY MITES v1** (codex §5: hospital-white beetle drones that quietly *repair* - your product). Contracts v8 widens `WildlifeState.kind` with `'parity-mite'` — - they ride the wildlife array. Behaviour: spawn from the world rim when - `shippedTotal` corruption crosses thresholds (escalate with progress); seek belts - carrying tier-2 glitch products; on reaching one, EAT the item and emit a new - `{kind:'repaired'; item; pos; tick}` event (v8) — the work is not destroyed, it is - *corrected*, which is worse. Deterministic, save/load carried, capped like swarms. -2. **The counter**: DATA authors a FIREWALL machine on your trap pattern (recipe-shape - detection, radius) — a mite in range is caught and canned (`parity-mite` item, - forward-canon in data). Coordinate via NOTES. -3. **Reference factory v6**: survives a mite wave without losing its melt regression - (a firewall on the uplink approach is the natural layout teach). +1. **PARITY DEBT.** One scalar, five bands (NOMINAL/OBSERVED/AUDITED/SEALED/REFUSED), + thresholds exported from constants.ts. Rises on tier>=2 shipments (per-item tier + from data). DECAYS always; decays faster while shipping tier-0/1 — and completing a + `compliance:true` commission vents a chunk. Emit `debtBand` on band edges only. + RULING: canning a Correction unit adds NO debt — an immune system does not hold a + grudge; "it cannot perceive you" is the joke. +2. **CHECKSUM WARDEN (band>=2).** Emit `notice` FIRST (fax-first is contractual), + ~20s later it walks to its target, audits (phase+progress visible), rolls back the + last N outputs (new small per-machine output ring buffer), stamps `sealed:true` + (emit `sealed`), leaves. A sealed machine refuses to run. Counters: the firewall + recipe-shape catcher (same detection you shipped for mites) OR the new `pry` + command — ~90 ticks standing at the machine, clears the seal, ADDS debt (you + defaced a compliance notice). +3. **REDUNDANCY GUNSHIP (band>=3).** Picks the 8x8 sector with the most DEVIATION + (most tier>=2 output — RULING: not highest throughput; it corrects corruption, not + productivity), tethers to a PARITY ANCHOR (the sector's most corrupting machine, + `target`), publishes `rect`. Crafts inside the sector feed its progress; at + threshold it emits `mirrored` (which SCREEN subtracts from the sky ledger — the + shipped `repaired` path). Break the tether by starving/sealing/idling/removing the + anchor; it leaves when the tether breaks or a firewall cans it. +4. **HASH AUDITOR (band 4).** `notice`, then a visible 5s PRESCAN phase, then + `stasis` on: a rect where entities stop ticking and belt items freeze, with a + deterministic `lockHash` string. SAFETIES ARE CONTRACTUAL: it ALWAYS auto-releases + after AUDITOR_STASIS_TICKS even if the player does nothing. Counter is ABSTENTION: + if nothing crafted in its rect during prescan, it finds nothing and leaves without + locking. Material counter: FORGED HASH — a two-input recipe on the existing + hex-splicer (DATA authors it); holding a forged-hash item in any machine inside + the prescan rect voids the audit. NOTE: your recipe-shape catcher path assumes + empty inputs — this one has inputs, budget ~40-60 lines for a second detection. +5. **Reference factory v7**: survives one full warden+gunship cycle at 20k ticks with + melt regression intact (a firewall near the uplink is the natural teach). + Save v5 carries debt/units/seals. Determinism suite green. -**DoD:** mite lifecycle tested (spawn → seek → repair → event; firewall catch); -zero-brownout regression intact; mites never touch tier-0/1 cargo (they correct -CORRUPTION, not raw material — that's the fiction and the balance). +**DoD:** full lifecycle tests for all three rungs incl. abstention and forged-hash +voiding; a sealed machine provably dead until pried; `mirrored` arithmetic verified; +auto-release pinned by test (this one is the safety — it must be impossible to cut). --- diff --git a/fktry/lanes/LANE-UI.md b/fktry/lanes/LANE-UI.md index c10f8cd..b564bae 100644 --- a/fktry/lanes/LANE-UI.md +++ b/fktry/lanes/LANE-UI.md @@ -24,23 +24,35 @@ dispatch Commands via the bus and read state from `update(snap, events)`. --- -## CURRENT ORDERS — Round 6 (goal: the enemy has a face, the dial has teeth) +## CURRENT ORDERS — Round 7 (Phase 1: the enemy has paperwork) -Your tuner dock now drives the real engine (orchestrator adapter — the dead-dial -finding from the voice review is fixed and live-verified, station names and all). +Contracts v9: `snapshot.correction` (debt/band/units), `sealed` on entities, `pry` +command, `notice`/`sealed`/`mirrored`/`stasis`/`debtBand` events, `compliance` flag +on commissions. -1. **Mite surfacing**: toasts in voice ("A PARITY MITE IS EDITING YOUR MELT.", - "IT LEFT A RECEIPT."), `repaired` events in the ticker, firewall inspector shows - catches. The Correction is polite; the copy should make players furious. -2. **Tuner tick marks**: the adapter now passes `listStations()` through — draw - station ticks on the dial band so hunting has landmarks (keep the hunt: ticks - mark THAT something is there, not WHAT). -3. **Credits line** (from the voice-cloning plan, cheap now): an ABOUT/credits - entry reachable from the tech panel footer — repo, codex, and the standing - disclosure slot for future synthetic-voice credit. +1. **PARITY DEBT gauge** in the top strip: five labelled bands — NOMINAL / OBSERVED / + AUDITED / SEALED / REFUSED — hospital-white/green when calm, never red (The + Correction does not do alarm; the player's own systems do). Hidden until debt + first moves. +2. **Notices are faxes.** `notice` events render as incoming faxes in the existing + fax voice, BUT in The Correction's register: "NOTICE OF SCHEDULED AUDIT. NO + ACTION REQUIRED." — RULING: no grid reference, no unit name. A faction that + cannot perceive you does not give you coordinates. Compliance quotas + (`compliance:true` commissions) get a distinct COMPLIANCE stamp. +3. **Seal + pry.** Sealed machines: inspector shows a compliance seal panel + ("THIS UNIT HAS BEEN BROUGHT INTO COMPLIANCE.") with a PRY button dispatching + `pry`; progress while prying; toast on completion ("SEAL REMOVED. THIS WILL BE + NOTED."). Sealed state also visible in the jam line. +4. **Stasis surfacing**: `stasis` on -> toast naming the lockHash ("SECTOR LOCKED. + HASH 8C4F119E. AWAIT RELEASE.") + a countdown chip; auditor prescan gets one + warning toast ("AN AUDITOR IS READING. STOP MOVING.") — that line teaches the + abstention counter without a tutorial. +5. **Mirrored ticker**: mirrored events join the CORRECTED ticker (rename or split — + your call, note it). -**DoD:** a mite raid is narratable from UI alone; ticks render from real station -data; credits reachable in-game. +**DoD:** a full warden cycle and a full auditor cycle are narratable from UI alone; +the abstention teach verified against the real sim in live.test.ts; gauge bands +pinned by test. --- diff --git a/fktry/public/assets/models/archaeology-lab.glb b/fktry/public/assets/models/archaeology-lab.glb index 7163df4..381dcfb 100644 Binary files a/fktry/public/assets/models/archaeology-lab.glb and b/fktry/public/assets/models/archaeology-lab.glb differ diff --git a/fktry/src/contracts.ts b/fktry/src/contracts.ts index 6e9fa82..8053743 100644 --- a/fktry/src/contracts.ts +++ b/fktry/src/contracts.ts @@ -81,6 +81,8 @@ export interface CommissionDef { wants: Record; rewardBandwidth: number; repeat?: boolean; // v2: standing order — re-activates after completion + compliance?: boolean; // v9: a Correction quota — completing it vents PARITY + // DEBT; wants must be tier-0/1 (validator-enforced) } // v7: lifted verbatim from SIM's round-5 mirror — data/seams.json's shape. @@ -122,6 +124,8 @@ export interface EntityState { heat: number; // 0..1, throttles >0.7, scrams at 1 scrammed?: boolean; // v3: heat-scram latch (heat alone can't show the // hysteresis window; renderer/UI read this, not 0.5) + sealed?: boolean; // v9: warden compliance seal — machine refuses to run + // until pried (the pry command). UI/renderer read this. } export interface BeltItem { @@ -149,6 +153,24 @@ export interface SimSnapshot { research?: ResearchState; // v4: research progress (hardens in v6) wildlife?: ReadonlyArray; // v5: piles & swarms (M2's living hazards) relics?: ReadonlyArray; // v6: buried secrets (the hidden pipe) + correction?: CorrectionState; // v9: PARITY DEBT + rungs 2-4 (mite stays wildlife) +} + +/** v9: THE CORRECTION, embodied. Debt is the escalation throttle; bands gate spawns. */ +export interface CorrectionState { + debt: number; // 0..1 + band: 0 | 1 | 2 | 3 | 4; // NOMINAL | OBSERVED | AUDITED | SEALED | REFUSED + units: ReadonlyArray; +} +export interface CorrectionUnit { + id: number; + kind: 'checksum-warden' | 'redundancy-gunship' | 'hash-auditor'; + pos: Vec2; + /** sim-defined phase, e.g. 'approach' | 'audit' | 'tether' | 'prescan' | 'stasis' | 'leaving' */ + phase: string; + progress: number; // 0..1 of current phase + target?: number; // warden: audited entity; gunship: the PARITY ANCHOR + rect?: { x: number; y: number; w: number; h: number }; // gunship sector / auditor stasis } export interface RelicState { @@ -185,6 +207,9 @@ export type Command = // sandbox/demo verb, also a // legitimate creative mode | { kind: 'excavate'; pos: Vec2 } // v6: dig at a relic site + | { kind: 'pry'; pos: Vec2 } // v9: pry a compliance seal + // off (takes time, adds debt + // - you defaced a notice) | { kind: 'setPaused'; paused: boolean }; export type SimEvent = @@ -200,7 +225,15 @@ export type SimEvent = | { kind: 'wildlife'; on: 'spawned' | 'cleared'; wildlife: 'dust-pile' | 'mosquito-swarm' | 'parity-mite'; id: number; pos: Vec2; tick: number } // v5: hazard lifecycle | { kind: 'relicFound'; relic: 'optical-fossil'; id: number; tick: number } // v6 - | { kind: 'repaired'; item: string; pos: Vec2; tick: number }; // v8: a mite corrected your work + | { kind: 'repaired'; item: string; pos: Vec2; tick: number } // v8: a mite corrected your work + // v9 — THE CORRECTION, rungs 2-4. 'notice' always precedes action (fax first, never + // silent); auditor stasis ALWAYS auto-releases (safety is contractual, not tunable). + | { kind: 'notice'; unit: 'checksum-warden' | 'redundancy-gunship' | 'hash-auditor'; tick: number } + | { kind: 'sealed'; entity: number; on: boolean; tick: number } + | { kind: 'mirrored'; item: string; pos: Vec2; tick: number } // subtracts from the sky ledger + | { kind: 'stasis'; rect: { x: number; y: number; w: number; h: number }; on: boolean; + lockHash: string; tick: number } + | { kind: 'debtBand'; band: 0 | 1 | 2 | 3 | 4; tick: number }; // ---------------------------------------------------------------- module interfaces @@ -229,6 +262,10 @@ export interface Renderer { * demolition tint. def is null in remove mode. The '__remove' sentinel is deprecated * and main.ts stops sending it in v5. */ setGhost(def: string | null, pos: Vec2 | null, dir: Dir, mode?: 'build' | 'remove'): void; + /** v9 GRANT (requested round 6, three consumers by round 7): the same event array + * ScreenFX/AudioFX get, fanned out by main.ts each frame. Optional — a renderer + * without it keeps deriving from snapshot deltas. */ + onEvents?(events: SimEvent[]): void; } export interface UIBus { diff --git a/fktry/src/main.ts b/fktry/src/main.ts index 920c95f..b19ae1a 100644 --- a/fktry/src/main.ts +++ b/fktry/src/main.ts @@ -190,6 +190,7 @@ async function boot() { const snap = sim.snapshot(); const events = sim.drainEvents(); refreshGhost(); + renderer.onEvents?.(events); // v9: same array Screen/Audio get — read-only, same frame renderer.render(snap, acc / MS_PER_TICK); ui.update(snap, events); screen.onEvents(events);