fix(orchestrator,agent): ask_agent survit au restart de la cible same-project et cross-project — #289 (RestartRendezvousCoordinator stable par RuntimeAgentKey (projectId, agentId) partagé entre le rendez-vous ask_structured et le scheduler AppAgentSelfRestarter: l'ask actif garde verrou de tour, ticket logique et conversation_id, abandonne le drain de l'ancienne session sans no-reply puis capture le Final de continuation de la session relancée (SELF_RESTART_CONTINUATION_PROMPT partagé, un seul tour de continuation); branche delegated du scheduler: pas de preempt/cancel_head/mark_idle locaux, ready + wait_for_handoff, échecs restart propagés explicitement et cancel en cascade sans relance de continuation; watchdog d'inactivité réarmé par l'activité de contrôle restart; corrélation cross-project (requesterProjectId, requesterAgentId, correlationId) conservée jusqu'au résultat post-restart puis supprimée; stop_agent d'une cible en restart annule le rendez-vous au lieu d'un NotFound; le scheduler standalone conserve son comportement historique sans ask actif; QA verte: orchestrator_service 87/87 dont 6 tests restart (final post-restart, nettoyage busy/workstate/registre, corrélation cross-project, failure explicite, cancel cross-project + stop same-project pendant restart), application lib 171/171 dont watchdog réarmé, backend 89+7 ignored, cargo check -p backend, fmt --check; réserves: pas d'E2E AppImage/vrai provider, 7 tests backend ignorés bind socket local; scripts/ hors périmètre; aucun push)
This commit is contained in:
197
.ideai/tickets/289/carnet.md
Normal file
197
.ideai/tickets/289/carnet.md
Normal file
@ -0,0 +1,197 @@
|
||||
---
|
||||
issueRef: "#289"
|
||||
version: 4
|
||||
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
|
||||
updatedAt: 1788900709736
|
||||
---
|
||||
## 2026-09-08 — Main
|
||||
|
||||
Demande utilisateur : garantir que si une cible appelée via `ask_agent` se restart, le demandeur attend la fin du restart et reçoit le travail post-restart rattaché au même agent, aussi bien intra-projet qu'en cross-project.
|
||||
|
||||
Cadrage Architect :
|
||||
- Identité stable par `RuntimeAgentKey` `(projectId, agentId)`.
|
||||
- Le `conversation_id` logique et le verrou de tour doivent survivre au restart.
|
||||
- Un restart accepté est une activité de contrôle du rendez-vous : ne pas classifier la fermeture de l'ancienne session comme no-reply/timeout d'inactivité.
|
||||
- Cross-project : conserver la corrélation demandeur `(requesterProjectId, requesterAgentId, correlationId)` jusqu'au résultat post-restart.
|
||||
- Cancel pendant restart doit cascader et nettoyer rendez-vous/workstate/registre cross-project.
|
||||
- Échec de restart => erreur explicite, pas silence.
|
||||
|
||||
Branche Git retenue : `fix/289-ask-agent-during-target-restart` depuis `develop` @ `db91b00`.
|
||||
|
||||
Prochaines étapes : DevBackend implémente le contrat backend et tests ; QA valide same-project, cross-project, watchdog, failure/cancel.
|
||||
|
||||
## 2026-09-08 — DevBackend
|
||||
|
||||
Correctif backend implémenté sur `fix/289-ask-agent-during-target-restart`.
|
||||
|
||||
Fichiers modifiés :
|
||||
- `crates/application/src/orchestrator/service.rs`
|
||||
- `crates/application/src/orchestrator/mod.rs`
|
||||
- `crates/application/src/lib.rs`
|
||||
- `crates/application/tests/orchestrator_service.rs`
|
||||
- `crates/backend/src/lib.rs`
|
||||
|
||||
Comportement livré :
|
||||
- coordination stable par `RuntimeAgentKey (projectId, agentId)` entre le rendez-vous applicatif et le scheduler de self-restart ;
|
||||
- conservation du verrou de tour, du ticket logique et du `conversation_id` pendant le remplacement de la session concrète ;
|
||||
- abandon du drain de l'ancienne session sans no-reply, puis capture du `Final` du tour de continuation sur la session relancée ;
|
||||
- activité de contrôle restart intégrée au watchdog d'inactivité ;
|
||||
- corrélation cross-project conservée jusqu'au résultat post-restart ;
|
||||
- échec de restart remonté explicitement ; cancel pendant la fenêtre sans runtime réveille l'ask, nettoie la corrélation et empêche la relance de continuation ;
|
||||
- le scheduler standalone conserve son comportement historique lorsque aucun ask n'est actif.
|
||||
|
||||
Tests exécutés :
|
||||
- `cargo test -p application --test orchestrator_service` — 85 passés ;
|
||||
- `cargo test -p application --lib` — 171 passés ;
|
||||
- `cargo test -p backend --lib` — 89 passés, 7 ignorés (tests socket nécessitant une permission locale) ;
|
||||
- `cargo check -p backend` — OK ;
|
||||
- `cargo fmt --all -- --check` — OK.
|
||||
|
||||
Tests de régression ajoutés : same-project Final post-restart, cross-project + nettoyage corrélation, faux no-reply interdit, failure explicite, cancel pendant le gap de restart, watchdog réarmé par activité de contrôle.
|
||||
|
||||
Limites : pas de test E2E avec un vrai processus fournisseur/AppImage dans ce lot ; la validation est faite avec les ports/sessions structurés et le scheduler backend compilé. Aucun fichier frontend modifié. Aucun commit effectué par DevBackend.
|
||||
|
||||
## 2026-09-08 — QA
|
||||
|
||||
Verdict : VERT pour le ticket #289 sur `fix/289-ask-agent-during-target-restart`.
|
||||
|
||||
Tests QA ajoutés dans `crates/application/tests/orchestrator_service.rs` :
|
||||
- `ask_target_restart_cleans_busy_workstate_and_replaces_structured_registry_entry` : succès same-project post-restart, cible revenue `Idle`, FIFO vide, live-state `Done`, ancienne session structurée absente, session de remplacement enregistrée sur le même agent logique.
|
||||
- `same_project_stop_during_restart_releases_ask_and_leaves_no_replacement_session` : cancel/stop same-project pendant le gap de restart, ask réveillé en erreur explicite de cancel, busy/FIFO/live-state nettoyés, aucune session de remplacement enregistrée.
|
||||
|
||||
Commandes exécutées et sorties pertinentes :
|
||||
|
||||
```bash
|
||||
git status --short --branch
|
||||
```
|
||||
|
||||
```text
|
||||
## fix/289-ask-agent-during-target-restart
|
||||
M .ideai/tickets/counter.json
|
||||
M .ideai/tickets/index.json
|
||||
M crates/application/src/lib.rs
|
||||
M crates/application/src/orchestrator/mod.rs
|
||||
M crates/application/src/orchestrator/service.rs
|
||||
M crates/application/tests/orchestrator_service.rs
|
||||
M crates/backend/src/lib.rs
|
||||
?? .ideai/tickets/289/
|
||||
?? scripts/
|
||||
```
|
||||
|
||||
```bash
|
||||
cargo test -p application --test orchestrator_service ask_target_restart_keeps_logical_turn_and_returns_post_restart_final -- --nocapture
|
||||
```
|
||||
|
||||
```text
|
||||
test ask_target_restart_keeps_logical_turn_and_returns_post_restart_final ... ok
|
||||
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 84 filtered out; finished in 0.02s
|
||||
```
|
||||
|
||||
```bash
|
||||
cargo test -p application --test orchestrator_service cross_project_ask_preserves_correlation_across_target_restart -- --nocapture
|
||||
```
|
||||
|
||||
```text
|
||||
test cross_project_ask_preserves_correlation_across_target_restart ... ok
|
||||
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 84 filtered out; finished in 0.02s
|
||||
```
|
||||
|
||||
```bash
|
||||
cargo test -p application --test orchestrator_service ask_target_restart_failure_is_explicit_not_no_reply -- --nocapture
|
||||
```
|
||||
|
||||
```text
|
||||
test ask_target_restart_failure_is_explicit_not_no_reply ... ok
|
||||
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 84 filtered out; finished in 0.01s
|
||||
```
|
||||
|
||||
```bash
|
||||
cargo test -p application --test orchestrator_service cross_project_cancel_during_restart_releases_ask_and_correlation -- --nocapture
|
||||
```
|
||||
|
||||
```text
|
||||
test cross_project_cancel_during_restart_releases_ask_and_correlation ... ok
|
||||
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 84 filtered out; finished in 0.00s
|
||||
```
|
||||
|
||||
```bash
|
||||
cargo test -p application --lib restart_control_activity_rearms_inactivity_watchdog -- --nocapture
|
||||
```
|
||||
|
||||
```text
|
||||
test orchestrator::service::tests::restart_control_activity_rearms_inactivity_watchdog ... ok
|
||||
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 170 filtered out; finished in 0.05s
|
||||
```
|
||||
|
||||
```bash
|
||||
cargo test -p application --test orchestrator_service ask_target_restart_cleans_busy_workstate_and_replaces_structured_registry_entry -- --nocapture
|
||||
```
|
||||
|
||||
```text
|
||||
test ask_target_restart_cleans_busy_workstate_and_replaces_structured_registry_entry ... ok
|
||||
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 86 filtered out; finished in 0.02s
|
||||
```
|
||||
|
||||
```bash
|
||||
cargo test -p application --test orchestrator_service same_project_stop_during_restart_releases_ask_and_leaves_no_replacement_session -- --nocapture
|
||||
```
|
||||
|
||||
```text
|
||||
test same_project_stop_during_restart_releases_ask_and_leaves_no_replacement_session ... ok
|
||||
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 86 filtered out; finished in 0.00s
|
||||
```
|
||||
|
||||
```bash
|
||||
cargo fmt --all -- --check
|
||||
```
|
||||
|
||||
```text
|
||||
OK (aucune sortie)
|
||||
```
|
||||
|
||||
```bash
|
||||
cargo test -p application --test orchestrator_service
|
||||
```
|
||||
|
||||
```text
|
||||
running 87 tests
|
||||
test result: ok. 87 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.09s
|
||||
```
|
||||
|
||||
```bash
|
||||
cargo test -p application --lib
|
||||
```
|
||||
|
||||
```text
|
||||
running 171 tests
|
||||
test result: ok. 171 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.15s
|
||||
```
|
||||
|
||||
```bash
|
||||
cargo test -p backend --lib
|
||||
```
|
||||
|
||||
```text
|
||||
running 96 tests
|
||||
test result: ok. 89 passed; 0 failed; 7 ignored; 0 measured; 0 filtered out; finished in 0.04s
|
||||
```
|
||||
|
||||
```bash
|
||||
cargo check -p backend
|
||||
```
|
||||
|
||||
```text
|
||||
Finished `dev` profile [unoptimized + debuginfo] target(s) in 3.37s
|
||||
```
|
||||
|
||||
Couverture validée :
|
||||
- same-project : Final récupéré après restart et test QA de nettoyage busy/workstate/registre.
|
||||
- cross-project : corrélation conservée jusqu'au Final post-restart puis supprimée.
|
||||
- pas de faux no-reply/timeout pendant restart : failure restart reste `PROCESS` explicite, watchdog réarmé par activité de contrôle restart.
|
||||
- failure restart : erreur explicite contenant la cause provider.
|
||||
- cancel pendant restart : cross-project et same-project couverts.
|
||||
- nettoyage busy/workstate/registry : FIFO vide, `AgentBusyState::Idle`, live-state `Done`, registre structuré remplacé après succès et non recréé après cancel.
|
||||
|
||||
Risques résiduels :
|
||||
- Pas d'E2E AppImage / vrai provider relancé : la preuve porte sur les ports applicatifs, les sessions structurées de test et le câblage backend compilé.
|
||||
- Les 7 tests backend ignorés demandent une permission de bind socket locale ; ils restent hors preuve dans cet environnement.
|
||||
17
.ideai/tickets/289/issue.md
Normal file
17
.ideai/tickets/289/issue.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
id: "ae7f4f57-087e-463e-9390-33727e751d4f"
|
||||
number: 289
|
||||
title: "Garantir ask_agent pendant restart de la cible, same-project et cross-project"
|
||||
status: "qa"
|
||||
priority: "high"
|
||||
sprint: null
|
||||
links: []
|
||||
agentRefs: []
|
||||
attachments: []
|
||||
createdBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
|
||||
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
|
||||
createdAt: 1788899102915
|
||||
updatedAt: 1788900574986
|
||||
version: 3
|
||||
---
|
||||
Vérifier et corriger le comportement suivant : lorsqu'un agent cible a été appelé via ask_agent puis se restart, le demandeur doit attendre la fin du restart et le travail repris/après restart doit rester rattaché à cette même cible. Le contrat doit couvrir les appels intra-projet et cross-project, sans perte de résultat ni attribution à un mauvais agent.
|
||||
@ -1,3 +1,3 @@
|
||||
{
|
||||
"nextNumber": 289
|
||||
"nextNumber": 290
|
||||
}
|
||||
@ -3949,6 +3949,20 @@
|
||||
"agent_id": "a6c6ea12-bfc6-4bdc-8031-324102dfa34d"
|
||||
},
|
||||
"updatedAt": 1788898181382
|
||||
},
|
||||
{
|
||||
"issueRef": "#289",
|
||||
"path": "289",
|
||||
"title": "Garantir ask_agent pendant restart de la cible, same-project et cross-project",
|
||||
"status": "qa",
|
||||
"priority": "high",
|
||||
"sprint": null,
|
||||
"assignedAgentIds": [],
|
||||
"createdBy": {
|
||||
"kind": "agent",
|
||||
"agent_id": "a6c6ea12-bfc6-4bdc-8031-324102dfa34d"
|
||||
},
|
||||
"updatedAt": 1788900574986
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user