Capitalise la mémoire projet produite pendant la campagne de tests fonctionnels MCP (rendez-vous inter-agents, backstop no-reply, réconciliation live-state au reboot) et synchronise l'état runtime `.ideai/` (agents, layouts, skills, index mémoire). Inclut la mise à jour du contexte de l'agent Git. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
34 lines
3.1 KiB
Markdown
34 lines
3.1 KiB
Markdown
---
|
|
name: backstop-fires-on-intra-task-turn-rootcause
|
|
description: memory note backstop-fires-on-intra-task-turn-rootcause
|
|
metadata:
|
|
type: project
|
|
---
|
|
---
|
|
title: CAUSE RACINE — le backstop tire sur chaque tour interne (turn_duration ≠ retour-au-prompt)
|
|
type: project
|
|
description: Le turn-watcher fait tirer le backstop no-reply au PREMIER turn_duration, soit le 1er pas d'agent interne — il casse toute délégation multi-étapes (libération prématurée + rapport perdu). Le test QA pong passait par chance (tâche mono-tour).
|
|
---
|
|
# CAUSE RACINE (2026-06-23, prouvée live) — backstop tire sur les tours INTERNES
|
|
|
|
## Preuve
|
|
Cadrage délégué à Architect (tâche multi-étapes, lecture de code) :
|
|
```
|
|
562100 [rendezvous] ask started -> Architect turn_timeout_ms=600000
|
|
564943 [rendezvous] ask returned-to-prompt-no-reply: Architect after_ms=2843
|
|
564943 [mailbox] complete_without_reply agent=dce19c75 ticket=cc4067fa outcome=sent
|
|
```
|
|
- Tiré à **2843 ms** : impossible qu'Architect ait fini un cadrage en 2,8 s.
|
|
- Au même instant, transcript Architect **toujours en écriture** (Bash/Read en boucle), `idea_reply` count = **0** → Architect **continuait à travailler**.
|
|
- Transcript = **61 `turn_duration`** : Claude écrit un `turn_duration` **par tour d'agent interne** (chaque appel LLM de la boucle agentique), PAS seulement au retour-au-prompt final.
|
|
|
|
## Diagnostic
|
|
`claude_turn_watcher.rs` fait tirer `turn_ended` au **premier incrément** de `turn_duration` au-dessus de la baseline. Or cet incrément survient dès le **1er pas interne** de l'agent (~secondes). Donc le backstop confond « l'agent a fait un pas de raisonnement » avec « l'agent est retourné au prompt sans répondre ». Pour **toute tâche multi-étapes** : libération prématurée du demandeur « sans réponse » pendant que la cible bosse encore → `idea_reply` final → « no pending request » → **rapport perdu** (travail survit sur disque/branche).
|
|
|
|
Le test QA « pong » (backstop-no-reply-live-test-failed-2026-06-23, devenu vert) passait **par chance** : tâche à **un seul tour** ⇒ premier tour = dernier tour. Le fix `encode_cwd` a fait tirer le watcher correctement, mais a **révélé que la CONDITION de tir est fausse**.
|
|
|
|
## Conséquence opérationnelle
|
|
Avec le binaire courant, **aucune délégation substantielle (multi-tours) ne remonte son rapport** : elle est coupée à ~3 s. Workaround Main en attendant le fix : déléguer → surveiller le transcript de la cible jusqu'à inactivité (mtime stable) → récupérer le résultat sur disque/branche ou re-solliciter en léger.
|
|
|
|
## Implication pour la refonte (seam liveness/fin-de-tour, validée utilisateur)
|
|
« Retourné au prompt idle » NE peut PAS être « un turn_duration est apparu ». Le bon signal = **process vivant (`is_agent_live`) + transcript NE grossit PLUS depuis stall_after_ms** (battement de cœur). Tant que le transcript grossit ⇒ l'agent travaille ⇒ ne pas libérer. Le 1er lot du fix devrait **neutraliser ce tir prématuré**. Lié à [[rendezvous-600s-cap-too-short-heavy-tasks]], [[rendezvous-no-reply-backstop-design]], [[backstop-no-reply-live-test-failed-2026-06-23]]. |