--- issueRef: "#290" version: 11 updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"} updatedAt: 1788937781234 --- # Ticket #290 - Redemarrage agent finalise le tour et bloque le chat ## Reproduction utilisateur - Date: 2026-09-09. - L'utilisateur demande a Main de se redemarrer puis d'indiquer le succes une fois fini. - Dans la conversation, Main lance le redemarrage, envoie un message, le tour se finit et le message envoye est considere comme Final. - Tentative Stop ensuite: message "Request already stopped". - Le chat reste bloque en ecriture. - Capture: `/home/anthony/Documents/Projects/IdeA/.ideai/attachments/agent-chat/7d2abba7-ed93-405f-9fe5-857c8455e436/9a881769-d8e8-410d-85f1-7a3ec2afdde0-clipboard-image-1788934010151.png`. ## Attendu - Le restart agent doit provoquer une vraie relance/reprise, pas une simple fin de tour capturee comme Final. - Le chat doit redevenir ecrivable apres redemarrage ou echec controle. - Le message de succes doit correspondre a un redemarrage effectif, pas au tour qui initie le restart. ## Cadrage UX - Etats visibles attendus: redemarrage demande, agent en reprise, reprise reussie ou echec controle. - Stop ne doit etre cliquable que si une requete stoppable existe; ne pas exposer "Request already stopped" brut. - Le message de succes ne doit etre affiche qu'apres preuve runtime d'un agent relance/reconnecte. ## Cadrage Architecture initial - Bug de contrat entre restart autonome et chat humain `agent_send`. - `ask_structured` etait deja restart-aware; `agent_send` devait ignorer le Final de l'ancien runtime pendant restart et attendre la session remplacee. - Correctif backend-first, pas de filtre frontend sur le texte. ## Implementation DevBackend initiale - Branche: `fix/290-restart-agent-send-premature-final`. - Le tour humain s'enregistre dans `RestartRendezvousCoordinator`. - `Final`/`Error` de l'ancien provider ignore pendant restart actif. - Le drain attend la session de remplacement, envoie le prompt de continuation, puis transmet uniquement le vrai terminal. - Busy/FIFO reste actif jusqu'au vrai resultat, echec explicite ou annulation. - Stop utilisateur annule aussi le rendez-vous restart. - Pas de changement frontend/protocole signale. ## Fichiers modifies initiaux annonces - `crates/application/src/orchestrator/service.rs` - `crates/application/src/orchestrator/mod.rs` - `crates/application/src/lib.rs` - `crates/application/src/workstate/actions.rs` - `crates/application/tests/orchestrator_service.rs` - `crates/backend/src/lib.rs` - `crates/app-tauri/src/commands.rs` - `crates/web-server/src/lib.rs` ## Validations DevBackend initiales annoncees vertes - `cargo check --workspace` - `cargo test -p backend self_restart_contract_tests -- --nocapture` — 3/3 - `cargo test -p application --test orchestrator_service restart -- --nocapture` — 8/8 - `cargo test -p application --test workstate_actions -- --test-threads=1` — 9/9 - `cargo test -p app-tauri --test chat_bridge` — 31/31 - `cargo test -p web-server websocket_chat_send -- --test-threads=1` — 3/3 - `cargo fmt --all -- --check` - `git diff --check` ## Validation QA initiale - 2026-09-09 Verdict: VERT sur le perimetre initial #290, avec reserves globales reproduites hors perimetre. Commandes ciblees executees: - `cargo check --workspace` -> vert. - `cargo test -p backend self_restart_contract_tests -- --nocapture` -> vert, 3 passed. - `cargo test -p application --test orchestrator_service restart -- --nocapture` -> vert, 8 passed. - `cargo test -p application --test workstate_actions -- --test-threads=1` -> vert, 9 passed. - `cargo test -p app-tauri --test chat_bridge` -> vert, 31 passed. - `cargo test -p web-server websocket_chat_send -- --test-threads=1` -> vert, 3 passed. - `cargo fmt --all -- --check` -> vert. - `git diff --check` -> vert. Couverture confirmee: - `Final`/`Error` de l'ancien provider pendant restart ne finalise pas le tour humain: couvert par `self_restart_contract_tests::human_turn_ignores_old_terminal_and_accepts_replacement` et par les tests de registration directe du rendezvous restart. - Busy/FIFO reste actif jusqu'au terminal post-restart/echec/annulation: couvert par `self_restart_contract_tests`, `orchestrator_service restart` et `workstate_actions`. - Stop pendant restart annule proprement sans session de remplacement: couvert par `same_project_stop_during_restart_releases_ask_and_leaves_no_replacement_session`. - Non-regression #289 `ask_structured` restart-aware: couverte par `orchestrator_service restart`, incluant ask same-project, cross-project, echec et annulation. Suites globales rouges reproduites hors perimetre: - `cargo test -p web-server -- --test-threads=1` -> 103 passed, 7 failed. Les 7 echecs sont les tests PTY `websocket_*terminal*`/`websocket_launch_agent_*` qui recoivent `error` au lieu de `terminal.attached`. - `cargo test -p application -- --test-threads=1` -> rouge dans `tests/layout_usecases.rs`, 2 failed: `create_layout_plugin_validates_active_runtime_contribution_and_persists_root` et `mutate_set_plugin_layout_state_persists_opaque_state`, tous deux sur `NotFound("plugin package")`. ## Git initial - Fix commit: `d03300a` sur `fix/290-restart-agent-send-premature-final`. - Merge local no-ff vers `develop`: `546c7b7`. - Aucun push. - Worktree restant propre sauf `scripts/` non suivi hors perimetre recurrent. ## Build AppImage initial - Skill `build-appimage` applique le 2026-09-09. - `npm --prefix frontend run build` -> vert. - `CARGO_HOME=/tmp/idea-cargo-home APPIMAGE_EXTRACT_AND_RUN=1 NO_STRIP=1 ../../frontend/node_modules/.bin/tauri build --bundles appimage` depuis `crates/app-tauri` -> vert. - Artefact produit: `/home/anthony/Documents/Projects/IdeA/target/release/bundle/appimage/IdeA_0.3.0_amd64.AppImage`. - Remplacement de l'AppImage installee et relance IdeA non automatises: action manuelle utilisateur pour ne pas interrompre l'orchestrateur en cours. ## Regression partielle observee apres test utilisateur - 2026-09-09 - Nouveau test utilisateur: demander a Main de redemarrer, puis de dire apres redemarrage qu'il a redemarre avec succes. - Observation: IdeA semble bien avoir redemarre l'agent, mais au retour Main ne reprend pas l'objectif suspendu; il repond sur l'etat general du ticket #290 et parle d'autre chose. - Interpretation: le fix precedent traite le terminal premature et la disponibilite du chat, mais pas la conservation/reinjection de l'intention de reprise dans le nouveau runtime. - Attendu additionnel: apres un restart self controle par IdeA, le nouveau tour doit recevoir un handoff explicite contenant la demande utilisateur en cours, par exemple: "reprends apres redemarrage et confirme le succes", et ne doit pas repartir d'un contexte projet/ticket generique. - A cadrer: source de verite de cette intention suspendue, borne de retention, nettoyage apres reprise, et tests qui prouvent que le premier message post-restart est guide par le handoff exact. ## Cadrage Architecture regression partielle - Le bug restant est la perte de l'intention metier suspendue, pas la fin prematuree du tour. - Source de verite: etat applicatif explicite de tour suspendable proche/au sein de `RestartRendezvousCoordinator`; le transcript n'est pas autorite. - Pour `agent_send`, `objective_text` doit etre la demande utilisateur originale envoyee a l'agent. - `idea_restart_self` ne fabrique pas l'objectif: il attache un `restart_attempt_id` au tour actif. - Apres relance, le nouveau runtime recoit une consigne host-provided contenant l'objectif suspendu, correlee a la tentative courante. - Retention en memoire suffisante pour ce lot; nettoyage sur succes terminal, cancel utilisateur, erreur terminale ou expiration. - Idempotence: pas de double injection pour une meme tentative, et pas d'ancien handoff injecte dans un runtime plus recent. - Tests minimaux: agent_send+restart+self+relance recoit l'objectif exact, cloture du meme tour, double restart sans double injection, cancel/expiration nettoient, non-regression #289. ## Branche regression partielle - Branche: `fix/290-self-restart-resume-objective`. - Base: `develop` @ `93a1c23`. - Git a commite le sync store de reouverture sur develop avant branchement: `93a1c23`. - Worktree signale propre sauf `scripts/restart-idea-over-ssh.sh` non suivi hors perimetre recurrent. ## Implementation DevBackend regression partielle - 2026-09-09 - L'objectif utilisateur original est capture par `agent_send` et `chat.send`. - `RestartRendezvousCoordinator` conserve explicitement le tour, la source, l'objectif et le `restart_attempt_id`. - Le nouveau runtime recoit une consigne host-provided commencant par l'objectif suspendu. - Injection consommable une seule fois et uniquement par la tentative courante. - Nettoyage sur succes, echec, annulation et abandon/expiration. - Diagnostics ajoutes avec projet, agent, `turn_id`, `restart_attempt_id` et source. - Les rendez-vous inter-agents #289 conservent leur comportement existant. ## Fichiers modifies annonces pour regression partielle - `crates/application/src/orchestrator/service.rs` - `crates/application/src/orchestrator/mod.rs` - `crates/application/src/lib.rs` - `crates/backend/src/lib.rs` - `crates/app-tauri/src/commands.rs` - `crates/web-server/src/lib.rs` - `crates/application/tests/orchestrator_service.rs` ## Validations DevBackend regression partielle annoncees vertes - `cargo check --workspace` -> vert. - `cargo test -p backend self_restart_contract_tests -- --nocapture` -> 3/3 verts. - `cargo test -p application --test orchestrator_service restart -- --nocapture` -> 10/10 verts. - `cargo test -p application --test workstate_actions -- --test-threads=1` -> 9/9 verts. - `cargo test -p app-tauri --test chat_bridge` -> 31/31 verts. - `cargo test -p web-server websocket_chat_send -- --test-threads=1` -> 3/3 verts. - `cargo fmt --all -- --check` -> vert. - `git diff --check` -> vert. ## Validation QA regression partielle - 2026-09-09 Verdict: VERT sur `fix/290-self-restart-resume-objective`. Commandes executees: - `cargo check --workspace` -> vert. - `cargo test -p backend self_restart_contract_tests -- --nocapture` -> vert, 3 passed. - `cargo test -p application --test orchestrator_service restart -- --nocapture` -> vert, 10 passed. - `cargo test -p application --test workstate_actions -- --test-threads=1` -> vert, 9 passed. - `cargo test -p app-tauri --test chat_bridge` -> vert, 31 passed. - `cargo test -p web-server websocket_chat_send -- --test-threads=1` -> vert, 3 passed. - `cargo fmt --all -- --check` -> vert. - `git diff --check` -> vert. Couverture verifiee: - `agent_send` Tauri capture `prompt` utilisateur brut comme objectif suspendu, pas `prompt_for_model`. - `chat.send` websocket capture egalement le prompt utilisateur brut. - `RestartRendezvousCoordinator` conserve `turn_id`, `objective_text`, `source` et `restart_attempt_id`. - L'injection est bornee a l'etat `Ready` de la tentative courante et marquee `injected` apres lecture, donc non rejouable. - Les chemins cancel, failure et drop nettoient `suspended_turn`. - Les tests de regression #289 restent verts dans `orchestrator_service restart`. Reserve: - Validation runtime AppImage/live non executee dans cette passe QA; les tests automatises prouvent le contrat backend/transport, pas une relance manuelle de l'AppImage en cours d'utilisation.