From 090712edfb6f19e3595ebb0b611fadea8396fdac Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Sat, 31 Oct 2026 05:47:54 +0100 Subject: [PATCH] tests: rig stamps launches on its clock, reply keys in persona tests, pulse in the schema command and the target count Co-Authored-By: Claude Opus 5.5 --- crates/eureka-state/src/bin/huginn/schema.rs | 2 +- crates/huginn-mind/src/rows.rs | 2 +- crates/mind-body/src/heartbeat/tests.rs | 4 ++++ crates/mind-body/src/persona/tests.rs | 8 ++++---- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/crates/eureka-state/src/bin/huginn/schema.rs b/crates/eureka-state/src/bin/huginn/schema.rs index 9fe9a39..b8592a5 100644 --- a/crates/eureka-state/src/bin/huginn/schema.rs +++ b/crates/eureka-state/src/bin/huginn/schema.rs @@ -20,7 +20,7 @@ macro_rules! kinds { kinds!( campaign, target, question, ruling, cut_spec, cut_report, verdict, finding, follow_up, resolution, instance, stewardship, - hand_off, run, + hand_off, run, pulse, ); /// The schema named, or the names when none is: the exit code is 2 for a name diff --git a/crates/huginn-mind/src/rows.rs b/crates/huginn-mind/src/rows.rs index 4cb9490..367f006 100644 --- a/crates/huginn-mind/src/rows.rs +++ b/crates/huginn-mind/src/rows.rs @@ -421,7 +421,7 @@ mod tests { } assert_eq!(Vocabulary.target_leaves("answers"), vec![K::Question.type_id().to_string()]); assert_eq!(Vocabulary.target_leaves("rulings"), vec![K::Ruling.type_id().to_string()]); - assert_eq!(Vocabulary.target_leaves("subject").len(), 14); + assert_eq!(Vocabulary.target_leaves("subject").len(), 15); assert_eq!( sorted(Vocabulary.target_leaves("claims")), sorted([K::CutSpec, K::Finding, K::FollowUp].iter().map(|kind| kind.type_id().to_string()).collect()) diff --git a/crates/mind-body/src/heartbeat/tests.rs b/crates/mind-body/src/heartbeat/tests.rs index 20c8773..8e02834 100644 --- a/crates/mind-body/src/heartbeat/tests.rs +++ b/crates/mind-body/src/heartbeat/tests.rs @@ -176,6 +176,10 @@ impl Rig { } fn poll(&self) -> Outcome { + // Launches are admitted by the mind own clock; keep it on the rig clock so a launched turn is dated now. + for mind in &self.minds { + mind.admit_at(self.now()); + } let ports: Vec = self.minds.iter().zip(self.calls.iter().zip(&self.down)).map(|(inner, (calls, down))| Counting { inner, calls, down }).collect(); let seats: Vec = self.config.personas.iter().enumerate().map(|(index, who)| Seat { who: who.clone(), mind: &ports[index], chat: &self.chats[index] }).collect(); let organs = Organs { seats: &seats, control: &self.control, launcher: &self.launcher, clock: &self.clock, host: "test-host", store: &self.store }; diff --git a/crates/mind-body/src/persona/tests.rs b/crates/mind-body/src/persona/tests.rs index b8d2293..a692a55 100644 --- a/crates/mind-body/src/persona/tests.rs +++ b/crates/mind-body/src/persona/tests.rs @@ -487,7 +487,7 @@ fn a_reply_without_start_self_run_is_not_a_reply_though_null_is() { #[test] fn the_decoder_holds_the_bounds_the_schema_states() { let c = config(); - let start = |brief: &str, repo: &str, campaign: &str| json!({ "say": [], "start_self_run": { "brief": brief, "repo": repo, "campaign": campaign } }).to_string(); + let start = |brief: &str, repo: &str, campaign: &str| json!({ "say": [], "start_self_run": { "brief": brief, "repo": repo, "campaign": campaign }, "tempo_vote_beat_s": null, "urgency_permille": null }).to_string(); let ok = |brief: &str, repo: &str, campaign: &str| decode_reply(&start(brief, repo, campaign), &c.rooms).is_ok(); assert!(ok("b", "GameCult/Huginn", "eureka-body")); assert!(ok(&"b".repeat(1000), "a-b/c.d_e-f", &"c".repeat(64))); @@ -676,7 +676,7 @@ fn no_member_text_name_or_context_can_read_as_an_operator_line() { #[test] fn a_self_run_in_a_campaign_the_mind_does_not_hold_is_refused_before_anything_is_admitted() { - let reply = json!({ "say": [], "start_self_run": { "brief": "Work", "repo": REPO, "campaign": "no-such-campaign" } }).to_string(); + let reply = json!({ "say": [], "start_self_run": { "brief": "Work", "repo": REPO, "campaign": "no-such-campaign" }, "tempo_vote_beat_s": null, "urgency_permille": null }).to_string(); let rig = Rig::new(vec![operator_says(1, "go")], &[reply]); let Outcome::Served { failure, self_run, .. } = rig.go() else { panic!("served") }; assert_eq!((failure, self_run), (Some(Failure::SelfRun), None)); @@ -684,7 +684,7 @@ fn a_self_run_in_a_campaign_the_mind_does_not_hold_is_refused_before_anything_is assert!(rig.launcher.started.borrow().is_empty()); assert!(rig.chat.acked.borrow().is_empty()); // A prefix of a real campaign's name is not that campaign. - let prefix = json!({ "say": [], "start_self_run": { "brief": "Work", "repo": REPO, "campaign": &CAMPAIGN[..CAMPAIGN.len() - 1] } }).to_string(); + let prefix = json!({ "say": [], "start_self_run": { "brief": "Work", "repo": REPO, "campaign": &CAMPAIGN[..CAMPAIGN.len() - 1] }, "tempo_vote_beat_s": null, "urgency_permille": null }).to_string(); let rig = Rig::new(vec![operator_says(1, "go")], &[prefix]); let Outcome::Served { failure, .. } = rig.go() else { panic!("served") }; assert_eq!(failure, Some(Failure::SelfRun)); @@ -810,7 +810,7 @@ fn the_campaigns_in_force_are_listed_and_are_the_schemas_campaign_enum() { #[test] fn a_self_run_naming_a_listed_campaign_passes_the_campaign_check() { - let reply = json!({ "say": [], "start_self_run": { "brief": "Work", "repo": REPO, "campaign": CAMPAIGN } }).to_string(); + let reply = json!({ "say": [], "start_self_run": { "brief": "Work", "repo": REPO, "campaign": CAMPAIGN }, "tempo_vote_beat_s": null, "urgency_permille": null }).to_string(); let rig = Rig::new(vec![operator_says(1, "go")], &[reply]); let Outcome::Served { failure, self_run, .. } = rig.go() else { panic!("served") }; assert_eq!(failure, None);