From 0975caedbee3efe268bf79176fc7d9efbed2bcc2 Mon Sep 17 00:00:00 2001 From: Cameron Date: Tue, 7 Jul 2026 17:48:21 -0700 Subject: [PATCH] Day-job loop to IMPLEMENTED: device residency and attended work Audit and close wiki/mechanics/day-job.md criteria 1-7 (ROADMAP #3): - Signature gains an emission site; the day job's JobAnomaly emissions are stamped with the host rack's tile, and the running job stands Thermal/Power signatures there scaling with the delivered rate (1 Thermal per 8/t, 1 Power per 16/t [TUNE]). Stolen machines' standing Power signatures carry their own tile. - The active job is inspectable at the host rack as telemetry: process, band, delivered rate, deadline, attendance - the same facts the panel shows, listed ahead of the hardware details. - Attended work: Sim::set_attended(bool) is the command surface; both frontends and agent mode derive it from the cursor (attended iff the cursor is on the host rack; agent mode adds an `attend` verb that parks the cursor there). Attended: +15% delivered rate [TUNE] and `target` is per-job fine control. Unattended: the job reverts to the standing policy each tick and `target` sets that policy. - Agent frame 70x22 -> 70x54: at 22 rows the sidebar truncated before the CORE/DETECTION/DAY JOB sections rendered (agent-play criterion 5 was silently unmet); the spec sets 70x22 as the minimum. The padding rows now carry the sidebar column instead of blanking it. - Save v5 (attendance + signature sites, serde-defaulted; v1-v4 migrate). New tests: attention escalations (unit + the Compliance observer), a real standing-policy test (the old one was vacuous), attended bonus, policy reversion, emission sites, host-rack card, sim-level pilot shutdown, day-job save round-trip. day-job.md -> IMPLEMENTED (deferred, noted in Status: the pilot soft-loss survival scenario; per-machine processes are ROADMAP #25). agent-play.md, bevy.md, sim-mechanics.md updated; DEVLOG + session log added. Defense: constitution "Work is somewhere" - the job is a process resident on the host rack: inspectable there, emitting from there (thermal on Priya's channels, JobAnomaly where an observer can walk), attended by cursor presence with the standing policy as the unattended level. "Justification and legibility" - splitting the dial into attended fine control vs standing policy makes the automation dial a real mechanic instead of a label that always wrote both; the agent frame growth fixes a surface that claimed sections it never rendered. No manual-increment key (rejected in the decisions log); the compute channel model is untouched - the day-job channel remains the global source of delivered compute, and the ComputeQuota trust unlock is unmodified (economy.md owns its re-expression). --- src/bin/bevy.rs | 29 ++ src/bin/terminal/agent.rs | 64 +++- src/bin/terminal/mod.rs | 13 + src/bin/terminal/ui.rs | 20 ++ src/core_sys.rs | 3 + src/dayjob.rs | 139 +++++++- src/detection.rs | 8 + src/machine.rs | 4 +- src/save.rs | 9 +- src/sim.rs | 376 ++++++++++++++++++++- wiki/interface/agent-play.md | 17 +- wiki/interface/bevy.md | 5 +- wiki/log/2026-07-07-day-job-implemented.md | 91 +++++ wiki/log/DEVLOG.md | 23 ++ wiki/mechanics/day-job.md | 18 +- wiki/mechanics/sim-mechanics.md | 33 +- wiki/process/ROADMAP.md | 23 +- wiki/process/specs.md | 2 +- 18 files changed, 810 insertions(+), 67 deletions(-) create mode 100644 wiki/log/2026-07-07-day-job-implemented.md diff --git a/src/bin/bevy.rs b/src/bin/bevy.rs index 2b0539b..190c368 100644 --- a/src/bin/bevy.rs +++ b/src/bin/bevy.rs @@ -219,6 +219,12 @@ impl Game { self.cursor_x = x.clamp(0, self.sim.map.width - 1); self.cursor_y = y.clamp(0, self.sim.map.height - 1); } + /// Attendance follows the cursor (day-job.md criterion 7): the job + /// runs attended exactly while the cursor sits on the host rack. + fn sync_attendance(&mut self) { + let on_host = (self.cursor_x, self.cursor_y) == self.sim.core_position(); + self.sim.set_attended(on_host); + } fn add_log(&mut self, tick: u64, msg: &str) { self.log.push((tick, msg.to_string())); let n = self.log.len(); @@ -667,6 +673,8 @@ fn handle_input( if kb.just_pressed(KeyCode::KeyQ) { exit.write(AppExit::Success); } + // Cursor moves above may have landed on / left the host rack. + game.sync_attendance(); game.drain(); } @@ -838,6 +846,11 @@ fn advance_sim(time: Res