# Lantern fuel — scope investigation, not implementation authorization Status: research complete; exact wiring plan pending. Baseline `757962b` accepted Tinker. No runtime/config/content changes made. Full HEXWORK1.0 remains incomplete. ## Problem Production stores/hashes item fuel and displays the lowest-ID carried lamp, but actual lighting uses an independent player light source. `spend_fuel` has no production caller. Refilling a number without burn/extinction would be cosmetic; do not ship it as functional oil use. Item prose is not an effects interpreter. Source evidence (current investigation): `core/light.rs:44–55` LightSource has position/radius/warm but no owner; `core/state.rs:2262–2269` light phase consumes sources, not item fuel; `cli/session.rs:1034–1047` creates standalone player light, `:3222–3226` syncs lights[0] position. Item fuel, light sources and voxel light contribute to canonical state hashes. `core/item.rs:411–426` spend_fuel changes final-unit condition to Spent. Full step and unattended Inn advancement differ (`core/state.rs:1717–1735`); any cadence must specify both. ## Compatibility decision not yet made by operator Parent asked whether to introduce a new version rejecting old recordings, preserve v4 execution, or defer. The structured question could not reach the unavailable operator during unattended goal continuation. **No answer/approval was received.** Prior preference for current Rust over old-toolchain maintenance does not automatically authorize breaking player saves/replays. Conservative planning assumption: preserve v4 while proposing new fuel semantics for new runs. This is a proposal, not an indefinite support promise or implementation handoff. An adversarial independent read-only review found it technically feasible; user absence is not itself a technical block. Do not falsely mark the entire goal blocked or complete. ## Why a semantics contract is necessary Run/replay globals currently4 (`save/protocol.rs:53–56`), headers carry format/hash versions but gates accept only current values (`:777–780,1428–1452`). RunIdentity (`:567–579`) and StateImage (`core/checkpoint.rs:46–91`) have no semantics selector. Replay reconstructs via Session::from_identity; State::from_image recomputes hashes. A CLI-only flag would disappear across checkpoint/image/replay boundaries. Canonical v4 prefix/domains must remain byte-identical for legacy states, not gain an extra flag. An explicit Refuel action does not solve automatic burn compatibility: old ticks would still change. First-refill implicit activation is a hidden semantics transition and leaves default lamps artificially infinite; reject that shortcut. ## Candidate conservative architecture - Closed immutable runtime semantics enum LegacyV4/FuelV5, carried through State, StateImage, identity, checkpoints, resurrection, recovery and replay reconstruction. - Preserve exact v4 wire layout/encoder/decoder and canonical hash stream. Validated v4 format/hash pair selects LegacyV4. Loaded v4 continues and exports as v4; no silent migration. - New supported envelope/hash pair selects FuelV5. No redundant serialized selector required if header pair uniquely determines it, but all reconstructed runtime/image boundaries must retain and validate semantics consistency. - Dispatch before initial kit/light creation, not only during ticks. Legacy keeps current source initialization/movement/no-burn/unattended behavior. New hash prefix and fields cover all future-affecting lamp state. - Share unchanged code; explicitly branch only changed simulation behavior. This still adds permanent codec/selector/regression costs, not just an enum. ## Exact decisions needed in the next wiring plan 1. Which carried instance owns light; multiple lamps, pickup/drop/death, whether dropped lamps stay lit, and treatment of non-lamp callings. 2. Fuel units/capacity/rate and cadence ownership; full-step phase order and unattended sleep behavior. Define replenishment of Spent condition honestly. 3. Light invalidation on movement/extinction/refuel; do not leave old voxel illumination or replace environmental sources via lights[0]. 4. Exact selected lamp+oil instance action, consumption/capacity/rejection and atomic save/event handling. No generic uses interpreter or oil sale without functioning effect. 5. Header/version support table and selector flow through every constructor/wire conversion. No silent upgrade, mutation or deletion of old artifacts. 6. New-run default and intended future support/migration policy must be stated as proposed choices, not alleged operator approval. ## Required evidence before acceptance Separate compatibility plumbing and actual gameplay slices in the dependency graph. Inventory affected constructors/serializers first, then review exact plan before writers. Test genuine v4 decode/reencode/replay hashes plus resumed/exported continuity; unknown/mismatched version pairs rejected; new default fuel consumption, refill, depletion/extinction, multiple-lamp/drop/light-cache and sleep semantics deterministic; save/checkpoint/replay reconstruct same future behavior. Use ordinary starter content/process inputs, focused opt1 checks and one frozen checkpoint per development-validation.md. Preserve existing fixture files and provenance. No additional old-Rust matrix. ## Constructor and wire inventory (read-only follow-up) These are current symbols, not implemented new APIs. Line anchors refer to gameplay baseline757962b and may shift. No LegacyV4/FuelV5 selector or RunIdentity constructor methods exist today; identity construction uses struct literals. | Boundary | Current symbols / source anchors | Required consideration in proposed versioned design | |---|---|---| | Core construction | `State`, `State::new(seed)`, state.rs147–176,401–451 | Explicit immutable semantics before initialization; no silently changed existing caller defaults. | | Full versus unattended time | `State::step`, `phase_light`, `preflight_unattended`, `advance_unattended`, `spend_copper_and_advance_unattended`, state.rs1717–1815,2262–2269 | Separate specified burn behavior; retain legacy spatial omissions and paid-time atomicity. | | Images | `StateImage`, checkpoint.rs46–87; `State::to_image/from_image`, state.rs2484–2693 | Selector survives all reconstruction and is validated, not defaulted. | | Hashing | `CANONICAL_HASH_VERSION`, `try_hash_state`, state.rs260–265,2696–2860 | Exact legacy prefix/domain stream; new hash contract includes new future-affecting state. | | Identity | `RunIdentity`, `identity_to_wire/from_wire`, protocol.rs567–579,1525–1560 | Immutable reconstruction input, no CLI-only selector lost during replay. | | Envelopes/wire | `EnvelopeHeader`, `RunWire`, `ReplayWire`, `RunIdentityWire`, protocol.rs774–814; version gates1409–1453 | Preserve v4 layout; validated format/hash pair may infer selector, then materialize it in runtime/image boundaries. | | Run codecs | `encode_run/decode_run`, protocol.rs1222–1283 | Version-dispatch codec and validate identity/current/checkpoint consistency. | | Replay codecs | `encode_replay/decode_replay`, protocol.rs1286–1336; entry.rs683–710 | Replay has identity/events, no state snapshot; semantics must reach bootstrap before any tick. | | Hashed images | `HashedState`, `hashed_state_to_wire/from_wire`, `validate_hashed_image`, protocol.rs581–620,1756–1819 | Image→State recomputes hash; selector cannot live only on decoder. | | Checkpoints | `StoryCheckpoint`, protocol.rs623–628,1788–1804; `build_checkpoint`, session.rs2335–2364 | Same semantics throughout checkpoint creation, prefix proof and resurrection. | | New/resumed sessions | app.rs372–419 identity literal; `from_identity`, session.rs995–1079; `from_decoded`,1917–1958 | New bootstrap creates kit/standalone light; resume reconstructs decoded state directly. Both must be explicit. | | Source movement/resurrection | `sync_player_light*`, session.rs3214–3227,4260–4268; resurrection2278–2297 | Legacy index0 behavior versus new owned lamp source and invalidation. | | Replay/time/lifecycle | session.rs2060–2341,3597–3647; Inn3481–3503; app budget1868–1872 | Full idle ticks, unattended Inn time and checkpoint restoration all preserve selector/timeline. | | Durable artifacts | save/artifact/mod.rs1299–1324,1729–1737 codec consumers | Coordinate downstream save/replay identity construction and validation. | Core owns State/image/light/item and must not gain a content dependency: content already depends on core. Save owns identities/hashed states/wire/codecs and depends on core/content. CLI owns startup/replay/lifecycle and presentation. Core and Save workers may only proceed with frozen shared signatures; CLI follows their interface checkpoint. Do not assign overlapping state/image/protocol/session constructor changes to independent workers. Existing oracle targets (not rerun during this inventory): Save `genuine_pretransfer_v4_fixtures_decode_and_reencode_identically` and `genuine_v3_run_replay_fixtures_reject_before_v4_body_parse`; immutable Classic/Story v4 run fixtures and v4 replay plus provenance. Core `same_seed_same_hash`, `full_tick_mutates_and_hashes`, `unattended_advance_matches_empty_world_clock_scope`, `unattended_advance_overflow_is_atomic`. CLI `exact_run_restore_retains_state_history_and_continuation`, `mixed_replay_reconstructs_same_tick_actions_idle_gaps_and_terminal_hash`, `inn_service_charges_unattended_work_before_dispatch`, `resume_resurrection_export_replay_matches`, `repeated_resurrection_keeps_ordered_history_and_active_checkpoint_reference`, `resurrection_continue_export_replay_matches`, `story_death_restores_town_checkpoint_and_can_repeat`, `deep_to_town_refreshes_checkpoint_after_transition_event`, `v4_replay_preserves_latest_story_checkpoint_reference`. These existing tests do not certify a proposed selector or fuel system. Research itself does not certify a fuel mechanic or authorize broad compatibility implementation. Next useful work is a bounded exact version/lantern wiring plan, then independent review and any remaining operator-owned decision.