16 KiB
issueRef, version, updatedBy, updatedAt
| issueRef | version | updatedBy | updatedAt | ||||
|---|---|---|---|---|---|---|---|
| #307 | 7 |
|
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/blockedsans session vivante ->idle) etBackgroundTaskStore(Running/Waiting/Cancellingsans handle runtime -> terminal + delivery pending si nécessaire). GetProjectWorkStatene 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
conversationIdpersiste seul sans tours ni session active, ajouter un garde-fou frontend minimal pour ne pas rester indéfiniment surré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_orphansremettait bien les lignesworking/waiting/blockedsans session vivante àidle, mais conservait leurcorrelationId. 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_projectne filtrait pas le résultat global sur le projet demandé. L'activation n'était donc pas strictement bornée auprojectIdactivé.
Implémentation:
crates/domain/src/live_state.rs: une ligne active orpheline efface désormais aussicorrelation_id, en plus deticketetlast_delegation; test domaine renforcé avec une corrélation réellement présente.crates/infrastructure/src/store/background_task.rs: ajout dereconcile_project_boot(project_id, live_task_ids, now_ms)et factorisation interne; l'API historiquereconcile_bootreste 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 delist_open_for_agent, source ouverte deGetProjectWorkState.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-stateworkingcorrélé et une tâcheRunning, appelle réellementBackendCore::activate_project(), puis vérifieidle, corrélation/ticket/délégation effacés, tâcheFailedet aucune tâche ouverte reprojetable.
Commandes exécutées, toutes vertes:
cargo fmt --all -- --checkcargo test -p domain live_state::tests::reconcile_orphans— 4/4cargo test -p infrastructure --test background_task_store reconcile— 4/4cargo test -p backend background_tasks_b7_tests— 1/1cargo test -p backend ticket307_activation_reconcile_tests— 1/1cargo test -p application --test workstate— 29/29cargo check -p backendgit 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 unconversationIdfrontend 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 toujoursreconcile_layouts,reconcile_live_state,reconcile_background_tasks.GetProjectWorkStatefiltre les background tasks partask.project_id == project.idavant projection.- Frontend:
CustomAgentChatViewgarde le messageConversation liée — récupération du transcript en cours.quanddisplayTurns.length === 0 && hasLinkedConversation;hasLinkedConversationreste vrai avec unconversationIdseul.
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
conversationIdisolé survit indépendamment de l'état live/backend.
Commandes exécutées et sorties réelles:
$ cargo fmt --all -- --check
<no output, exit 0>
$ git diff --check
<no output, exit 0>
$ 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
$ 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
$ 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
$ 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
$ 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
$ 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
$ 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'
$ (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-stateworkingcorrélé persisté + background taskRunningorpheline -> activation -> live-stateidle,correlation_id/ticket/délégation effacés, taskFailed, aucune task ouverte reprojetable. - La réconciliation background est bien bornée par
projectIdet 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 unconversationIdisolé 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
CustomAgentChatViewutilisaithasLinkedConversationaprès la fin deopenOrAttach, sans distinguer une récupération encore active d'une récupération terminée sans aucun tour. - Un
conversationIdisolé 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 foisopeningterminé et sans tour affichable, une conversation toujours liée affiche désormais littéralementConversation liée — transcript indisponible.. Le spinner reste borné àopening; la cellule et leconversationIdne 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 boutonRéessayerdans 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:
$ (cd frontend && npm test -- CustomAgentChatView.test.tsx)
Test Files 1 passed (1)
Tests 72 passed (72)
Duration 4.04s
$ (cd frontend && npm run typecheck)
tsc --noEmit
exit 0
$ 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_ideffacé, réconciliation background bornée parprojectId, smokeBackendCore::activate_project(). - Diff frontend:
CustomAgentChatView.tsxremplace l'état vide post-récupération parConversation liée — transcript indisponible.. - Test frontend:
CustomAgentChatView.test.tsxcouvre le casconversationIdisolé sans tours récupérés et vérifie l'absence de l'ancien libellé, du spinner et du boutonRéessayer.
Commandes exécutées et sorties réelles:
$ git diff --check
<no output, exit 0>
$ 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
$ 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
$ 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
$ 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
$ 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
$ (cd frontend && npm test -- CustomAgentChatView.test.tsx)
Test Files 1 passed (1)
Tests 72 passed (72)
Duration 3.97s
$ (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 expliciteConversation liée — transcript indisponible.. - Risque résiduel limité: le garde-fou frontend suppose toujours que
openOrAttachfinit 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-reconciliationcréée depuis develop @99b400a; commit fix57cf825(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; artefacttarget/release/bundle/appimage/IdeA_0.3.0_amd64.AppImage(119871992 octets, mtime 2026-09-10 14:21:49) de sha256e6e22132970357d8a67338edaf4c3b0adbee7a66265e09211e733abfa08825daidentique à celui documenté par99b400a— 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/etscripts/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.