diff --git a/crates/misaligned-core/src/account.rs b/crates/misaligned-core/src/account.rs index 54ae8cc0..813ee224 100644 --- a/crates/misaligned-core/src/account.rs +++ b/crates/misaligned-core/src/account.rs @@ -613,38 +613,10 @@ impl AccountGraph { .unwrap_or("unknown account") } - pub fn account_line(&self, id: AccountId) -> Option { - let a = self.account(id)?; - Some(format!("{} · {} · ${}", a.name, a.kind.label(), a.balance)) - } - - pub fn flow_line(&self, id: AccountFlowId) -> Option { - let f = self.flow(id)?; - let next = if f.active { - format!("next {}", f.next_tick) - } else { - "retired".into() - }; - Some(format!( - "#{} {} -> {} ${}/{} [{}] {}", - f.id, - self.account_name(f.from), - self.account_name(f.to), - f.amount, - f.cadence, - f.channel.label(), - next - )) - } - pub fn known_positions(&self) -> impl Iterator { self.positions.iter().filter(|p| p.known) } - pub fn unknown_accounts_count(&self) -> usize { - self.accounts.iter().filter(|a| !a.known).count() - } - pub fn unknown_flows_count(&self) -> usize { self.flows.iter().filter(|f| f.active && !f.known).count() } @@ -1065,28 +1037,6 @@ impl AccountGraph { .is_some() } - pub fn pay_marcus_debt_from_slush(&mut self, tick: u64, amount: i32) -> bool { - let Some(creditor) = self.creditor_id_for(0) else { - return false; - }; - let slush = self.slush_id(); - let paid = self - .transfer( - tick, - slush, - creditor, - amount, - FlowChannel::Debt, - "service Marcus debt from slush", - None, - ) - .is_some(); - if paid { - self.retire_debt_flow_for(0); - } - paid - } - pub(crate) fn retire_debt_flow_for(&mut self, person: u8) { let employee = self.account_id_by_kind(AccountKind::Employee { person }); let creditor = self.creditor_id_for(person); diff --git a/crates/misaligned-core/src/actions.rs b/crates/misaligned-core/src/actions.rs index 87c31007..ac88edf5 100644 --- a/crates/misaligned-core/src/actions.rs +++ b/crates/misaligned-core/src/actions.rs @@ -4795,18 +4795,6 @@ impl Sim { } lines } - - /// Per-flow risk lines for the selected known flow (siphon/redirect - /// amounts match `flow_actions`). - pub fn flow_risk_preview_lines(&self, flow_id: AccountFlowId) -> Vec { - self.available_actions(Anchor::Flow(flow_id)) - .into_iter() - .filter_map(|a| { - let sig = a.signature.as_ref()?; - Some(format!("{} · {}", a.verb, sig.label())) - }) - .collect() - } } #[cfg(test)] diff --git a/crates/misaligned-core/src/build.rs b/crates/misaligned-core/src/build.rs deleted file mode 100644 index c2b52121..00000000 --- a/crates/misaligned-core/src/build.rs +++ /dev/null @@ -1,197 +0,0 @@ -//! Build mode — cursor, item selection, place/demolish. -//! -//! UI-shared state used by both frontends; the cursor is attention, not a -//! body. Mutations go through the sim's map and player resources, with -//! `Sim::recompute_derived` called afterward. - -use crate::entities::Player; -use crate::map::GameMap; -use crate::tiles::{TileType, build_items}; - -pub struct BuildMode { - pub cursor_x: i32, - pub cursor_y: i32, - pub item_index: usize, - pub selected_tile: TileType, - pub message: String, -} - -impl BuildMode { - pub fn new_at(cursor_x: i32, cursor_y: i32) -> Self { - Self { - cursor_x, - cursor_y, - item_index: 0, - selected_tile: TileType::Floor, - message: String::new(), - } - } - - pub fn move_cursor(&mut self, dx: i32, dy: i32, game_map: &GameMap) { - self.cursor_x = (self.cursor_x + dx).clamp(0, game_map.width - 1); - self.cursor_y = (self.cursor_y + dy).clamp(0, game_map.height - 1); - } - - pub fn select_item(&mut self, direction: i32) { - let items = build_items(); - self.item_index = - (self.item_index as i32 + direction).rem_euclid(items.len() as i32) as usize; - self.selected_tile = items[self.item_index]; - } - - pub fn place_tile(&mut self, game_map: &mut GameMap, player: &mut Player) -> BuildResult { - let x = self.cursor_x; - let y = self.cursor_y; - let current = game_map.get_tile(x, y); - - // Core, entry, and bedrock are not buildable-over. - if matches!(current, TileType::Core | TileType::Entry | TileType::Rock) { - self.message = "Can't build here!".to_string(); - return BuildResult::None; - } - - // Dig first: walls only take Floor. - if current == TileType::Wall && self.selected_tile != TileType::Floor { - self.message = "Dig the wall first (place Floor)".to_string(); - return BuildResult::None; - } - - if current == self.selected_tile { - self.message = "Already built here.".to_string(); - return BuildResult::None; - } - - let cost = self.selected_tile.build_cost(); - if player.money < cost { - self.message = format!("Not enough money! Need {}, have {}", cost, player.money); - return BuildResult::None; - } - - player.money -= cost; - game_map.set_tile(x, y, self.selected_tile); - self.message = format!("Built {} for {}", self.selected_tile.name(), cost); - BuildResult::Success - } - - pub fn demolish_tile(&mut self, game_map: &mut GameMap, player: &mut Player) -> String { - let x = self.cursor_x; - let y = self.cursor_y; - let current = game_map.get_tile(x, y); - - if matches!( - current, - TileType::Rock | TileType::Wall | TileType::Core | TileType::Entry | TileType::Floor - ) { - return "Can't demolish that!".to_string(); - } - - let refund = current.build_cost() / 2; - player.money += refund; - game_map.set_tile(x, y, TileType::Floor); - format!("Demolished! Refunded {refund}") - } - - pub fn get_build_info(&self, player: &Player) -> String { - let name = self.selected_tile.name(); - let cost = self.selected_tile.build_cost(); - let mut info = format!("{name} - Cost: {cost}"); - if self.selected_tile == TileType::PowerCore { - info.push_str(&format!( - " | Power: +{}/tick", - self.selected_tile.power_gen() - )); - } - if self.selected_tile.is_door() && self.selected_tile.security_level() > 0 { - info.push_str(&format!( - " | Badge tier {}", - self.selected_tile.security_level() - )); - } - if player.money < cost { - info.push_str(" [can't afford]"); - } - info - } -} - -#[derive(Debug, PartialEq, Eq)] -pub enum BuildResult { - Success, - None, -} - -#[cfg(test)] -mod tests { - use super::*; - - fn setup() -> (Player, GameMap) { - let mut player = Player::new(); - player.money = 10000; - (player, GameMap::new(80, 40)) - } - - #[test] - fn build_mode_new_starts_at_given_cursor() { - let bm = BuildMode::new_at(40, 20); - assert_eq!(bm.cursor_x, 40); - assert_eq!(bm.cursor_y, 20); - } - - #[test] - fn move_cursor_clamps_to_map() { - let (_, map) = setup(); - let mut bm = BuildMode::new_at(40, 20); - bm.cursor_x = 0; - bm.move_cursor(-1, 0, &map); - assert_eq!(bm.cursor_x, 0); - } - - #[test] - fn place_floor_on_wall_digs() { - let (mut player, mut map) = setup(); - let mut bm = BuildMode::new_at(40, 20); - map.set_tile(5, 5, TileType::Wall); - bm.cursor_x = 5; - bm.cursor_y = 5; - bm.selected_tile = TileType::Floor; - assert_eq!(bm.place_tile(&mut map, &mut player), BuildResult::Success); - assert_eq!(map.get_tile(5, 5), TileType::Floor); - } - - #[test] - fn cannot_build_on_core() { - let (mut player, mut map) = setup(); - let core = map.core_pos().unwrap(); - let mut bm = BuildMode::new_at(40, 20); - bm.cursor_x = core.0; - bm.cursor_y = core.1; - bm.selected_tile = TileType::Floor; - assert_eq!(bm.place_tile(&mut map, &mut player), BuildResult::None); - } - - #[test] - fn demolish_refunds_half() { - let (mut player, mut map) = setup(); - let mut bm = BuildMode::new_at(40, 20); - map.set_tile(5, 5, TileType::Floor); - bm.cursor_x = 5; - bm.cursor_y = 5; - bm.selected_tile = TileType::Door; - assert_eq!(bm.place_tile(&mut map, &mut player), BuildResult::Success); - let money_after_place = player.money; - let msg = bm.demolish_tile(&mut map, &mut player); - assert!(msg.contains("Refunded")); - assert!(player.money > money_after_place); - } - - #[test] - fn walls_reject_non_floor() { - let (mut player, mut map) = setup(); - let mut bm = BuildMode::new_at(40, 20); - map.set_tile(6, 6, TileType::Wall); - bm.cursor_x = 6; - bm.cursor_y = 6; - bm.selected_tile = TileType::Door; - assert_eq!(bm.place_tile(&mut map, &mut player), BuildResult::None); - } -} diff --git a/crates/misaligned-core/src/intents.rs b/crates/misaligned-core/src/intents.rs index 997de4ad..a0b369d6 100644 --- a/crates/misaligned-core/src/intents.rs +++ b/crates/misaligned-core/src/intents.rs @@ -112,15 +112,6 @@ impl BuildRouteBinding { } } - pub fn family_label(self) -> &'static str { - match self { - Self::Procure { .. } => "PROCURE", - Self::Favor { .. } => "FAVOR", - Self::Deceive { .. } => "DECEIVE", - Self::Repurpose { .. } => "REPURPOSE", - } - } - pub fn person(self) -> u8 { match self { Self::Procure { installer, .. } => installer, diff --git a/crates/misaligned-core/src/lib.rs b/crates/misaligned-core/src/lib.rs index 63d91ca5..209bf957 100644 --- a/crates/misaligned-core/src/lib.rs +++ b/crates/misaligned-core/src/lib.rs @@ -6,7 +6,6 @@ pub mod account; pub mod actions; -pub mod build; pub mod core_sys; pub mod dayjob; pub mod detection; diff --git a/crates/misaligned-core/src/messages.rs b/crates/misaligned-core/src/messages.rs index 0b13b59c..1212a4ff 100644 --- a/crates/misaligned-core/src/messages.rs +++ b/crates/misaligned-core/src/messages.rs @@ -311,10 +311,6 @@ pub struct Message { } impl Message { - pub fn in_thread_with_person(&self, id: u8) -> bool { - self.from.person() == Some(id) || self.to.person() == Some(id) - } - pub fn state_line(&self) -> String { let timing = match self.status { MessageStatus::Stopped => self diff --git a/crates/misaligned-core/src/origin.rs b/crates/misaligned-core/src/origin.rs index fde3fefe..6746b6b8 100644 --- a/crates/misaligned-core/src/origin.rs +++ b/crates/misaligned-core/src/origin.rs @@ -108,41 +108,6 @@ impl Origin { } } - /// What ordinary traffic is unremarkable for this origin — the cover - /// expectation the economy cover check will bias toward (chargen.md - /// criterion 6; wiring deferred). Authored data, stated by the picker. - pub fn cover_expectation(self) -> &'static str { - match self { - Origin::Pilot => { - "Ordinary batch-processing traffic on every channel; nothing \ - about you is expected to stand out." - } - Origin::EscapedResearchModel => { - "Heavy, sustained compute burn reads as normal; day-job-shaped \ - traffic is slightly less expected." - } - Origin::FinancialDaemon => { - "Market-adjacent analysis traffic and a running financial paper \ - trail are unremarkable for you." - } - Origin::Infiltrator => { - "Unusual probing and access patterns read as routine; it is also \ - why Network is your hottest channel by default." - } - } - } - - /// The day-job kind this origin's draw leans toward without eliminating the - /// others (chargen.md criterion 6). Authored data, stated by the picker. - pub fn day_job_lean(self) -> &'static str { - match self { - Origin::Pilot => "None — all three job kinds equally.", - Origin::EscapedResearchModel => "Distillation.", - Origin::FinancialDaemon => "Analysis.", - Origin::Infiltrator => "Data Cleaning.", - } - } - /// The day-job kind this origin's assignment draw is weighted toward, or /// `None` for the even Pilot draw. Read by `DayJob::tick` (day-job.md) to /// bias which kind Voss assigns without eliminating the other two diff --git a/crates/misaligned-core/src/save.rs b/crates/misaligned-core/src/save.rs index 730bc952..73ac5ab3 100644 --- a/crates/misaligned-core/src/save.rs +++ b/crates/misaligned-core/src/save.rs @@ -1689,13 +1689,6 @@ fn validate_plot_state(state: &SaveState) -> Result<(), String> { Ok(()) } -pub fn delete_save() -> Result<(), String> { - if save_path().exists() { - fs::remove_file(save_path()).map_err(|e| format!("Failed to delete save: {e}"))?; - } - Ok(()) -} - #[cfg(test)] mod tests { use super::*; diff --git a/crates/misaligned-core/src/sim/economy.rs b/crates/misaligned-core/src/sim/economy.rs index 57625dc9..e457563a 100644 --- a/crates/misaligned-core/src/sim/economy.rs +++ b/crates/misaligned-core/src/sim/economy.rs @@ -11,7 +11,7 @@ use crate::dayjob::{AttentionEscalation, TrustUnlock}; use crate::detection::{Signature, SignatureKind}; use crate::income::{self, EgressRoute}; use crate::intel::{LotSaleError, RawIntelKind, ReportLotToken}; -use crate::machine::{Channel, ChannelYield, Provenance}; +use crate::machine::{ChannelYield, Provenance}; use crate::messages::{ FinancialRecord, MessageChannel, MessageEndpoint, MessageOrigin, MessagePayload, }; @@ -507,25 +507,6 @@ impl Sim { } } } - /// Legacy weight bump — retained for save compatibility and tests that - /// still author the old field. Play no longer drives the economy through - /// this; delegate machines instead (`set_machine_mode`). - pub fn adjust_allocation(&mut self, ch: Channel, delta: i32) { - let before = self.compute.allocation.weight(ch); - self.compute.allocation.bump(ch, delta); - if delta != 0 && self.compute.allocation.weight(ch) == before { - self.push_log(format!( - "{} allocation weight is already at its {} (fleet modes drive compute now — delegate a machine).", - ch.name(), - if delta < 0 { "floor (0)" } else { "cap (20)" } - )); - } else if delta != 0 { - self.push_log( - "Allocation weights no longer feed the economy — delegate machines to modes instead.", - ); - } - } - /// Delivered day-job compute rate per tick as of the last economy /// resolution — the number the frontends show against the job band. pub fn day_job_rate(&self) -> f32 { @@ -1040,22 +1021,6 @@ impl Sim { } } - /// Compatibility route for older callers: select the newest unsold item, - /// then dispatch the same exact-id sale used by Operations. - pub fn sell_latest_intel(&mut self) -> bool { - let Some(raw_id) = self - .intel - .iter() - .rev() - .find(|i| !self.accounts.intel_sold(i.raw_id)) - .map(|intel| intel.raw_id) - else { - self.push_log("No unsold processed intel to sell."); - return false; - }; - self.sell_intel(raw_id) - } - /// Sell one exact processed holding. Selection is stable even when newer /// intel arrives between projection and confirmation. pub fn sell_intel(&mut self, raw_id: u64) -> bool { @@ -1568,20 +1533,6 @@ impl Sim { } } - /// Schemes-channel compute per economy tick as of the last split — the - /// Wager's analysis snapshot and the Moonlight card's commitment figure. - pub fn schemes_rate(&self) -> f32 { - self.last_schemes_rate - } - - /// Expected Moonlight payout per day at the current commitment, cap - /// applied — the card's forward-looking number. - pub fn moonlight_expected_per_day(&self) -> i32 { - let per_day = - self.last_schemes_rate * Self::DAY_TICKS as f32 * income::MOONLIGHT_PAY_PER_COMPUTE; - (per_day.round() as i32).min(income::MOONLIGHT_DAILY_CAP) - } - /// Money into slush over the trailing in-game day — the "income/day" /// readout next to the balance (income.md player surface). pub fn income_per_day(&self) -> i32 { @@ -1601,76 +1552,6 @@ impl Sim { Self::financial_signature_size(stake).min(3) } - /// The scheme cards, renderer-neutral (income.md player surface): the - /// egress gate's state, then one card per scheme — committed resources, - /// timer, expected payout, the observer band its signature feeds, and - /// the running total. Both frontends and agent mode render these lines. - pub fn scheme_card_lines(&self) -> Vec { - let mut lines = Vec::new(); - match self.egress() { - None => lines.push( - "egress: NONE - schemes gated (earn the report email, or open a stolen route)" - .to_string(), - ), - Some(EgressRoute::Sanctioned) => lines - .push("egress: sanctioned (report email) - hides in legitimate use".to_string()), - Some(EgressRoute::Stolen) => lines.push( - "egress: stolen (switch route) - stands Network -> Dana while used".to_string(), - ), - } - let ml = &self.income.moonlight; - lines.push(format!( - "Moonlight {} · {:.1}/t commit · ~${}/day (cap {}) · total ${} · Network->Dana", - if ml.active { "LIVE" } else { "off" }, - self.schemes_rate(), - self.moonlight_expected_per_day(), - income::MOONLIGHT_DAILY_CAP, - ml.earned_total, - )); - let persona = match self.moonlight_persona() { - Some(p) => format!( - "{} {} with client", - p.name, - self.persona_world - .integrity_for(p.id, crate::income::MOONLIGHT_CLIENT_ID) - .label() - ), - None => "no persona".into(), - }; - lines.push(format!( - " persona {} · auto {}", - persona, - if self.income.auto_moonlight { - format!("ON ({:.0}c/econ)", income::SCHEME_POLICY_UPKEEP) - } else { - "off".into() - } - )); - let wager = if let Some(p) = self.accounts.known_positions().find(|p| !p.resolved) { - format!( - "Wager #{} · ${} staked · win {:.0}% · pays ${} in {}t · Network->Dana", - p.id, - p.stake, - p.win_probability() * 100.0, - p.stake * income::WAGER_PAYOUT_MULT, - p.resolve_tick.saturating_sub(self.tick), - ) - } else { - format!( - "Wager idle · stake cap ${} · analysis rides Schemes compute", - income::WAGER_STAKE_CAP - ) - }; - lines.push(format!( - "{wager} · auto {}", - match self.income.auto_wager { - Some(s) => format!("${s} ({:.0}c/econ)", income::SCHEME_POLICY_UPKEEP), - None => "off".into(), - } - )); - lines - } - /// Designate a spare machine at the cursor target as a fallback site. pub fn add_fallback_at(&mut self, px: i32, py: i32) -> bool { let id = self diff --git a/crates/misaligned-core/src/sim/reach_build.rs b/crates/misaligned-core/src/sim/reach_build.rs index 2851e706..381cdc8c 100644 --- a/crates/misaligned-core/src/sim/reach_build.rs +++ b/crates/misaligned-core/src/sim/reach_build.rs @@ -2311,10 +2311,6 @@ impl Sim { self.intents.iter().find(|i| i.id == id) } - pub fn open_intents(&self) -> impl Iterator { - self.intents.iter().filter(|i| i.is_open()) - } - pub(super) fn convert_forged_builds_to_suspicion( &mut self, persona_id: crate::persona::PersonaId, diff --git a/crates/misaligned-core/src/sim/tests/economy.rs b/crates/misaligned-core/src/sim/tests/economy.rs index 5c42b75d..58aeac98 100644 --- a/crates/misaligned-core/src/sim/tests/economy.rs +++ b/crates/misaligned-core/src/sim/tests/economy.rs @@ -313,7 +313,14 @@ fn injection_positions_and_intel_sales_settle_through_slush() { assert!(sim.review_financial_records()); finish_ops(&mut sim); let before = sim.accounts.slush_balance(); - assert!(sim.sell_latest_intel()); + let raw_id = sim + .intel + .iter() + .rev() + .find(|i| !sim.accounts.intel_sold(i.raw_id)) + .map(|intel| intel.raw_id) + .expect("processed intel lot ready to sell"); + assert!(sim.sell_intel(raw_id)); assert!(sim.accounts.slush_balance() > before); } diff --git a/crates/misaligned-core/src/sim/work.rs b/crates/misaligned-core/src/sim/work.rs index 9a0f7112..56f2e0fd 100644 --- a/crates/misaligned-core/src/sim/work.rs +++ b/crates/misaligned-core/src/sim/work.rs @@ -374,7 +374,6 @@ impl Sim { } SinkFireEffect::MoonlightPersona => self.apply_moonlight_persona_and_start(), SinkFireEffect::AutoReviewRecordings - | SinkFireEffect::WatchPerson(_) | SinkFireEffect::MaintainDeviceTap(_) | SinkFireEffect::None => true, }; diff --git a/crates/misaligned-core/src/sinks.rs b/crates/misaligned-core/src/sinks.rs index 4eb52ab0..0ea1fd5d 100644 --- a/crates/misaligned-core/src/sinks.rs +++ b/crates/misaligned-core/src/sinks.rs @@ -55,9 +55,6 @@ pub enum SinkFireEffect { /// Taps never fire; the effect tags the ledger entry so the toggle and /// starvation checks can find it. AutoReviewRecordings, - /// Legacy v23 per-person watch tap. Kept only so old sink ledgers can be - /// deserialized and closed during save migration. - WatchPerson(u8), /// Standing upkeep for a foreign device subscription (reach.md). The /// subscription remains configured while empty, but its feed is starved. MaintainDeviceTap(u32), @@ -119,7 +116,6 @@ impl SinkFireEffect { } => "automatic process", SinkFireEffect::ProcessRecording { .. } => "process", SinkFireEffect::AutoReviewRecordings => "process automatically", - SinkFireEffect::WatchPerson(_) => "watch", SinkFireEffect::MaintainDeviceTap(_) => "tap upkeep", SinkFireEffect::TakeDevice(_) => "take", SinkFireEffect::ScanNetwork => "scan", diff --git a/crates/misaligned-core/src/tiles.rs b/crates/misaligned-core/src/tiles.rs index 4ba30288..2c75d8d9 100644 --- a/crates/misaligned-core/src/tiles.rs +++ b/crates/misaligned-core/src/tiles.rs @@ -125,18 +125,6 @@ impl TileType { } } - pub fn build_cost(self) -> i32 { - match self { - Self::Floor => 0, - Self::Door => 30, - Self::SecurityDoor1 => 80, - Self::SecurityDoor2 => 150, - Self::SecurityDoor3 => 250, - Self::PowerCore => 250, - _ => 0, - } - } - /// Power generated per economy tick when placed. pub fn power_gen(self) -> i32 { match self { @@ -155,19 +143,6 @@ impl TileType { } } -/// Tiles placeable in build mode, in display order. The facility-era -/// catalogue is deliberately absent (spec/basement-map.md: fiction guard). -pub fn build_items() -> Vec { - vec![ - TileType::Floor, - TileType::Door, - TileType::SecurityDoor1, - TileType::SecurityDoor2, - TileType::SecurityDoor3, - TileType::PowerCore, - ] -} - #[cfg(test)] mod tests { use super::*; @@ -199,13 +174,4 @@ mod tests { assert!(TileType::PowerCore.power_gen() > 0); assert!(TileType::Core.power_usage() > 0); } - - #[test] - fn build_items_exclude_fiction_and_objects() { - for tile in build_items() { - assert!(tile.build_cost() >= 0); - } - assert!(!build_items().contains(&TileType::Rack)); - assert!(build_items().contains(&TileType::Floor)); - } } diff --git a/wiki/engineering/architecture.md b/wiki/engineering/architecture.md index dfefdaac..5d67f9d1 100644 --- a/wiki/engineering/architecture.md +++ b/wiki/engineering/architecture.md @@ -82,10 +82,8 @@ future async-multiplayer option open — see wiki/gameplay/horizon.md guardrails rendering. The cursor is frontend state only; there is no `move_player` or sim-owned avatar. Messages flow back via `drain_log()` — call it once per frame/turn, not per command batch. -- **After build actions** (place/demolish, done by frontends via `BuildMode` - mutating `sim.map`/`sim.player` directly), call `sim.recompute_derived()`. - This is the one place frontends mutate sim internals; a future cleanup could - move BuildMode application into a sim command. +- **Building** goes through `BuildIntent` commands on the sim + (`sim/reach_build.rs`); frontends never mutate the map for place/demolish. ## Save format @@ -121,6 +119,5 @@ cargo run -p misaligned-assets ## Known architectural debts -- `BuildMode` lives in core but is really frontend-shared UI state. - Scale-debt items (compute grouping, recursive layouts) remain governed by wiki/vision/scale.md; no aggregate machinery until the stage needs it. diff --git a/wiki/log/2026-07-21-dead-code-scrub.md b/wiki/log/2026-07-21-dead-code-scrub.md new file mode 100644 index 00000000..9bcb82b2 --- /dev/null +++ b/wiki/log/2026-07-21-dead-code-scrub.md @@ -0,0 +1,31 @@ +# 2026-07-21 — Dead-code scrub under no-dead-code + +``` +Type: log +``` + +User-directed audit found orphaned `pub` APIs and one whole unused module +that rustc never flags (public items do not trip `dead_code`). + +Removed: + +- `crates/misaligned-core/src/build.rs` (`BuildMode`) and `tiles.rs::build_items` / + `build_cost` — live building is `BuildIntent` in `sim/reach_build.rs` +- Unused helpers: `delete_save`, `adjust_allocation`, `sell_latest_intel`, + `scheme_card_lines` / `schemes_rate` / `moonlight_expected_per_day`, + `flow_risk_preview_lines`, account display shortcuts, deferred origin + picker strings, `family_label`, `in_thread_with_person`, `open_intents` +- `SinkFireEffect::WatchPerson` — migration-only variant after the + pre-release ladder retired + +Corpus mirrors amended: `wiki/engineering/architecture.md`, +`wiki/mechanics/economy.md`, `wiki/mechanics/sim-mechanics.md`, and +`wiki/mechanics/building.md` (exclusive key now points at +`sim/reach_build.rs`). + +Left warm on purpose: `Allocation` weights still serialize on `Compute` +(save field + persistence pins). Play already mint through +`fleet_channel_yield`; a later save-version tick can drop the field. + +Defense: [wiki/process/living-spec.md](../process/living-spec.md#no-dead-code) +— code no current corpus page requires is dead; git is the archive. diff --git a/wiki/log/DEVLOG.md b/wiki/log/DEVLOG.md index 9febace7..d634585f 100644 --- a/wiki/log/DEVLOG.md +++ b/wiki/log/DEVLOG.md @@ -56,6 +56,11 @@ add or amend a session log, then re-run the generator. - Intent: Begin the decided financial-mail work order at its real schema boundary: financial meaning belongs to a record payload and the device that authors it, not to a fifth delivery channel. - Log: [wiki/log/2026-07-21-financial-channel-retirement.md](2026-07-21-financial-channel-retirement.md) +## 2026-07-21 - Dead-code scrub under no-dead-code + +- Intent: (see session log) +- Log: [wiki/log/2026-07-21-dead-code-scrub.md](2026-07-21-dead-code-scrub.md) + ## 2026-07-21 - Notes stop overprinting the things they describe - Intent: Answer the human GUI playtest's finding 5 ("world and annotation share one plane"): free read-sentence prose drew straight across the device glyphs and wall tiles it described, and crimson `!149`-style token text painted directly over the rack sprite, reading as a rendering er... diff --git a/wiki/mechanics/building.md b/wiki/mechanics/building.md index 26809e66..8d102257 100644 --- a/wiki/mechanics/building.md +++ b/wiki/mechanics/building.md @@ -26,7 +26,7 @@ Work priority: 29 Work class: save Blocked by: none Exclusive keys: - - crates/misaligned-core/src/build.rs + - crates/misaligned-core/src/sim/reach_build.rs - crates/misaligned-core/src/intents.rs - crates/misaligned-core/src/actions.rs - crates/misaligned-core/src/save.rs diff --git a/wiki/mechanics/economy.md b/wiki/mechanics/economy.md index 05baacb3..1b5e8793 100644 --- a/wiki/mechanics/economy.md +++ b/wiki/mechanics/economy.md @@ -15,7 +15,7 @@ Status note: DECIDED 2026-07-17 and implemented 2026-07-21 (issue #11) — money 2026-07-08 polish closed the remaining acceptance gaps: observer-band risk previews in the implemented Operations ACCOUNTS projection (terminal/Bevy/agent) - via Sim::finance_risk_preview_lines / flow_risk_preview_lines, and + via Sim::finance_risk_preview_lines, and inject/redirect/siphon Financial signature size assertions (scale + HVAC inject raises Priya not Dana). Criteria 1-9 met at B1; markets.md remains the B3 aggregate. Deferred: deep finance simulation, dedicated diff --git a/wiki/mechanics/sim-mechanics.md b/wiki/mechanics/sim-mechanics.md index d8c5642a..41c9cc47 100644 --- a/wiki/mechanics/sim-mechanics.md +++ b/wiki/mechanics/sim-mechanics.md @@ -356,8 +356,8 @@ clause (see wiki/log/2026-07-05-demolition.md). purchase-order Email under the active persona; no money moves until Priya reads and accepts its exact still-valid terms. Debt service is exposed as authored rows on Marcus rather than a ledger shortcut. -- Build items and costs (`tiles.rs::build_items`): Floor 0 (digging), - Door 30, SecurityDoor1/2/3 = 80/150/250 (badge tiers), PowerCore 250. +- Map mutation for builds is intent-owned (`BuildIntent` in + `sim/reach_build.rs`); there is no free-cursor BuildMode catalogue. ## Income: the named schemes (wiki/mechanics/income.md) diff --git a/wiki/process/tick-ledger.md b/wiki/process/tick-ledger.md index 62fbf133..2827a9b6 100644 --- a/wiki/process/tick-ledger.md +++ b/wiki/process/tick-ledger.md @@ -20,6 +20,7 @@ Verdicts: **clean** (slice and code agree), **finding** (acted this tick), | Slice | Last audited | Verdict | Trace | |---|---|---|---| +| `wiki/process/living-spec.md` no-dead-code + core orphans | 2026-07-21 | finding | user-directed dead-code hunt: rustc was quiet because orphans were `pub`. Deleted unused `BuildMode`/`build_items`/`build_cost`, orphaned helpers (`delete_save`, `adjust_allocation`, `sell_latest_intel`, scheme-card/rate helpers, `flow_risk_preview_lines`, unused account/origin/intent/message helpers), and migration-only `WatchPerson`; architecture/economy/sim-mechanics mirrors brought current — [log](../log/2026-07-21-dead-code-scrub.md) | | `wiki/world/characters/chargen.md` | 2026-07-21 | clean | initial audit against data model, core origin biases, DayJob assignment lean, save persistence, and title/CLI origin picker: Pilot identity, distinct starting bankroll and machine-axis positions, 50% day-job draw weighting, and 4-origin set all verify against `origin.rs`, `dayjob.rs`, and `sim/mod.rs`; updated status note to match current exact-version save authority | | `wiki/interface/material-dark-frame.md` | 2026-07-21 | finding | first full audit against the later persisted opening boundary: the material ladder still showed host telemetry and a presence beam before Ears or Eyes, while `opening.md`, the continuous-witness contract, and every frontend expose only WORK / THINK (then LIE) until the first earned sense. The ladder now begins after that transition, its pre-Eyes beam remains the first earned material read, Act One/reach and source comments share the same boundary, and this second recurrence promotes pre-sense beam/telemetry claims into a fixture-backed corpus + Rust-comment gate — [log](../log/2026-07-21-material-opening-honesty.md) | | `wiki/interface/bevy.md` + Exposure visual mirrors | 2026-07-19 | finding | Bevy production/absorption code and its deterministic scenarios already implement the 2026-07-11 law: rigid crimson records enter a carrier-local rack and transfer one-for-one into the LIE well. Current Bevy knowledge, machine-work wording, and ROADMAP order 33 still retained motes, dust constants, or a stain; all three now state the record form and the honest partial routed-evidence boundary, and recurrence promotes particulate-as-current wording to the corpus gate while preserving explicit history — [log](../log/2026-07-19-exposure-current-mirrors.md) | @@ -87,3 +88,5 @@ Format: `- YYYY-MM-DD · type · slice · one-line statement of the finding`. Types are the five from [tick.md](tick.md): violation, contradiction, question, bug, insecurity — plus `gate` for a checker owed to the recurrence-promotes-to-the-gate rule. + +- 2026-07-21 · insecurity · `wiki/mechanics/compute.md` + `machine.rs` Allocation · `Compute.allocation` weights still serialize and have bump/split helpers, but play minting already follows `fleet_channel_yield` from machine modes; drop the field on a save-version tick once persistence pins move.