mind-body: mind-control check, the brake gate a unit runs before it starts

Exit 0 only when the one derivation reads Released; every other reading
(absent, held, no dial, dial out of bounds, undecodable store) is an error
and exits 2, which systemd's ExecCondition reads as skip. A pure read through
FileSource: no writer, no created file or directory.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-10-12 07:33:20 +02:00
commit f1f36d5ff1
2 changed files with 128 additions and 2 deletions

View file

@ -7,8 +7,12 @@
//! mind-control --instance <slug> brake hold (also stops her running units)
//! mind-control --instance <slug> brake release
//! mind-control --instance <slug> dial set --heat H --base-cooldown-s S --base-run-usd U
//! mind-control [--root <dir>] --instance <slug> check
//! ```
//!
//! `check` exits 0 only when the brake is released and the dial in bounds; a
//! systemd unit runs it as its `ExecCondition`. It writes nothing.
//!
//! `brake hold` writes the brake held and then, whatever the write's outcome,
//! stops the instance's running units through the `stop_units` parameter. It
//! fails if either step failed. No other command stops anything.
@ -22,11 +26,11 @@ use chrono::{DateTime, Utc};
use eureka_pipeline::{RunTurn, Slug};
use rust_decimal::Decimal;
use crate::control::{BurnRate, ControlWriter, FileSource, control_path, derive, load_state};
use crate::control::{BurnRate, ControlWriter, Effective, FileSource, control_path, derive, load_state};
use crate::launch::unit;
const USAGE: &str =
"usage: mind-control [--root <dir>] --instance <slug> show | brake hold | brake release | dial set --heat H --base-cooldown-s S --base-run-usd U";
"usage: mind-control [--root <dir>] --instance <slug> show | check | brake hold | brake release | dial set --heat H --base-cooldown-s S --base-run-usd U";
/// Who made the change: `SUDO_USER`, else `USER`, else `unknown`. An empty
/// variable counts as unset.
@ -59,6 +63,7 @@ pub fn run(
let words: Vec<&str> = command.iter().map(String::as_str).collect();
match words.as_slice() {
["show"] => show(root, &instance, out),
["check"] => check(&path, &instance, out),
["brake", "hold"] => {
let written = ControlWriter::open(&path).and_then(|mut writer| writer.set_brake(false, now, set_by));
let stopped = stop_units(&instance);
@ -109,6 +114,20 @@ fn need<'a>(value: Option<&'a str>, name: &str) -> Result<&'a str> {
value.ok_or_else(|| anyhow!("{name} is required"))
}
/// The gate a unit runs before it starts: Ok only when the one derivation
/// (`derive`, the reader behind `read_effective`) says Released. It is a pure
/// read through `FileSource`: it opens no writer and creates no file or
/// directory. Any other reading is an error, which `main` turns into exit 2,
/// and systemd's `ExecCondition` skips the unit on 1-254.
fn check(path: &Path, instance: &Slug, out: &mut impl Write) -> Result<()> {
let effective = derive(&FileSource::new(path), instance);
writeln!(out, "effective: {effective:?}")?;
match effective {
Effective::Released(_) => Ok(()),
Effective::Held { reason } => bail!("held: {reason:?}"),
}
}
fn show(root: &Path, instance: &Slug, out: &mut impl Write) -> Result<()> {
let source = FileSource::new(control_path(root, instance)?);
writeln!(out, "instance: {}", instance.0)?;

View file

@ -128,6 +128,43 @@ fn the_binary_exits_nonzero_with_the_usage_when_refused() {
assert!(output.stdout.is_empty());
}
#[test]
fn the_binary_exits_2_for_check_while_held_and_0_after_release_with_a_dial() {
let root = tempfile::tempdir().unwrap();
let run = |args: &[&str]| {
std::process::Command::new(env!("CARGO_BIN_EXE_mind-control"))
.arg("--root")
.arg(root.path())
.args(["--instance", "eureka"])
.args(args)
.output()
.unwrap()
};
// Absent store: refused, and the gate wrote nothing.
let output = run(&["check"]);
assert_eq!(output.status.code(), Some(2));
assert!(String::from_utf8_lossy(&output.stderr).contains("held: BrakeAbsent"));
assert_eq!(std::fs::read_dir(root.path()).unwrap().count(), 0);
// Released with no dial is still refused; with a dial it opens.
assert!(run(&["brake", "release"]).status.success());
assert_eq!(run(&["check"]).status.code(), Some(2));
assert!(run(&["dial", "set", "--heat", "0.5", "--base-cooldown-s", "3600", "--base-run-usd", "5"]).status.success());
let open = run(&["check"]);
assert_eq!(open.status.code(), Some(0));
assert!(String::from_utf8_lossy(&open.stdout).contains("Released"));
// Holding closes it again. The brake is written through the library: the
// binary's `brake hold` would also ask systemd to stop units.
mind_body::control::ControlWriter::open(root.path().join("eureka").join("control.cc"))
.unwrap()
.set_brake(false, Utc.timestamp_opt(1_800_000_009, 0).unwrap(), "op")
.unwrap();
let closed = run(&["check"]);
assert_eq!(closed.status.code(), Some(2));
assert!(String::from_utf8_lossy(&closed.stderr).contains("held: BrakeHeld"));
}
#[test]
fn a_leading_root_flag_replaces_the_default_root() {
let default = tempfile::tempdir().unwrap();
@ -152,6 +189,76 @@ fn a_root_flag_without_a_directory_or_an_instance_is_refused_and_writes_nothing(
assert!(!std::path::Path::new("/nonexistent-root-for-test").exists());
}
fn check_out(root: &std::path::Path) -> (anyhow::Result<()>, String) {
go(root, &["--instance", "eureka", "check"], "op", 0)
}
#[test]
fn check_refuses_every_reading_but_released() {
let root = tempfile::tempdir().unwrap();
let held = |root: &std::path::Path, reason: &str| {
let (result, out) = check_out(root);
let error = format!("{:#}", result.unwrap_err());
assert!(error.contains(reason), "{reason}: {error}");
assert!(out.contains(reason), "{reason}: {out}");
};
held(root.path(), "BrakeAbsent");
go(root.path(), &["--instance", "eureka", "brake", "hold"], "op", 1).0.unwrap();
held(root.path(), "BrakeHeld");
go(root.path(), &["--instance", "eureka", "brake", "release"], "op", 2).0.unwrap();
held(root.path(), "DialAbsent");
go(root.path(), &["--instance", "eureka", "dial", "set", "--heat", "1000", "--base-cooldown-s", "3600", "--base-run-usd", "5"], "op", 3)
.0
.unwrap();
held(root.path(), "DialOutOfBounds");
// An undecodable store is a held reading too.
let broken = tempfile::tempdir().unwrap();
std::fs::create_dir(broken.path().join("eureka")).unwrap();
std::fs::write(broken.path().join("eureka").join("control.cc"), b"not a store").unwrap();
held(broken.path(), "Undecodable");
}
#[test]
fn check_opens_on_release_with_a_dial_and_is_per_instance() {
let root = tempfile::tempdir().unwrap();
go(root.path(), &["--instance", "eureka", "brake", "release"], "op", 0).0.unwrap();
go(root.path(), &["--instance", "eureka", "dial", "set", "--heat", "0.5", "--base-cooldown-s", "3600", "--base-run-usd", "5"], "op", 1)
.0
.unwrap();
let (result, out) = check_out(root.path());
result.unwrap();
assert!(out.contains("Released"), "{out}");
// Another instance's store is a different file: still absent, still refused.
let (other, _) = go(root.path(), &["--instance", "other", "check"], "op", 2);
assert!(format!("{:#}", other.unwrap_err()).contains("BrakeAbsent"));
}
#[test]
fn check_writes_nothing_and_creates_no_directory() {
let root = tempfile::tempdir().unwrap();
assert!(check_out(root.path()).0.is_err());
assert_eq!(std::fs::read_dir(root.path()).unwrap().count(), 0);
go(root.path(), &["--instance", "eureka", "brake", "release"], "op", 0).0.unwrap();
let file = root.path().join("eureka").join("control.cc");
let before = (std::fs::read(&file).unwrap(), std::fs::metadata(&file).unwrap().modified().unwrap());
let _ = check_out(root.path());
let _ = check_out(root.path());
assert_eq!((std::fs::read(&file).unwrap(), std::fs::metadata(&file).unwrap().modified().unwrap()), before);
assert_eq!(std::fs::read_dir(root.path().join("eureka")).unwrap().count(), 1);
}
#[test]
fn check_takes_no_extra_word_and_needs_an_instance() {
let root = tempfile::tempdir().unwrap();
go(root.path(), &["--instance", "eureka", "brake", "release"], "op", 0).0.unwrap();
for args in [&["--instance", "eureka", "check", "now"][..], &["--instance", "eureka", "check", "show"][..], &["check"][..]] {
let (result, out) = go(root.path(), args, "op", 1);
assert!(format!("{:#}", result.unwrap_err()).contains("usage: mind-control"), "{args:?}");
assert!(out.is_empty(), "{args:?}: {out}");
}
}
fn shown(root: &std::path::Path) -> String {
go(root, &["--instance", "eureka", "show"], "op", 0).1
}