diff --git a/hive-subagent-mcp/src/session.rs b/hive-subagent-mcp/src/session.rs index 37d2ff05..48230c58 100644 --- a/hive-subagent-mcp/src/session.rs +++ b/hive-subagent-mcp/src/session.rs @@ -1738,8 +1738,8 @@ fn describe_stopped(name: &str, stop: &StopReason, turns: &str) -> String { StopReason::NeedHelp(msg) => format!( "subagent `{name}` is BLOCKED and needs help: {msg}. It called `need_help`, which \ stopped its goal continuation, and nothing is in flight — it stays blocked until you \ - answer it.{turns} `continue` is how you answer: give it what it asked for as the \ - next turn's prompt." + answer it. `continue` is how you answer: give it what it asked for as the next \ + turn's prompt." ), StopReason::TurnCap { turns: spent } => format!( "subagent `{name}` ran out of turns — the harness limit of {spent} was reached and it \ @@ -2884,8 +2884,9 @@ mod tests { "the block and its reason must both be in the answer: {blocked}" ); assert!( - blocked.contains("Turn 2 of 5"), - "with the progress that says how far it got: {blocked}" + !blocked.contains("Turn 2 of 5"), + "a subagent waiting on an answer needs the answer, not a turn count competing for \ + attention: {blocked}" ); assert!( !blocked.contains("idle"), @@ -2893,6 +2894,23 @@ mod tests { ); } + #[test] + fn turn_cap_status_still_carries_the_turn_count() { + // The turn count is the whole point of a `TurnCap` stop — omitting + // it here (unlike `NeedHelp`) would be the regression a later + // refactor could silently reintroduce. + let capped = describe_status(&StatusFacts { + stop: Some(StopReason::TurnCap { turns: 5 }), + turns: Some((5, 5)), + ..StatusFacts::new("n") + }) + .expect("a capped session is a state, not an error"); + assert!( + capped.contains("Turn 5 of 5"), + "the turn count is the point of a TurnCap status: {capped}" + ); + } + #[test] fn a_reported_goal_never_reads_as_a_verified_one() { // The failure this is built against: `goal_reached` is self-reported