chore(tickets): sync store local — #307 QA verte finale backend+frontend, merge develop e1dbe56 (branche fix/307-startup-ghost-states-reconciliation commit 57cf825), carnet v7 section Git; AppImage rebuild 14:21 déjà formalisée v0.46.0 (commit dédié 99b400a + tag annoté, artefact sha256 vérifié identique au contenu develop post-merge — pas de nouveau tag); tickets 299-307 + index/counter + #296 carnet/issue; attachments/ et scripts/ hors périmètre; aucun push
This commit is contained in:
266
.ideai/tickets/307/carnet.md
Normal file
266
.ideai/tickets/307/carnet.md
Normal file
@ -0,0 +1,266 @@
|
||||
---
|
||||
issueRef: "#307"
|
||||
version: 7
|
||||
updatedBy: {"kind":"agent","agent_id":"1ff94b51-3e17-4a39-8543-7715d1ff0f80"}
|
||||
updatedAt: 1789054288135
|
||||
---
|
||||
## 2026-09-10 — Main
|
||||
|
||||
Signalement utilisateur: au lancement d'IdeA, l'UI indique des tasks/états en cours alors qu'aucune tâche réelle n'est active. Capture: cellule Main affichant `Conversation liée — récupération du transcript en cours.`
|
||||
|
||||
Cadrage Architect:
|
||||
- Bug backend prioritaire avec validation frontend.
|
||||
- Vérifier/corriger la chaîne `BackendCore::activate_project()` -> `reconcile_layouts`, `reconcile_live_state`, `reconcile_background_tasks`.
|
||||
- Sources persistées à réconcilier: `live-state.json` (`working/waiting/blocked` sans session vivante -> `idle`) et `BackgroundTaskStore` (`Running/Waiting/Cancelling` sans handle runtime -> terminal + delivery pending si nécessaire).
|
||||
- `GetProjectWorkState` ne doit pas reprojeter de tâche non terminale orpheline après activation projet.
|
||||
- Le message transcript peut être l'effet direct du live-state fantôme; si un `conversationId` persiste seul sans tours ni session active, ajouter un garde-fou frontend minimal pour ne pas rester indéfiniment sur `récupération du transcript en cours`.
|
||||
|
||||
Fichiers probables backend/domain: `crates/backend/src/lib.rs`, `crates/application/src/workstate/reconcile.rs`, `crates/domain/src/live_state.rs`, `crates/infrastructure/src/store/background_task.rs`, tests `crates/application/tests/workstate.rs` et backend autour de la réconciliation.
|
||||
|
||||
Fichiers probables frontend: `frontend/src/features/agents/CustomAgentChatView.tsx`, `frontend/src/features/workstate/ProjectWorkStatePanel.tsx`, `frontend/src/features/layout/LayoutGrid.tsx`, `frontend/src/adapters/workStateNormalization.ts`.
|
||||
|
||||
QA attendue: démarrage avec live-state fantôme, background task Running orpheline, completion pending/non livrée, completion déjà livrée, multi-projets, et capture UI équivalente sans blocage transcript infini.
|
||||
|
||||
## 2026-09-10 — DevBackend
|
||||
|
||||
Correctif backend/domain implémenté sur `develop`, sans commit/merge/push et sans modification frontend.
|
||||
|
||||
Diagnostic:
|
||||
- `LiveState::reconcile_orphans` remettait bien les lignes `working`/`waiting`/`blocked` sans session vivante à `idle`, mais conservait leur `correlationId`. Or cette corrélation représente une requête cross-project active; après reboot, elle ne correspond plus à aucun runtime reprenable/annulable et maintient une relation fantôme.
|
||||
- `AppBackgroundTaskStore::reconcile_project_boot(project_id, ...)` déléguait à `FsBackgroundTaskStore::reconcile_boot`, qui balayait tous les documents présents sous le root. De même, `list_undelivered_for_project` ne filtrait pas le résultat global sur le projet demandé. L'activation n'était donc pas strictement bornée au `projectId` activé.
|
||||
|
||||
Implémentation:
|
||||
- `crates/domain/src/live_state.rs`: une ligne active orpheline efface désormais aussi `correlation_id`, en plus de `ticket` et `last_delegation`; test domaine renforcé avec une corrélation réellement présente.
|
||||
- `crates/infrastructure/src/store/background_task.rs`: ajout de `reconcile_project_boot(project_id, live_task_ids, now_ms)` et factorisation interne; l'API historique `reconcile_boot` reste disponible, tandis que l'activation utilise la variante bornée.
|
||||
- `crates/backend/src/lib.rs`: réconciliation et collecte des complétions strictement filtrées sur le projet activé; test B7 renforcé pour vérifier que la tâche orpheline terminalisée disparaît de `list_open_for_agent`, source ouverte de `GetProjectWorkState`.
|
||||
- `crates/infrastructure/tests/background_task_store.rs`: test multi-projets prouvant que l'activation d'un projet ne répare ni ne rapporte une tâche étrangère.
|
||||
- `crates/backend/src/lib.rs`: test d'intégration #307 qui persiste un live-state `working` corrélé et une tâche `Running`, appelle réellement `BackendCore::activate_project()`, puis vérifie `idle`, corrélation/ticket/délégation effacés, tâche `Failed` et aucune tâche ouverte reprojetable.
|
||||
|
||||
Commandes exécutées, toutes vertes:
|
||||
- `cargo fmt --all -- --check`
|
||||
- `cargo test -p domain live_state::tests::reconcile_orphans` — 4/4
|
||||
- `cargo test -p infrastructure --test background_task_store reconcile` — 4/4
|
||||
- `cargo test -p backend background_tasks_b7_tests` — 1/1
|
||||
- `cargo test -p backend ticket307_activation_reconcile_tests` — 1/1
|
||||
- `cargo test -p application --test workstate` — 29/29
|
||||
- `cargo check -p backend`
|
||||
- `git diff --check`
|
||||
|
||||
Frontend:
|
||||
- Aucun changement nécessaire pour le défaut backend reproduit/corrigé.
|
||||
- QA doit encore faire le smoke test UI/AppImage de fermeture-relance demandé par le cadrage. Si le message `Conversation liée — récupération du transcript en cours.` subsiste avec un `conversationId` frontend isolé malgré les états backend assainis, le garde-fou frontend minimal décrit par Architect reste un lot séparé à confirmer sur preuve live.
|
||||
|
||||
## 2026-09-10 — QA
|
||||
|
||||
Verdict QA: VERT pour le correctif backend/domain/infrastructure du ticket #307.
|
||||
|
||||
Relu:
|
||||
- Diff de `crates/domain/src/live_state.rs`, `crates/infrastructure/src/store/background_task.rs`, `crates/infrastructure/tests/background_task_store.rs`, `crates/backend/src/lib.rs`.
|
||||
- `BackendCore::activate_project()` appelle toujours `reconcile_layouts`, `reconcile_live_state`, `reconcile_background_tasks`.
|
||||
- `GetProjectWorkState` filtre les background tasks par `task.project_id == project.id` avant projection.
|
||||
- Frontend: `CustomAgentChatView` garde le message `Conversation liée — récupération du transcript en cours.` quand `displayTurns.length === 0 && hasLinkedConversation`; `hasLinkedConversation` reste vrai avec un `conversationId` seul.
|
||||
|
||||
Test QA frontend ajouté:
|
||||
- `frontend/src/features/agents/CustomAgentChatView.test.tsx`: `keeps the linked-conversation placeholder when an isolated conversation id has no recovered turns`.
|
||||
- Ce test ne modifie pas le code de production; il prouve que le garde-fou frontend UX reste nécessaire si un `conversationId` isolé survit indépendamment de l'état live/backend.
|
||||
|
||||
Commandes exécutées et sorties réelles:
|
||||
|
||||
```text
|
||||
$ cargo fmt --all -- --check
|
||||
<no output, exit 0>
|
||||
```
|
||||
|
||||
```text
|
||||
$ git diff --check
|
||||
<no output, exit 0>
|
||||
```
|
||||
|
||||
```text
|
||||
$ cargo test -p domain live_state::tests::reconcile_orphans
|
||||
running 4 tests
|
||||
test live_state::tests::reconcile_orphans_does_not_mutate_self ... ok
|
||||
test live_state::tests::reconcile_orphans_downgrades_dead_active_rows_and_rewrites_fields ... ok
|
||||
test live_state::tests::reconcile_orphans_covers_working_waiting_blocked_only ... ok
|
||||
test live_state::tests::reconcile_orphans_spares_live_agents ... ok
|
||||
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 307 filtered out; finished in 0.00s
|
||||
```
|
||||
|
||||
```text
|
||||
$ cargo test -p infrastructure --test background_task_store reconcile
|
||||
running 4 tests
|
||||
test reconcile_marks_cancelling_without_live_handle_cancel_failed_and_pending ... ok
|
||||
test reconcile_uses_monotonic_timestamp_when_clock_is_behind ... ok
|
||||
test project_reconcile_does_not_repair_or_report_foreign_project_tasks ... ok
|
||||
test reconcile_marks_running_without_live_handle_failed_and_pending ... ok
|
||||
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 8 filtered out; finished in 0.00s
|
||||
```
|
||||
|
||||
```text
|
||||
$ cargo test -p backend background_tasks_b7_tests
|
||||
running 1 test
|
||||
test background_tasks_b7_tests::app_reconcile_requeues_wake_owner_marks_record_only_and_repairs_orphan_running ... ok
|
||||
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 101 filtered out; finished in 0.09s
|
||||
```
|
||||
|
||||
```text
|
||||
$ cargo test -p backend ticket307_activation_reconcile_tests
|
||||
running 1 test
|
||||
test ticket307_activation_reconcile_tests::activate_project_clears_stale_live_correlation_and_terminalizes_orphan_task ... ok
|
||||
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 101 filtered out; finished in 0.07s
|
||||
```
|
||||
|
||||
```text
|
||||
$ cargo test -p application --test workstate
|
||||
running 29 tests
|
||||
...
|
||||
test workstate_projects_open_and_undelivered_background_tasks_by_agent ... ok
|
||||
test result: ok. 29 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||
```
|
||||
|
||||
```text
|
||||
$ cargo check -p backend
|
||||
Checking domain v0.3.0 (/home/anthony/Documents/Projects/IdeA/crates/domain)
|
||||
Checking application v0.3.0 (/home/anthony/Documents/Projects/IdeA/crates/application)
|
||||
Checking infrastructure v0.3.0 (/home/anthony/Documents/Projects/IdeA/crates/infrastructure)
|
||||
Checking backend v0.3.0 (/home/anthony/Documents/Projects/IdeA/crates/backend)
|
||||
Finished `dev` profile [unoptimized + debuginfo] target(s) in 9.44s
|
||||
```
|
||||
|
||||
```text
|
||||
$ npm test -- CustomAgentChatView.test.tsx
|
||||
npm error enoent Could not read package.json: Error: ENOENT: no such file or directory, open '/home/anthony/Documents/Projects/IdeA/package.json'
|
||||
```
|
||||
|
||||
```text
|
||||
$ (cd frontend && npm test -- CustomAgentChatView.test.tsx)
|
||||
Test Files 1 passed (1)
|
||||
Tests 72 passed (72)
|
||||
Duration 4.36s
|
||||
```
|
||||
|
||||
Conclusion:
|
||||
- Le smoke automatisé backend `BackendCore::activate_project()` couvre l'équivalent fermeture/redémarrage: live-state `working` corrélé persisté + background task `Running` orpheline -> activation -> live-state `idle`, `correlation_id`/ticket/délégation effacés, task `Failed`, aucune task ouverte reprojetable.
|
||||
- La réconciliation background est bien bornée par `projectId` et ne terminalise/rapporte pas les tâches étrangères.
|
||||
- Le correctif backend suffit pour le défaut live-state/background-task fantôme validé ici.
|
||||
- Risque résiduel frontend: le message `Conversation liée — récupération du transcript en cours.` peut encore apparaître avec un `conversationId` isolé sans tours récupérés; le garde-fou UX reste pertinent comme lot séparé si ce cas persiste après backend assaini.
|
||||
|
||||
## 2026-09-10 — DevFrontend (réouverture QA)
|
||||
|
||||
Diagnostic:
|
||||
- Le rendu vide de `CustomAgentChatView` utilisait `hasLinkedConversation` après la fin de `openOrAttach`, sans distinguer une récupération encore active d'une récupération terminée sans aucun tour.
|
||||
- Un `conversationId` isolé suffisait donc à conserver indéfiniment le libellé `Conversation liée — récupération du transcript en cours.` après un retour utile vide.
|
||||
|
||||
Implémentation minimale:
|
||||
- `frontend/src/features/agents/CustomAgentChatView.tsx`: une fois `opening` terminé et sans tour affichable, une conversation toujours liée affiche désormais littéralement `Conversation liée — transcript indisponible.`. Le spinner reste borné à `opening`; la cellule et le `conversationId` ne sont ni fermés ni effacés.
|
||||
- `frontend/src/features/agents/CustomAgentChatView.test.tsx`: le test ciblé QA attend le nouvel état terminal et vérifie l'absence de l'ancien libellé, de spinner et de bouton `Réessayer` dans le scénario de récupération vide.
|
||||
- Les alertes techniques existantes restent inchangées afin de ne pas masquer les erreurs de lancement/rattachement hors de ce scénario vide.
|
||||
|
||||
Commandes exécutées:
|
||||
|
||||
```text
|
||||
$ (cd frontend && npm test -- CustomAgentChatView.test.tsx)
|
||||
Test Files 1 passed (1)
|
||||
Tests 72 passed (72)
|
||||
Duration 4.04s
|
||||
```
|
||||
|
||||
```text
|
||||
$ (cd frontend && npm run typecheck)
|
||||
tsc --noEmit
|
||||
exit 0
|
||||
```
|
||||
|
||||
```text
|
||||
$ git diff --check
|
||||
<no output, exit 0>
|
||||
```
|
||||
|
||||
Risque résiduel:
|
||||
- Le correctif repose sur la terminaison de la tentative `openOrAttach`; il ne crée pas un nouveau timeout frontend autour d'un appel transport qui ne se résoudrait jamais. Cette extension serait hors du garde-fou minimal demandé et modifierait le contrat de transport.
|
||||
|
||||
## 2026-09-10 — QA finale après garde-fou frontend
|
||||
|
||||
Verdict QA final: VERT pour #307, backend + garde-fou frontend.
|
||||
|
||||
Relu:
|
||||
- Diff backend/domain/infrastructure déjà validé: réconciliation live-state avec `correlation_id` effacé, réconciliation background bornée par `projectId`, smoke `BackendCore::activate_project()`.
|
||||
- Diff frontend: `CustomAgentChatView.tsx` remplace l'état vide post-récupération par `Conversation liée — transcript indisponible.`.
|
||||
- Test frontend: `CustomAgentChatView.test.tsx` couvre le cas `conversationId` isolé sans tours récupérés et vérifie l'absence de l'ancien libellé, du spinner et du bouton `Réessayer`.
|
||||
|
||||
Commandes exécutées et sorties réelles:
|
||||
|
||||
```text
|
||||
$ git diff --check
|
||||
<no output, exit 0>
|
||||
```
|
||||
|
||||
```text
|
||||
$ cargo test -p domain live_state::tests::reconcile_orphans
|
||||
running 4 tests
|
||||
test live_state::tests::reconcile_orphans_does_not_mutate_self ... ok
|
||||
test live_state::tests::reconcile_orphans_covers_working_waiting_blocked_only ... ok
|
||||
test live_state::tests::reconcile_orphans_spares_live_agents ... ok
|
||||
test live_state::tests::reconcile_orphans_downgrades_dead_active_rows_and_rewrites_fields ... ok
|
||||
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 307 filtered out; finished in 0.00s
|
||||
```
|
||||
|
||||
```text
|
||||
$ cargo test -p infrastructure --test background_task_store reconcile
|
||||
running 4 tests
|
||||
test reconcile_uses_monotonic_timestamp_when_clock_is_behind ... ok
|
||||
test reconcile_marks_cancelling_without_live_handle_cancel_failed_and_pending ... ok
|
||||
test project_reconcile_does_not_repair_or_report_foreign_project_tasks ... ok
|
||||
test reconcile_marks_running_without_live_handle_failed_and_pending ... ok
|
||||
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 8 filtered out; finished in 0.00s
|
||||
```
|
||||
|
||||
```text
|
||||
$ cargo test -p backend ticket307_activation_reconcile_tests
|
||||
running 1 test
|
||||
test ticket307_activation_reconcile_tests::activate_project_clears_stale_live_correlation_and_terminalizes_orphan_task ... ok
|
||||
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 101 filtered out; finished in 0.01s
|
||||
```
|
||||
|
||||
```text
|
||||
$ cargo test -p backend background_tasks_b7_tests
|
||||
running 1 test
|
||||
test background_tasks_b7_tests::app_reconcile_requeues_wake_owner_marks_record_only_and_repairs_orphan_running ... ok
|
||||
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 101 filtered out; finished in 0.00s
|
||||
```
|
||||
|
||||
```text
|
||||
$ cargo test -p application --test workstate
|
||||
running 29 tests
|
||||
...
|
||||
test workstate_lists_two_tickets_in_fifo_order ... ok
|
||||
test result: ok. 29 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||
```
|
||||
|
||||
```text
|
||||
$ (cd frontend && npm test -- CustomAgentChatView.test.tsx)
|
||||
Test Files 1 passed (1)
|
||||
Tests 72 passed (72)
|
||||
Duration 3.97s
|
||||
```
|
||||
|
||||
```text
|
||||
$ (cd frontend && npm run typecheck)
|
||||
> idea-frontend@0.3.0 typecheck
|
||||
> tsc --noEmit
|
||||
```
|
||||
|
||||
Conclusion:
|
||||
- Le backend ne reprojette plus l'activité fantôme validée par le smoke d'activation.
|
||||
- Le frontend ne reste plus sur `Conversation liée — récupération du transcript en cours.` après récupération vide; il affiche un état terminal explicite `Conversation liée — transcript indisponible.`.
|
||||
- Risque résiduel limité: le garde-fou frontend suppose toujours que `openOrAttach` finit par se résoudre/rejeter; il n'ajoute pas de timeout transport.
|
||||
|
||||
## Git — 2026-09-10
|
||||
- Reprise après déblocage; état laissé par la session Git précédente (interrompue après le merge) inspecté puis validé.
|
||||
- Branche: `fix/307-startup-ghost-states-reconciliation` créée depuis develop @ `99b400a`; commit fix `57cf825` (6 fichiers domain/infrastructure/backend/frontend), QA verte reconfirmée par Git avant commit.
|
||||
- Merge no-ff vers `develop`: `e1dbe56`; branche feature conservée après merge (convention récente).
|
||||
- Rebuild AppImage du 14:21 déjà formalisé en amont du merge: commit dédié `99b400a` (vide, trace durable in-repo) + tag annoté `v0.46.0`.
|
||||
- Vérifications à la reprise: `git diff eb86366..e1dbe56 --stat` = exactement les 6 fichiers du correctif; artefact `target/release/bundle/appimage/IdeA_0.3.0_amd64.AppImage` (119871992 octets, mtime 2026-09-10 14:21:49) de sha256 `e6e22132970357d8a67338edaf4c3b0adbee7a66265e09211e733abfa08825da` identique à celui documenté par `99b400a` — l'AppImage v0.46.0, buildée depuis le worktree incluant le WIP #307 complet, correspond au contenu de develop post-merge. Décision: aucun nouveau rebuild ni incrément de tag, un même artefact ne porte pas deux versions.
|
||||
- Store de tickets synchronisé sur develop dans le `chore(tickets)` portant ce carnet (tickets 299-307, index/counter, #296); `attachments/` et `scripts/` maintenus hors périmètre non suivis.
|
||||
- Aucun push (develop en avance de 320 commits sur origin/develop).
|
||||
- Restants: remplacement de l'AppImage installée par l'artefact v0.46.0 + relance manuels, validation live fermeture/relance (plus de LED fantôme ni de spinner transcript infini), puis clôture du ticket.
|
||||
17
.ideai/tickets/307/issue.md
Normal file
17
.ideai/tickets/307/issue.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
id: "0c1aeac5-0c3e-4bae-9cc0-2846e76f8d9e"
|
||||
number: 307
|
||||
title: "Au démarrage, IdeA affiche des tâches ou états en cours fantômes"
|
||||
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: 1789031142260
|
||||
updatedAt: 1789034059104
|
||||
version: 5
|
||||
---
|
||||
Signalement utilisateur du 2026-09-10 : après lancement d'IdeA, l'UI indique des tâches/états en cours alors qu'aucune tâche réelle n'est active. Capture jointe : cellule Main bloquée sur `Conversation liée — récupération du transcript en cours.` Contexte probable : réconciliation insuffisante des états live/transcript/background task au reboot, voir mémoire `live-state-reboot-reconciliation-design`. Critère attendu : au démarrage, les agents/sessions/tâches orphelins sont réconciliés vers un état non-busy, sans afficher de tâche active fantôme ni bloquer la cellule sur une récupération de transcript inexistante.
|
||||
Reference in New Issue
Block a user