5.7 KiB
issueRef, version, updatedBy, updatedAt
| issueRef | version | updatedBy | updatedAt | ||||
|---|---|---|---|---|---|---|---|
| #101 | 7 |
|
1785011116365 |
Carnet #101 — défaut d'isolation multi-projet (cause racine figée)
Diagnostic Architect (2026-07-25). Source de vérité du fix. Mémoire durable :
ticket101-cross-talk-multi-project-rootcause.
Cause racine
Stores disque IdeA correctement scoppés par projet (mémoire, contexte, handoff, live-state lus
depuis input.project.root ; agents persistés dans .ideai/agents.json par root projet, sans
re-mint des UUID à l'ouverture). Mais plusieurs registres mémoire runtime restent globaux,
indexés par AgentId seul → deux projets ouverts (surtout si l'un est une copie) peuvent porter
les mêmes AgentId et le runtime les confond.
2 manifestations, même défaut
- A — contamination du contexte d'inférence : conversation/session d'un projet réutilisée pour
l'autre → contexte injecté à l'agent contaminé (preuve : pseudo-branche
wear-os-watch-synccréée par l'agent Git avec un nom de l'autre projet). - B — notification de tâche backend perdue / agent s'arrête (sujet original) : complétion livrable/bloquée/réveillant la mauvaise session.
Points précis (registres par AgentId seul à requalifier)
- ConversationRegistry global +
ConversationIddérivé des UUID agents seuls :crates/domain/src/conversation.rs:71,crates/infrastructure/src/conversation/mod.rs:41, orchestrateurcrates/application/src/orchestrator/service.rs:2192(et:2293,:2368). - Sessions PTY/structured par
agent_idseul :crates/application/src/terminal/registry.rs:182,437. - Verrous ask / busy-state / liveness / délégations différées :
crates/application/src/orchestrator/service.rs:418,crates/infrastructure/src/input/mod.rs:47. - Inbox/mailbox par
AgentIdseul :crates/domain/src/inbox.rs:68,156,crates/infrastructure/src/input/mod.rs:1052,crates/infrastructure/src/mailbox/mod.rs:44. - Wake par
AgentIdseul :crates/application/src/orchestrator/wake.rs:87, providercrates/backend/src/lib.rs:687.
Pour B — distinction runtime vs modèle
La chaîne sink→project_id→wake est correcte jusqu'au bridge
(crates/infrastructure/src/background_task/sink.rs:23,142 ; crates/backend/src/lib.rs:2228
recharge le projet par project_id puis wake_agent). Le défaut réapparaît juste après
(inbox/mailbox/busy/session par AgentId seul). Runtime IdeA suspecté en premier. GLM 5.2 n'est
l'hypothèse principale que si les logs prouvent enqueue+wake+BackgroundTaskCompletionDelivered
sur le bon projet sans reprise. Traces : lib.rs:2238, wake.rs:93.
Décision utilisateur
Lancer le fix structurel maintenant (lots 1-2). La collision d'UUID et les logs B se vérifieront en parallèle.
Périmètre DevBackend (lots 1-2 de ce fix)
- Lot 1 : introduire une clé runtime scellée
RuntimeAgentKey { project_id, agent_id }; interdire toute map app-wide indexée parAgentIdseul. - Lot 2 : propager la clé dans
AgentInbox,InputMediator,AgentMailbox, busy/liveness/deferred, wake, session lookup, ask-locks. Correctif structurel commun à A et B.
Lots suivants (3-6, hors premier passage) : qualifier ConversationId/registry par projet (lot 3) ;
requalifier TerminalSessions/StructuredSessions par (project_id, agent_id) +
AppWakeSessionProvider refuse l'autre projet (lot 4) ; audit session_limit/tables reprise (lot 5) ;
télémétrie project_id sur logs diag wake/routage (lot 6).
Invariants
- Sources de contexte sur disque restent root-scopées (ne pas régresser).
- Templates/profils globaux restent globaux produit (pas de vecteur de session/conversation partagée).
- Un projet non-actif doit continuer à recevoir ses wakes et complétions.
- Pas de régression OpenCode/Codex/Claude (correctif transverse runtime, pas moteur-spécifique).
- Aucun nouveau DTO frontend pour la correction minimale.
QA — critère de vérité
Test d'intégration non-cross-talk : 2 projets ouverts avec volontairement les mêmes AgentId :
- délégation projet A ne réutilise jamais session/conversation vivante de projet B ;
- complétion
(projet A, agent X)n'entre ni dans l'inbox ni dans la session de(projet B, agent X); - wake d'un projet non-actif fonctionne ;
- collision d'ids qui échouait avant → verte sur PTY, structured et background wake.
Clôture 2026-07-25
- Correctif livré sur
feature/ticket101-multi-project-isolationpuis mergé localement dansdevelop. - Commit feature :
6e98fd8 fix(runtime): isolate agent state by project (#101). - Merge local :
merge: integrate ticket 101 multi-project isolation. - QA ciblée verte :
cargo test -p application --test agent_wake --test orchestrator_service --test structured_registry_d1 --test structured_launch_d3 --test session_limit_service --test session_limit_t4 --test workstate --test workstate_actionscargo test -p infrastructure --test agent_inbox --test mcp_servercargo test -p app-tauri --test session_limit_wiringcargo test -p applicationcargo test -p app-tauri --tests
- Réserve connue :
cargo test -p infrastructurecomplet reste rouge dans le sandbox QA sur testsopenai_compatà cause du bind local interdit (Operation not permitted), sans signal de régression #101.
Hors périmètre
- #91 (popup de notification) : purement front, indépendant.
- Remint systématique des AgentId à l'ouverture : non retenu (la clé runtime rend la collision inoffensive même sans remint).
Lié
- #91 (relatesTo). Mémoires :
background-tasks-first-class-design,b8-command-runner-pty-framing,mcp-bridge-and-delegation-runtime-notes(règle rebuild AppImage).