Self run: a refused reply holds back the replies behind it, so a long result reaches the mind in order

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Eureka 2026-11-10 14:21:04 +00:00
commit 59aca09c62
2 changed files with 19 additions and 5 deletions

View file

@ -795,17 +795,19 @@ impl<'a> SelfInbox<'a> {
Self { mind, start, plan: render_plan(plan_quota, now_ms), told, waiting: Vec::new(), heard, run: run.clone(), carried, echoed: Vec::new(), serving, last_answers, flush_written: false, flushing: false, replies: 0, unadmitted: Vec::new() }
}
/// Admits each reply the mind has not taken, in order; one try each. A refusal or an unreachable mind keeps the reply and never ends the session.
/// Admits each reply the mind has not taken, in order; one try each. A refusal or an unreachable mind keeps that reply and every one behind it
/// (the admission ordinal is the order the Persona hears them in, so none may overtake a refused one) and never ends the session.
fn admit_unadmitted(&mut self) {
let label = self.run.id.0.rsplit(':').next().unwrap_or(&self.run.id.0).to_string();
let mut kept = Vec::new();
for reply in std::mem::take(&mut self.unadmitted) {
let mut queue = std::mem::take(&mut self.unadmitted).into_iter();
for reply in queue.by_ref() {
let taken = matches!(self.mind.admit(AGENT, &label, vec![PipelineDocument::Reply(reply.clone())]), Ok(PipelineAdmissionOutcome::Committed { .. } | PipelineAdmissionOutcome::AlreadyAdmitted { .. }));
if !taken {
kept.push(reply);
self.unadmitted.push(reply);
break;
}
}
self.unadmitted = kept;
self.unadmitted.extend(queue);
}
/// One result of the main thread: with words, one reply answering the briefs the CLI has taken since the last reply (the first 64, in tell

View file

@ -106,3 +106,15 @@ fn a_reply_the_mind_did_not_take_is_tried_once_more_when_the_run_ends() {
assert!(ran.outcome.is_ok());
assert_eq!(text_of(&mind, 1), "last words");
}
#[test]
fn a_refused_piece_of_a_long_result_holds_back_the_pieces_behind_it() {
let mind = live_mind();
let seen = Seen::of(&mind);
seen.fail_admits.set(1); // the first piece is refused
let long = "w".repeat(REPLY_TEXT_LIMIT * 2 + 1);
let ran = carry_with(&seen, vec![Out(echo()), Out(at("m1", 10)), Out(saying(&long))], Some(0), false);
assert!(ran.outcome.is_ok());
let ordinals: Vec<u64> = (1..=3).map(|n| mind.view(K::Reply, &format!("{INSTANCE}:reply:selfrun-a-r{n}")).unwrap_or_else(|| panic!("piece {n} lost")).admission.ordinal).collect();
assert!(ordinals.windows(2).all(|w| w[0] < w[1]), "the pieces reached the mind out of order: {ordinals:?}");
}