-
Notifications
You must be signed in to change notification settings - Fork 7
Give the conductor's steps wire forms, and link rows and events #69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -59,7 +59,7 @@ fn an_ask_opens_a_conversation_that_runs_first_and_concludes_to_the_asker() { | |
| )); | ||
| assert!(matches!( | ||
| answered.events.as_slice(), | ||
| [Event::Concluded { root: at, asker, askee, forced: false }] | ||
| [Event::Concluded { root: at, asker, askee, forced: false, .. }] | ||
| if *at == root && asker == "one" && askee == "two" | ||
| )); | ||
| assert_eq!(conductor.conversations(), 1); | ||
|
|
@@ -122,7 +122,7 @@ fn a_completion_while_a_conversation_is_open_is_refused_and_explained() { | |
| .expect("wave"); | ||
| assert!(seen.events.iter().any(|event| matches!( | ||
| event, | ||
| Event::Refused { seat, thread: None, why: Refusal::AwaitingReply { waiting_on } } | ||
| Event::Refused { seat, thread: None, why: Refusal::AwaitingReply { waiting_on }, .. } | ||
| if seat == "one" && waiting_on == &["two".to_owned()] | ||
| ))); | ||
| assert!( | ||
|
|
@@ -370,7 +370,7 @@ fn a_broadcast_or_ask_inside_a_conversation_is_desk_work_and_a_dm_is_dropped() { | |
| assert!( | ||
| seen.events | ||
| .iter() | ||
| .any(|event| matches!(event, Event::Broadcast { seat, to } if seat == "two" && !to.is_empty())), | ||
| .any(|event| matches!(event, Event::Broadcast { seat, to, .. } if seat == "two" && !to.is_empty())), | ||
| "{:?}", | ||
| seen.events | ||
| ); | ||
|
|
@@ -423,3 +423,67 @@ fn nothing_due_concludes_every_open_conversation_without_an_answer() { | |
| ); | ||
| assert_eq!(conductor.conversations(), 1); | ||
| } | ||
|
|
||
| #[test] | ||
| fn a_conclusion_the_fold_refuses_leaves_the_conversation_to_conclude_later() { | ||
| let hive = hive(&["one", "two"]); | ||
| let driver = CompletionDriver::new(&hive, 4).expect("driver"); | ||
| let route_policy = policy(1); | ||
| let routing = BroadcastRouting { | ||
| primary: None, | ||
| reasoning: None, | ||
| policy: &route_policy, | ||
| roster_version: 1, | ||
| thread_context: &[], | ||
| }; | ||
| let journal = Journal::default(); | ||
| let mut conductor = two_seat(&driver, routing, ConductPolicy::default(), &journal); | ||
| let asked = wave(&mut conductor, &journal, &[("one", vec![ask("two", "?")])]).expect("wave"); | ||
| let root = asked.commits[0].0; | ||
|
|
||
| // The askee answers, and the host reports the conclusion's row at a | ||
| // sequence the episode already holds: the fold refuses it. | ||
| conductor.begin_wave(); | ||
| let turns = conductor.turns().expect("turns"); | ||
| for turn in &turns { | ||
| conductor.open_turn(turn, journal.latest(), Vec::new(), |root| { | ||
| journal.thread(root) | ||
| }); | ||
| if turn.seat == "two" { | ||
| conductor.record(turn, vec![ToolCall::Speak(complete("port 8080"))]); | ||
| } | ||
| } | ||
| let mut refused = false; | ||
| while let Some(step) = conductor.step().expect("steps") { | ||
| if let Step::Commit(commit) = step { | ||
| let sequence = if matches!(commit.utterance, Utterance::Dm { .. }) { | ||
| root | ||
| } else { | ||
| journal.append( | ||
| &commit.author, | ||
| "row", | ||
| commit.thread, | ||
| commit.only_for.clone(), | ||
| ) | ||
| }; | ||
| if run(conductor.committed(sequence)).is_err() { | ||
| refused = true; | ||
| } | ||
| } | ||
| } | ||
| assert!(refused, "a reused sequence is refused by the fold"); | ||
| assert_eq!(conductor.conversations(), 0, "nothing concluded"); | ||
| assert!(!conductor.finished(), "the conversation is still open"); | ||
|
|
||
| // The next wave concludes it, at a row the host gives properly. | ||
| let later = wave(&mut conductor, &journal, &[]).expect("wave"); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Preserve the child until its conclusion commit succeeds The failed [RULE] state-preservation-on-error · |
||
| assert!( | ||
| later | ||
| .events | ||
| .iter() | ||
| .any(|event| matches!(event, Event::Concluded { root: at, .. } if *at == root)), | ||
| "{:?}", | ||
| later.events | ||
| ); | ||
| assert_eq!(conductor.conversations(), 1); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update every event constructor for the new required fields
Adding
atas a required field to event variants changes everyEvent::Broadcast,Unplaced,CompletedByBroadcast,Handoff,Refused,Discharged, andConcludedconstruction site. The unchanged conductor code still constructs these variants using their previous field sets, so the crate will fail to compile until each caller supplies the corresponding sequence (or the field is made optional/defaulted).[RULE] build-break ·
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Every construction site is updated in this commit: the seven sites in
conduct/wave.rs(Broadcast,Unplaced,CompletedByBroadcast,Handoff, bothRefusedarms andDischarged, plusConcluded), and the example's matches take... The Rust job on this head compiles the crate and the example, so no site was missed.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved — the reply explains why it is not a problem (advisory), as of
5d16143.If this is wrong, reopen the conversation and say so; the finding will be re-raised on the next push if it still reproduces.