tests: restore the self_run ceiling and flush tests and the persona DM-room, flag and outcome tests on the usage-only surface; close the red tests; regenerate public_surface.txt; strip stale initiative and dial wording

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-10-31 05:58:44 +01:00
commit a6302f0dd9
8 changed files with 361 additions and 84 deletions

View file

@ -971,9 +971,10 @@ fn schema_prints_the_published_files() {
let names = run(&[], &["schema"], None);
assert_eq!(names.code, 0);
let names: Vec<&str> = names.out.lines().collect();
assert_eq!(names.len(), 15, "{names:?}");
assert_eq!(names.len(), 16, "{names:?}");
assert_eq!(names[0], "campaign");
assert_eq!(names[14], "selection");
assert_eq!(names[14], "pulse");
assert_eq!(names[15], "selection");
for kind in PipelineKind::ALL {
assert!(names.contains(&kind.name()), "{}", kind.name());
}

View file

@ -12,7 +12,7 @@ wrong or the mind cannot be reached.
## The heartbeat
`mind-heartbeat` is the one process that decides who wakes and when: acting burns initiative by spend, the classifier's urgency multiplies how fast it regains, and the operator tagging or naming a Persona fills it. `mind-heartbeat timeline` prints its latest record.
`mind-heartbeat` is the one process that decides who wakes and when: each beat falls when the Minds' voted tempo has passed and goes to the Mind that has waited longest, bent by the urgency she declares and a member addressing her; the operator tagging or naming a Persona launches her at once. `mind-heartbeat timeline` prints its latest record.
The actuator has its own ignored test, `the_real_bin_finds_her_run_...` in
`tests/self_run.rs`: the real `mind-self-run` against the real daemon with a

View file

@ -10,7 +10,7 @@
//! and (a later cut) topics she subscribed to. Two things launch a Persona off
//! the beat: the operator tagging or naming her, once per message, and her own
//! Self run having ended since her last turn. Nothing is metered here: no
//! dollars, no budget, no model call.
//! meter and no model call.
//!
//! The heartbeat owns `heartbeat.cc` and is its only writer; Persona units read
//! it. The brakes stay the operator's and are read on every poll. Busy and idle
@ -49,7 +49,7 @@ const PENDING_PAGES: usize = 16;
/// Who a Persona is, for the two things the heartbeat matches on: the Matrix
/// user id its tags carry, and the names a message may call it by. Each Mind is
/// its own Huginn daemon, so the entry also carries the daemon the Persona's
/// control, initiative and launches are read from.
/// control, runs and launches are read from.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PersonaId {
pub slug: Slug,
@ -203,7 +203,7 @@ pub trait TempoView {
/// The store as a CultCache single-file store under the unit's state directory.
/// It registers the state and the trace and nothing else: a file still holding
/// the dollar initiative documents does not decode, and every use of it fails
/// any older document does not decode, and every use of it fails
/// naming the file. It is never migrated.
pub struct FileStore {
path: PathBuf,

View file

@ -366,7 +366,8 @@ fn the_operator_naming_a_persona_launches_her_at_once_off_the_beat_and_once_per_
// Her turn fails without acking; the same message does not launch her again.
rig.end_run(BOB);
assert_eq!(rig.poll(), Outcome::Polled { launched: vec![] });
assert_eq!(rig.runs(BOB), 3);
assert_eq!(rig.runs(BOB), 2, "her old turn and the one launch, no second launch for the same message");
assert_eq!(rig.launched(), vec![Slug("bob".into())]);
// A tag in m.mentions counts as naming.
rig.say(ANN, delivery(2, "@op:chat", "please look", &["@ann:chat"]));
assert_eq!(rig.poll(), Outcome::Polled { launched: vec![Slug("ann".into())] });

View file

@ -945,3 +945,163 @@ fn a_usage_readout_that_cannot_be_had_is_said_and_the_turn_goes_on() {
assert_eq!((failure, answered), (None, 1), "usage is display only");
assert!(rig.connector.requests.borrow()[0].input.contains("Plan usage: unavailable."));
}
#[test]
fn the_turn_is_one_tool_less_call_constrained_to_the_reply_schema_with_her_rooms() {
let rig = Rig::new(vec![operator_says(1, "a")], &[says(&[])]);
rig.go();
let requests = rig.connector.requests.borrow();
assert_eq!(requests[0].caller, INSTANCE);
assert!(requests[0].instructions.contains("You are Eureka."));
let schema: serde_json::Value = serde_json::from_str(&requests[0].output_schema_json).unwrap();
assert_eq!(schema["properties"]["say"]["items"]["properties"]["room"]["enum"], json!(["swarm", "usage", "operator"]));
}
#[test]
fn a_members_dm_is_answered_in_its_room_and_no_other_unconfigured_room_is() {
let dm = "!abc:chat";
let rig = Rig::new(vec![direct(1, dm, "@m:chat", "hello, are you there")], &[says(&[(dm, "yes")])]);
let Outcome::Served { failure, answered, .. } = rig.go() else { panic!("served") };
assert_eq!((failure, answered), (None, 1));
assert_eq!(rig.chat.sent.borrow()[0].room_alias, dm);
let request = &rig.connector.requests.borrow()[0];
let schema: serde_json::Value = serde_json::from_str(&request.output_schema_json).unwrap();
assert_eq!(schema["properties"]["say"]["items"]["properties"]["room"]["enum"], json!(["swarm", "usage", "operator", dm]));
assert!(request.input.contains(dm), "the DM's room is among the rooms she is told she may speak in");
let rig = Rig::new(vec![direct(1, dm, "@m:chat", "hello")], &[says(&[("!other:chat", "psst")])]);
let Outcome::Served { failure, .. } = rig.go() else { panic!("served") };
assert_eq!(failure, Some(Failure::RoomNotAllowed));
assert!(rig.chat.sent.borrow().is_empty() && rig.chat.acked.borrow().is_empty());
let rig = Rig::new(vec![delivery(1, "!notdm:chat", "@m:chat", "hello")], &[says(&[("!notdm:chat", "psst")])]);
let Outcome::Served { failure, .. } = rig.go() else { panic!("served") };
assert_eq!(failure, Some(Failure::RoomNotAllowed), "a room that is not a DM is hers only when configured");
}
#[test]
fn deliveries_from_different_dm_rooms_are_never_in_one_turn() {
let (a, b) = ("!a:chat", "!b:chat");
let pending = vec![
direct(1, a, "@ann:chat", "secret-a"),
direct(2, b, "@bob:chat", "hi-b"),
delivery(3, "swarm", "@m:chat", "public-c"),
direct(4, a, "@ann:chat", "more-a"),
direct(5, a, "@ann:chat", "again-a"),
];
let replies = [says(&[(a, "1")]), says(&[(b, "2")]), says(&[("swarm", "3")]), says(&[(a, "4")])];
let rig = Rig::new(pending, &replies);
let Outcome::Served { failure, answered, .. } = rig.go() else { panic!("served") };
assert_eq!((failure, answered), (None, 4));
let inputs: Vec<String> = rig.connector.requests.borrow().iter().map(|request| request.input.clone()).collect();
let texts = ["secret-a", "hi-b", "public-c", "more-a"];
for (turn, input) in inputs.iter().enumerate() {
for (other, text) in texts.iter().enumerate() {
assert_eq!(input.contains(text), turn == other, "turn {turn} text {text}");
}
}
assert!(inputs[3].contains("again-a"), "one room's consecutive deliveries share its turn");
assert!(!inputs[0].contains("again-a"), "a later delivery waits for its turn");
assert_eq!(*rig.chat.acked.borrow(), vec![1, 2, 3, 5]);
}
#[test]
fn outcomes_and_failures_read_as_one_line_each_without_values() {
assert_eq!(Outcome::Dead(HeldReason::BrakeHeld).to_string(), "dead: BrakeHeld");
let served = Outcome::Served { run: run_ref("r1"), answered: 2, failure: Some(Failure::Send), self_run: Some(run_ref("s1")) };
let line = served.to_string();
assert!(line.contains("r1") && line.contains("answered 2") && line.contains("a send was refused or failed") && line.contains("self run") && line.contains("s1"), "{line}");
assert_eq!(Failure::Held(HeldReason::BrakeAbsent).to_string(), "held: BrakeAbsent");
let all = [
Failure::Chat,
Failure::Persona,
Failure::Doctrine,
Failure::DoctrineTooLarge,
Failure::Connector,
Failure::Undecodable,
Failure::RoomNotAllowed,
Failure::Send,
Failure::SelfRun,
Failure::Pulse,
Failure::Ack,
];
for failure in all {
assert!(!failure.to_string().is_empty());
}
let texts: std::collections::BTreeSet<_> = all.map(|failure| failure.to_string()).into();
assert_eq!(texts.len(), all.len(), "each failure reads differently");
}
#[test]
fn a_turn_is_named_by_its_run_and_its_number() {
let rig = Rig::new(vec![operator_says(1, "a")], &(0..4).map(|_| says(&[("swarm", "x")])).collect::<Vec<_>>());
rig.mind.committed(vec![run("woken", RunTurn::PersonaTurn, RunOperator::Mind, &[])]);
rig.clock.0.set(600_000);
let (deliveries, next) = (rig.chat.deliveries.clone(), Cell::new(1));
*rig.connector.during.borrow_mut() = Some(Box::new(move || {
next.set(next.get() + 1);
if next.get() < 3 {
deliveries.borrow_mut().push(operator_says(next.get(), "more"));
}
}));
let Outcome::Served { run: carried, answered, .. } = rig.start_with(&config()) else { panic!("served") };
assert_eq!((carried, answered), (run_ref("woken"), 2));
let ids: Vec<_> = rig.connector.requests.borrow().iter().map(|request| request.request_id.clone()).collect();
assert_eq!(ids, ["woken-t0", "woken-t1"]);
let trace = rig.trace.0.borrow();
assert_eq!(trace.iter().map(|record| (record.run.as_str(), record.turn)).collect::<Vec<_>>(), [("woken", 0), ("woken", 1)]);
}
#[test]
fn the_persona_flags_are_taken_out_and_the_rest_is_left_for_the_shared_parser() {
let args = |text: &str| text.split_whitespace().map(String::from).collect::<Vec<_>>();
let (parsed, rest) = Config::from_args(
&args("--instance eureka --rooms swarm,usage,operator --operator @op:chat,@op2:chat --self-sender @eureka:chat --endpoint rudp://10.0.0.1:1"),
"usage",
)
.unwrap();
assert_eq!(parsed.rooms, ["swarm", "usage", "operator"]);
assert_eq!((parsed.own_sender.as_str(), parsed.max_turns), ("@eureka:chat", MAX_TURNS_PER_START));
assert_eq!(parsed.operators, ["@op:chat", "@op2:chat"]);
assert_eq!(rest, args("--instance eureka --endpoint rudp://10.0.0.1:1"));
let (two, _) = Config::from_args(&args("--rooms a --operator o --self-sender s --max-turns 2"), "usage").unwrap();
assert_eq!(two.max_turns, 2);
for bad in [
"--rooms a --operator o",
"--rooms a,,b --operator o --self-sender s",
"--rooms a --rooms a --operator o --self-sender s",
"--rooms a --operator o --self-sender s --max-turns 0",
"--rooms a --operator o --self-sender s --max-turns x",
"--rooms a --operator o --self-sender",
] {
assert!(Config::from_args(&args(bad), "usage").is_err(), "{bad}");
}
}
#[test]
fn the_persona_flags_come_from_the_environment_when_the_command_line_lacks_them() {
let env = |name: &str| {
Some(
match name {
ENV_ROOMS => "swarm,usage",
ENV_OPERATOR => "@op:chat,@op2:chat",
ENV_SELF_SENDER => "@eureka:chat",
_ => "",
}
.to_string(),
)
};
let args = |text: &str| text.split_whitespace().map(String::from).collect::<Vec<_>>();
let (config, rest) = Config::from_args_and_env(&args("--instance eureka"), env, "usage").unwrap();
assert_eq!(
config,
Config { rooms: vec!["swarm".into(), "usage".into()], operators: vec!["@op:chat".into(), "@op2:chat".into()], own_sender: "@eureka:chat".into(), max_turns: MAX_TURNS_PER_START, doctrine: vec![] }
);
assert_eq!(rest, ["--instance", "eureka"]);
// A flag wins over its variable, one at a time.
let (flagged, _) = Config::from_args_and_env(&args("--instance eureka --rooms swarm"), env, "usage").unwrap();
assert_eq!((flagged.rooms.len(), flagged.operators.len()), (1, 2));
// An empty variable is unset, and a missing setting is the usage error.
assert!(Config::from_args_and_env(&args("--instance eureka"), |name| if name == ENV_ROOMS { Some(String::new()) } else { env(name) }, "usage").is_err());
assert!(Config::from_args_and_env(&args("--instance eureka"), |_| None, "usage").is_err());
}

View file

@ -470,6 +470,41 @@ fn a_mind_that_cannot_be_read_or_a_child_that_cannot_start_is_an_error_not_an_ou
// ---- what is started ------------------------------------------------------
#[test]
fn claude_args_is_exactly_the_fixed_list_for_a_session() {
let session = Uuid::parse_str(SESSION_OF_RUN_A).unwrap();
let args = claude_args(session);
assert_eq!(
args,
[
"-p",
"--input-format",
"stream-json",
"--output-format",
"stream-json",
"--verbose",
"--session-id",
SESSION_OF_RUN_A,
"--max-turns",
"500",
"--permission-mode",
"bypassPermissions",
"--permission-prompts",
"none",
"--setting-sources",
"user",
]
);
// Those belong to the run measure or to the unit's managed settings.
for forbidden in ["--resume", "--continue", "--fork-session", "--model", "--dangerously-skip-permissions", "--settings", "--system-prompt", "--max-budget"] {
assert!(!args.iter().any(|arg| arg.starts_with(forbidden) || arg.contains("dangerously")), "{forbidden}");
}
// Print mode starts in Manual without a mode, and prompts none then denies.
let mode = args.iter().position(|arg| arg == "--permission-mode").expect("mode flag");
assert_eq!(args[mode + 1], "bypassPermissions");
assert_eq!(MAX_TURNS, 500);
}
#[test]
fn the_session_id_is_uuid_v5_of_the_run_id_and_differs_per_run() {
assert_eq!(session_id(&foreign_run("eureka:run:mind-20261022T120000000Z")).to_string(), SESSION_OF_MIND_RUN);
@ -477,6 +512,18 @@ fn the_session_id_is_uuid_v5_of_the_run_id_and_differs_per_run() {
assert_eq!(session_id(&run_ref("selfrun-b")).to_string(), SESSION_OF_RUN_B);
}
#[test]
fn the_child_is_started_for_her_run_with_the_fixed_list_whatever_the_run_record_says() {
// The run's budget field is a dead record; nothing in what is started depends on it.
for budget in ["0", "0.5", "10", "100"] {
let mind = TestMind::seeded();
mind.committed(vec![self_run("selfrun-b", budget)]);
let ran = carry_with(&Seen::of(&mind), vec![Out(result_line())], Some(0), false);
assert_eq!(ran.spawns.len(), 1, "{budget}");
assert_eq!(ran.spawns[0], claude_args(Uuid::parse_str(SESSION_OF_RUN_B).unwrap()), "{budget}");
}
}
#[test]
fn the_start_message_is_the_first_thing_written_and_names_the_skill_the_instance_and_the_run() {
let ran = go(vec![Out(result_line())]);
@ -647,6 +694,27 @@ fn read_usage_classifies_the_owners_real_records() {
}
}
#[test]
fn records_that_share_a_message_id_count_once_and_subagent_records_never_move_the_prefix() {
let mut steps: Vec<Step> = RECORDS.lines().map(|line| Out(line.to_string())).collect();
steps.insert(3, Out(subagent("msg_sub", 999_999)));
let ran = go(steps);
assert_eq!(
ran.out,
"request 1 prefix 84210
request 2 prefix 100751
request 3 prefix 117174
request 4 prefix 118336
request 5 prefix 126746
request 6 prefix 127250
request 7 prefix 129853
"
);
let (cause, _, requests, prefix) = ran.ended();
assert_eq!((cause, requests, prefix), (Cause::Own, 7, 129_853), "the newest prefix, 129853, not a subagent's 999999");
assert_eq!(flushes(&ran), 0);
}
#[test]
fn the_prefix_is_the_newest_requests_not_the_largest() {
let ran = go(vec![Out(at("m1", 200_000)), Out(at("m2", 150_000))]);
@ -744,6 +812,41 @@ fn the_headroom_counts_the_requests_after_the_first_result_that_follows_the_flus
assert_eq!(same_turn.count(&Event::Stopped(Stop::Interrupt)), 0);
}
#[test]
fn a_jump_past_the_ceiling_plus_the_headroom_writes_the_flush_and_the_running_turn_cannot_use_up_the_flushs_turn() {
let jump = carry_with(
&Seen::of(&with_run()),
vec![Out(at("m1", 290_000)), Out(at("m2", 400_000)), Out(at("m3", 470_000)), Out(result_line()), Out(at("m4", 459_999)), Out(at("m5", 460_000)), Out(at("m6", 470_000))],
Some(130),
true,
);
let kinds: Vec<&str> = jump
.events
.iter()
.filter_map(|event| match event {
Event::Wrote(line) if line.contains("context ceiling") => Some("flush"),
Event::Stopped(_) => Some("interrupt"),
Event::InputClosed => Some("closed"),
Event::Asked(_) => Some("read"),
_ => None,
})
.collect();
// Reads: m1, m2 (the jump, which writes the flush), m3 (the running turn's 470k, past the headroom: no interrupt).
assert_eq!(kinds[..5], ["read", "read", "flush", "read", "read"], "{kinds:?}");
// The headroom is measured from the prefix the flush was asked at (400k) and counts the requests after the
// first result only: 459_999 does not interrupt; 460_000 does, once, and m6 is never read.
assert_eq!(jump.count(&Event::Stopped(Stop::Interrupt)), 1, "{kinds:?}");
assert_eq!(jump.out, "request 1 prefix 290000
request 2 prefix 400000
request 3 prefix 470000
result subtype=success is_error=true: Failed to authenticate: OAuth session expired and could not be refreshed
request 4 prefix 459999
request 5 prefix 460000
");
assert_eq!(jump.ended().0, Cause::Signalled(Stop::Interrupt));
assert_eq!(flushes(&jump), 1);
}
#[test]
fn a_child_that_ends_before_the_grace_is_never_interrupted() {
let ran = go(vec![Out(at("m1", CEILING_TOKENS)), Out(result_line())]);
@ -938,6 +1041,27 @@ fn the_outcome_names_how_it_ended_and_the_exit_status_follows_the_childs_code()
// ---- the real child -----------------------------------------------------------
#[test]
fn unreadable_and_foreign_lines_are_skipped_and_never_printed() {
let canary = "canary-stream-line-8c41";
let mut foreign: Value = serde_json::from_str(&init_line()).unwrap();
foreign["cwd"] = json!(canary);
foreign["type"] = json!(canary);
let ran = go(vec![
Out(format!("not json {canary}")),
Out(foreign.to_string()),
Out(format!("[\"{canary}\"]")),
Out(at("m1", 10)),
Out(result_line()),
]);
assert_eq!(ran.out, "request 1 prefix 10
result subtype=success is_error=true: Failed to authenticate: OAuth session expired and could not be refreshed
");
let outcome = ran.outcome.as_ref().unwrap().to_string();
assert!(!ran.out.contains(canary) && !outcome.contains(canary));
assert!(!ran.written().iter().any(|text| text.contains(canary)), "nothing from the stream is written back");
}
#[cfg(unix)]
mod process {
mod lease_child;
@ -1107,6 +1231,34 @@ mod process {
}
}
#[test]
fn a_whole_run_through_the_real_child_flushes_at_the_ceiling_and_ends_on_the_result() {
let dir = tempfile::tempdir().unwrap();
let lines = [at("m1", 10), at("m2", CEILING_TOKENS)].join("
");
let result = result_line();
// Prints two requests, waits for the flush on stdin, then the result, as a stand-in for a Self that obeys.
let body = format!("cat <<'EOF'
{lines}
EOF
read -t 5 start
read -t 5 flush
cat <<'EOF'
{result}
EOF
while read more; do :; done
exit 0");
let program = script(&dir, &body);
let mind = with_run();
let mut out = Vec::new();
let outcome = carry(&Seen::of(&mind), &SystemClock, &FakeLender::new(Answer::Grant), &Spawn(program), TEST_CAP_S, &mut out).unwrap();
assert_eq!(outcome, SelfRunOutcome::Ended { cause: Cause::FlushRequested, code: Some(0), requests: 2, prefix: 300_000 });
assert_eq!(String::from_utf8(out).unwrap(), "request 1 prefix 10
request 2 prefix 300000
result subtype=success is_error=true: Failed to authenticate: OAuth session expired and could not be refreshed
");
}
#[test]
fn a_failure_result_before_any_request_closes_stdin_and_ends_the_run_promptly_through_the_real_child() {
let dir = tempfile::tempdir().unwrap();

View file

@ -69,7 +69,6 @@ fn malformed_commands_are_refused_and_write_nothing() {
&["--instance", "eureka"],
&["--instance", "eureka", "brake"],
&["--instance", "eureka", "brake", "toggle"],
&["--instance", "eureka", "dial", "set", "--heat", "1"],
&["--instance", "../evil", "brake", "release"],
&["--instances", "eureka", "brake", "release"],
&["eureka", "eureka", "brake", "release"],
@ -187,9 +186,10 @@ fn check_refuses_every_reading_but_released() {
held(root.path(), "BrakeHeld");
go(root.path(), &["--instance", "eureka", "brake", "release"], "op", 2).0.unwrap();
held(root.path(), "BrakeAbsent");
go(root.path(), &["swarm", "brake", "release"], "op", 3).0.unwrap();
held(root.path(), "DialAbsent");
// DialOutOfBounds cannot be written through the CLI: it is pinned in the crate's own tests.
go(root.path(), &["swarm", "brake", "hold"], "op", 3).0.unwrap();
held(root.path(), "BrakeHeld");
go(root.path(), &["swarm", "brake", "release"], "op", 4).0.unwrap();
check_out(root.path()).0.unwrap();
// An undecodable store is a held reading too.
let broken = tempfile::tempdir().unwrap();
std::fs::create_dir(broken.path().join("eureka")).unwrap();
@ -215,7 +215,7 @@ fn check_holds_for_the_named_instance_with_a_released_prefix_neighbour() {
let root = tempfile::tempdir().unwrap();
go(root.path(), &["--instance", "eureka", "brake", "hold"], "op", 0).0.unwrap();
go(root.path(), &["swarm", "brake", "release"], "op", 0).0.unwrap();
// Neighbours that share the held instance's text as a prefix, or only an edge of it, are released with a dial.
// Neighbours that share the held instance's text as a prefix, or only an edge of it, are released.
for (i, neighbour) in ["eureka-two", "eureka2", "xeureka"].into_iter().enumerate() {
let at = 1 + 2 * i as i64;
go(root.path(), &["--instance", neighbour, "brake", "release"], "op", at).0.unwrap();
@ -281,7 +281,6 @@ fn only_brake_hold_calls_the_stopper() {
&["--instance", "eureka", "show"],
&["--instance", "eureka", "brake"],
&["--instance", "eureka", "brake", "toggle"],
&["swarm", "dial", "set", "--heat", "99", "--base-rate", "4", "--base-run", "1", "--k", "2"],
&["--instance", "../evil", "brake", "release"],
&["--instance", "eureka", "brake", "hold", "now"],
&[],
@ -470,14 +469,6 @@ fn swarm_commands_refuse_bad_input_and_write_nothing() {
let root = tempfile::tempdir().unwrap();
for args in [
&["swarm"][..],
&["swarm", "dial", "set", "--heat", "1"],
&["swarm", "dial", "set", "--heat", "3", "--base-rate", "4", "--base-run", "2", "--k", "3"],
&["swarm", "dial", "set", "--heat", "1", "--base-rate", "4", "--base-run", "2", "--k", "0"],
&["swarm", "dial", "set", "--heat", "1", "--heat", "1", "--base-rate", "4", "--base-run", "2", "--k", "3"],
&["swarm", "share", "set", "weksa", "0"],
&["swarm", "share", "set", "weksa", "heavy"],
&["swarm", "share", "set", "Not A Slug", "1"],
&["swarm", "share", "set", "weksa"],
&["swarm", "brake", "release", "now"],
] {
assert!(go(root.path(), args, "op", 0).0.is_err(), "{args:?} was accepted");

View file

@ -9,6 +9,7 @@ mind_body: mod lease_client
mind_body: mod persona
mind_body: mod queue
mind_body: mod self_run
mind_body: mod tempo
mind_body::chat_client: # [derive (Clone , Copy , Debug , PartialEq , Eq)] pub enum Refusal { Brake , PersonaMismatch , UnknownRoom , EmptyText , SendFailed , UnknownPersona , }
mind_body::chat_client: const ACK : & str
mind_body::chat_client: const PENDING : & str
@ -43,22 +44,18 @@ mind_body::cli: fn run (args : & [String] , root : & Path , set_by : & str , now
mind_body::connector: const MAX_OUTPUT_TOKENS : u32
mind_body::connector: fn endpoint (text : & str) -> Result < SocketAddr >
mind_body::connector: fn key (key_file_text : & str) -> String
mind_body::connector: fn render_plan (windows : & [PlanQuota] , now_ms : u64) -> String
mind_body::connector: impl Connector for KitConnector
mind_body::connector: impl KitConnector
mind_body::connector: impl KitConnector: fn new (endpoint : SocketAddr , key_text : & str , model : impl Into < String > , caller : impl Into < String >) -> Result < Self >
mind_body::connector: struct KitConnector pub-fields[]
mind_body::control: # [derive (Clone , Copy , Debug , PartialEq , Eq)] pub enum HeldReason { BrakeAbsent , BrakeHeld , DialAbsent , DialOutOfBounds , HeatZero , ShareOutOfBounds , Undecodable , }
mind_body::control: # [derive (Clone , Copy , Debug , PartialEq , Eq)] pub enum HeldReason { BrakeAbsent , BrakeHeld , Undecodable , }
mind_body::control: # [derive (Debug , PartialEq , Eq)] pub enum Effective { Held { reason : HeldReason } , Released (Grant) , }
mind_body::control: # [derive (Debug , PartialEq , Eq)] pub enum SwarmEffective { Held (HeldReason) , Released (Envelope) , }
mind_body::control: # [derive (Debug , PartialEq , Eq)] pub enum SwarmEffective { Held (HeldReason) , Released , }
mind_body::control: const BRAKE_KEY : & str
mind_body::control: const CONTROL_ROOT : & str
mind_body::control: const DIAL_KEY : & str
mind_body::control: const K_MAX : u32
mind_body::control: const SWARM_FILE : & str
mind_body::control: fn base_rate_max () -> Decimal
mind_body::control: fn base_run_max () -> Decimal
mind_body::control: fn control_path (root : & Path , instance : & Slug) -> Result < PathBuf >
mind_body::control: fn heat_max () -> Decimal
mind_body::control: fn load_state (source : & impl ControlSource) -> Result < ControlState >
mind_body::control: fn load_swarm_state (source : & impl ControlSource) -> Result < SwarmState >
mind_body::control: fn read_effective (instance : & Slug) -> Effective
@ -69,81 +66,54 @@ mind_body::control: impl ControlState
mind_body::control: impl ControlWriter
mind_body::control: impl ControlWriter: fn open (path : impl Into < PathBuf >) -> Result < Self >
mind_body::control: impl ControlWriter: fn set_brake (& mut self , released : bool , set_at : DateTime < Utc > , set_by : & str) -> Result < () >
mind_body::control: impl Envelope
mind_body::control: impl Envelope: fn grant_for (& self , instance : & Slug , instance_effective : & Effective , budget_usd : Decimal) -> Option < Grant >
mind_body::control: impl Envelope: fn k (& self) -> u32
mind_body::control: impl Envelope: fn rate_usd_per_h (& self) -> Decimal
mind_body::control: impl Envelope: fn run_cap_usd (& self) -> Decimal
mind_body::control: impl Envelope: fn share (& self , instance : & Slug) -> Decimal
mind_body::control: impl FileSource
mind_body::control: impl FileSource: fn new (path : impl Into < PathBuf >) -> Self
mind_body::control: impl Grant
mind_body::control: impl Grant: fn instance (& self) -> & Slug
mind_body::control: impl Grant: fn run_cap_usd (& self) -> Decimal
mind_body::control: impl Share
mind_body::control: impl Share: fn in_bounds (& self) -> bool
mind_body::control: impl SwarmDial
mind_body::control: impl SwarmDial: fn in_bounds (& self) -> bool
mind_body::control: impl SwarmState
mind_body::control: impl SwarmWriter
mind_body::control: impl SwarmWriter: fn open (path : impl Into < PathBuf >) -> Result < Self >
mind_body::control: impl SwarmWriter: fn set_brake (& mut self , released : bool , set_at : DateTime < Utc > , set_by : & str) -> Result < () >
mind_body::control: impl SwarmWriter: fn set_dial (& mut self , dial : SwarmDial) -> Result < () >
mind_body::control: impl SwarmWriter: fn set_share (& mut self , share : Share) -> Result < () >
mind_body::control: impl std :: error :: Error for UnsafeStore
mind_body::control: impl std :: fmt :: Display for UnsafeStore
mind_body::control: pub trait ControlSource { fn snapshot (& self) -> Result < Vec < CultCacheEnvelope > > ; }
mind_body::control: struct Brake # [derive (Clone , Debug , PartialEq , Eq , DatabaseEntry)] pub-fields[released: bool, set_at: DateTime < Utc >, set_by: String]
mind_body::control: struct ControlState # [derive (Clone , Debug , PartialEq , Eq , Default)] pub-fields[brake: Option < Brake >]
mind_body::control: struct ControlWriter pub-fields[]
mind_body::control: struct Envelope # [derive (Debug , PartialEq , Eq)] pub-fields[]
mind_body::control: struct FileSource pub-fields[]
mind_body::control: struct Grant # [derive (Debug , PartialEq , Eq)] pub-fields[]
mind_body::control: struct Share # [derive (Clone , Debug , PartialEq , Eq , DatabaseEntry)] pub-fields[instance: String, weight: Decimal]
mind_body::control: struct SwarmDial # [derive (Clone , Debug , PartialEq , Eq , DatabaseEntry)] pub-fields[heat: Decimal, base_rate_usd_per_h: Decimal, base_run_usd: Decimal, k: u32, set_at: DateTime < Utc >, set_by: String]
mind_body::control: struct SwarmState # [derive (Clone , Debug , PartialEq , Eq , Default)] pub-fields[brake: Option < Brake >, dial: Option < SwarmDial >, shares: Vec < Share >]
mind_body::control: struct SwarmState # [derive (Clone , Debug , PartialEq , Eq , Default)] pub-fields[brake: Option < Brake >]
mind_body::control: struct SwarmWriter pub-fields[]
mind_body::control: struct UnsafeStore # [derive (Debug)] pub-fields[path: PathBuf, mode: u32, uid: u32]
mind_body::heartbeat: # [derive (Clone , Debug , PartialEq , Eq)] pub enum Outcome { Held (HeldReason) , Polled { launched : Vec < Slug > , } , }
mind_body::heartbeat: const AGENT : & str
mind_body::heartbeat: const CLASSIFIER_CALLER : & str
mind_body::heartbeat: fn poll (organs : & Organs , config : & Config) -> Result < Outcome >
mind_body::heartbeat: fn store_classifier_config (path : impl Into < PathBuf > , config : & ClassifierConfig) -> Result < () >
mind_body::heartbeat: impl ClassifierConfig
mind_body::heartbeat: impl ClassifierConfig: fn standard () -> Self
mind_body::heartbeat: impl ClassifierConfig: fn validate (& self) -> Result < () >
mind_body::heartbeat: impl Config
mind_body::heartbeat: impl Config: fn new (personas : Vec < PersonaId > , operators : Vec < String >) -> Result < Self >
mind_body::heartbeat: impl Control for FileControl
mind_body::heartbeat: impl FileStore
mind_body::heartbeat: impl FileStore: fn check (& self) -> Result < () >
mind_body::heartbeat: impl FileStore: fn new (path : impl Into < PathBuf >) -> Self
mind_body::heartbeat: impl FileTunables
mind_body::heartbeat: impl FileTunables: fn new (path : impl Into < PathBuf >) -> Self
mind_body::heartbeat: impl Initiative
mind_body::heartbeat: impl Models for KitConnector
mind_body::heartbeat: impl MindRead
mind_body::heartbeat: impl PersonaId
mind_body::heartbeat: impl PersonaId: fn parse (spec : & str) -> Result < Self >
mind_body::heartbeat: impl Row < '_ >
mind_body::heartbeat: impl Store for FileStore
mind_body::heartbeat: impl Tunables for FileTunables
mind_body::heartbeat: impl TempoView for FileStore
mind_body::heartbeat: impl fmt :: Display for Outcome
mind_body::heartbeat: impl fmt :: Display for PollTrace
mind_body::heartbeat: pub trait Control { fn envelope (& self) -> SwarmEffective ; fn effective (& self , instance : & Slug) -> Effective ; }
mind_body::heartbeat: pub trait Models { fn classify (& self , request : & TurnRequest) -> Result < String > ; fn spent (& self , caller : & str) -> Result < Spend > ; }
mind_body::heartbeat: pub trait Store { fn load (& self , instance : & Slug) -> Result < Option < Initiative > > ; fn save (& self , instance : & Slug , initiative : & Initiative) -> Result < () > ; fn record (& self , trace : & PollTrace) -> Result < () > ; fn latest (& self) -> Result < Option < PollTrace > > ; }
mind_body::heartbeat: pub trait Tunables { fn classifier (& self) -> Result < ClassifierConfig > ; }
mind_body::heartbeat: struct BurnTrace # [derive (Clone , Debug , PartialEq , Eq , Serialize , Deserialize)] pub-fields[run: String, spend_usd: Decimal, source: String]
mind_body::heartbeat: struct ClassifierConfig # [derive (Clone , Debug , PartialEq , Eq , DatabaseEntry)] pub-fields[instructions: String, show_idle: bool, show_urgency: bool, show_completions: bool, urgency_min: Decimal, urgency_max: Decimal, urgency_ttl_s: u32]
mind_body::heartbeat: pub trait Store { fn load (& self) -> Result < Option < HeartbeatState > > ; fn save (& self , state : & HeartbeatState) -> Result < () > ; fn record (& self , trace : & PollTrace) -> Result < () > ; }
mind_body::heartbeat: pub trait TempoView { fn latest (& self) -> Result < Option < PollTrace > > ; }
mind_body::heartbeat: struct Config # [derive (Clone , Debug , PartialEq , Eq)] pub-fields[personas: Vec < PersonaId >, operators: Vec < String >]
mind_body::heartbeat: struct FileControl pub-fields[]
mind_body::heartbeat: struct FileStore pub-fields[]
mind_body::heartbeat: struct FileTunables pub-fields[]
mind_body::heartbeat: struct Initiative # [derive (Clone , Debug , PartialEq , Eq , DatabaseEntry)] pub-fields[initiative_usd: Decimal, as_of: DateTime < Utc >, urgency: Decimal, urgency_at: DateTime < Utc >, last_burned_run: String, filled_events: Vec < String >, classified_seq: String, launched_run: String, launch_spend_usd: Decimal, launch_spend_known: bool, completions_through: String, launch_window: u64]
mind_body::heartbeat: struct InstanceTrace # [derive (Clone , Debug , PartialEq , Eq , Serialize , Deserialize)] pub-fields[instance: String, initiative_usd: Decimal, rate_usd_per_h: Decimal, urgency: Decimal, urgency_age_s: i64, busy: bool, released: bool, crossing_at: String, waited_s: i64, idle_s: i64, filled_by: String, fill_reason: String, note: String]
mind_body::heartbeat: struct Organs< 'a > pub-fields[seats: & 'a [Seat < 'a >], control: & 'a dyn Control, models: & 'a dyn Models, tunables: & 'a dyn Tunables, launcher: & 'a dyn Launcher, clock: & 'a dyn Clock, host: & 'a str, store: & 'a dyn Store]
mind_body::heartbeat: struct HeartbeatState # [derive (Clone , Debug , PartialEq , Eq , DatabaseEntry)] pub-fields[last_beat_at: DateTime < Utc >, handled_mentions: Vec < String >]
mind_body::heartbeat: struct InstanceTrace # [derive (Clone , Debug , PartialEq , Eq , serde :: Serialize , serde :: Deserialize)] pub-fields[instance: String, vote_beat_s: Option < u32 >, urgency_permille: u16, addressed: bool, busy: bool, released: bool, idle_s: i64, score: String, note: String]
mind_body::heartbeat: struct Organs< 'a > pub-fields[seats: & 'a [Seat < 'a >], control: & 'a dyn Control, launcher: & 'a dyn Launcher, clock: & 'a dyn Clock, host: & 'a str, store: & 'a dyn Store]
mind_body::heartbeat: struct PersonaId # [derive (Clone , Debug , PartialEq , Eq)] pub-fields[slug: Slug, public_name: String, handle: String, matrix_id: String, huginn: SocketAddr]
mind_body::heartbeat: struct PollTrace # [derive (Clone , Debug , PartialEq , Eq , DatabaseEntry)] pub-fields[at: DateTime < Utc >, instances: Vec < InstanceTrace >, launches: Vec < String >, burns: Vec < BurnTrace >, classifier: String]
mind_body::heartbeat: struct PollTrace # [derive (Clone , Debug , PartialEq , Eq , DatabaseEntry)] pub-fields[at: DateTime < Utc >, tempo_s: u32, instances: Vec < InstanceTrace >, launches: Vec < String >]
mind_body::heartbeat: struct Seat< 'a > pub-fields[who: PersonaId, mind: & 'a dyn MindPort, chat: & 'a dyn Chat]
mind_body::heartbeat: struct Spend # [derive (Clone , Copy , Debug , PartialEq , Eq)] pub-fields[usd: Decimal, window: u64]
mind_body::launch: # [derive (Clone , Debug , PartialEq , Eq)] pub enum Declined { Admission (MindRefusal) , Conflict , AlreadyAdmitted , StartFailed , GrantForOtherInstance , PersonaRunTakesNoClaims , }
mind_body::launch: # [derive (Clone , Debug , PartialEq , Eq)] pub enum LaunchOutcome { Launched { run : PipelineRef , } , NotQueued { item : PipelineRef , } , Tripped { item : PipelineRef , question : PipelineRef , } , Busy { run : PipelineRef , } , Refused (Declined) , }
mind_body::launch: const START_GRACE_S : i64
@ -164,7 +134,7 @@ mind_body::launch: struct Ports< 'a > pub-fields[mind: & 'a dyn MindPort, launc
mind_body::launch: struct SystemClock pub-fields[]
mind_body::launch: struct SystemctlReply pub-fields[success: bool, code: Option < i32 >, stdout: String]
mind_body::launch: struct SystemdLauncher pub-fields[]
mind_body::lease_client: # [derive (Clone , Copy , Debug , PartialEq , Eq , Serialize , Deserialize)] pub enum LeaseRefusalKind { SpendCeiling , CostBound , UnknownCaller , Expired , Busy , }
mind_body::lease_client: # [derive (Clone , Copy , Debug , PartialEq , Eq , Serialize , Deserialize)] pub enum LeaseRefusalKind { UnknownCaller , Expired , Busy , ProviderRejected , }
mind_body::lease_client: const LEASE_SOCKET_VARIABLE : & str
mind_body::lease_client: const MAX_LEASE_FRAME_BYTES : usize
mind_body::lease_client: impl Inheritable
@ -176,28 +146,23 @@ mind_body::lease_client: impl TokenFd
mind_body::lease_client: impl TokenFd: fn inheritable (& self) -> Result < Inheritable >
mind_body::lease_client: impl std :: fmt :: Debug for TokenFd
mind_body::lease_client: pub enum Lent { Granted (Box < dyn Lease >) , Refused (LeaseRefused) , }
mind_body::lease_client: pub trait Lease { fn token (& self) -> & TokenFd ; fn settle (self : Box < Self > , settlement : Settlement) -> Result < u64 > ; }
mind_body::lease_client: pub trait Lease { fn token (& self) -> & TokenFd ; fn plan_quota (& self) -> & [PlanQuota] ; }
mind_body::lease_client: pub trait Lender { fn lend (& self , request : & LeaseRequest) -> Result < Lent > ; }
mind_body::lease_client: struct Inheritable pub-fields[]
mind_body::lease_client: struct LeaseRefused # [derive (Clone , Debug , PartialEq , Eq , Serialize , Deserialize)] pub-fields[kind: LeaseRefusalKind, detail: String]
mind_body::lease_client: struct LeaseRequest # [derive (Clone , Debug , PartialEq , Eq , Serialize , Deserialize)] pub-fields[expires_at_unix_ms: u64]
mind_body::lease_client: struct ModelUsage # [derive (Clone , Debug , PartialEq , Eq , Serialize , Deserialize)] pub-fields[model: String, usage: TokenUsage]
mind_body::lease_client: struct Settlement # [derive (Clone , Debug , Default , PartialEq , Eq)] pub-fields[usage: Vec < ModelUsage >]
mind_body::lease_client: struct SocketLender pub-fields[]
mind_body::lease_client: struct TokenFd pub-fields[]
mind_body::lease_client: struct TokenUsage # [derive (Clone , Debug , Default , PartialEq , Eq , Serialize , Deserialize)] pub-fields[input_tokens: u64, cache_read_tokens: u64, cache_write_tokens: u64, output_tokens: u64, reasoning_tokens: Option < u64 >]
mind_body::lease_client::socket: impl Lease for Granted
mind_body::persona: # [derive (Clone , Copy , Debug , PartialEq , Eq)] pub enum Failure { Held (HeldReason) , Chat , Persona , Doctrine , DoctrineTooLarge , Readout , Connector , Undecodable , RoomNotAllowed , Send , SelfRun , Ack , }
mind_body::persona: # [derive (Clone , Copy , Debug , PartialEq , Eq)] pub enum Failure { Held (HeldReason) , Chat , Persona , Doctrine , DoctrineTooLarge , Connector , Undecodable , RoomNotAllowed , Send , SelfRun , Pulse , Ack , }
mind_body::persona: # [derive (Debug , PartialEq , Eq)] pub enum Outcome { Dead (HeldReason) , NoRun , Served { run : PipelineRef , answered : u32 , failure : Option < Failure > , self_run : Option < PipelineRef > } , }
mind_body::persona: const AGENT : & str
mind_body::persona: const DOCTRINE_MAX_BYTES : usize
mind_body::persona: const ENV_BURN_ROOM : & str
mind_body::persona: const ENV_DOCTRINE : & str
mind_body::persona: const ENV_OPERATOR : & str
mind_body::persona: const ENV_ROOMS : & str
mind_body::persona: const ENV_SELF_SENDER : & str
mind_body::persona: const MAX_TURNS_PER_START : u32
mind_body::persona: fn burn_line (readout : & SpendReadout , caller : & str , heat : Option < Decimal > , live_runs : usize) -> Option < String >
mind_body::persona: fn reply_schema (rooms : & [String] , campaigns : & [String]) -> String
mind_body::persona: fn start (organs : & Organs , control : & impl ControlSource , swarm : & impl ControlSource , config : & Config) -> Result < Outcome >
mind_body::persona: impl Config
@ -213,19 +178,19 @@ mind_body::persona: impl Trace for FileTrace
mind_body::persona: impl Trace for Noted < '_ >
mind_body::persona: impl fmt :: Display for Failure
mind_body::persona: impl fmt :: Display for Outcome
mind_body::persona: pub trait Connector { fn turn (& self , request : & TurnRequest) -> Result < String > ; fn spend_readout (& self) -> Result < SpendReadout > ; }
mind_body::persona: pub trait Connector { fn turn (& self , request : & TurnRequest) -> Result < String > ; fn usage_readout (& self) -> Result < UsageReadout > ; }
mind_body::persona: pub trait PersonaState { fn instructions (& self) -> Result < String > ; }
mind_body::persona: pub trait Trace { fn record (& self , trace : & TurnTrace) -> Result < () > ; }
mind_body::persona: pub use model_connector :: { CallerSpend , PlanQuota , SpendReadout } ;
mind_body::persona: struct Config # [derive (Clone , Debug , PartialEq , Eq)] pub-fields[rooms: Vec < String >, burn_room: String, operators: Vec < String >, own_sender: String, max_turns: u32, doctrine: Vec < PathBuf >]
mind_body::persona: pub use model_connector :: { PlanQuota , UsageReadout } ;
mind_body::persona: struct Config # [derive (Clone , Debug , PartialEq , Eq)] pub-fields[rooms: Vec < String >, operators: Vec < String >, own_sender: String, max_turns: u32, doctrine: Vec < PathBuf >]
mind_body::persona: struct FileTrace pub-fields[]
mind_body::persona: struct HuginnPersona pub-fields[]
mind_body::persona: struct Organs< 'a > pub-fields[mind: & 'a dyn MindPort, launcher: & 'a dyn Launcher, clock: & 'a dyn Clock, host: & 'a str, chat: & 'a dyn Chat, connector: & 'a dyn Connector, persona: & 'a dyn PersonaState, trace: & 'a dyn Trace]
mind_body::persona: struct PersonaReply # [derive (Clone , Debug , PartialEq , Eq , Serialize , Deserialize)] pub-fields[say: Vec < Say >, start_self_run: Option < StartSelfRun >]
mind_body::persona: struct Organs< 'a > pub-fields[mind: & 'a dyn MindPort, launcher: & 'a dyn Launcher, clock: & 'a dyn Clock, host: & 'a str, chat: & 'a dyn Chat, connector: & 'a dyn Connector, persona: & 'a dyn PersonaState, trace: & 'a dyn Trace, tempo: Option < & 'a dyn TempoView >]
mind_body::persona: struct PersonaReply # [derive (Clone , Debug , PartialEq , Eq , Serialize , Deserialize)] pub-fields[say: Vec < Say >, start_self_run: Option < StartSelfRun >, tempo_vote_beat_s: Option < u32 >, urgency_permille: Option < u16 >]
mind_body::persona: struct Say # [derive (Clone , Debug , PartialEq , Eq , Serialize , Deserialize)] pub-fields[room: String, text: String]
mind_body::persona: struct StartSelfRun # [derive (Clone , Debug , PartialEq , Eq , Serialize , Deserialize)] pub-fields[brief: String, repo: String, campaign: String]
mind_body::persona: struct TraceItem # [derive (Clone , Debug , PartialEq , Eq , Serialize , Deserialize)] pub-fields[provenance: String, room: String, text: String]
mind_body::persona: struct TurnRequest # [derive (Clone , Debug , PartialEq , Eq)] pub-fields[caller: String, request_id: String, max_cost_micro_usd: u64, instructions: String, input: String, output_schema_json: String]
mind_body::persona: struct TurnRequest # [derive (Clone , Debug , PartialEq , Eq)] pub-fields[caller: String, request_id: String, instructions: String, input: String, output_schema_json: String]
mind_body::persona: struct TurnTrace # [derive (Clone , Debug , PartialEq , Eq , DatabaseEntry)] pub-fields[run: String, turn: u32, at: DateTime < Utc >, inputs: Vec < TraceItem >, outputs: Vec < TraceItem >, outcome: String]
mind_body::queue: # [derive (Clone , Copy , Debug , PartialEq , Eq)] pub enum Breaker { Clear , Trip , }
mind_body::queue: const CONSECUTIVE : usize
@ -257,23 +222,30 @@ mind_body::self_run: const SCRATCH_VARIABLE : & str
mind_body::self_run: const SEED_VARIABLE : & str
mind_body::self_run: const SESSION_NAMESPACE : Uuid
mind_body::self_run: fn carry (mind : & dyn MindPort , clock : & dyn Clock , lender : & dyn Lender , spawner : & dyn Spawner , run_cap_s : u64 , out : & mut dyn Write) -> Result < SelfRunOutcome >
mind_body::self_run: fn claude_args (session : Uuid , budget_usd : & str) -> Vec < String >
mind_body::self_run: fn claude_args (session : Uuid) -> Vec < String >
mind_body::self_run: fn read_usage (line : & str) -> Usage
mind_body::self_run: fn session_id (run : & PipelineRef) -> Uuid
mind_body::self_run: fn start_message (instance : & Slug , run : & PipelineRef) -> String
mind_body::self_run: fn start_message (instance : & Slug , run : & PipelineRef , plan_quota : & [PlanQuota] , now_ms : u64) -> String
mind_body::self_run: impl Child for ClaudeProcess
mind_body::self_run: impl ClaudeSpawner
mind_body::self_run: impl ClaudeSpawner: fn new (unit_environment : impl IntoIterator < Item = (OsString , OsString) >) -> Result < Self >
mind_body::self_run: impl Drop for FreshConfig
mind_body::self_run: impl FreshConfig
mind_body::self_run: impl Heard
mind_body::self_run: impl SelfRunOutcome
mind_body::self_run: impl SelfRunOutcome: fn exit_status (& self) -> i32
mind_body::self_run: impl Spawner for ClaudeSpawner
mind_body::self_run: impl Spent
mind_body::self_run: impl Stop
mind_body::self_run: impl fmt :: Display for SeedLinkRefused
mind_body::self_run: impl std :: error :: Error for SeedLinkRefused
mind_body::self_run: impl fmt :: Display for SelfRunOutcome
mind_body::self_run: impl std :: error :: Error for SeedLinkRefused
mind_body::self_run: pub trait Child { fn write_line (& mut self , line : & str) ; fn close_input (& mut self) ; fn next (& mut self , timeout : StdDuration) -> Read ; fn stop (& mut self , how : Stop) -> bool ; }
mind_body::self_run: pub trait Spawner { fn spawn (& self , args : & [String] , token : & TokenFd) -> Result < Box < dyn Child > > ; }
mind_body::self_run: struct ClaudeSpawner pub-fields[]
mind_body::tempo: const DEFAULT_BEAT_S : u32
mind_body::tempo: const LOG_BOUND_ORDERS : f64
mind_body::tempo: fn pick (rows : & [Standing] , beat_s : u32) -> Option < usize >
mind_body::tempo: fn score (standing : & Standing , beat_s : u32) -> f64
mind_body::tempo: fn tally (votes : & [u32]) -> u32
mind_body::tempo: fn urgency_permille (standing : & Standing) -> u16
mind_body::tempo: struct Standing # [derive (Clone , Debug , PartialEq , Eq)] pub-fields[slug: String, eligible: bool, waited_s: Option < u64 >, last_turn_ms: Option < i64 >, self_permille: u16, topic_permille: u16, addressed_by_member: bool]