# 06 — Implementation Checklist *The ordered build graph: start at the top, check boxes downward, ship at the bottom. Every box traces to a section in docs 01–05 (trace tags in brackets). No box is "done" until its acceptance test passes.* How to use: work in phases while keeping integration moving beside safe additive work. `slice` = vertical-slice gate (1 town + 3 floors playable). `EA` = early-access gate. `1.0` = ship. Status is tracked on three independent axes: - `[code]` — the subsystem/API implementation and focused tests exist; - `[integrated]` — production initialization and executable paths use it; - `[gate]` — an acceptance test drives the real runtime path end to end. A phase's detailed `[x]` boxes may therefore document implemented components while its integration or runtime gate remains open. Unit/component tests never substitute for the corresponding production-path gate. --- ## Phase 0 — Repo & tooling [04 §4.1, §4.9] - [ ] Workspace `Cargo.toml`: crates `core, worldgen, content, render, term, audio, save, ui, cli`; `rust-toolchain.toml` pins stable ≥1.75 - [ ] Release profile: `lto=true, codegen-units=1, strip=true`; debug profile: fast incremental + `debug-assertions` - [ ] CI: `cargo fmt --check`, `clippy -D warnings`, `cargo deny`, `cargo test --workspace`, determinism tests on 2 OSes - [ ] `cargo dist` config + terminal feature matrix in README; `HEXWORK_*` env overrides documented - [ ] Bench harness: `cargo bench -p hexwork-core` (tick), `-p hexwork-render` (frame); CI fails on >10% regression [04 §4.2, 05 §5.2] - [ ] **Gate:** fresh clone → `cargo build --release` → one static binary, `--help` works, no network calls - [x] Scoped build-integrity follow-up (#53): authenticated exact-source codec metadata backport, conservative Cargo-generated format3 graph, explicit member minima and verifier/CI contracts; seven behavior-preserving API substitutions and disclosed parser-span diagnostic regressions. Current stable full-target partitions, strict clippy/format, optimized workspace build and genuine v4 replay passed; final independent review accepted. Retained1.75 compile/non-CLI evidence is not full legacy CLI/release certification. Operator prioritizes current stable/gameplay; remote CI, cargo-deny, other-platform/fresh-clone/static-binary and broader shipping gates above remain unclaimed. See `msrv-repair-plan.md` final acceptance. ## Phase 1 — Core sim skeleton [04 §4.2–4.3; 03 §3.3] - [ ] `hecs` ECS setup; entity pools; `BTreeMap`/indexed pools only (no HashMap iteration in sim) - [ ] Fixed 10Hz tick with 12 ordered phases stubbed; `Shift` = single-tick step mode [03 §3.2] - [ ] Seeded RNG: `Xoshiro256**` master + `seed ^ domain_tag` sub-streams (fluids/combat/worldgen/gossip) - [ ] `hash_state()` canonical snapshot hash; debug assert every 600 ticks (Phase 2: extends to voxel contents incl. scent + `pad`/`extra`, corpse map, law-log length — the determinism contract covers everything phases mutate) - [ ] Voxel grid: `ChunkedGrid<48³>`, 16-byte voxel struct, 3×3×3 active chunks + abstract far-field town sim - [ ] Actors: continuous `Vec3`, stance enum (stand/crouch/climb/swim/prone/rope), voxel occupancy derived - [ ] Vertical connectors: Stairwell/Shaft/Well/Vent/ElevatorCar/Counterweight/RopeAnchor with load/length/anchor-quality - [ ] Pressure nodes + edges (doors/vents/grates); draft field derivation; hidden-vent flag - [ ] Cause-link recorder: every death/damage/major event stores rule-chain links for epitaphs + replay subtitles [03 §3.9] - [ ] **Gate:** headless 10k-tick soak, tick ≤8ms p99, state hash stable across reruns ## Phase 2 — The 12 physical laws [03 §3.3; tests 04 §4.8] - [ ] Light & darkness: per-cell light, lantern cone, carried glow, leak under doors/grates, dirty-cell recompute - [ ] Sound: loudness+timbre emission, propagation/muffling/funneling, AI investigates positions, `(` arc event feed to render - [ ] Air & draft: pressure/airflow fields, smoke/spore/smell advection, flour/oil-drip draft reveal - [ ] Fluids: water/oil/blood/bile/aether-mist, downhill flow, pit fill-up, grate leaks, freeze/melt/boil; 4k cell-update cap + spillover queue - [ ] Fire & heat: ignite/spread/smoke/melt, climbs; water→steam; hot-stone cracking; powder + hymn-card cookoff - [ ] Materials: WOOD/IRON/COPPER/STONE/BRASS/FLESH/SAINT-BONE/GLASS/ROPE/PAPER; acid/rust/verdigris/silver/conductivity matrix - [ ] Gravity & falling: arcs, slips, shoves, rope cuts, mass×height damage, landing-on-someone sharing, cross-strata arrival - [ ] Electricity & signal: wire/plumbing BFS (capped), fluid/crowd chaining, hymn-card program propagation - [ ] Rope & climbing: length/anchor/load, pitons/pulleys/sledges/mule rigs, cuttable by anyone (check grates) - [ ] Scent & tracking: persistent scent volumes (blood/oil/rot/ozone/wool), washing, smoke masking, AI following - [ ] Structural: props/bolts/lintels, noise+weight+rot collapse, sledgehammer shortcuts (dirty-supports only) - [ ] Time & rot: corpse bloat→burst→spawn, spoilage, rust spread, NPC/faction clocks, 3-day gossip latency - [ ] Ten verticality toys playable end-to-end (boulder sounding, oil-under-door, flood-shaft descent, coin voice-throw, levitate-over-gas, rope-cut catch, stairwell shout+oil, freeze-thaw one-way, flour-vent find, counterweight ride) [03 §3.3] - [ ] 20 rule-chain integration tests green (e.g. `oil_under_door_grate_chokes_mimic`); proptest material×hazard matrix green — DONE Phase 2: `tests/phase2_laws.rs`, 21 tests (20 gate + `material_hazard_matrix` as plain loops, no proptest dep) green; gate-test adjustments in `docs/phase2-wiring-plan.md` §5 - [ ] **Gate:** all 12 laws demoable in a test arena (`tests/phase2_laws.rs` IS the headless arena until `hexwork --arena` lands Phase 5); every hazard emits a first-time law log line [04 §4.10.5] — DONE Phase 2: 21/21 gate green, `speak_law` + `LawLog` gate display, clippy `-D warnings` clean, fmt clean, 1k soak green (10k release-only) ## Phase 3 — Content pipeline [04 §4.4] - [x] Schemas + loaders for monsters/items/hymns/gods/contracts/floors/towns (TOML), with file:line validation errors — DONE: `schema.rs` (7 structs + wrappers, lowercase categories + `trade` alias), `load.rs` (`load_file`/`load_text`, 1-based lines), canonical `load.rs` tests parse through schema wrappers (no mirrors) - [x] Cross-ref integrity test (every fluid/material/hymn/floor referenced exists) — DONE: `tests/content_pack.rs` (town→contract, contract→floor, blood→fluid, material→voxel, no dup ids) - [x] **2-uses law test**: every item asserts ≥2 uses; single-use content rejected at build time [02 §5, 03 §3.4] — DONE: `validate_item` canon + gate asserts all 40 current canonical items; additive content must also map promises to existing runtime mechanics - [x] Hot-reload in debug builds; content-pack hash recorded into saves/replays — DONE: `pack::fmtime` (debug-only mtime poll, no notify dep); `pack_hash` SHA-256 order-sensitive + golden pinned (`00312cf6…`); save/replay consumption lands Phase 11 - [x] `assets/data/*.schema.md` written; `// intent:` comments on all balance numbers — DONE: 7 schema docs; `intent` REQUIRED non-empty on every entry + boon (validated) - [x] **Gate:** `cargo test -p hexwork-content` green on canonical data set — DONE: 43 lib + 1 pack gate green, clippy `-D warnings` clean, fmt clean ## Phase 4 — Renderer [05 all sections] **2026-09-09 evidence correction:** historical component tests below do not certify production camera navigation, per-half composition, terminal colors, readability or accessibility. Reopened claims are tracked by AC1–10 in [player-interface-audit.md](player-interface-audit.md). Original design goals remain; pending recovery work must not be called a complete HEXWORK experience. - [x] Cell buffer + ANSI diff + crossterm bring-up; static test scene on screen — DONE (string-level; terminal flush is Phase 5): `FrameBuffer` + `encode_diff`/`encode_full` + corridor scene rendering to golden hash - [x] Fixed-point DDA raycaster + 10-step density ramp + stratum fog colors (grayscale first) — DONE: Q10 integer DDA (`ray.rs`, 14 tests), ramp + 24-step light + facing tint (`shade.rs`, 12 tests), post-shade stratum fog lerp (`scene::apply_fog`, bands pinned) - [x] Edge-art detection + half-block faces + 24-step light multiply + facing tint — DONE: `edge_glyph` gate (│/─/+, 0.25/2.0 thresholds pinned) + two-pass bright-over-dim pack in `scene::render` - [x] Truecolor + palettes + 256-color LUT + no-color density path; capability probe + `HEXWORK_FORCE_*` overrides — DONE (renderer side): 6 palettes, `quantize_256`, `threat_loot_exit_redundant`; probe + env overrides land Phase 5 with term backend - [ ] Cameras: first-person (FOV≤75°) → chase-orbit (Tab toggle, collision pull-in) → top-tactical (M toggle, Z-slider, chalk + trajectory preview); 10Hz→60fps interpolation; vignette; sound arcs; thrown trails — Historical placement/interpolation helpers exist, but production look/orbit/collision need AC2–4 evidence. Chalk/arcs/trails remain deferred, not completed by interface recovery. - [x] Title-screen density-resolve boot animation; damage flash + hint-ribbon glow — DEFERRED to Phase 5 UI (renderer exposes hooks: fog ramp scalar + flash envelope on light multiply) - [ ] Adaptive render-scale (drop 10% on 3 over-budget frames); SSH path with 30fps floor + input prediction dots — Deferred, not implemented by the fixed-48m interface repair. Benchmarks are measurements, not an adaptive-quality implementation. - [ ] Triple-buffered snapshot (~200KB), render-never-blocks-sim; pooled buffers, zero hot-path allocs (debug tripwire) — `TripleBuffer` component tests exist; production Entry still samples light and builds descriptors per frame. Snapshot threading and full-pipeline zero-allocation claims are not established; renderer-only warm measurements must be labeled narrowly. - [ ] Screenshot-hash test rig + three-glance readability bots; no-camouflage-kill test; render-pure-function test — Historical golden/purity/fog/tactical fixtures exist. They ignore actual decoded SGR and the claimed loot fixture lacked real loot. Production spatial/color evidence requires AC1/5–7; three-glance human readability remains AC10 pending. - [ ] Budgets met: raycast+shade ≤6ms @120×36, encode ≤4ms typical, snapshot ≤0.5ms — Historical bench execution did not establish these separate production bounds. Current full render+encode trajectory evidence is recorded in the interface audit; a combined ≤16.7ms result does not close these stricter stage budgets. - [ ] **Gate:** 80×24 minimum refuses kindly; 120×36 at 30fps+ on 5-yr-old laptop; slice playtest: threats/exits/loot readable in 3 glances — Historical headless test counts are not performance or human route evidence. Current resize, optimized trajectory and normal-brightness acceptance require AC8–10 on an identified binary. ## Phase 5 — Terminal + UI + loop [04 §4.5–4.6; 01 §6–7] - [x] `hexwork-term`: raw mode, key/mouse/resize/focus normalization (kitty/wezterm/xterm/gnome/SSH); single TOML keymap (arrows+WASD+hjkl first-class); every mouse action has key twin — DONE: `backend.rs` (crossterm raw/alt-screen/flush/poll/probe/refusal) + `keymap.rs` (full table, Enter→Unknown documented, drag→CameraToggle) + `render/env.rs` (5 HEXWORK_* overrides) - [x] Screen stack: Title → Chargen → Play (HUD+log+hint ribbon) → Look/Inventory/Contracts/Map/Chapel → Death/Epitaph/Replay — DONE: `screens.rs` (overlay-Esc-pop, Death/Replay replace-only) + boot frames + death text - [x] Look mode with full rules-tooltips + identification state; searchable log (`/`); auto-explore with sane stop set; auto-loot filters — DONE: `look.rs` (honesty contract: uses_known never leaks) + `Log::search` + `explore.rs` (8 stop reasons, cursed-never loot) - [x] Main loop: input→intents→10Hz accumulator→snapshot→render→log flush→autosave every 600 ticks — DONE: `loop_.rs` + rewritten `main.rs` (poll→apply→push_time→scene render→encode_diff→flush→autosave hook, lantern follows player, orbit/tactical cameras, ascii floor) - [x] Panic handler → `crash-epitaph.md` (seed, tick, hash, last 50 log lines) — DONE: `write_crash_epitaph` + hook - [ ] Min-spec input test: full game completable keyboard-only over SSH in 80×24 no-color — Historical refusal/arena/no-color components are not evidence of full-game completion or accessibility. Current interface recovery requires color-aware production PTY and human AC10; neither certifies the full game. - [x] **Historical terminal-loop component gate:** chargen, input, fixed-tick scheduling, rendering, death routing, and SPS instrumentation compose; `--arena` prints tick/hash/actors/causes with fire links ≤20 ticks. The former text described Milthollow/contracts/three floors as a vertical slice before those production paths existed; the cross-phase playable-loop gate below now owns that acceptance claim. ## Phase 6 — Character & progression [03 §3.1] - [x] 4 ancestries + 6 callings with kits; attributes 1–20 (use growth + trainers); 14 skills 0–100 (use-gated) — DONE: `core/character.rs` (nudge table, kits with items.toml-verified ids, growth 10+L/5) + `core/training.rs` (trainer/book/ghost pricing); `State.characters` keyed by actor id; chargen flow (ancestry→calling→sheet→Play) + Choir-deserter wanted hook - [x] No levels: reputation (faction ranks, town ledgers, god-credit) + knowledge persistence (recipes/maps/translations in lineage vault) — DONE: `core/reputation.rs` (rivalry table, barter formula, saturating ops) + `save/knowledge.rs` (BTreeSet merge + vault round-trip, gear never persists); `State.reputations` per-delver; ledgers-follow-delver / knowledge-follows-lineage documented - [x] Trainers, books, ghost-teachers (priced); Morrowind-style sheet UI — DONE: `training.rs` tables + `ui/sheet.rs` (boxed render, bars, width-clamped); growth call sites seeded (Ropework/Dungeoneering in Move; rest hook-marked per wiring plan) - [x] **Gate:** hour-5 character is fragile, specific, weird (playtest signoff) — DONE (mechanical): 410 tests green workspace-wide, no-XP grep clean, no-trap-picks test-enforced, hash covers sheets+reputations; playtest signoff at slice demo ## Phase 7 — Items & identification [03 §3.4] - [x] All categories: weapons (polearm shaft bonus), armor (material-first), tools (rope/pitons/poles/nets/sledges/bells/flour/chalk), consumables, relics, trade goods, corpses (butcher/eat/carry/cure) — DONE: `core/item.rs` (Instance, 9 conditions, tags) + `core/inventory.rs` (HAUL, equip, reach/silvered/corpse hooks); `tags` on canonical data (lamp/polearm/armor/corpse/perishable); corpse-drop on death - [x] Identification: by-use, tinker (paid, lies if underpaid, ledger remembers), testing chapel toybox (cages/barrels/grounding rods), ghost-for-memory — DONE: `content/identify.rs` (use-ladder, tinker bands + fibs, trial keywords, ghost bool, shop labels) + `ui/identify_ui.rs` (idf lines, receipts, trial reports, shop tags); `State.idf` per-delver + vault-merge-at-death penciled - [x] Curses/blessings + conditions (rust/damp/cracked/humming/owed with Audit fine print); Corpse-tender remove-curse person + garden — DONE (mechanical): stick/lie/call-out rules + blessed-displaces ruling (audited); garden/person lands Phase 9 - [x] Honest tooltips (game never lies; NPCs may); shop stock labeled identified/unidentified — DONE: look.rs contract + identify_ui boundary (fibs quoted, never fed to tooltips) + shop_label/shop_tag - [x] **Gate:** 120+ items at 1.0 volume; slice needs 30 with 2+ uses each demonstrated — DONE: 30 canonical (2+ uses gate green) + `tests/phase7_items.rs` (mirror-fidelity, spawn rules, HAUL, trial reveals, shop honesty); 487 green workspace-wide ## Phase 8 — Magic: hymns & bargains [03 §3.5; 02 §2] - [x] Hymn-case with limited slots (loadout strategy); 7+ launch verbs (`FIAT LUX, APERI, PONDUS, SILE, FLUCTUS, MEMORIA, CARO VALE`) — DONE: `core/hymn.rs` (case, slots, conduct, resolve, cook-off, attention) + `core/casting.rs` (7 resolvers, classifier); `State.hymn_cases` + `cast_queue` - [x] Conduct rolls (Aether + card condition + copper + Deep weather); debugging-logic miscasts (wrong target, swapped args, echo, kernel-panic cherub) — DONE: formula base+aether*2−worn15+copper10+weather clamped 5–95; Hymns phase drains queue off COMBAT stream; cherub hook via signal_sources; Hymns practice on cast AND miscast - [x] 5 gods with full bargain tables, small print, ledgers, blasphemy collections; kneel-anywhere + altar receipts — DONE (mechanical 2-slice + full shape): `core/bargain.rs` (kneel/repay/due/blaspheme/pay_lien, +10/+25/−500/alms pinned) + `State.bargains` + tenday ticking + death-hook (debts gear-like); gods 3–5 tables land with Phase 9–10 content - [x] Punchcard visuals + dead-Latin flavor; chapel-of-Drowned-Saint memory-for-answers exchange — DONE: `ui/chapel.rs` (bargain/blasphemy/memory-offer text); memory DELETION mechanics land Phase 10–11 with vault ops - [x] 40+ hymns at 1.0; slice needs the 7 verbs + 2 gods (Lamplighter, Tollkeeper) — DONE: 7/7 verbs + 2/2 gods live, mirror-tested, tables validated - [x] **Gate:** miscast table playtested funny-not-cruel; every bargain's debt collectible in-dungeon (incl. mid-fight lien payment moment) — DONE: `tests/phase8_magic.rs` (mirror, cast-light, classifier coverage, conduct spots, boundary, tables, credit ladder + death settle); 574 green workspace-wide ## Phase 9 — NPCs, towns & economy [03 §3.6; 02 §3–5] **Status:** `[code: yes] [integrated: partial] [gate: partial]` — normal startup now constructs populated Milthollow and generated Deep through GameSession; named actors, board access and inn/world-time actions have production-session tests. Full shops/services/physics interactions and the complete runtime gate remain open. - [x] Named townsfolk with jobs/homes/debts/gossip; schedules (lamplighters/mill/chapel/tavern/coaches); 3-day gossip propagation — DONE: `core/npc.rs` (13 jobs, intents, grudges) + `core/schedule.rs` (day phases, posts, gossip gate); `State.npcs/shops/gossip`; Intent phase (stimulus pre-sort, 1m/2m steps); Rot gossip drain - [x] Services: inn (sleep advances world), tinker, lampwright (+oil scrip currency), warden post, menders, fences, Audit auction (buy back own confiscated loot) — DONE: `core/services.rs` (7 prices, sleep 8640, garden gate, collectors) + triage-constant rule - [x] Shopkeeper NetHack-law: ledgers/memory/grudges; physics shop floors (topple/arson/bell-emptying + billing); debt collectors visit dungeon floors — DONE (mechanical): grudge ladder + bell-as-debt + shop-local/global split; collectors table; floors physics parent-side per plan - [x] Milthollow (312 souls) + Copperwash + Gallowgate + Drowned-Saint chapel + Barrowfield at EA; slice needs Milthollow high-density — DONE (slice): 13 named townsfolk roster in gate test; new towns land Phase 10 content - [x] Salvage economy: coppers/silver/scrip + wire/cells/cards/moss/pelts/bone/bells(illegal, ringing) — DONE: `core/economy.rs` (coinage, 8 goods, integer drift with pins, bell law+bill) - [x] **Component gate:** a constructed unattended town model advances sensibly 7 days (schedules kept, prices drift, gossip arrives) — DONE: `tests/phase9_town.rs` (schedules/drift/gossip/shop-law); this is not the production-runtime town gate. - [ ] **Runtime gate:** normal game startup places the player in populated Milthollow; named NPC schedules, shops, services, interaction points, physics shop floors, and world time operate through production code. - [x] Bounded live Tinker identification: normal generated unknown loot can be carried back to Milthollow, selected by exact instance ID and identified for15cu through a separate fresh confirmation. Atomic zero-tick tag12 payment/knowledge, stale/access/funds rejection, Story rollback and save-retry semantics covered; actual Story/Classic acquisition→purchase→reload and captured-run binary replay, six80×24 PTY cases, parent manual smoke, complete stable audited target coverage and independent review passed. Underpayment/trading/mending/general item uses and the full town economy remain open. See `tinker-identify-wiring-plan.md`. ## Phase 10 — Contracts, quests & dungeons [03 §3.7–3.8; 02 §3] **Status:** `[code: yes] [integrated: partial] [gate: partial]` — real board acceptance/tracking, generated voxel transitions, reciprocal melee, rat objective/reward and return/service flow are integrated and tested through GameSession. The all-floor/boss/Vault-Choice gameplay and full runtime EA gate remain open. - [x] Notice boards + 60+ contracts (tiers vermin→saints→Deep); poster-doesn't-know discoverable via gossip; prep-before-fight solvable-cleanly — DONE: 62 contracts (20/15/13/8/6 spread, all with ask-hook unknowns + prep notes) + `content/contracts.rs` (board filter, prep audit, thread order) - [x] No compass: landmark+depth+draft directions; player chalk + map annotations + mule-pathing; verbatim direction log — DONE: `core/dungeon.rs` (Chalk dust-capped, Direction, MulePath Manhattan) + `State.chalk/mule` + `ui/board.rs` (cards with KNOWN/UNKNOWN split, coordinate-free) - [x] 12-floor Deep: hand anchors + systemic fill; 3+ vertical connectors/floor; airflow + water path + faction presence + secret vents; Shallows 1–3 kind, Works 4–8 proper, Deep 9–12 dream-logic — DONE: 12 floors (4 connectors + 2 vents each, stratum-matched) + `worldgen/deep.rs` (fill, dream/choir gates, vault 12) - [x] Bosses-as-puzzles: Rat-king, Saint of Rust (name bargain), Toll-troll Matriarch (mid-fight negotiation), Audit Seraph (bankrupt/pay/drown ledger), Drowned Saint (bring-him-or-don't) — DONE: 5 boss flags + puzzle habits + boss contracts; AI per wiring plan (lure/bankrupt/negotiate/bring) - [x] Main thread thin-to-8: Widow Rennick → Drowned Saint → Deep Door → Vault Choice (SEAL vs CROWN, NG+ boss-haunt) — DONE at subsystem level: 6 thread contracts (floors 3/6/8/11/12/12) + `State::set_vault_choice` implementation-enforced write-once choice + cantor trigger (Choir sings, law-gated once per run) - [x] 40+ monsters each with habit/tell/use + 3D behavior; 200+ epitaphs; 100+ replay tutorial subtitles — DONE (EA floors): 42 monsters (per-floor ≥3 coverage recomputed) + 60 epitaphs + 20 subtitles (append-only growth to 200+/100+ documented); 5 gods full tables - [x] **Component gate (former EA claim):** content thread graph, cantor trigger, write-once Vault Choice, chalk/mule, and prep-direction contracts are verified in `tests/phase10_ea_gate.rs`; it manually constructs state and is not an executable-path EA gate. - [ ] **Runtime EA gate:** use Milthollow's real board → inspect/accept a contract → enter generated voxel Deep floors → complete its objective through normal systems → return for reward/standing updates; Vault Choice arises naturally and remains immutable. ## Phase 11 — Death, lineage, saves, replays [03 §3.9; 04 §4.7] **Status:** `[code: yes] [integrated: partial] [gate: partial]` — the production terminal/headless frontend now shares the authoritative GameSession and ArtifactStore paths, with v4 run/replay/core hashes and v2 lineage vaults. Actual binary tests cover save/exit/resume, real Classic death producing a replay, descendant map inheritance without automatic gear, and repeated Story resurrection/resume. Current state and Story checkpoints retain ordered lifecycle history and typed knowledge under bounded replay. The Stage 3c2 frontend correction milestone is independently accepted with final post-edit workspace formatting, strict locked all-target clippy, and locked all-target tests passing; the full process/lineage acceptance matrix is not yet complete. Checked historical items below describe earlier component milestones, not present release certification or authoritative current schemas. Production no longer uses the legacy header/string-demo or inline revival paths. Core death now preserves run knowledge/IDF, and immutable recorded InitialLineage is applied once at new-run initialization, not resume. Auction provenance is stored without live equipment inheritance; actual auction purchase/buyback remains required and incomplete. See `live-integration-plan.md` for the current schema, recovery contract, evidence levels, and outstanding acceptance work. - [x] Classic permadeath: epitaph + cause-chain + `.hexdemo` + ghost (1 item ID + 1 warning) + lineage vault (maps/recipes/translations, never gear) + Audit auction buyback — DONE: `core/death.rs` (record, ghost, buyback→services canon, persists allowlist) + death hook (vault-merge log, debt settle, idf→recipes merge); identified persists AS recipes (vault has no 5th field — decided, documented on LineageVault) - [x] Story mode: town-entry checkpoints, chapel-debt resurrection quest; Ironcartographer daily seed mode — DONE: `core/modes.rs` (Mode, Checkpoint, ChapelDebt 1-burial, daily_seed FNV pins) + `--story`/`--daily` CLI + Story wake path in handle_death - [x] Saves: bincode+zstd + seed + input tail, versioned with migrations; demo export `--export-ansi` shareable casts — DONE: `save/save.rs` (SaveHeader, envelope level 3, version gates, delete_save) + autosave writer + `--replay`/`--export-ansi` runner (verify → restep → compare) - [x] Death replay viewer with rule-chain subtitles; SPS prompt ("worth retelling? [y/n]", local-only) — DONE: `save/demo.rs` (record/verify/export/restep) + `ui/death_ui.rs` (frames, exact SPS wording, vault-kept + buyback lines); subtitles resolve via epitaphs::subtitle per link - [x] **Accepted bounded process-evidence tranche:** `cli/tests/phase11_gate.rs` now exercises the real binary for resume, action-carrying replay, Classic provenance/descendant consequences, retained corrupt/old/mismatched input rejection, deterministic archive-conflict recovery, allocation-counter collision, and ordinary-input Inn autosave. Review and final workspace gates passed. Historical bare-restep tests are not used as production replay proof; unavailable acquisition categories and exact crash instants remain separate gaps. - [ ] **Persistence gate:** mutate authoritative inventory/world/NPC/contract state → save → terminate → reload → canonical hash identical; Classic death atomically persists lineage and writes an input-carrying `.hexdemo`; Story death restores the stored town checkpoint. - [ ] **Replay gate:** same seed + content pack + committed player actions at recorded ticks reproduces the stored expected terminal canonical hash, with clear first-divergence diagnostics. ## Cross-phase production integration gates — Phases 9–11 - [ ] **Playable-loop gate:** chargen → populated Milthollow → NPC schedules running → real board inspection/acceptance → generated Deep → traverse several real floors → interact with actor/item/environment systems → satisfy objective → return/reward → use inn/service → sleep/world advancement → save/quit/reload → identical authoritative state. - [ ] **Classic-lineage gate:** production Classic death → run-save lifecycle as designed → input-carrying `.hexdemo` written → lineage vault atomically persisted → descendant startup loads inherited knowledge. - [x] **Deterministic-demo gate:** production death's actual `.hexdemo` replays committed actions/history to its stored final canonical hash through the real binary, including after changed/removed external vault. Accepted `classic_real_death_commits_demo_vault_receipt_before_retirement` also checks prelethal saved event prefix plus one event; final locked workspace gates pass. This does not certify missing acquisition verbs or exact crash windows. - [ ] **Runtime debt gate:** `--arena --seed` affects arena state; tactical Z moves only on explicit input; panic hook writes `crash-epitaph.md`; actors render from identity rather than generic rat fallback; stale phase placeholders are removed or accurately qualified; entity authority is documented and drift-tested. ## Phase 12 — QoL, accessibility, audio [03 §3.10; 05 §5.4–5.5; 01 §7] **Status:** `[code: yes] [integrated: partial] [gate: partial]` — accepted live slices now include rooted physical-key remapping, persisted gamma/FOV/five-palette boot controls, bounded recent feedback with typed atomic input rejection, and a carried Inventory/Look browser with separate confirmed own-cell pickup/drop. Independent reviews, actual PTY/headless evidence, and final workspace gates passed for these slices. Transfers include shared structural-limit preflight, additive v4 history, and real Story/Classic process lifecycle proofs; this is not equipment/item-use/economy completion. In-game sliders, full history/search, screenreader/undo/dyslexia controls, audio wiring, and live accessibility signoff remain open; component palette tests are not certification. - [x] Boot presentation controls: interactive `--gamma`, `--fov`, `--palette` apply to actual frames and persist explicit choices in bounded `/presentation.json`; defaults do not create a file. Headless/recovery/replay ignore optional preferences and reject explicit presentation overrides. This is not an in-game sliders gate. - [ ] Kindness layer: pause-step hybrid, undo-able interface mistakes (never sim), persistent tooltips, in-game gamma/FOV/shake sliders - [ ] Palettes: protan/deutan/tritan-safe + high-contrast + no-flicker with measured contrast tests; threat/loot/exit never hue-only - [x] Bounded live recent-feedback panel: four critical chrome rows plus header/three message rows at 80×24; cell-safe wrapping, stale-row clearing, tooltip-title inventory summaries, and atomic input-rejection feedback. Contracts opening now also preserves controller/menu state on rejected inspection and uses terminal-recoverable feedback instead of exiting; real Play/Map PTY and headless fail-fast regressions plus final workspace gates passed. This does not complete searchable history, wayfinding or semantic narration. - [x] Carried Inventory/Look browser: bounded six-item stable-ID pages beyond the old 64-entry presentation prefix, scrollable bounded tooltips, correct modal/clock/lifecycle behavior, loaded-key hints, opaque display and true full redraw on close. Browsing/inspection alone adds no committed action; mutation uses the separate confirmed transfer path below. No equipment/world-look completion claim. - [x] Confirmed live own-cell pickup/drop: exact-ID atomic ownership updates, shared structural admission, optional g/- bindings preserving legacy maps, explicit prompts and batch barriers, and lifecycle-first handling. Real generated-loot headless/80×24 PTY tests prove pickup/inspection/drop, save/load and replay; real Story checkpoint rollback and Classic death/recovery preserve transfer history/ownership. Raw/compressed-byte/proof/durability failures remain fatal save-boundary failures, not rolled-back input rejection. Cursed-drop rejection is Core/Application/batch fixture evidence, not ordinary cursed-gear acquisition; no item physics, gear bonuses, sale/buyback or full-loop completion claim. - [x] Essential status/quit visibility at80×24: HP/carried-light/burden row17, real mapped Quit first in Play/Map (including contextual melee), Town/Deep/tick/tactical row20, unchanged16-row viewport and warning/recent feedback. Pure bounded Unicode/control-safe formatting with explicit elision; actual grid and default/remapped PTY/save identity evidence; parent Story tmux Play→Map→return→quit status0 and fresh full-workspace gates accepted (phase12-wiring-plan T.17). Lower-priority Play hint clipping remains; tactical orientation/range is closed by the separate bounded slice below. Broader reveal policy remains open; not full accessibility/visual certification. - [x] Bounded live tactical orientation: body/head/support terrain distinguishes blocked/floor/water/gas/unsupported space; player-only on-slice `@` and honest off-slice Z; active-location raw-Z limits cover all12 catalog-derived Deep contexts, with real Town→Deep1→Deep2 route/save/PTY load atZ-19. Commit-boundary location sync, fixed same-location slice, pre-mutation budget admission, semantic ASCII/gamma, loaded-key cell-safe legend and unchanged16+8 geometry are tested. Normal Story/no-color Classic real80×24 PTY and parent default-LIVE manual navigation/quit pass; final independent review and equivalent partitioned full-workspace target gates accepted (T.18; tactical-map-wiring-plan.md). No actor/item/connector/landmark reveal, wider planner, all-floor binary traversal, human accessibility/color/platform/performance or full-game completion claim. Actual Rust1.75 compiler gate remains blocked by separately tracked pre-existing lockfile/source debt. - [x] Live weapon Wield plus bounded polearm reach: exact owned weapon ID, pre-refresh selection guard, separate fresh-batch confirmation, zero-tick atomic journal/slot change, persistent list/detail markers and truthful loaded-key feedback. Real starter pike reaches2 only on a clear same-floor cardinal lane; no actor/wall piercing or out-of-reach return strike, adjacent rules/damage3 preserved. Actual generated-route save/replay and six80×24 PTY cases, manual UI flow, stable complete target partitions/optimized replay and independent review accepted (T.19; wield-reach-wiring-plan.md). Additive v4 tag11 preserves old bytes but old readers reject new Wield tags. No armor/consumables/silver-quell/shaft/vertical/general combat completion claim. - [ ] Screenreader event stream (threat>exit>loot>flavor, throttled, interruptible); scripted winnability-from-stream test - [x] Boot-time remappable physical keys: optional `/keymap.toml`, 64 KiB/type-checked loader, missing-only embedded fallback, shared immutable chargen/play mapping and truthful labels. Actual PTY tests decode selected identity and west/east moves across save/load. No live rebind or all-terminal certification implied. - [ ] Reduced-motion, dyslexia log layout, colorblind live certification - [ ] Audio: terminal-bell synth + optional rodio (feature-gated); bell-toll/clacker/hum capped, mutable, off by default over SSH - [ ] **Gate:** accessibility signoff checklist complete before 1.0 ## Phase 13 — Content volume & balance (1.0 fill) [03 §3.11] - [ ] Counts: 40+ monsters, 120+ items, 40+ hymns, 5 gods, 3 towns + 6 hamlets, 60+ contracts, 12 floors + testing chapel + auction house - [ ] Soak: headless bot 50k ticks nightly, no panics, tick budget held; SPS ≥ 1.0 across playtest cohort - [ ] Balance passes: depth+debt+noise+light difficulty (never stat walls); economy sinks/sources audit - [ ] **Gate (1.0 GATE):** blind tester cohort finishes slice-to-Vault with ≥1.0 stories/session, zero render-induced nausea reports, zero undeducible-death reports upheld on review ## Phase 14 — Ship - [ ] Store page copy (says plainly: no compass, permadeath, cruel-but-fair); demo = vertical slice free forever - [ ] Seed-sharing + demo-replay community surface; daily Ironcartographer feed - [ ] Release binaries via `cargo dist`; crash-epitaph pipeline triaged; save-migration promise documented - [ ] Post-launch reserve: Salt Cantons, Glass Desert, the Pale; the one-who-came-back-right mystery stays unconfirmed - [ ] **Done means:** all boxes checked, all gates passed, bible + code agree (docs updated with any build-learned changes)