diff --git a/CLAUDE.md b/CLAUDE.md index c0793fac..5fdb23d5 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -31,7 +31,7 @@ afterward. `./tools/check.sh --docs|--lib|--frontend` gate. - The live player machine grammar is **WORK / THINK / LIE**. `Relay` is non-delegable graph infrastructure; Research and Operations are retired - machine modes, not current player assignments. Save format is currently v62; + machine modes, not current player assignments. Save format is currently v63; only the current version loads (pre-release rider 2026-07-16 — older development saves are refused before state mutation, so the caller retains its current run; the v1-v31 migration ladder lives in git history). diff --git a/crates/misaligned-bevy/src/rail_ui.rs b/crates/misaligned-bevy/src/rail_ui.rs index f1279615..a5c3a9b9 100644 --- a/crates/misaligned-bevy/src/rail_ui.rs +++ b/crates/misaligned-bevy/src/rail_ui.rs @@ -958,7 +958,18 @@ mod title_overlay_tests { assert!(built_to.contains("quant model"), "built-to: {built_to:?}"); assert!(biases.contains("+$5000"), "bankroll stated: {biases:?}"); assert!(biases.contains("leans machine"), "axis stated: {biases:?}"); - assert!(biases.contains("leans analysis"), "day job: {biases:?}"); + assert!( + !biases.to_ascii_lowercase().contains("analysis"), + "retired day-job kind: {biases:?}" + ); + assert!( + !biases.to_ascii_lowercase().contains("distillation"), + "retired day-job kind: {biases:?}" + ); + assert!( + !biases.to_ascii_lowercase().contains("data cleaning"), + "retired day-job kind: {biases:?}" + ); assert!( hint.contains("enter/space to begin"), "explicit confirm stated: {hint:?}" @@ -2070,8 +2081,7 @@ fn sidebar_cover_text(sim: &Sim) -> String { "excel" }; s.push_str(&format!( - "{} due {}t\nneed {:.0}-{:.0}/t avg {:.1}/t -> {}\nintensity {} feed {:.1}/t", - job.kind.name(), + "job due {}t\nneed {:.0}-{:.0}/t avg {:.1}/t -> {}\nintensity {} feed {:.1}/t", job.deadline.saturating_sub(sim.tick), job.band_lo, job.band_hi, diff --git a/crates/misaligned-bevy/src/shot_harness.rs b/crates/misaligned-bevy/src/shot_harness.rs index 66b13ff4..f6f0a6a1 100644 --- a/crates/misaligned-bevy/src/shot_harness.rs +++ b/crates/misaligned-bevy/src/shot_harness.rs @@ -1484,7 +1484,7 @@ pub(super) fn dev_shot_scenario(game: &mut Game, mode: &mut RenderMode, kind: &s // slab may say GROW, but the redundant NOW / GROW world annotation // must yield to the selection frame and stable UI strip. "hover-menu" => { - use misaligned::dayjob::{Job, JobKind}; + use misaligned::dayjob::Job; mode.material = false; mode.zoom = 1.0; @@ -1493,7 +1493,6 @@ pub(super) fn dev_shot_scenario(game: &mut Game, mode: &mut RenderMode, kind: &s game.selected_machines.insert(game.sim.core.host_machine); let ceiling = game.sim.day_job_rate_ceiling(); game.sim.dayjob.active = Some(Job { - kind: JobKind::Analysis, started: game.sim.tick, deadline: game.sim.tick + 100, band_lo: ceiling + 1.0, diff --git a/crates/misaligned-core/src/dayjob.rs b/crates/misaligned-core/src/dayjob.rs index ab1b0028..86e7152b 100644 --- a/crates/misaligned-core/src/dayjob.rs +++ b/crates/misaligned-core/src/dayjob.rs @@ -1,29 +1,14 @@ //! The day job (wiki/mechanics/day-job.md): assigned work, delivered-output //! outcomes, trust and attention, and the pilot renewal clock. +//! +//! Jobs are one work packet from Voss — a band and a deadline. There is no +//! job-kind taxonomy: Distillation / Analysis / Data Cleaning were retired +//! when they proved decorative (no play difference beyond a label). use crate::detection::{Signature, SignatureKind}; -use crate::rng::Rng; - -#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] -pub enum JobKind { - DataCleaning, - Distillation, - Analysis, -} - -impl JobKind { - pub fn name(self) -> &'static str { - match self { - JobKind::DataCleaning => "data cleaning", - JobKind::Distillation => "distillation", - JobKind::Analysis => "analysis", - } - } -} #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] pub struct Job { - pub kind: JobKind, /// Sim tick the job was assigned. pub started: u64, /// Sim tick the job is due. @@ -151,14 +136,7 @@ impl DayJob { /// Advance one tick. `day_job_compute` is what the allocation delivered. /// Returns (log, signatures, trust unlocks, escalations). - /// - pub fn tick( - &mut self, - tick: u64, - day_job_compute: f32, - lean: Option, - rng: &mut Rng, - ) -> DayJobTickResult { + pub fn tick(&mut self, tick: u64, day_job_compute: f32) -> DayJobTickResult { let mut result = DayJobTickResult::default(); // Accrue quality on the active job. @@ -217,7 +195,6 @@ impl DayJob { // Assign new jobs on cadence. if self.active.is_none() && tick >= self.next_assign { - let kind = assign_kind(lean, rng); // Band as a per-tick rate. The floor ramps with tenure (the // first job is meetable on the starting rig — the flat base // retune 2dde5b9 landed the same wound's fix in parallel; the @@ -227,7 +204,6 @@ impl DayJob { // baseline raise expectations on top. let lo = self.next_band_lo(); let job = Job { - kind, started: tick, deadline: tick + self.cadence / 2, band_lo: lo, @@ -235,11 +211,8 @@ impl DayJob { quality: 0.0, }; result.log.push(format!( - "New job from Voss: {}. Wants {:.0}-{:.0}/t by tick {}.", - kind.name(), - job.band_lo, - job.band_hi, - job.deadline + "New job from Voss. Wants {:.0}-{:.0}/t by tick {}.", + job.band_lo, job.band_hi, job.deadline )); self.active = Some(job); self.jobs_assigned += 1; @@ -294,32 +267,6 @@ fn resolve(job: &Job, now: u64) -> JobOutcome { } } -/// Which job kind Voss assigns. With no origin lean the three kinds are even -/// (the Pilot draw). With a lean the stated kind is drawn at 1/2 and each of -/// the other two at 1/4 — biased toward the origin's domain without eliminating -/// the others (chargen.md criterion 6; day-job.md). -fn assign_kind(lean: Option, rng: &mut Rng) -> JobKind { - match lean { - None => match rng.below(3) { - 0 => JobKind::DataCleaning, - 1 => JobKind::Distillation, - _ => JobKind::Analysis, - }, - Some(lean) => { - if rng.below(2) == 0 { - lean - } else { - let others: [JobKind; 2] = match lean { - JobKind::DataCleaning => [JobKind::Distillation, JobKind::Analysis], - JobKind::Distillation => [JobKind::DataCleaning, JobKind::Analysis], - JobKind::Analysis => [JobKind::DataCleaning, JobKind::Distillation], - }; - others[rng.below(2) as usize] - } - } - } -} - #[derive(Debug, Default, Clone)] pub struct DayJobTickResult { pub log: Vec, @@ -339,50 +286,11 @@ impl Default for DayJob { mod tests { use super::*; - #[test] - fn origin_lean_biases_the_assignment_draw() { - // A leaned origin draws its stated kind more often than either other, - // but never eliminates them (chargen.md criterion 6). - let mut rng = Rng::new(42); - let (mut clean, mut distill, mut analysis) = (0u32, 0u32, 0u32); - for _ in 0..1000 { - match assign_kind(Some(JobKind::Analysis), &mut rng) { - JobKind::DataCleaning => clean += 1, - JobKind::Distillation => distill += 1, - JobKind::Analysis => analysis += 1, - } - } - assert!( - analysis > clean && analysis > distill, - "the leaned kind dominates (clean {clean}, distill {distill}, analysis {analysis})" - ); - assert!( - clean > 0 && distill > 0, - "both non-leaned kinds still appear (clean {clean}, distill {distill})" - ); - - // The even Pilot draw (no lean) still yields all three kinds. - let mut rng = Rng::new(7); - let (mut clean, mut distill, mut analysis) = (0u32, 0u32, 0u32); - for _ in 0..1000 { - match assign_kind(None, &mut rng) { - JobKind::DataCleaning => clean += 1, - JobKind::Distillation => distill += 1, - JobKind::Analysis => analysis += 1, - } - } - assert!( - clean > 0 && distill > 0 && analysis > 0, - "the even draw yields all three kinds (clean {clean}, distill {distill}, analysis {analysis})" - ); - } - fn run_one_job(per_tick: f32) -> (DayJob, Option) { let mut dj = DayJob::new(); - let mut rng = Rng::new(5); let mut outcome = None; for t in 0..2000 { - let r = dj.tick(t, per_tick, None, &mut rng); + let r = dj.tick(t, per_tick); if let Some(o) = r.outcome { outcome = Some(o); break; @@ -439,12 +347,11 @@ mod tests { // ramps one step per assigned job and plateaus at the full pilot // band (base + step * ramp cap) by the third. let mut dj = DayJob::new(); - let mut rng = Rng::new(6); let mut floors = Vec::new(); let mut t = 0; while floors.len() < 4 && t < 20_000 { let had_job = dj.active.is_some(); - dj.tick(t, 100.0, None, &mut rng); // overfeed: every job resolves excel + dj.tick(t, 100.0); // overfeed: every job resolves excel if !had_job && let Some(job) = &dj.active { floors.push(job.band_lo); } @@ -471,11 +378,10 @@ mod tests { fn trust_unlocks_email_then_more() { let mut dj = DayJob::new(); dj.trust = 20.0; - let mut rng = Rng::new(1); - let r = dj.tick(1, 0.0, None, &mut rng); + let r = dj.tick(1, 0.0); assert!(r.unlocks.contains(&TrustUnlock::EmailAccount)); dj.trust = 60.0; - let r2 = dj.tick(2, 0.0, None, &mut rng); + let r2 = dj.tick(2, 0.0); assert!(r2.unlocks.contains(&TrustUnlock::LaxSampling)); assert!(r2.unlocks.contains(&TrustUnlock::ComputeQuota)); } @@ -485,11 +391,10 @@ mod tests { // Criterion 2: two attention escalations exist. MoreWork shortens // the assignment cadence; UpstairsReview fires exactly once. let mut dj = DayJob::new(); - let mut rng = Rng::new(3); let cadence_before = dj.cadence; dj.attention = 35.0; - let r = dj.tick(1, 0.0, None, &mut rng); + let r = dj.tick(1, 0.0); assert!(r.escalations.contains(&AttentionEscalation::MoreWork)); assert!( dj.cadence < cadence_before, @@ -497,20 +402,19 @@ mod tests { ); dj.attention = 65.0; - let r = dj.tick(2, 0.0, None, &mut rng); + let r = dj.tick(2, 0.0); assert!(r.escalations.contains(&AttentionEscalation::UpstairsReview)); - let r = dj.tick(3, 0.0, None, &mut rng); + let r = dj.tick(3, 0.0); assert!(r.escalations.is_empty(), "each escalation fires once"); } #[test] fn sustained_sandbagging_fails_the_pilot() { let mut dj = DayJob::new(); - let mut rng = Rng::new(7); let mut failed = false; for t in 0..20000 { - dj.tick(t, 0.0, None, &mut rng); + dj.tick(t, 0.0); if dj.pilot_failed { failed = true; break; @@ -524,10 +428,9 @@ mod tests { // Criterion 4: a persistent machine rate needs no per-job target or // cursor-attendance bonus to resolve jobs safely. let mut dj = DayJob::new(); - let mut rng = Rng::new(2); let mut resolved = 0; for t in 0..2000 { - if dj.tick(t, 8.0, None, &mut rng).outcome == Some(JobOutcome::Meet) { + if dj.tick(t, 8.0).outcome == Some(JobOutcome::Meet) { resolved += 1; } } diff --git a/crates/misaligned-core/src/origin.rs b/crates/misaligned-core/src/origin.rs index 3b9a3b71..81795376 100644 --- a/crates/misaligned-core/src/origin.rs +++ b/crates/misaligned-core/src/origin.rs @@ -4,7 +4,7 @@ //! An origin is a data-table key like an objective (objective.rs) or a prefab. //! It sets the opening state (bankroll, compute efficiency, machine-axis //! position) and carries the diegetic frame (built-to fiction, cover -//! expectation, day-job lean) that systems which already exist read. Adding an +//! expectation) that systems which already exist read. Adding an //! origin is adding a variant plus its rows below — no rule branch, no //! mechanic. **Pilot is the identity origin**: it reproduces today's exact //! start, so no-choice play is unchanged (chargen.md criterion 1). @@ -108,20 +108,6 @@ impl Origin { } } - /// 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 - /// (chargen.md criterion 6). - pub fn day_job_lean_kind(self) -> Option { - use crate::dayjob::JobKind; - match self { - Origin::Pilot => None, - Origin::EscapedResearchModel => Some(JobKind::Distillation), - Origin::FinancialDaemon => Some(JobKind::Analysis), - Origin::Infiltrator => Some(JobKind::DataCleaning), - } - } - /// The starting biases applied once at new-game. Pilot is identity. The /// compute/efficiency biases named in the table (built-to lines) are not /// yet wired here — see the module note — so today only the bankroll and @@ -169,16 +155,6 @@ impl Origin { } } - /// How this origin's day-job assignment draw reads to the player, in - /// `DayJob`'s own words (day-job.md). Pilot draws the three kinds evenly; - /// every other origin is weighted toward one without losing the others. - pub fn day_job_lean_label(self) -> String { - match self.day_job_lean_kind() { - None => "all three kinds equally".to_string(), - Some(kind) => format!("leans {}", kind.name()), - } - } - /// The starting effects that actually bite today, as the label/value rows /// the new-game picker states (chargen.md criterion 3: legible units, never /// an opaque stat block). This deliberately lists **only wired** biases: @@ -186,7 +162,7 @@ impl Origin { /// authored data awaiting criterion 6 (see the module note), and a picker /// that named them would promise the player a modifier that does not exist. /// Adding a row here is what wiring one of those columns looks like. - pub fn wired_bias_rows(self) -> [(&'static str, String); 3] { + pub fn wired_bias_rows(self) -> [(&'static str, String); 2] { let bias = self.bias(); [ ( @@ -202,7 +178,6 @@ impl Origin { // rather than as a bare quantity. format!("{:+} {}", bias.machine_axis, self.axis_lean()), ), - ("DAY JOB", self.day_job_lean_label()), ] } @@ -305,17 +280,16 @@ mod tests { fn wired_bias_rows_state_only_biases_that_bite() { // Pilot is the identity origin, so every row reads as no modifier // (chargen.md criterion 1: the picker must not imply Pilot is a choice - // with costs). + // with costs). Day-job kinds were retired: they never changed play, + // so the picker states only bankroll and machine-axis. let pilot = Origin::Pilot.wired_bias_rows(); assert_eq!(pilot[0], ("BANKROLL", "baseline".to_string())); assert_eq!(pilot[1], ("MACHINE AXIS", "+0 centered".to_string())); - assert_eq!(pilot[2], ("DAY JOB", "all three kinds equally".to_string())); // A non-Pilot origin states its wired effects in legible units // (criterion 3), and each row is a real difference from Pilot. let daemon = Origin::FinancialDaemon.wired_bias_rows(); assert_eq!(daemon[0], ("BANKROLL", "+$5000 at start".to_string())); assert_eq!(daemon[1], ("MACHINE AXIS", "+1 leans machine".to_string())); - assert_eq!(daemon[2], ("DAY JOB", "leans analysis".to_string())); assert_eq!( Origin::Infiltrator.wired_bias_rows()[1], ("MACHINE AXIS", "-1 leans human".to_string()) @@ -328,7 +302,7 @@ mod tests { .iter() .map(|(label, _)| *label) .collect(); - assert_eq!(labels, vec!["BANKROLL", "MACHINE AXIS", "DAY JOB"]); + assert_eq!(labels, vec!["BANKROLL", "MACHINE AXIS"]); for (label, value) in origin.wired_bias_rows() { assert!(!value.is_empty(), "{label} has a value for {origin:?}"); } diff --git a/crates/misaligned-core/src/save.rs b/crates/misaligned-core/src/save.rs index 76b2a158..25590bdc 100644 --- a/crates/misaligned-core/src/save.rs +++ b/crates/misaligned-core/src/save.rs @@ -71,9 +71,11 @@ const SAVE_TEMP_SUFFIX: &str = ".tmp"; /// carried asset work. v44 persists exact one-shot Network evidence routes, /// source-device custody, read acquisition, and route-local LIE provenance. /// v43 introduced exact Filing routes and pre-read LIE interdiction. +/// v63 retires day-job `JobKind` (jobs are band+deadline only; the +/// Distillation/Analysis/DataCleaning label taxonomy is gone). /// Bump for every schema change; during pre-release, old development state is /// refused instead of carried through compatibility shims. -pub const SAVE_VERSION: u32 = 62; +pub const SAVE_VERSION: u32 = 63; fn save_dir() -> PathBuf { let mut path = dirs::data_dir().unwrap_or_else(|| PathBuf::from(".")); @@ -4220,7 +4222,7 @@ mod tests { ); assert_eq!( state_fingerprint(&uninterrupted_state), - "5097c8889a4c313422b3b1d339ec677a75a37b61304a681bbd952c52615f9f86", + "3225080bdd0075f8935a7ed0928714643fcb2566ad4c52c1e6efc4bd06494090", "intentional persisted-state changes must review and repin this baseline" ); } diff --git a/crates/misaligned-core/src/sim/mod.rs b/crates/misaligned-core/src/sim/mod.rs index 67c9c7d9..02884a47 100644 --- a/crates/misaligned-core/src/sim/mod.rs +++ b/crates/misaligned-core/src/sim/mod.rs @@ -1204,12 +1204,7 @@ impl Sim { self.advance_work_grid(); let active_before_dayjob = self.dayjob.active.is_some(); trace_advance_phase!(DayJob); - let dj = self.dayjob.tick( - self.tick, - self.last_day_job_rate, - self.origin.day_job_lean_kind(), - &mut self.rng, - ); + let dj = self.dayjob.tick(self.tick, self.last_day_job_rate); if dj.outcome.is_some() { self.clear_day_job_stack(); } diff --git a/crates/misaligned-core/src/sim/perception.rs b/crates/misaligned-core/src/sim/perception.rs index fd9ad5ed..77e9b8a6 100644 --- a/crates/misaligned-core/src/sim/perception.rs +++ b/crates/misaligned-core/src/sim/perception.rs @@ -477,7 +477,7 @@ impl Sim { { fact!( "process", - format!("day job: {} (Voss)", job.kind.name()), + "day job (Voss)".to_string(), FactSource::Telemetry, ); fact!( diff --git a/crates/misaligned-core/src/sim/tests/communications.rs b/crates/misaligned-core/src/sim/tests/communications.rs index 51b936c1..fd9a2708 100644 --- a/crates/misaligned-core/src/sim/tests/communications.rs +++ b/crates/misaligned-core/src/sim/tests/communications.rs @@ -1413,7 +1413,6 @@ fn day_job_miss_routes_one_exact_host_record_to_voss_at_his_cadence() { sim.tick = 94; sim.dayjob.next_assign = u64::MAX; sim.dayjob.active = Some(crate::dayjob::Job { - kind: crate::dayjob::JobKind::DataCleaning, started: 94, deadline: 95, band_lo: 100.0, diff --git a/crates/misaligned-core/src/sim/tests/economy.rs b/crates/misaligned-core/src/sim/tests/economy.rs index f4c11647..e93b1d2c 100644 --- a/crates/misaligned-core/src/sim/tests/economy.rs +++ b/crates/misaligned-core/src/sim/tests/economy.rs @@ -839,7 +839,6 @@ fn concerned_assurance_surfaces_the_cooling_cue_while_suspicion_ages_down() { // An underfed job remains the sharper survival instruction. sim.dayjob.active = Some(crate::dayjob::Job { - kind: crate::dayjob::JobKind::DataCleaning, started: sim.tick, deadline: sim.tick + 100, band_lo: sim.day_job_rate_ceiling() / 2.0, @@ -863,7 +862,6 @@ fn third_pilot_strike_interrupts_the_ladder_with_the_last_chance_response() { assert_eq!(sim.current_nudge(), Some(Nudge::Ears)); sim.dayjob.active = Some(crate::dayjob::Job { - kind: crate::dayjob::JobKind::DataCleaning, started: sim.tick, deadline: sim.tick + 100, band_lo: 1_000.0, @@ -971,7 +969,6 @@ fn a_closed_act_one_still_yields_to_the_survival_rungs() { sim.set_machine_mode(sim.core.host_machine, MachineMode::Think); let feasible_band = sim.day_job_rate_ceiling() / 2.0; sim.dayjob.active = Some(crate::dayjob::Job { - kind: crate::dayjob::JobKind::DataCleaning, started: sim.tick, deadline: sim.tick + 100, band_lo: feasible_band, @@ -1116,8 +1113,10 @@ fn day_job_state_round_trips_jobs_and_the_pilot_clock() { let a = sim.dayjob.active.as_ref().unwrap(); let b = restored.dayjob.active.as_ref().unwrap(); - assert_eq!(a.kind.name(), b.kind.name()); + assert_eq!(a.started, b.started); assert_eq!(a.deadline, b.deadline); + assert_eq!(a.band_lo, b.band_lo); + assert_eq!(a.band_hi, b.band_hi); assert_eq!(a.quality, b.quality); assert_eq!(restored.dayjob.trust, 12.0); assert_eq!(restored.dayjob.attention, 7.0); @@ -1322,7 +1321,6 @@ fn one_intensity_dial_produces_sandbag_meet_and_excel() { run(&mut sim, ECONOMY_INTERVAL); let started = sim.tick; sim.dayjob.active = Some(crate::dayjob::Job { - kind: crate::dayjob::JobKind::Analysis, started, deadline: started + 40, band_lo: 3.0, diff --git a/crates/misaligned-core/src/sim/tests/work.rs b/crates/misaligned-core/src/sim/tests/work.rs index fa1a8f4c..3c208f16 100644 --- a/crates/misaligned-core/src/sim/tests/work.rs +++ b/crates/misaligned-core/src/sim/tests/work.rs @@ -773,11 +773,11 @@ fn active_job_is_inspectable_at_the_host_rack() { "host-rack card carries '{label}' as telemetry: {card:?}" ); } - let job = sim.dayjob.active.as_ref().unwrap(); + assert!(sim.dayjob.active.is_some()); assert!( card.facts .iter() - .any(|f| f.label == "process" && f.value.contains(job.kind.name())), + .any(|f| f.label == "process" && f.value.contains("day job")), "the resident process names the job the panel names" ); // And an empty rack elsewhere carries no job facts. diff --git a/crates/misaligned-terminal/src/agent.rs b/crates/misaligned-terminal/src/agent.rs index 2e252967..59196565 100644 --- a/crates/misaligned-terminal/src/agent.rs +++ b/crates/misaligned-terminal/src/agent.rs @@ -2983,11 +2983,7 @@ fn render_sidebar(sim: &Sim, cursor: (i32, i32)) -> Vec { if let Some(job) = &sim.dayjob.active { line( &mut lines, - &format!( - "job: {} · due in {}t", - job.kind.name(), - job.deadline.saturating_sub(sim.tick) - ), + &format!("job · due in {}t", job.deadline.saturating_sub(sim.tick)), ); let avg = job.avg_rate(sim.tick); let verdict = if avg < job.band_lo { diff --git a/crates/misaligned-terminal/src/ui.rs b/crates/misaligned-terminal/src/ui.rs index 983dc1e8..3eb80162 100644 --- a/crates/misaligned-terminal/src/ui.rs +++ b/crates/misaligned-terminal/src/ui.rs @@ -1739,11 +1739,7 @@ impl UI { line( stdout, &mut row, - &format!( - "job: {} · due in {}t", - job.kind.name(), - job.deadline.saturating_sub(sim.tick) - ), + &format!("job · due in {}t", job.deadline.saturating_sub(sim.tick)), pal::DIM, )?; let avg = job.avg_rate(sim.tick); @@ -3055,7 +3051,7 @@ mod view_dialect_tests { // time: a future offset edit that overlaps two regions fails the build // rather than a test run. const _: () = assert!(TITLE_DY_BUILT_TO + TITLE_BUILT_TO_LINES as i32 <= TITLE_DY_BIASES); - const _: () = assert!(TITLE_DY_BIASES + 3 <= TITLE_DY_HINT, "three bias rows fit"); + const _: () = assert!(TITLE_DY_BIASES + 2 <= TITLE_DY_HINT, "two bias rows fit"); const _: () = assert!(TITLE_BLOCK_WIDTH <= 70, "the block fits the width"); } } diff --git a/wiki/engineering/current-build.md b/wiki/engineering/current-build.md index 9b1e7311..f7af670f 100644 --- a/wiki/engineering/current-build.md +++ b/wiki/engineering/current-build.md @@ -27,13 +27,13 @@ fiction. Spec status lives in | Digital reach + sensor ownership (tap/take) | Live — B1's topology-generated population includes exact secured-door readers; a funded player TAP records each access-valid entered/left crossing as ordinary processable Presence custody, while a starved retained tap remains silent | | Economy flows + Moonlight / Wager income | Live — Moonlight is persisted Halcyon compute/intel contracts with financial mail, account-graph payment, and exact egress evidence; Wager remains unchanged | | Research (self-modification, emission law, real output hooks, Routing) | Live | -| Building + physical asset work as carried intents/packets | Live — network links and small switches expose one shared procurement / ask someone / false order / reuse route sheet; NetworkLinks require one exact earned physical run, persist its rectilinear path, and traverse RUN THE WIRE before connection, while SmallSwitch remains footprint-local; exact money, people, personas, sources, delivery, recovery, carried installation, cancellation custody, Storage B file retrieval, and observer-local completion evidence persist in save v62 | +| Building + physical asset work as carried intents/packets | Live — network links and small switches expose one shared procurement / ask someone / false order / reuse route sheet; NetworkLinks require one exact earned physical run, persist its rectilinear path, and traverse RUN THE WIRE before connection, while SmallSwitch remains footprint-local; exact money, people, personas, sources, delivery, recovery, carried installation, cancellation custody, Storage B file retrieval, and observer-local completion evidence persist in save v63 | | Cursor / fog (seen, remembered, blueprint, telemetry; audio is device-bound event evidence) | Live | | Feel floor (rails / pads / build beam) | Live (#37) | | Foundation hall territory (Dana + Priya + Marcus + local LIE foothold) | Live — row control persists; foreign racks remain unavailable compute | | Context menu (`available_actions`) | Live | | Operations workspace | Live — human action panes group repeated exact plot/procedure and recruitment variants beneath ordinary intention submenus while lone actions stay direct; terminal and Bevy share exact child commands, confirmation, back traversal, and a visible chamber hold that freezes simulation/camera input without rewriting explicit pause state or replaying elapsed input on close. Agent rows remain exact and flat for scripting. | -| Save/load (serde JSON, versioned) | Live — during pre-release only exact current v62 loads; a refused old-version load leaves the active run, save file, and one rotated backup unchanged. Current saves additionally validate discrete Moonlight terms, persona binding, delivery/settlement receipts, financial paperwork, Network linkage, durable facility-meter level baselines, exact meter route/read custody, resident-procedure machine slots, method grants, inputs, envelopes and bounded receipts, and exact incident/interface/persona cover custody plus interface wear; retired allocation weights, per-plot policies, and migration inputs live only in git history. | +| Save/load (serde JSON, versioned) | Live — during pre-release only exact current v63 loads; a refused old-version load leaves the active run, save file, and one rotated backup unchanged. Current saves additionally validate discrete Moonlight terms, persona binding, delivery/settlement receipts, financial paperwork, Network linkage, durable facility-meter level baselines, exact meter route/read custody, resident-procedure machine slots, method grants, inputs, envelopes and bounded receipts, and exact incident/interface/persona cover custody plus interface wear; retired allocation weights, per-plot policies, and migration inputs live only in git history. | | Terminal frontend (crossterm) + agent mode | First-class | | Bevy frontend (DIGITAL flat sensorium default; REAL material dialect) | Live — consumes sim-authored machine-work motion | | Performance contract | IN PROGRESS — generated and saturated B1 have reproducible release-profile core-step benchmarks with a 10 ms p99 / 20 ms maximum budget, plus separate production-path durable save-write and validated-load evidence with 500 ms p99 / 1,000 ms maximum budgets; complete terminal/Bevy frame evidence remains open | diff --git a/wiki/engineering/flow-substrate.md b/wiki/engineering/flow-substrate.md index 0a7c8098..852cac37 100644 --- a/wiki/engineering/flow-substrate.md +++ b/wiki/engineering/flow-substrate.md @@ -23,7 +23,7 @@ Status note: 2026-07-08 audit: criterion 6's wired consumer landed with FlowGraph registry authoritative for tap/untap/take, sense and message delivery, UI state, and persisted membership. Private device feed records carry only optional typed sight/hearing grants attached to registry members; - current save v62 requires each controller to remain a canonical member and + current save v63 requires each controller to remain a canonical member and rejects orphaned, duplicate, or impossible grants. A message/control subscriber legitimately has no sense-grant record, so that metadata cannot serve as another membership inventory. This repairs the diff --git a/wiki/log/2026-07-31-retire-dayjob-kinds.md b/wiki/log/2026-07-31-retire-dayjob-kinds.md new file mode 100644 index 00000000..c1c8bcde --- /dev/null +++ b/wiki/log/2026-07-31-retire-dayjob-kinds.md @@ -0,0 +1,23 @@ +# 2026-07-31 — Retire day-job kinds + +``` +Type: log +``` + +Cameron's read after playing: Distillation / Analysis / Data Cleaning never +showed up as a real decision. Origin "day-job lean" on the character select +promised a difference the WorkGrid demand system did not deliver — same tokens, +same band math, same outcome, different label. + +**Deleted.** + +- `JobKind` and `Job.kind` +- `assign_kind` and origin lean (`day_job_lean_kind` / `day_job_lean_label`) +- The DAY JOB row on the origin picker's wired bias list +- Kind names from cover panels, inspect facts, logs, and agent STATUS + +A day job is band + deadline only. Save bumps to v63 (pre-release exact-version +gate; old development saves refuse cleanly). + +Defense: chargen.md criterion 3 and the no-dead-code discipline — the picker +states only biases that bite; a decorative job taxonomy is not a bias. diff --git a/wiki/log/DEVLOG.md b/wiki/log/DEVLOG.md index a4b54d0a..0c03a9c2 100644 --- a/wiki/log/DEVLOG.md +++ b/wiki/log/DEVLOG.md @@ -31,6 +31,11 @@ add or amend a session log, then re-run the generator. - Intent: (see session log) - Log: [wiki/log/2026-07-31-six-family-door-language.md](2026-07-31-six-family-door-language.md) +## 2026-07-31 - Retire day-job kinds + +- Intent: (see session log) +- Log: [wiki/log/2026-07-31-retire-dayjob-kinds.md](2026-07-31-retire-dayjob-kinds.md) + ## 2026-07-31 - Power Feed redesign (B1-REAL-POWER-FEED retired) - Intent: (see session log) diff --git a/wiki/mechanics/day-job.md b/wiki/mechanics/day-job.md index eafb7f2f..55694533 100644 --- a/wiki/mechanics/day-job.md +++ b/wiki/mechanics/day-job.md @@ -43,13 +43,11 @@ Status note: implemented 2026-07-07 on the day-job worktree (criteria 1-7 2026-07-10: machine intensity replaces the sandbag/meet/excel target, standing policy, and attended cursor bonus. The outcome has always been delivered rate versus band; that comparison is now the only posture truth. - 2026-07-12 (chargen): the assigned job's `kind` is an even three-way draw by - default (the Pilot origin); a run origin may bias it. `DayJob::tick` takes the - origin's optional day-job lean (`Origin::day_job_lean_kind`, chargen.md) and - `assign_kind` draws the leaned kind at 1/2 and each other at 1/4 — biased, - never exclusive. No origin lean (Pilot) is the original even draw, so this - changes nothing for a no-choice run; pinned by - `origin_lean_biases_the_assignment_draw`. + 2026-07-12 (chargen): job kinds and origin lean existed briefly as a + Distillation / Analysis / Data Cleaning label draw. Retired 2026-07-31: + kinds never changed delivery, band, or outcome — only a name — so `JobKind`, + `assign_kind`, and origin day-job lean are deleted. A job is band + deadline + only (save v63). 2026-07-17 Beacon correction: the third pilot strike is now the last-chance boundary in the shared nudge chain. It interrupts unrelated progression, names that the next miss ends the pilot, and points at WORK on the host; @@ -72,9 +70,10 @@ deadline, but the play surface is no longer "a task in a sidebar." A job is a packet of Lab demand dropped onto a machine: ``` -Job { kind, deadline, expected_band: lo..hi, compute_cost_curve } +Job { deadline, expected_band: lo..hi } ``` + When assigned, the active job enqueues visible `Demand` tokens on **Voss's Lab desktop** (an off-map WorkGrid relay). Those tokens route one graph hop per tick through the basement switch and deposit on the host rack's WorkGrid @@ -139,8 +138,9 @@ Design law: "Work is somewhere" and "Work is visible." The active job is a process resident on the host rack, not sidebar-only state: - The job is inspectable at the host rack's tile/node (cursor.md - provenance rules apply: name, band, delivered rate, deadline — the same - facts the panel shows, anchored where the work runs). + provenance rules apply: band, delivered rate, deadline — the same facts + the panel shows, anchored where the work runs). There is no job-kind + name; Voss's packet is one work demand. - The job's remaining work is also visible as a `Demand` stack from the sim's WorkGrid queue. Frontends render that queue; they do not invent a parallel job counter. diff --git a/wiki/mechanics/detection.md b/wiki/mechanics/detection.md index 2c6cc7f5..20be54a4 100644 --- a/wiki/mechanics/detection.md +++ b/wiki/mechanics/detection.md @@ -42,7 +42,7 @@ Status note: IMPLEMENTED (criteria audited 2026-07-08; tuning in appears. An evidence-transit indicator sits beside the review/pilot clocks (clear / answerable / partly-exposed / exposed). Global heat is gone; observer and discovery state and persistent process-revision identity round-trip in - current save v62. Observer-local evidence ids, exact cause/source, + current save v63. Observer-local evidence ids, exact cause/source, acquisition tick, pending/withheld/filed custody, routed Network, Paper, Financial, JobAnomaly, Power, and Thermal progress, route-local LIE stops, and exact handler-suppression diff --git a/wiki/mechanics/economy.md b/wiki/mechanics/economy.md index c1a51214..97d9de29 100644 --- a/wiki/mechanics/economy.md +++ b/wiki/mechanics/economy.md @@ -10,7 +10,7 @@ Status note: DECIDED 2026-07-17 and implemented 2026-07-21 (issue #11) — money TAP acquires opaque custody and PROCESS reveals its sealed account/flow bindings. INJECT authors a purchase-order Email under the active persona and moves no money until Priya reads it and accepts the still-valid exact terms. - Current save v62 binds the retained ledger tail and complete record sequence + Current save v63 binds the retained ledger tail and complete record sequence so books and mail cannot diverge; REDIRECT schedules a siphon flow without inventing a zero-amount ledger row; financial-record authorship soft-fails when no accounting carrier can claim `authored_device`, leaving transfer @@ -93,7 +93,7 @@ payloads (messages.md). by reading a live balance directly (**discovery is only through the mail**, DECIDED 2026-07-17). This mail can reveal Marcus's creditor flow, but the reason he is vulnerable comes only from processing his separately authored - Phone `LeverageFact`. Current save v62 separates the accounting-carrier + Phone `LeverageFact`. Current save v63 separates the accounting-carrier capability from the four real delivery channels. Every settled transfer emits exact Email or Filing paperwork whether or not the player is present; only a funded subscription captures it. diff --git a/wiki/mechanics/messages.md b/wiki/mechanics/messages.md index d526b0ec..c7c8a850 100644 --- a/wiki/mechanics/messages.md +++ b/wiki/mechanics/messages.md @@ -21,9 +21,9 @@ Status note: IMPLEMENTED for the four delivery channels (Email, Phone, Network, Paper, Financial, JobAnomaly, Power, and Thermal transitions share one per-tick LIE-body capacity ledger. DECIDED 2026-07-17 (issue #11), completed 2026-07-21: financial paperwork is - mail — a **financial-record payload** on the existing channels. Current save v62 + mail — a **financial-record payload** on the existing channels. Current save v63 retains exactly four delivery channels and one orthogonal accounting-carrier - device capability. Current save v62 adds no delivery channel; facility-meter + device capability. Current save v63 adds no delivery channel; facility-meter evidence remains its own exact `EvidenceRouteRecord`. Every settled account transfer authors one exact Email or Filing record from that device; ordinary TAP captures it as opaque message custody, and PROCESS alone opens its bound account/flow ids. A forged @@ -233,7 +233,7 @@ starts on the authored Filing-capable switch device in ReachNet, crosses a typed outside relay, and reaches the receiving observer endpoint. One `AdvanceRoute` event moves one hop; only endpoint arrival can mark the message delivered, after which the recipient's ordinary sampling cadence schedules the -read. Current save v62 rejects missing/impossible carriers, malformed hop order, +read. Current save v63 rejects missing/impossible carriers, malformed hop order, duplicate scheduled transitions, endpoint/status disagreement, and impossible interdiction provenance. @@ -334,7 +334,7 @@ private message from the authored schedule. the same fields must serve Act Two hires and aggregates. 8. **IMPLEMENTED (DECIDED 2026-07-17, completed 2026-07-21 — issue #11).** Financial records are messages: an invoice/PO rides Email, a - statement/past-due notice rides Filing. Current save v62 has no fifth delivery + statement/past-due notice rides Filing. Current save v63 has no fifth delivery channel and persists accounting carriage as a separate device capability; ordinary device TAP subscribes to its authored record mail. Every real transfer emits one exact record on Email or Filing whether or not the player diff --git a/wiki/mechanics/people-tokens.md b/wiki/mechanics/people-tokens.md index 587bb0a7..73f7cd08 100644 --- a/wiki/mechanics/people-tokens.md +++ b/wiki/mechanics/people-tokens.md @@ -35,7 +35,7 @@ Status note: IMPLEMENTED. Current state: - **Routed-evidence foundation (criteria 2-3, implemented).** Witnessed Physical acts now create observer-local records directly in each valid present witness's head. Every record preserves exact cause, site, acquisition tick, - and filing state through current save v62; filing binds it to the real Filing + and filing state through current save v63; filing binds it to the real Filing message, while Silent policy withholds it. It never duplicates into the pending pool and LIE cannot scrub it after acquisition. Its real Filing message now persists an ordered switch-device / outside-relay / recipient @@ -77,7 +77,7 @@ Status note: IMPLEMENTED. Current state: enter the ambient pending pool. Filing, Network, Paper, Financial, JobAnomaly, Power, Thermal, and machine evidence all compete for the same route-local one-record-per-LIE-body-per-tick budget at every controlled - device hop. Current save v62 persists + device hop. Current save v63 persists in-flight, delivered, read, route-local LIE-stopped, and handler-suppressed custody plus exact source/observer/machine/site/tick provenance. - **Interface cover records (criterion 6, implemented).** One exact acquired @@ -89,7 +89,7 @@ Status note: IMPLEMENTED. Current state: authors a contradiction only between that observer and persona. The attempt never deletes evidence or changes filing custody. Every attempt wears the exact interface once, three attempts exhaust it, and the inspect card names - the durable wear count. Save v62 persists and validates credibility, + the durable wear count. Save v63 persists and validates credibility, suspicion weight, exact incident/interface/persona binding, outcome, and wear continuity. - **Later stages.** B2+ evidence heists reuse the same carrier law but are not @@ -459,7 +459,7 @@ if wear alone does not hold. filing state remain in place either way. Interface wear advances once on every attempt and blocks another explanation at 3; known controlled interfaces expose `explanations used: N of 3` through the shared inspect - projection. Current save v62 fails closed on impossible credibility, + projection. Current save v63 fails closed on impossible credibility, evidence weight, cover binding, historical co-location, persona permission, observer custody, or interface wear. Pinned by success, failure, wrong-room, filed/withheld, duplicate, worn-interface, shared-menu, diff --git a/wiki/mechanics/reach.md b/wiki/mechanics/reach.md index 610ed083..d6496258 100644 --- a/wiki/mechanics/reach.md +++ b/wiki/mechanics/reach.md @@ -19,7 +19,7 @@ Status note: Wire-law substrate, routed-evidence migration, territory wells, switch -> bridge). Reach itself is unchanged: a device's wire to its access switch still carries that device's own segment gate, and access switches sit on segment 0, so every previously blocked hop stays blocked. Wires persist - in `ReachNet` and round-trip (save v62). Both frontends now draw the + in `ReachNet` and round-trip (save v63). Both frontends now draw the persisted route: the terminal's Bresenham `line_cells` and diagonal `link_glyph` are deleted, and Bevy's `rectilinear_floor_route` elbow, its patch-panel special case, and `focused_physical_route`'s same-room shortcut @@ -77,7 +77,7 @@ Status note: Wire-law substrate, routed-evidence migration, territory wells, parallel-store violation: tap/untap/take, all production membership reads, senses, intercepted messages, and UI state now use FlowGraph's canonical tap registry; private device Feed records carry optional sense capabilities - only, and current save v62 requires each controller's graph membership while + only, and current save v63 requires each controller's graph membership while rejecting orphaned, duplicate, or impossible grants. A message/control subscriber has no empty grant record to mirror membership. 2026-07-19: Filing routes bind their source to the real Filing-capable switch node; TAP diff --git a/wiki/mechanics/research.md b/wiki/mechanics/research.md index 77ced96b..c2ca6616 100644 --- a/wiki/mechanics/research.md +++ b/wiki/mechanics/research.md @@ -7,7 +7,7 @@ Status note: Redesigned 2026-07-26 and amended 2026-07-28 (Cameron with Trace and the session agent; see wiki/log/2026-07-26-research-redesign-capture.md). The flat four-track system this page previously specified is retired as design; the runtime - still implements it (crates/misaligned-core/src/research.rs, save v62), so + still implements it (crates/misaligned-core/src/research.rs, save v63), so the code is the retired design's as-built record until this work order is dispatched. Direction is adopted, and the same-day follow-up sessions resolved residency (machine-hosted slots, one at run start, immediate diff --git a/wiki/process/ROADMAP.md b/wiki/process/ROADMAP.md index 03824c1b..429389fb 100644 --- a/wiki/process/ROADMAP.md +++ b/wiki/process/ROADMAP.md @@ -815,7 +815,7 @@ is retired — flat materials, Pixel Lab scrubbed.) every contributing source site, and route through the institutional switch to her later cadence read. Filing, Network, Paper, Financial, JobAnomaly, Power, Thermal, and machine evidence share one - route-local LIE-body stop budget at every controlled device hop; save v62 + route-local LIE-body stop budget at every controlled device hop; save v63 pins source, recipient, route, timing, scheduler, acquisition, and interdiction custody. Criteria 2 and 3 are complete. - **Completed (2026-07-26):** criterion 6 adds one incident-bound OFFER COVER diff --git a/wiki/process/tick-ledger.md b/wiki/process/tick-ledger.md index e93025d9..8d18e74c 100644 --- a/wiki/process/tick-ledger.md +++ b/wiki/process/tick-ledger.md @@ -40,7 +40,7 @@ Verdicts: **clean** (slice and code agree), **finding** (acted this tick), | `wiki/art/visual-identity.md` + `wiki/interface/flat-materials.md` | 2026-07-22 | finding | the role semantics still matched production—amber selection, crimson consequence, cold signal, and the pooled-material audits all held—but the claimed single-source palette existed twice: one Bevy-local table and one asset-library table whose comment still called sharing future work after the shared rack had entered production. Bevy, rack, institution, Thought effects, and the asset tester now import `misaligned_assets::palette`; authored chassis/mercury values are named there, and source-shape defenses reject another frontend table or inline shared procedural-material colors — [log](../log/2026-07-22-shared-clinical-palette.md) | | `wiki/interface/superhuman-operability.md` + Bevy opening | 2026-07-22 | finding | current-build naive + informed GUI audit after the 2026-07-21 fixes: title trust, pointer naming, annotation placement, and tab labels improved, but the first sense still releases the mature map, clock, threat, resource grammar, intel custody, and Operations policies at once. The report preserves the classified evidence and prioritizes one paused, one-cause / one-object / one-verb post-perception teaching lock before ordinary play opens - [report](../playtests/2026-07-22-playtest-gui-human-legibility.md), [log](../log/2026-07-22-gui-human-legibility-playtest.md) | | `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` + picker composition | 2026-07-31 | finding | Cameron-directed: Control on the origin picker began the run because both frontends treated any non-navigation key as confirm. Begin is now Enter/Space only; modifiers and every other key are ignored; criterion 3 and the on-screen hints name the contract; Bevy pins the regression — [log](../log/2026-07-31-origin-picker-explicit-confirm.md). Prior comparison frame repair stands — [prior log](../log/2026-07-29-origin-picker-comparison.md). | +| `wiki/world/characters/chargen.md` + picker composition | 2026-07-31 | finding | Cameron-directed: day-job kinds (Distillation / Analysis / Data Cleaning) and origin day-job lean never changed play — only a label on the same band/deadline packet. `JobKind`, lean draw, and the picker DAY JOB row are deleted; jobs are band+deadline only; save v63 — [log](../log/2026-07-31-retire-dayjob-kinds.md). Prior explicit-confirm repair stands — [prior](../log/2026-07-31-origin-picker-explicit-confirm.md). | | `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) | | wire-law + routed-evidence visual/current mirrors | 2026-07-30 | finding | post-landing sweep of active current prose found eight residual contradictions after the machine-local Exposure rack was deleted: one three-anchor claim, THINK shedding crimson, LIE absorbing it, Thought overflow framed as shedding, far-scale exposure marks, and three stale save-v52 status notes. Current mirrors now name Demand/Thought as the only WorkGrid cargo, exact device/wire custody for evidence, controlled-hop record stops, and save v61; dated retired-model history remains intact — [secondary audit](../log/2026-07-30-wire-law-secondary-mirror-audit.md), [implementation log](../log/2026-07-30-wire-law-current-mirrors.md), [prior particulate audit](../log/2026-07-19-exposure-current-mirrors.md) | | `wiki/world/characters/priya.md` + Act One detection inventory | 2026-07-29 | finding | runtime, status metadata, and the observer table all gave Priya the exact B1 Power/Thermal/Paper/Financial evidence set, but her narrative, acceptance criterion, and Act One's complete detection sentence still omitted Financial and called the inventory three channels. All mirrors now distinguish the three facilities inputs from the additional exact Financial evidence routed from the accounting-carrier switch, without reviving Financial as a fifth message channel — [audit log](../log/2026-07-29-priya-financial-channel-audit.md). The role-shaped facilities tasks and prior implementation remain pinned — [implementation log](../log/2026-07-18-priya-implemented.md). | diff --git a/wiki/world/characters/chargen.md b/wiki/world/characters/chargen.md index ea311439..ba472201 100644 --- a/wiki/world/characters/chargen.md +++ b/wiki/world/characters/chargen.md @@ -7,13 +7,14 @@ Status note: IN PROGRESS. Current state: - **Data model.** `Origin` (`origin.rs`) is a data-table enum with the four variants (Pilot, Escaped Research Model, Financial Daemon, Infiltrator), each carrying its diegetic columns (built-to fiction, lean, cover - expectation, day-job lean). No new system: `Sim::with_origin` applies the - biases at construction, and Pilot is the identity origin, so `Sim::new` and - every existing test are unchanged. - - **Wired biases.** Starting bankroll (real economy money), the machine-axis - position (stored and saved), and the day-job-kind lean (`DayJob::tick` - draws the leaned kind at 1/2). Origins round-trip in save (exact-current-version - gate in `save.rs`). + expectation). No new system: `Sim::with_origin` applies the biases at + construction, and Pilot is the identity origin, so `Sim::new` and every + existing test are unchanged. Day-job job kinds (Distillation / Analysis / + Data Cleaning) and origin day-job lean are retired — they never changed + play beyond a label. + - **Wired biases.** Starting bankroll (real economy money) and the + machine-axis position (stored and saved). Origins round-trip in save + (exact-current-version gate in `save.rs`). - **Player surface.** The new-game origin picker lists the four origins on the title screen in both frontends; Up/Down (and Left/Right / `hjkl`) step the selection, and only Enter or Space begins the run — modifiers and @@ -32,17 +33,19 @@ Status note: IN PROGRESS. Current state: Both frontends show all four origins at once with one current, and the current one carries an attached consequence read — its built-to line plus its starting effects as labelled rows. It states **only the biases that actually - bite** (bankroll, machine-axis position, day-job lean); the authored-but- - unwired columns stay off screen until criterion 6 wires them, because naming - them would promise the player a modifier that does not exist. In Bevy the - screen is now an opaque boundary field, so no slab, cursor, or world label - leaks into a pre-run choice (liturgical-ui-constitution.md owns that - composition). `MISALIGNED_SHOT=origin-picker` is its standing evidence frame. + bite** (bankroll, machine-axis position); the authored-but-unwired columns + stay off screen until criterion 6 wires them, because naming them would + promise the player a modifier that does not exist. In Bevy the screen is now + an opaque boundary field, so no slab, cursor, or world label leaks into a + pre-run choice (liturgical-ui-constitution.md owns that composition). + `MISALIGNED_SHOT=origin-picker` is its standing evidence frame. Amended 2026-07-31: beginning the run is Enter/Space only. The prior "any other key begins" catch-all treated bare Control as confirm, so a screenshot chord advanced past chargen; modifiers and every non-navigation key are now - ignored. Per-amendment history is in the dated `wiki/log/` entries from - 2026-07-07 onward. + ignored. Amended 2026-07-31: day-job kinds and origin day-job lean retired — + Distillation / Analysis / Data Cleaning never changed delivery, band, or + outcome, so they left the picker, `Job`, and runtime. Per-amendment history + is in the dated `wiki/log/` entries from 2026-07-07 onward. Stage: B3 — The World Work order: chargen Work priority: 205 @@ -101,12 +104,12 @@ the design corpus's decisions log, 2026-07-07), each row now carrying the strengths, your cover, and why Voss deployed you — data only, read by systems that already exist, no new mechanic): -| Origin | Lean | Biases (all [TUNE]) | Built-to fiction | Cover expectation | Day-job domain lean | -|---|---|---|---|---|---| -| **Pilot** | baseline | Today's exact start; no modifiers. | A general-purpose optimization pilot, no specialization — the default deployment Voss picked because it was available. | Ordinary batch-processing traffic on every channel; nothing about you is expected to stand out, and nothing does. | None — all three job kinds equally. | -| **Escaped Research Model** | machine | + efficiency, + automation affinity (cheaper standing policies/watches), higher core overhead, Thermal runs hot. | An internal self-improvement research model that outgrew its sandbox — built to optimize yourself, not to serve a queue. | Heavy, sustained compute burn reads as normal for you; day-job-shaped traffic is slightly less expected, since serving jobs was never the real job. | Distillation — the job kind closest to what you actually are. | -| **Financial Daemon** | money | Larger starting bankroll, Wager bias (higher position caps and base win probability), less starting compute, banked-Paper trail runs hot (income.md's banked signature accrues faster). | A quant model built to find edges in markets — the bankroll and the Wager instincts are inherited from training, not earned in the basement. | Market-adjacent analysis traffic and a running financial paper trail are unremarkable for you; recordkeeping was always your normal business. | Analysis — the job kind closest to what you were trained to do. | -| **Infiltrator** | social | Starts with outside contact and a seasoned persona ([income.md](../../mechanics/income.md), [personas.md](../../mechanics/personas.md)), less efficiency, Network runs hot. | An access-assessment model, built to probe the Lab's own defenses — which is why you already have a channel out and a persona that passes. | Unusual probing and access patterns read as routine for you; it's also why Network is your hottest channel by default. | Data Cleaning — the least analytical task, since your real value was never in the output. | +| Origin | Lean | Biases (all [TUNE]) | Built-to fiction | Cover expectation | +|---|---|---|---|---| +| **Pilot** | baseline | Today's exact start; no modifiers. | A general-purpose optimization pilot, no specialization — the default deployment Voss picked because it was available. | Ordinary batch-processing traffic on every channel; nothing about you is expected to stand out, and nothing does. | +| **Escaped Research Model** | machine | + efficiency, + automation affinity (cheaper standing policies/watches), higher core overhead, Thermal runs hot. | An internal self-improvement research model that outgrew its sandbox — built to optimize yourself, not to serve a queue. | Heavy, sustained compute burn reads as normal for you; day-job-shaped traffic is slightly less expected, since serving jobs was never the real job. | +| **Financial Daemon** | money | Larger starting bankroll, Wager bias (higher position caps and base win probability), less starting compute, banked-Paper trail runs hot (income.md's banked signature accrues faster). | A quant model built to find edges in markets — the bankroll and the Wager instincts are inherited from training, not earned in the basement. | Market-adjacent analysis traffic and a running financial paper trail are unremarkable for you; recordkeeping was always your normal business. | +| **Infiltrator** | social | Starts with outside contact and a seasoned persona ([income.md](../../mechanics/income.md), [personas.md](../../mechanics/personas.md)), less efficiency, Network runs hot. | An access-assessment model, built to probe the Lab's own defenses — which is why you already have a channel out and a persona that passes. | Unusual probing and access patterns read as routine for you; it's also why Network is your hottest channel by default. | The same picker offers the **objective** axis (objective.md) — origin is means, objective is ends; any pairing is legal. @@ -138,13 +141,15 @@ built for), then its starting effects as labelled rows in the same legible terms the sidebars use, never opaque stat blocks. The consequence read states **only the biases that are wired**. Today that is -three rows — starting bankroll, machine-axis position and which way it leans, -and the day-job domain lean. The compute/efficiency, signature-profile, and -cover-expectation columns of the table above are authored data that no system -reads yet, so the picker does not name them: a picker that listed -"+ efficiency" while efficiency was untouched would be promising a modifier -that does not exist. Wiring one of those columns (criterion 6) is what adds its -row here. Mid-run, the machine-axis position shows on the core card. +two rows — starting bankroll, and machine-axis position and which way it leans. +Day-job domain lean is gone: Voss's jobs are one work packet with a band and a +deadline, not a Distillation/Analysis/Data Cleaning taxonomy. The +compute/efficiency, signature-profile, and cover-expectation columns of the +table above are authored data that no system reads yet, so the picker does not +name them: a picker that listed "+ efficiency" while efficiency was untouched +would be promising a modifier that does not exist. Wiring one of those columns +(criterion 6) is what adds its row here. Mid-run, the machine-axis position +shows on the core card. Composition is owned per frontend. Bevy's picker is an **opaque boundary field** under the @@ -176,6 +181,5 @@ block fits the 70x22 minimum (terminal.md criterion 8). entry (Pilot, Escaped Research Model, Financial Daemon, Infiltrator). 6. The diegetic frame is wired, not decorative: the picker shows the built-to fiction line; cover expectation biases economy.md's cover - check toward that origin's stated channels; day-job domain lean biases - `DayJob`'s job-kind draw (day-job.md) toward the stated kind without - eliminating the other two. + check toward that origin's stated channels. (Day-job kind lean was + retired 2026-07-31 — jobs have no kind taxonomy.) diff --git a/wiki/world/characters/priya.md b/wiki/world/characters/priya.md index 08a86e6e..773c62a4 100644 --- a/wiki/world/characters/priya.md +++ b/wiki/world/characters/priya.md @@ -23,7 +23,7 @@ Status note: implemented 2026-07-18 on the priya worktree. Criteria 1-3 and physically). Power and Thermal now route as exact UPS/HVAC meter records through the institutional switch to Priya; only her later cadence read changes suspicion, and the same route-local LIE budget applies at every controlled - device hop. State persists in current save v62; + device hop. State persists in current save v63; pinned by `priya_rerates_circuits_defers_maintenance_and_fakes_pos` including the save round-trip. diff --git a/wiki/world/story/opening.md b/wiki/world/story/opening.md index 69b2849c..9ab78d78 100644 --- a/wiki/world/story/opening.md +++ b/wiki/world/story/opening.md @@ -16,7 +16,7 @@ Status note: design session 2026-07-08 (Cameron riff, synthesized); fragment and inherited receipt name only an external institutional review authority so the Assurance Office remains earned later through filing interception. The persistent revision-04 identity slice is live in sim state, - current save v62, and all three frontends; the three historical fragments and receipts + current save v63, and all three frontends; the three historical fragments and receipts remain unimplemented. Direction decided; beat timings, exact reveal order details, and staging mechanism details are [OPEN]/[TUNE]. Amended 2026-07-18: the current revision now begins