Files
IdeA/.ideai/tickets/101/carnet.md

5.7 KiB

issueRef, version, updatedBy, updatedAt
issueRef version updatedBy updatedAt
#101 7
kind agent_id
agent a6ced819-b893-4213-b003-9e9dc79b9641
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-sync créé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 + ConversationId dérivé des UUID agents seuls : crates/domain/src/conversation.rs:71, crates/infrastructure/src/conversation/mod.rs:41, orchestrateur crates/application/src/orchestrator/service.rs:2192 (et :2293, :2368).
  • Sessions PTY/structured par agent_id seul : 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 AgentId seul : crates/domain/src/inbox.rs:68,156, crates/infrastructure/src/input/mod.rs:1052, crates/infrastructure/src/mailbox/mod.rs:44.
  • Wake par AgentId seul : crates/application/src/orchestrator/wake.rs:87, provider crates/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 par AgentId seul.
  • 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-isolation puis mergé localement dans develop.
  • 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_actions
    • cargo test -p infrastructure --test agent_inbox --test mcp_server
    • cargo test -p app-tauri --test session_limit_wiring
    • cargo test -p application
    • cargo test -p app-tauri --tests
  • Réserve connue : cargo test -p infrastructure complet reste rouge dans le sandbox QA sur tests openai_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).