3.7 KiB
name, description, metadata
| name | description | metadata | ||
|---|---|---|---|---|
| ticket95-adapter-aware-liveness-probe | memory note ticket95-adapter-aware-liveness-probe |
|
#95 — Sonde de vivacité du rendez-vous devenue adapter-consciente
Type : correctif architecture / bug racine. Livré sur feature/rendezvous-liveness-probe-per-adapter (commit 376fc9f), AppImage 0.3.0 rebuildée.
Bug racine
Le rendez-vous idea_ask_agent (run_inactivity_watchdog, crates/application/src/orchestrator/rendezvous.rs) coupe en faux NoReply toute cible structurée dont le tour dépasse la fenêtre d'inactivité (défaut 600 s, = turn_timeout_ms du profil cible). Cause : la seule sonde de vivacité (transcript_activity_token) lisait le transcript Claude (~/.claude/projects/<encoded-cwd>/*.jsonl) — invisible pour OpenCode/Codex, et fragilise même Claude en mode -p headless si le transcript ne grossit pas mi-tour. has_probe=true mais la sonde renvoie None ⇒ bras (true,_,None)=>false ⇒ aucun réarmement ⇒ NoReply à la première fenêtre.
Fix (architecture figée)
- Port domaine (
crates/domain/src/ports.rs) :AgentSession::activity_token() -> Option<u64>(défautNone, zéro régression). Jeton monotone = « la session travaille ». - Machinerie (
crates/infrastructure/src/session/process.rs) :run_turn_with_activity(...)bump unArc<AtomicU64>à chaque ligne stdout lue (drain async ET drain sandboxé thread).run_turn(4 args) délègue avecNone⇒ les ~11 call sites de test sont intacts. - Sessions :
ClaudeSdkSession,CodexExecSession,OpenAiCompatibleSessionoverridentactivity_token()viarun_turn_with_activity;OpenCodeSession(drain inline) bump son propre compteur par ligne JSONL. - Sonde composite (
resolve_ask_liveness_token,crates/backend/src/lib.rs) : préfèresession.activity_token()de la session vivante (structured.session_for_agent), repli inchangé sur le transcript Claude. Câblée par.with_ask_liveness_probe.
Contrats clés
has_proberestetruedès qu'une sonde est câblée ; la sonde composite renvoie désormaisSome(token)qui avance ⇒ la fenêtre se réarme. Le repli transcript Claude couvre le cas « session vivante sans override ».- La fenêtre =
turn_timeout_msdu profil cible (turn_timeout_for→liveness_for_agent), défautASK_AGENT_TIMEOUT600 s. Pas d'env global pour la fenêtre (seul le plafond aIDEA_ASK_RENDEZVOUS_CEILING_MS, défaut 4 h). - Pour un test live rapide sans attendre 600 s : mettre un petit
turn_timeout_ms(ex. 20 000) sur le profil de la cible, puis déléguer une tâche de ~60-90 s.
État validation
- Tests unitaires verts :
run_turn_with_activity_bumps_counter_per_line,*_session_activity_token_advances_across_a_turn(claude/codex/opencode), + la sonde composite backend + le watchdog rendezvous existants. - AppImage 0.3.0 rebuildée + installée (
/home/anthony/Documents/IdeA_0.3.0_amd64.AppImage, backup.old-pre95fix). Relance IdeA requise pour l'activer (le binaire qui tourne = AppImage en mémoire ; relancer depuis l'intérieur tue la session courante).
À noter (dette / hors périmètre)
- #96 (EffectivePermissions assistants de ticket) laissé ouvert, documenté dans le carnet #96 (décision produit différée).
- Le souvenir utilisateur initial décrivait un échec « demandeur GLM/OpenCode → cible Claude ». Mécaniquement le watchdog est ciblé-cible (keyed sur l'agent cible) : un échec sur cible Claude longue n'est possible que si le transcript Claude
-pne grossit pas mi-tour (couvert désormais par l'activity_tokende ClaudeSdkSession). La théorie principale reste « cible structurée longue non observée → faux NoReply ».