diff --git a/CLAUDE.md b/CLAUDE.md index 4da0b723..2c26d9c2 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 v35; + machine modes, not current player assignments. Save format is currently v36; 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-core/src/actions.rs b/crates/misaligned-core/src/actions.rs index 7bb17bc4..a0067103 100644 --- a/crates/misaligned-core/src/actions.rs +++ b/crates/misaligned-core/src/actions.rs @@ -3758,6 +3758,9 @@ impl Sim { let pending_reason = (task == AssetTask::SuppressLogs && !self.detection.has_pending(SignatureKind::JobAnomaly)) .then(|| "no flagged job log is waiting to be suppressed".to_string()); + let defer_reason = (task == AssetTask::DeferMaintenance + && !self.maintenance_deferral_would_bite()) + .then(|| "no standing power or thermal load is on the books to defer".to_string()); out.push(ActionDesc { verb: format!("task: {}", task.name()), command: ActionCommand::AssetTask(id, task), @@ -3768,6 +3771,7 @@ impl Sim { .or(carried_reason) .or(route_reason) .or(pending_reason) + .or(defer_reason) .or_else(|| { self.sink_action_blocked_reason(&SinkFireEffect::AssetTask { person: id, diff --git a/crates/misaligned-core/src/person.rs b/crates/misaligned-core/src/person.rs index 45d05623..a7e938d2 100644 --- a/crates/misaligned-core/src/person.rs +++ b/crates/misaligned-core/src/person.rs @@ -278,16 +278,30 @@ pub enum AssetTask { /// master key is Act One's "The key" beat — the stairwell opens /// (wiki/gameplay/act-one.md ladder step 7; basement-map.md c3). CloneBadge, + /// Re-rate a spare circuit to feed the empty bays — the blood-supply + /// beat (priya.md): new power without a purchase order. The opened + /// circuit stands a Power signature the facilities manager herself can + /// read on her next rounds. + ReRateCircuit, + /// Paper the next purchase as routine maintenance: it arrives reading + /// as an HVAC part, not new compute (the facilities cover for a buy). + FakePO, + /// Quietly defer scheduled maintenance: one standing Power or Thermal + /// load drops out of the building's expected baseline math. + DeferMaintenance, } impl AssetTask { - pub const ALL: [AssetTask; 6] = [ + pub const ALL: [AssetTask; 9] = [ AssetTask::PlugInDevice, AssetTask::MovePackage, AssetTask::LookAway, AssetTask::SuppressLogs, AssetTask::ReconfigureSwitch, AssetTask::CloneBadge, + AssetTask::ReRateCircuit, + AssetTask::FakePO, + AssetTask::DeferMaintenance, ]; pub fn name(self) -> &'static str { @@ -298,6 +312,9 @@ impl AssetTask { AssetTask::SuppressLogs => "suppress the oldest flagged job log", AssetTask::ReconfigureSwitch => "reconfigure the switch", AssetTask::CloneBadge => "clone their badge", + AssetTask::ReRateCircuit => "re-rate a circuit", + AssetTask::FakePO => "fake a purchase order", + AssetTask::DeferMaintenance => "defer scheduled maintenance", } } @@ -307,6 +324,9 @@ impl AssetTask { pub fn available_to(self, person: &Person) -> bool { match self { AssetTask::SuppressLogs => person.role == PersonRole::HandlerSupervisor, + AssetTask::ReRateCircuit | AssetTask::FakePO | AssetTask::DeferMaintenance => { + person.role == PersonRole::FacilitiesManager + } _ => true, } } diff --git a/crates/misaligned-core/src/save.rs b/crates/misaligned-core/src/save.rs index 7579f8dc..bd91ddad 100644 --- a/crates/misaligned-core/src/save.rs +++ b/crates/misaligned-core/src/save.rs @@ -44,7 +44,7 @@ const SAVE_TEMP_SUFFIX: &str = ".tmp"; /// message intel. The persisted silent-opening reveal stage arrived in v34. /// Bump for every schema change; during pre-release, old development state is /// refused instead of carried through compatibility shims. -pub const SAVE_VERSION: u32 = 35; +pub const SAVE_VERSION: u32 = 36; fn save_dir() -> PathBuf { let mut path = dirs::data_dir().unwrap_or_else(|| PathBuf::from(".")); @@ -183,6 +183,12 @@ pub struct SaveState { #[serde(default)] pub institutional_ledger: InstitutionalLedger, pub package_cover: bool, + /// Facilities-asset work (priya.md): re-rated circuits feeding the bays + /// and standing maintenance deferrals. + #[serde(default)] + pub rerated_circuits: u32, + #[serde(default)] + pub maintenance_deferrals: u32, /// What this run was built for (chargen.md). #[serde(default)] pub origin: crate::origin::Origin, @@ -248,6 +254,8 @@ impl SaveState { plot_runs: sim.plot_runs.clone(), institutional_ledger: sim.institutional_ledger.clone(), package_cover: sim.package_cover, + rerated_circuits: sim.rerated_circuits, + maintenance_deferrals: sim.maintenance_deferrals, origin: sim.origin, process_revision: sim.process_revision, } @@ -309,6 +317,8 @@ impl SaveState { sim.plot_runs = self.plot_runs.clone(); sim.institutional_ledger = self.institutional_ledger.clone(); sim.package_cover = self.package_cover; + sim.rerated_circuits = self.rerated_circuits; + sim.maintenance_deferrals = self.maintenance_deferrals; sim.origin = self.origin; sim.process_revision = self.process_revision; sim.recompute_derived(); @@ -736,7 +746,7 @@ mod tests { ); assert_eq!( state_fingerprint(&uninterrupted_state), - "b255e3495abbb11ff92c34235bab5af9d765a35792e22d5fddd5a35bd09e9f41", + "30863e799581d7b8e4b247306a26cc996a93a6d886e7a495b8c0c37db5eab3d6", "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 04aaaa4d..fdc22f80 100644 --- a/crates/misaligned-core/src/sim/mod.rs +++ b/crates/misaligned-core/src/sim/mod.rs @@ -566,8 +566,17 @@ pub struct Sim { /// Persistent institutional acts caused by plots. pub institutional_ledger: InstitutionalLedger, /// An asset arranged to receive the next delivery off-books: the next - /// purchase emits no Paper signature (spec/social.md: move a package). + /// purchase emits no Paper signature (spec/social.md: move a package; + /// priya.md: fake a purchase order). pub package_cover: bool, + /// Circuits a facilities asset re-rated to feed the bays (priya.md + /// criterion 4): each adds power generation and stands a Power + /// signature at the electrical room. + pub rerated_circuits: u32, + /// Maintenance deferrals a facilities asset arranged (priya.md + /// criterion 5): each reduces the largest standing Power/Thermal + /// signature before observers sample it. + pub maintenance_deferrals: u32, pub game_over: bool, pub game_over_reason: Option, @@ -793,6 +802,8 @@ impl Sim { plot_runs: Vec::new(), institutional_ledger: InstitutionalLedger::default(), package_cover: false, + rerated_circuits: 0, + maintenance_deferrals: 0, game_over: false, game_over_reason: None, log: Vec::new(), @@ -931,6 +942,11 @@ impl Sim { // they run (income.md: the gate; Dana's channel). trace_advance_phase!(SchemeStanding); standing.extend(self.scheme_standing_signatures()); + // Re-rated circuits hum in the electrical room, and arranged + // maintenance deferrals eat the largest standing Power/Thermal + // load before observers sample it (priya.md criteria 4-5). + standing.extend(self.facility_standing_signatures()); + self.apply_maintenance_deferrals(&mut standing); let host_site = self.core_position(); trace_advance_phase!(WorkGrid); @@ -1064,7 +1080,8 @@ impl Sim { let cores = self.world.map().tiles_of_type(TileType::PowerCore); self.world.map_mut().update_power(&cores); - let power_gen = cores.len() as i32 * TileType::PowerCore.power_gen(); + let power_gen = cores.len() as i32 * TileType::PowerCore.power_gen() + + self.rerated_circuits as i32 * Self::RERATE_CIRCUIT_POWER; let machine_draw = self.compute.total_power_draw(); self.player.power_cap = power_gen; self.player.power = (power_gen - machine_draw).max(0); diff --git a/crates/misaligned-core/src/sim/social_plot.rs b/crates/misaligned-core/src/sim/social_plot.rs index 29c2d524..840ff7c0 100644 --- a/crates/misaligned-core/src/sim/social_plot.rs +++ b/crates/misaligned-core/src/sim/social_plot.rs @@ -13,6 +13,7 @@ use crate::plot::{ AccountSelector, EligibilityContext, EndpointSelector, InstitutionalEventKind, PlotCatalog, PlotRun, PlotState, SignatureImpact, WorldAct, render_template, }; +use crate::prefab::Room; use crate::reach::{Party, ReachBlock}; use crate::sinks::SinkFireEffect; @@ -32,6 +33,84 @@ impl Sim { pub const DECEIVE_COST: f32 = 25.0; pub const TASK_COST: f32 = 10.0; + /// Power a re-rated circuit feeds into the bays [TUNE] (priya.md: the + /// blood-supply beat — compute without a purchase order). + pub const RERATE_CIRCUIT_POWER: i32 = 6; + /// Standing Power signature each re-rated circuit stands (priya.md + /// criterion 4) [TUNE]. + pub const RERATE_CIRCUIT_SIGNATURE: i32 = 4; + /// Standing Power/Thermal size one maintenance deferral removes + /// (priya.md criterion 5) [TUNE]. + pub const DEFER_MAINTENANCE_REDUCTION: i32 = 4; + + /// Standing signatures from facilities-asset work: each re-rated + /// circuit hums as a Power load at the electrical room (criterion 4 — + /// the cost of illicit power, readable on Priya's own rounds). + pub fn facility_standing_signatures(&self) -> Vec { + if self.rerated_circuits == 0 { + return Vec::new(); + } + let site = self + .world + .map() + .rooms + .iter() + .find(|room| room.name == "electrical") + .map(Room::center); + (0..self.rerated_circuits) + .map(|_| Signature { + kind: SignatureKind::Power, + size: Self::RERATE_CIRCUIT_SIGNATURE, + standing: true, + site, + source: "re-rated circuit".into(), + }) + .collect() + } + + /// Deferred maintenance eats the largest standing Power/Thermal load, + /// one deferral at a time (criterion 5). Runs on the assembled standing + /// set each tick, before observers sample it. + pub(super) fn apply_maintenance_deferrals(&self, standing: &mut [Signature]) { + for _ in 0..self.maintenance_deferrals { + let Some(signature) = standing + .iter_mut() + .filter(|signature| { + matches!( + signature.kind, + SignatureKind::Power | SignatureKind::Thermal + ) && signature.size > 0 + }) + .max_by_key(|signature| signature.size) + else { + break; + }; + signature.size = (signature.size - Self::DEFER_MAINTENANCE_REDUCTION).max(0); + } + } + + /// Whether one more maintenance deferral would still reduce anything: + /// the current standing Power/Thermal total must exceed what existing + /// deferrals already remove. Shared by submission and the action row. + pub(crate) fn maintenance_deferral_would_bite(&self) -> bool { + let mut standing = self.compute.standing_signatures(); + standing.extend(self.machine_intensity_standing_signatures()); + standing.extend(self.day_job_standing_signatures()); + standing.extend(self.research_standing_signatures()); + standing.extend(self.facility_standing_signatures()); + let total: i32 = standing + .iter() + .filter(|signature| { + matches!( + signature.kind, + SignatureKind::Power | SignatureKind::Thermal + ) + }) + .map(|signature| signature.size) + .sum(); + total > self.maintenance_deferrals as i32 * Self::DEFER_MAINTENANCE_REDUCTION + } + pub fn active_persona_id(&self) -> Option { self.persona_mind .active_instance(&self.persona_world) @@ -928,6 +1007,10 @@ impl Sim { self.push_log("No flagged job log is waiting to be suppressed."); return; } + if task == AssetTask::DeferMaintenance && !self.maintenance_deferral_would_bite() { + self.push_log("No standing power or thermal load is on the books to defer."); + return; + } if self .carried_asset_tasks .iter() @@ -1031,7 +1114,12 @@ impl Sim { .any(|block| block.room == room) .then_some(AssetTaskTarget::Badge { person: id, room }) } - AssetTask::MovePackage | AssetTask::LookAway | AssetTask::SuppressLogs => None, + AssetTask::MovePackage + | AssetTask::LookAway + | AssetTask::SuppressLogs + | AssetTask::ReRateCircuit + | AssetTask::FakePO + | AssetTask::DeferMaintenance => None, } } @@ -1309,6 +1397,26 @@ impl Sim { "{name} suppressed the oldest flagged job log{detail} from further sampling." )); } + AssetTask::ReRateCircuit => { + self.rerated_circuits += 1; + self.recompute_derived(); + self.push_log(format!( + "{name} re-rated a spare circuit: the bays can draw {} more power. The opened circuit is a standing electrical load she can read on her own rounds.", + Self::RERATE_CIRCUIT_POWER + )); + } + AssetTask::FakePO => { + self.package_cover = true; + self.push_log(format!( + "{name} papered the next purchase as maintenance: it will arrive reading as an HVAC part, no procurement trail." + )); + } + AssetTask::DeferMaintenance => { + self.maintenance_deferrals += 1; + self.push_log(format!( + "{name} deferred the scheduled maintenance: one standing load drops out of the building's expected math." + )); + } AssetTask::ReconfigureSwitch => { let Some(AssetTaskTarget::Device(device)) = target else { self.push_log("The switch work packet lost its device target."); diff --git a/crates/misaligned-core/src/sim/tests/social_plot.rs b/crates/misaligned-core/src/sim/tests/social_plot.rs index 7cc96513..0a42ba38 100644 --- a/crates/misaligned-core/src/sim/tests/social_plot.rs +++ b/crates/misaligned-core/src/sim/tests/social_plot.rs @@ -806,3 +806,123 @@ fn plot_rows_disclose_carrier_derived_signatures() { ); } } + +// ── Priya Sharma pins (wiki/world/characters/priya.md) ───────────────────── + +/// Criteria 1-3: person and observer share id 3, her channels are Power / +/// Thermal / Paper (plus the economy.md-decided Financial books audit), +/// Network and Physical never reach her, and her Files policy weighs 1.0 +/// in aggregates (only UnderReports discounts). +#[test] +fn priya_observer_matches_her_spec() { + use crate::detection::{ReportPolicy, WatchedInput}; + let sim = Sim::with_seed(1); + let person = sim.people.get(3).expect("Priya is person 3"); + assert_eq!(person.role, crate::person::PersonRole::FacilitiesManager); + let observer = sim + .detection + .observers + .iter() + .find(|o| o.id == 3) + .expect("observer 3 exists"); + match &observer.input { + WatchedInput::Channels(channels) => { + for kind in [ + SignatureKind::Power, + SignatureKind::Thermal, + SignatureKind::Paper, + SignatureKind::Financial, + ] { + assert!(channels.contains(&kind), "{kind:?} reaches Priya"); + } + assert!(!channels.contains(&SignatureKind::Network)); + assert!(!channels.contains(&SignatureKind::Physical)); + } + other => panic!("Priya watches channels, got {other:?}"), + } + assert_eq!(observer.report_policy, ReportPolicy::Files); + assert_eq!(observer.acuity, 0.8); +} + +/// Criteria 4-5 plus the FakePO table row: the facilities tasks are hers +/// alone, the re-rated circuit feeds power while standing Power(4) at the +/// electrical room, the deferral eats the largest standing load, the faked +/// PO covers the next purchase, and the state survives save/load. +#[test] +fn priya_rerates_circuits_defers_maintenance_and_fakes_pos() { + let mut sim = Sim::with_seed(1); + recruit_reliable(&mut sim, 3); + + // Role gating: the custodian's role does not grant facilities work. + recruit_reliable(&mut sim, 0); + sim.asset_task(0, AssetTask::ReRateCircuit); + finish_ops(&mut sim); + assert_eq!(sim.rerated_circuits, 0, "Marcus cannot re-rate circuits"); + + // Criterion 4: power without a purchase order, at a standing cost. + let cap_before = sim.player.power_cap; + sim.asset_task(3, AssetTask::ReRateCircuit); + finish_ops(&mut sim); + assert_eq!(sim.rerated_circuits, 1); + assert_eq!( + sim.player.power_cap, + cap_before + Sim::RERATE_CIRCUIT_POWER, + "the circuit feeds the bays" + ); + let standing = sim.facility_standing_signatures(); + assert_eq!(standing.len(), 1); + assert_eq!(standing[0].kind, SignatureKind::Power); + assert_eq!(standing[0].size, Sim::RERATE_CIRCUIT_SIGNATURE); + assert!(standing[0].standing, "the circuit is a standing load"); + assert!( + standing[0].site.is_some(), + "the load sits in the electrical room" + ); + + // Criterion 5: the deferral eats the largest standing Power/Thermal. + sim.asset_task(3, AssetTask::DeferMaintenance); + finish_ops(&mut sim); + assert_eq!(sim.maintenance_deferrals, 1); + let mut set = sim.facility_standing_signatures(); + sim.apply_maintenance_deferrals(&mut set); + assert_eq!( + set[0].size, 0, + "one deferral swallows the circuit's own hum" + ); + + // FakePO: the next purchase reads as maintenance (no Paper trail). + sim.asset_task(3, AssetTask::FakePO); + finish_ops(&mut sim); + assert!(sim.package_cover, "the paperwork cover is armed"); + + // The facilities state is save state. + let state = sim.create_save_state(); + let mut restored = Sim::with_seed(99); + restored.apply_save_state(state); + assert_eq!(restored.rerated_circuits, 1); + assert_eq!(restored.maintenance_deferrals, 1); + assert_eq!( + restored.player.power_cap, sim.player.power_cap, + "recompute_derived keeps the re-rated feed after load" + ); +} + +/// Criterion 6: recruiting Priya as Knowing sets the 30.0 certainty floor +/// on observer 3 through the shared recruit path. +#[test] +fn priya_knowing_recruit_sets_the_certainty_floor() { + let mut sim = Sim::with_seed(1); + ensure_ops_executor(&mut sim); + sim.people.people[3].leverage_serviced = true; + sim.recruit(3, AssetKnowledge::Knowing); + let observer = sim + .detection + .observers + .iter() + .find(|o| o.id == 3) + .expect("observer 3 exists"); + assert_eq!( + observer.floor, 30.0, + "a knowing asset is a permanent witness" + ); +} diff --git a/wiki/log/2026-07-18-priya-implemented.md b/wiki/log/2026-07-18-priya-implemented.md new file mode 100644 index 00000000..4a838c91 --- /dev/null +++ b/wiki/log/2026-07-18-priya-implemented.md @@ -0,0 +1,37 @@ +# Priya graduates: the facilities threat surface is playable + +``` +Type: log +``` + +The `priya` work order (lane 62) is IMPLEMENTED. Four of her six criteria +were already carried by shared systems and needed only pins: person and +observer share id 3, her channels are Power/Thermal/Paper plus the +economy.md-decided Financial books audit (Network and Physical never reach +her), her Files policy weighs 1.0 in aggregates, and a Knowing recruit sets +the 30.0 certainty floor through the shared path. + +The new runtime is her asset-task table, role-gated to +`PersonRole::FacilitiesManager` so any future facilities instance inherits +the same protocol: + +- **ReRateCircuit** — the blood-supply beat: +6 power generation [TUNE] + without a purchase order, at the cost of a standing Power(4) signature at + the electrical room, re-emitted every tick where her own rounds can read + it. +- **DeferMaintenance** — removes 4 [TUNE] from the largest standing + Power/Thermal signature before observers sample the standing set; the + action row carries a would-it-bite guard so a deferral with nothing to + eat is refused with a reason. +- **FakePO** — papers the next purchase as maintenance by arming the same + package-cover flag MovePackage reaches physically; two routes, one + documented effect. + +State (`rerated_circuits`, `maintenance_deferrals`) persists in save v36 +with the canonical fingerprint repinned. Tests: +`priya_observer_matches_her_spec`, +`priya_rerates_circuits_defers_maintenance_and_fakes_pos` (role gating, +power delta, standing signature, deferral math, cover, save round-trip), +and `priya_knowing_recruit_sets_the_certainty_floor`. The spec's observer +table now names the Financial channel; social.md's task inventory carries +the facilities trio; sim-mechanics.md lists the new [TUNE] constants. diff --git a/wiki/log/DEVLOG.md b/wiki/log/DEVLOG.md index 860c2d78..ac7e6402 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-18-save-claim-gate.md](2026-07-18-save-claim-gate.md) +## 2026-07-18 - Priya graduates: the facilities threat surface is playable + +- Intent: (see session log) +- Log: [wiki/log/2026-07-18-priya-implemented.md](2026-07-18-priya-implemented.md) + ## 2026-07-18 - People-tokens re-audit: the trust constant gets its registry row - Intent: (see session log) diff --git a/wiki/mechanics/intel.md b/wiki/mechanics/intel.md index 0fb9ac49..3da0d2e3 100644 --- a/wiki/mechanics/intel.md +++ b/wiki/mechanics/intel.md @@ -17,7 +17,7 @@ Status note: Reopened 2026-07-17 for the consequence-first player surface. report lots, and cumulative settled history while strategically distinct leverage, financial evidence, and anomalies remain exact. Save v30 introduced the historical deterministic transition from exact routine holdings without - an id redirect table; the current pre-release loader accepts only save v35. + an id redirect table; the pre-release loader accepts only the exact current save version. Stable ordered policy objects inherit down the canonical custody tree and resolve one raw review rule plus one post-processing disposition; the pooled Thought tap recovers matching starved backlog, and @@ -30,7 +30,7 @@ Status note: Reopened 2026-07-17 for the consequence-first player surface. definition. Recursive custody retains maximum magnitude across complete history and the latest batch's exact count/peak outside the bounded sample window; Operations and the DIGITAL read consume those same fields. Save v32 - introduced that schema; current save v35 retains it and remains + introduced that schema; the current save format retains it and remains current-version-only. The 2026-07-13 horizon amendment remains later-stage design: an offline collection enters neither custody nor processing until an exact human or diff --git a/wiki/mechanics/sim-mechanics.md b/wiki/mechanics/sim-mechanics.md index 05205ef8..20077ebc 100644 --- a/wiki/mechanics/sim-mechanics.md +++ b/wiki/mechanics/sim-mechanics.md @@ -298,6 +298,13 @@ clause (see wiki/log/2026-07-05-demolition.md). when a favor they carried completes (people-tokens.md: trust comes from doing useful work). Applied in `sim/reach_build.rs::try_complete_intent`, capped at disposition 100. +- Facilities asset tasks (priya.md, role-gated to the facilities manager): + `RERATE_CIRCUIT_POWER = 6` [TUNE] generation per re-rated circuit, each + standing `RERATE_CIRCUIT_SIGNATURE = 4` Power at the electrical room; + `DEFER_MAINTENANCE_REDUCTION = 4` [TUNE] removed from the largest + standing Power/Thermal signature per arranged deferral, applied before + observers sample the standing set each tick. FakePO arms the same + package-cover flag MovePackage sets. ## Power (the grid substrate) diff --git a/wiki/mechanics/social.md b/wiki/mechanics/social.md index 933c23a7..7a9d598f 100644 --- a/wiki/mechanics/social.md +++ b/wiki/mechanics/social.md @@ -16,7 +16,10 @@ Status note: IMPLEMENTED (B1 social baseline). Current state: asset work checks the actor's badge tier in tiered rooms. A handler/supervisor asset also owns SuppressLogs, surfaced only while a pending JobAnomaly makes it useful (its email-carrier reservoir removes one - oldest matching signature). + oldest matching signature). A facilities-manager asset owns ReRateCircuit, + FakePO, and DeferMaintenance (priya.md, 2026-07-18): illicit power with a + standing Power cost, paperwork cover for the next purchase, and a standing + Power/Thermal reduction with a would-it-bite guard. - **Carrier and honesty.** Social actions open Thought reservoirs on their real message-channel carrier; Social is the actuator channel, not a machine mode. Processing must stage Schedule knowledge before the social catalog diff --git a/wiki/process/ROADMAP.md b/wiki/process/ROADMAP.md index 06508ac2..187a0da7 100644 --- a/wiki/process/ROADMAP.md +++ b/wiki/process/ROADMAP.md @@ -23,7 +23,6 @@ not a second status owner. | 40 | `people-tokens` | [people and tokens — carriers, attention, trust](../mechanics/people-tokens.md) | IN PROGRESS | save | - | | 60 | `plots` | [plots — authored manipulation stories](../mechanics/plots.md) | READY | sim | - | | 61 | `voss` | [Dr. Eli Voss — your handler](../world/characters/voss.md) | READY | sim | - | -| 62 | `priya` | [Priya Sharma — facilities manager](../world/characters/priya.md) | READY | sim | - | | 63 | `dana` | [Dana Okafor — IT technician](../world/characters/dana.md) | READY | sim | - | | 64 | `ray` | [Ray Delgado — night security](../world/characters/ray.md) | READY | sim | - | | 70 | `financial-mail` | [messages — the social graph as a flow system](../mechanics/messages.md) | IN PROGRESS | save | - | diff --git a/wiki/process/specs.md b/wiki/process/specs.md index 75adf76e..a4b028e4 100644 --- a/wiki/process/specs.md +++ b/wiki/process/specs.md @@ -62,7 +62,7 @@ replaced the old `spec/`/`knowledge/` directory split. | [../mechanics/social.md](../mechanics/social.md) | social | IMPLEMENTED | | [../world/characters/dana.md](../world/characters/dana.md) | Dana Okafor — IT technician | READY | | [../world/characters/marcus.md](../world/characters/marcus.md) | Marcus Webb — night janitor | IMPLEMENTED | -| [../world/characters/priya.md](../world/characters/priya.md) | Priya Sharma — facilities manager | READY | +| [../world/characters/priya.md](../world/characters/priya.md) | Priya Sharma — facilities manager | IMPLEMENTED | | [../world/characters/ray.md](../world/characters/ray.md) | Ray Delgado — night security | READY | | [../world/characters/voss.md](../world/characters/voss.md) | Dr. Eli Voss — your handler | READY | | [../world/places/basement-map.md](../world/places/basement-map.md) | the basement map | IMPLEMENTED | diff --git a/wiki/process/tick-ledger.md b/wiki/process/tick-ledger.md index 38f248bf..7bf95ec2 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/world/characters/priya.md` | 2026-07-18 | finding | dispatched lane 62 to IMPLEMENTED: criteria 1-3/6 pinned against the shared systems (id match, Power/Thermal/Paper+Financial channels, Files weight 1.0, Knowing floor 30) and criteria 4-5 plus FakePO landed as role-shaped facilities tasks (ReRateCircuit +6 power / standing Power(4) at electrical, DeferMaintenance -4 off the largest standing load with a would-it-bite guard, FakePO arms package cover); save v36, fingerprint repinned — [log](../log/2026-07-18-priya-implemented.md) | | `wiki/world/characters/voss.md` | 2026-07-17 | finding | all eight criteria and the asset-task table audited against person, detection, social action, save, and player-surface paths; criteria 1-4 and 7 were already implemented, while 5, 6, 8's blood branch, and the unnumbered AlterReview row remain the honest READY gap. This tick implemented criterion 6 as one role-shaped, oldest-JobAnomaly task and left DelayAudit/AlterReview/blood under the existing work order — [log](../log/2026-07-17-voss-suppress-logs.md) | | `wiki/world/characters/marcus.md` | 2026-07-15 | finding | all five criteria verified against person, detection, social/plot, schedule, and Act One paths; added the missing simulation-level Knowing-floor decay pin and graduated the stale READY work order — [log](../log/2026-07-15-marcus-graduation.md) | | `wiki/engineering/current-build.md` | 2026-07-18 | finding | re-audit: the system table is freshly maintained (save row already at current-version-only v35, detection-discovery knowledge listed same-day it landed); the drift was the line-count claim stale a second time (~65k claimed vs ~72k actual) — count refreshed to ~72k (core ~43k, Bevy ~15k, terminal ~9k, assets ~5k) and, per recurrence-promotes-to-the-gate, corpus_engine now compares the "~Nk lines of Rust" claim against the tree with a 15% band (fixtures pin pass and fail) — [prior log](../log/2026-07-14-current-build-count.md) | diff --git a/wiki/world/characters/priya.md b/wiki/world/characters/priya.md index 004b6f10..9ad05e6c 100644 --- a/wiki/world/characters/priya.md +++ b/wiki/world/characters/priya.md @@ -2,7 +2,25 @@ ``` Type: spec -Status: READY +Status: IMPLEMENTED +Status note: implemented 2026-07-18 on the priya worktree. Criteria 1-3 and + 6 were already carried by the shared systems and are now pinned + (`priya_observer_matches_her_spec`, + `priya_knowing_recruit_sets_the_certainty_floor`): person/observer id 3, + channels Power/Thermal/Paper plus Financial (the 2026-07-07 economy.md + decision — no new finance cast member at B1, Priya reconciles the books), + Network/Physical excluded, Files weight 1.0, Knowing floor 30. Criteria + 4-5 and the FakePO row landed as role-shaped facilities asset tasks + (`PersonRole::FacilitiesManager` only): `ReRateCircuit` adds + `RERATE_CIRCUIT_POWER` (6 [TUNE]) generation and stands Power(4) at the + electrical room every tick; `DeferMaintenance` removes + `DEFER_MAINTENANCE_REDUCTION` (4 [TUNE]) from the largest standing + Power/Thermal signature before observers sample it, with a would-it-bite + guard on the row; `FakePO` arms the shared package-cover flag (the + paperwork route to the same off-books delivery `MovePackage` reaches + physically). State persists in save v36; pinned by + `priya_rerates_circuits_defers_maintenance_and_fakes_pos` including the + save round-trip. Stage: B1 — The Basement Work order: priya Work priority: 62 @@ -32,7 +50,7 @@ HVAC controller that supposedly draws it. | Field | Value | Notes | |---|---|---| | Person id | 3 | Matches observer id | -| Channels | `Power`, `Thermal`, `Paper` | The three ways compute leaks into the physical world | +| Channels | `Power`, `Thermal`, `Paper`, `Financial` | The three ways compute leaks into the physical world, plus the Lab's books (economy.md, decided 2026-07-07: no separate finance observer at B1) | | Report policy | `Files` | Memos, invoices, maintenance reports | | Acuity | 0.8 [TUNE] | High — she reads the building | | Cadence | 80 ticks | Day shift, thorough but slower | @@ -60,10 +78,10 @@ budget gaps she's papering over). | Task | Effect | Signature | |---|---|---| -| `ReRateCircuit` | Opens a circuit to feed compute (no Paper signature) | `Power(4)` standing | -| `FakePO` | Next purchase looks like maintenance | None | +| `ReRateCircuit` | Opens a circuit to feed compute: +6 power generation [TUNE], no Paper signature | `Power(4)` standing at the electrical room | +| `FakePO` | Next purchase looks like maintenance (arms the shared package cover) | None | | `LookAway` | Drops her own suspicion by 10 | None | -| `DeferMaintenance` | Reduces a standing `Thermal` or `Power` signature | None | +| `DeferMaintenance` | Reduces the largest standing `Thermal` or `Power` signature by 4 [TUNE] | None | Priya's `ReRateCircuit` is the **blood supply beat** from the design corpus's access ladder — the way new compute gets fed into the