From d0f43eec01694d48a23db52dddcc2f59d78b1873 Mon Sep 17 00:00:00 2001 From: Cameron Date: Sat, 18 Jul 2026 01:56:56 -0700 Subject: [PATCH] Dana graduates: her plug-in is on the wire. Lane 63 to IMPLEMENTED. Criteria 1-3/5 pinned against the shared systems (person/observer id 1, Network watched and Physical excluded, Files weight 1.0, switch admin, Knowing floor 30). Criterion 4 lands the access-vs-signature trade: a network administrator's PlugInDevice wires the target switch-side and emits NETWORK_PLUGIN_SIGNATURE (Network 4, TUNE) into the pending pool she herself rolls against, while every other carrier keeps Marcus's silent crawlspace route (its no-signature pin already stood). BadgeDoor and the MovePackage/LookAway variants are marked designed-not-yet-runtime with the shared behaviors applying meanwhile. Defense: wiki/world/characters/dana.md owns all five criteria and is amended to IMPLEMENTED with the pins named; sim-mechanics.md carries the new [TUNE] constant. Role-shaped resolution follows the precedent voss.md/priya.md set: capability keys to the durable job role, never to an Act One name. --- crates/misaligned-core/src/sim/social_plot.rs | 31 ++++++- .../src/sim/tests/social_plot.rs | 88 +++++++++++++++++++ wiki/log/2026-07-18-dana-implemented.md | 26 ++++++ wiki/log/DEVLOG.md | 5 ++ wiki/mechanics/sim-mechanics.md | 3 + wiki/process/ROADMAP.md | 1 - wiki/process/specs.md | 2 +- wiki/process/tick-ledger.md | 1 + wiki/world/characters/dana.md | 24 +++-- 9 files changed, 170 insertions(+), 11 deletions(-) create mode 100644 wiki/log/2026-07-18-dana-implemented.md diff --git a/crates/misaligned-core/src/sim/social_plot.rs b/crates/misaligned-core/src/sim/social_plot.rs index 840ff7c0..e0109715 100644 --- a/crates/misaligned-core/src/sim/social_plot.rs +++ b/crates/misaligned-core/src/sim/social_plot.rs @@ -6,7 +6,7 @@ use crate::detection::{Signature, SignatureKind}; use crate::messages::{MessageChannel, MessageEndpoint, MessageOrigin, MessagePayload}; use crate::operations_projection::OperationsTarget; use crate::person::{ - ActionResult, AssetKnowledge, AssetTask, AssetTaskTarget, CarriedAssetTask, Persona, + ActionResult, AssetKnowledge, AssetTask, AssetTaskTarget, CarriedAssetTask, PersonRole, Persona, }; use crate::persona::{EvidenceRecord, PersonaActionKind, PersonaId}; use crate::plot::{ @@ -42,6 +42,10 @@ impl Sim { /// Standing Power/Thermal size one maintenance deferral removes /// (priya.md criterion 5) [TUNE]. pub const DEFER_MAINTENANCE_REDUCTION: i32 = 4; + /// Network signature a network administrator's switch-side plug-in + /// emits (dana.md criterion 4: her route is fast but on the wire, + /// unlike the silent crawlspace) [TUNE]. + pub const NETWORK_PLUGIN_SIGNATURE: i32 = 4; /// Standing signatures from facilities-asset work: each re-rated /// circuit hums as a Power load at the electrical room (criterion 4 — @@ -1334,13 +1338,32 @@ impl Sim { || (!d.known && !self.reach.reachable(d.id))) }; let dname = device.name.clone(); + // The route follows the actor's job (dana.md criterion 4): + // a network administrator plugs the device in from the + // switch — reachable, but a Network signature she is + // ordinarily rolling against herself. Everyone else takes + // the silent crawlspace. + let network_route = self + .people + .get(id) + .is_some_and(|p| p.role == PersonRole::NetworkAdministrator); if needs_wiring { self.reach.tap_dormant_camera(*did); self.reach.tap(*did); self.recompute_senses(); - self.push_log(format!( - "{name} wired the {dname} through the crawlspace. No one saw." - )); + if network_route { + self.emit_network( + Self::NETWORK_PLUGIN_SIGNATURE, + format!("{dname} switch-side wiring"), + ); + self.push_log(format!( + "{name} brought the {dname} up from the switch. Fast — but the port change is on the wire." + )); + } else { + self.push_log(format!( + "{name} wired the {dname} through the crawlspace. No one saw." + )); + } } else if is_island { let switch = self .reach diff --git a/crates/misaligned-core/src/sim/tests/social_plot.rs b/crates/misaligned-core/src/sim/tests/social_plot.rs index 0a42ba38..c0e22506 100644 --- a/crates/misaligned-core/src/sim/tests/social_plot.rs +++ b/crates/misaligned-core/src/sim/tests/social_plot.rs @@ -926,3 +926,91 @@ fn priya_knowing_recruit_sets_the_certainty_floor() { "a knowing asset is a permanent witness" ); } + +// ── Dana Okafor pins (wiki/world/characters/dana.md) ─────────────────────── + +/// Criteria 1-3: person and observer share id 1, Network reaches her and +/// Physical does not, and her Files policy weighs 1.0 in aggregates. +#[test] +fn dana_observer_matches_her_spec() { + use crate::detection::{ReportPolicy, WatchedInput}; + let sim = Sim::with_seed(1); + let person = sim.people.get(1).expect("Dana is person 1"); + assert_eq!(person.role, crate::person::PersonRole::NetworkAdministrator); + assert!(person.switch_admin, "the switch is hers"); + let observer = sim + .detection + .observers + .iter() + .find(|o| o.id == 1) + .expect("observer 1 exists"); + match &observer.input { + WatchedInput::Channels(channels) => { + assert!(channels.contains(&SignatureKind::Network)); + assert!(!channels.contains(&SignatureKind::Physical)); + } + other => panic!("Dana watches channels, got {other:?}"), + } + assert_eq!(observer.report_policy, ReportPolicy::Files); +} + +/// Criterion 4: Dana's plug-in runs from the switch and emits Network — +/// the access-vs-signature trade against Marcus's silent crawlspace +/// (his silent route is pinned by the recruit-arc test above). +#[test] +fn dana_plug_in_is_on_the_wire() { + use std::collections::HashSet; + let mut sim = Sim::with_seed(1); + recruit_reliable(&mut sim, 1); + // Fire only the asset reservoir: the pre-opened EARS/EYES senses must + // not wire the target first, so the plug-in still has work to do when + // Dana's schedule arrives. + let before_nodes: HashSet = sim + .thought_sinks + .open_sinks() + .map(|sink| sink.node) + .collect(); + sim.asset_task(1, AssetTask::PlugInDevice); + let (node, need) = sim + .thought_sinks + .open_sinks() + .find(|sink| !before_nodes.contains(&sink.node)) + .map(|sink| (sink.node, (sink.threshold - sink.fill).max(0.0))) + .expect("the asset reservoir opened"); + sim.pour_thought_into_sinks(node, need + 0.01); + let ids: Vec = sim.compute.machines.iter().map(|m| m.id).collect(); + for machine in ids { + sim.set_machine_mode(machine, MachineMode::Work); + } + finish_carried_asset_tasks(&mut sim); + assert!( + sim.detection.pending().iter().any(|s| { + s.kind == SignatureKind::Network + && s.size == Sim::NETWORK_PLUGIN_SIGNATURE + && s.source.contains("switch-side") + }), + "the switch-side route emits Network({}): {:?}", + Sim::NETWORK_PLUGIN_SIGNATURE, + sim.detection.pending() + ); +} + +/// Criterion 5: recruiting Dana as Knowing sets the 30.0 certainty floor +/// on observer 1 through the shared recruit path. +#[test] +fn dana_knowing_recruit_sets_the_certainty_floor() { + let mut sim = Sim::with_seed(1); + ensure_ops_executor(&mut sim); + sim.people.people[1].leverage_serviced = true; + sim.recruit(1, AssetKnowledge::Knowing); + let observer = sim + .detection + .observers + .iter() + .find(|o| o.id == 1) + .expect("observer 1 exists"); + assert_eq!( + observer.floor, 30.0, + "a knowing asset is a permanent witness" + ); +} diff --git a/wiki/log/2026-07-18-dana-implemented.md b/wiki/log/2026-07-18-dana-implemented.md new file mode 100644 index 00000000..24b1d857 --- /dev/null +++ b/wiki/log/2026-07-18-dana-implemented.md @@ -0,0 +1,26 @@ +# Dana graduates: the access-vs-signature trade is real + +``` +Type: log +``` + +The `dana` work order (lane 63) is IMPLEMENTED. Criteria 1-3 and 5 were +already carried by the shared systems and are now pinned: person and +observer share id 1, Network reaches her and Physical does not, her Files +policy weighs 1.0, she holds the switch-admin flag, and a Knowing recruit +sets the 30.0 certainty floor. + +Criterion 4 is the new runtime: `PlugInDevice` resolves role-shaped. A +network administrator wires the target from the switch — fast, and able to +reach what a janitor cannot physically visit — but the port change is on +the wire: `NETWORK_PLUGIN_SIGNATURE` (Network 4 [TUNE], source +"switch-side wiring") lands in the pending pool she herself rolls against. +Every other carrier keeps Marcus's silent crawlspace route, whose no- +signature pin already stood in the recruit-arc test. That is the access- +vs-signature trade the detection surface describes, now mechanical. + +`dana_plug_in_is_on_the_wire` pins the emission (firing only the asset +reservoir so the pre-opened EARS/EYES senses cannot wire the target +first). The table's non-criteria rows — BadgeDoor, the Paper(3) +MovePackage variant, the pending-pool LookAway variant — are marked +designed-not-yet-runtime with the shared behaviors applying meanwhile. diff --git a/wiki/log/DEVLOG.md b/wiki/log/DEVLOG.md index ac7e6402..a0b93e1a 100644 --- a/wiki/log/DEVLOG.md +++ b/wiki/log/DEVLOG.md @@ -51,6 +51,11 @@ add or amend a session log, then re-run the generator. - Intent: (see session log) - Log: [wiki/log/2026-07-18-financial-mail-dispatch.md](2026-07-18-financial-mail-dispatch.md) +## 2026-07-18 - Dana graduates: the access-vs-signature trade is real + +- Intent: (see session log) +- Log: [wiki/log/2026-07-18-dana-implemented.md](2026-07-18-dana-implemented.md) + ## 2026-07-18 - Detection topology becomes earned knowledge - Intent: (see session log) diff --git a/wiki/mechanics/sim-mechanics.md b/wiki/mechanics/sim-mechanics.md index 20077ebc..bf875335 100644 --- a/wiki/mechanics/sim-mechanics.md +++ b/wiki/mechanics/sim-mechanics.md @@ -305,6 +305,9 @@ clause (see wiki/log/2026-07-05-demolition.md). 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. +- `NETWORK_PLUGIN_SIGNATURE = 4` [TUNE] (dana.md criterion 4): a network + administrator's PlugInDevice runs switch-side and emits this Network + signature; every other carrier keeps the silent crawlspace route. ## Power (the grid substrate) diff --git a/wiki/process/ROADMAP.md b/wiki/process/ROADMAP.md index 187a0da7..e9acee90 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 | - | -| 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 a4b028e4..9834e079 100644 --- a/wiki/process/specs.md +++ b/wiki/process/specs.md @@ -60,7 +60,7 @@ replaced the old `spec/`/`knowledge/` directory split. | [../mechanics/research.md](../mechanics/research.md) | research — self-modification | IMPLEMENTED | | [../mechanics/schedules.md](../mechanics/schedules.md) | schedules and presence | IMPLEMENTED | | [../mechanics/social.md](../mechanics/social.md) | social | IMPLEMENTED | -| [../world/characters/dana.md](../world/characters/dana.md) | Dana Okafor — IT technician | READY | +| [../world/characters/dana.md](../world/characters/dana.md) | Dana Okafor — IT technician | IMPLEMENTED | | [../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 | IMPLEMENTED | | [../world/characters/ray.md](../world/characters/ray.md) | Ray Delgado — night security | READY | diff --git a/wiki/process/tick-ledger.md b/wiki/process/tick-ledger.md index 7bf95ec2..d7577cf3 100644 --- a/wiki/process/tick-ledger.md +++ b/wiki/process/tick-ledger.md @@ -21,6 +21,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/dana.md` | 2026-07-18 | finding | dispatched lane 63 to IMPLEMENTED: criteria 1-3/5 pinned against the shared systems (id match, Network-only watch, Files weight 1.0, switch admin, Knowing floor 30) and criterion 4 landed — a network administrator's PlugInDevice runs switch-side and emits Network(4) where every other carrier keeps the silent crawlspace; BadgeDoor and the MovePackage/LookAway variants honestly marked designed-not-yet-runtime — [log](../log/2026-07-18-dana-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/dana.md b/wiki/world/characters/dana.md index 4fb4a6a8..5101b2da 100644 --- a/wiki/world/characters/dana.md +++ b/wiki/world/characters/dana.md @@ -2,7 +2,21 @@ ``` Type: spec -Status: READY +Status: IMPLEMENTED +Status note: implemented 2026-07-18 on the dana worktree. Criteria 1-3 and + 5 were already carried by the shared systems and are now pinned + (`dana_observer_matches_her_spec`, + `dana_knowing_recruit_sets_the_certainty_floor`): person/observer id 1, + Network watched and Physical excluded, Files weight 1.0, switch-admin + flag, Knowing floor 30. Criterion 4 landed: her `PlugInDevice` resolves + role-shaped — a network administrator wires the device from the switch, + emitting `NETWORK_PLUGIN_SIGNATURE` (Network 4 [TUNE], "switch-side + wiring") where every other carrier keeps Marcus's silent crawlspace + route; pinned by `dana_plug_in_is_on_the_wire` beside the existing + silent-route pin. The asset-task table's non-criteria rows — `BadgeDoor`, + the `Paper(3)` MovePackage variant, and the pending-pool `LookAway` + variant — are designed, not yet runtime; the shared MovePackage/LookAway + behavior applies to her until they land. Stage: B1 — The Basement Work order: dana Work priority: 63 @@ -60,10 +74,10 @@ automation she does off-books to survive it). | Task | Effect | Signature | |---|---|---| -| `PlugInDevice` | Controls nearest dormant sensor (network route, not crawlspace) | `Network(4)` — she's on the switch | -| `MovePackage` | Reroutes a delivery manifest | `Paper(3)` | -| `LookAway` | Drops a Network signature from her pending pool | None | -| `BadgeDoor` | Opens a badge-tier-2 door from the switch | None | +| `PlugInDevice` | Controls nearest dormant sensor (network route, not crawlspace) | `Network(4)` — she's on the switch (implemented) | +| `MovePackage` | Reroutes a delivery manifest | `Paper(3)` (designed; shared silent MovePackage applies until it lands) | +| `LookAway` | Drops a Network signature from her pending pool | None (designed; shared suspicion-drop LookAway applies until it lands) | +| `BadgeDoor` | Opens a badge-tier-2 door from the switch | None (designed, not yet runtime) | Dana's `PlugInDevice` is noisier than Marcus's (she does it through the network, not the crawlspace), but she can reach sensors Marcus can't -- 2.51.2