fix(orchestrator): LiveStateTurnGuard ramène la LED live-state à Done au drop du futur ask cross-project — #281 (RAII armé après publication Working, désarmé sur sorties explicites mark_target_done_best_effort, Drop spawn best-effort UpdateLiveState Done avec last_delegation=ticket; test régression dropped_ask_future_marks_live_state_done; QA verte: cargo fmt, orchestrator_service 78/78, npm build frontend, AppImage rebuildée 2026-09-08 13:52; réserve documentée: échec préexistant launch_conventionfile_injects_assigned_skills_in_order hors périmètre)
This commit is contained in:
@ -2865,6 +2865,45 @@ async fn dropped_ask_future_frees_busy_target() {
|
||||
);
|
||||
}
|
||||
|
||||
/// Régression cross-project/workstate — si le client MCP appelant abandonne un
|
||||
/// `idea_project_ask_agent`, le futur `ask` est droppé. Le garde Busy libère déjà
|
||||
/// la FIFO ; il faut aussi nettoyer le live-state, sinon l'UI garde une LED
|
||||
/// `working`/jaune jusqu'au restart ou à la TTL.
|
||||
#[tokio::test]
|
||||
async fn dropped_ask_future_marks_live_state_done() {
|
||||
let agent = scratch_agent(aid(1), "architect", "agents/architect.md");
|
||||
let fx = ask_fixture(FakeContexts::with_agent(&agent, "# persona"));
|
||||
seed_live_pty(&fx.sessions, aid(1), sid(800));
|
||||
|
||||
let svc = Arc::clone(&fx.service);
|
||||
let ask = tokio::spawn(async move { svc.dispatch(&project(), cmd(ASK_JSON)).await });
|
||||
await_until(|| fx.mailbox.pending(&aid(1)) == 1).await;
|
||||
await_until(|| {
|
||||
fx.live
|
||||
.entry_for(aid(1))
|
||||
.is_some_and(|entry| entry.status == WorkStatus::Working)
|
||||
})
|
||||
.await;
|
||||
|
||||
ask.abort();
|
||||
let _ = ask.await;
|
||||
|
||||
await_until(|| {
|
||||
fx.live
|
||||
.entry_for(aid(1))
|
||||
.is_some_and(|entry| entry.status == WorkStatus::Done)
|
||||
})
|
||||
.await;
|
||||
let entry = fx
|
||||
.live
|
||||
.entry_for(aid(1))
|
||||
.expect("target live entry present");
|
||||
assert_eq!(
|
||||
entry.last_delegation, entry.ticket,
|
||||
"drop cleanup preserves the ticket as last_delegation"
|
||||
);
|
||||
}
|
||||
|
||||
/// Régression (garde RAII) — une **2e délégation** vers une cible dont un 1er `ask` a
|
||||
/// été abandonné est bien livrée : l'agent n'est pas coincé `Busy`, son tour suivant
|
||||
/// démarre et peut être résolu par `idea_reply`.
|
||||
|
||||
Reference in New Issue
Block a user