chore(tickets): sync store local — #292 passage qa après QA verte (carnet complet cause/fix/validations, index/counter; scripts/ hors périmètre; aucun push)

This commit is contained in:
2026-09-09 14:30:45 +02:00
parent 00a32220d1
commit 9fb87a6b74
4 changed files with 370 additions and 1 deletions

View File

@ -0,0 +1,336 @@
---
issueRef: "#292"
version: 5
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedAt: 1788956518862
---
# Carnet #292 — Agents Git TUI Native UnitySoundTool/UnityPlugin
## Symptôme utilisateur
Le 2026-09-09, l'utilisateur signale que les agents `Git` des projets `UnitySoundTool` (`/home/anthony/Documents/Projects/SoundTool`) et `UnityPlugin` (`/home/anthony/Documents/Projects/UnityPlugin`) bouclent sans répondre avec une entrée simple type `Hello` en TUI Native, et le CPU monte à 100%. L'agent `Git` du projet IdeA courant marche avec une configuration apparemment identique.
## Cadrage Architect
Architect confirme que les trois agents `Git` utilisent le même profil `5ef495f8-4e6c-58e5-b3c9-f32ec8ffac55` (`GLM5.2`), `command: opencode`, `structuredAdapter: openCode`, config MCP via `opencode.json`. Le libellé `TUI Native` décrit la surface visible, pas un profil Codex brut.
Contrat attendu si fix runtime: une entrée humaine dans une TUI Native/OpenCode ne peut produire qu'un seul write utilisateur, un seul tour actif par agent, et aucune relance automatique sans action explicite ou erreur terminale exposée.
## Données collectées
Agents Git:
- IdeA: `1ff94b51-3e17-4a39-8543-7715d1ff0f80`, template `07670754-878b-4a37-8e18-5b061c51cd9b`, syncedTemplateVersion `14`.
- UnityPlugin: `15e9bbaf-8212-4c6e-a592-9d4f7fb44bf1`, même profile/template, syncedTemplateVersion `13`.
- UnitySoundTool: `af772fd8-306e-4ea0-aa20-8f6f537c3377`, même profile/template, syncedTemplateVersion `14`.
`opencode.json` des trois run dirs est identique hors `--endpoint`, `--project`, `--requester` et `cwd`. Tous pointent vers `/home/anthony/Documents/Projects/IdeA/.appimage-build/target/release/bundle/appimage/IdeA_0.3.0_amd64.AppImage mcp-server` et le modèle `zai-coding-plan/glm-5.3`.
Run dirs Git:
- IdeA: `.ideai/run/1ff94b51-3e17-4a39-8543-7715d1ff0f80/{AGENTS.md,opencode.json,.mcp.json}`.
- UnityPlugin: `.ideai/run/15e9bbaf-8212-4c6e-a592-9d4f7fb44bf1/{AGENTS.md,opencode.json}`.
- UnitySoundTool: `.ideai/run/af772fd8-306e-4ea0-aa20-8f6f537c3377/{AGENTS.md,opencode.json}`.
`AGENTS.md` diff: les projets Unity ont naturellement un contexte projet différent; SoundTool a plusieurs skills Unity dans le contexte. Ce n'est pas censé expliquer une boucle CPU au simple `Hello`.
États persistés:
- IdeA `.ideai/live-state.json`: Git `done`.
- SoundTool `.ideai/live-state.json`: Git `done`, ticket `c5801e75-14f7-4564-9702-c9667174457e`.
- UnityPlugin `.ideai/live-state.json`: pas d'entrée Git.
- `chat-drafts.json`: drafts vides pour UnityPlugin et SoundTool.
- Les commandes `jq '.tabs, .nodes // empty' .ideai/layouts.json` ont retourné `null` pour UnityPlugin et SoundTool; format à inspecter plus directement si nécessaire.
Limite de diagnostic: depuis le sandbox Main, `ps` ne voit que les processus du sandbox, donc l'identification du process à 100% (`IdeA`, `opencode`, `node`, `mcp-server`) doit être faite par QA hors sandbox ou via logs applicatifs.
## Hypothèses actuelles
1. Boucle runtime OpenCode/MCP ou launch/reattach propre aux projets externes: les sockets/cwd changent mais le profil est identique.
2. Boucle frontend TUI Native: double submit, reattach/render loop ou écriture répétée de l'entrée humaine.
3. État projet/layout/session stale non capturé par `live-state.json` simple.
4. UnityPlugin a un template Git v13 au lieu de v14, mais SoundTool échoue aussi en v14, donc ce n'est pas la cause unique.
## Suite attendue
Demander à Git la branche locale, puis DevBackend pour investigation runtime/PTY/OpenCode/MCP/reconciliation. DevFrontend seulement si DevBackend trouve un double-submit ou une boucle de reattach côté surface. QA devra reproduire sur les trois projets avec le vrai binaire AppImage.
## Diagnostic DevBackend — 2026-09-09
Cause localisée dans la réattache frontend de la TUI native, pas dans le runtime
OpenCode structuré, le lancement PTY ni la réconciliation backend.
Preuves :
- `launch_agent` fixe `allow_structured_alongside_pty=false` et ne demande le chemin
structuré que pour une cellule `Chat`. La surface courante ignore ce `cellKind` et
rend toute cellule agent via `TerminalView` : le profil OpenCode est donc lancé une
fois comme TUI native dans un PTY. `OpenCodeSession::send_inner` n'est pas sur ce
chemin utilisateur.
- `LaunchAgent::execute` consulte les registres avant tout I/O et rend la session
existante sur réattache/idempotence. Les tests ciblés de non-respawn sont verts.
- `PortablePtyAdapter::Broadcast::subscribe` remplace le subscriber précédent : il
n'existe qu'un seul pump de sortie actif par PTY après réattache. Le test ciblé est
vert.
- Le log hôte `/home/anthony/.local/share/app.idea.ide/logs/idea.log` corrèle
directement SoundTool Git `af772fd8-306e-4ea0-aa20-8f6f537c3377` :
`front_attached=true` à `1788954519395`, puis 119 appels `write_terminal` sur la
session `557f7aff-2ee5-47f3-9e5b-4d268e255eab` avant le détachement à
`1788954524075`, sans séquence de saisie `Hello`/Entrée dans cette fenêtre.
Le burst commence par des réponses terminal synthétiques xterm : `ESC[1;1R`,
`ESC[?1016;2$y`, `ESC[?2027;0$y`, `ESC[?2031;0$y`, `ESC[?1004;2$y`,
`ESC[?2004;2$y`, `ESC[?2026;2$y`, device attributes et réponses focus.
- Dans `frontend/src/features/terminals/TerminalView.tsx`, `term.onData` est installé
avant la réattache. Le callback met toute donnée dans `pending` tant que le handle
est absent. Après `reattacher(...)`, le code fait `term.write(scrollback)` puis
`adopt(h)` ; le replay des anciennes requêtes terminal provoque donc de nouvelles
réponses xterm, les accumule dans `pending`, puis `adopt` les réinjecte physiquement
dans le PTY. C'est une boucle de replay/réponse propre aux sessions TUI riches en
séquences de contrôle, ce qui explique l'écart entre projets malgré le même profil.
Le correctif appartient à DevFrontend : pendant le replay du scrollback de réattache,
les données synthétiques produites par xterm ne doivent pas être relayées au handle ni
ajoutées à `pending`. Le relais `term.onData` doit devenir actif seulement après le
callback de fin de `term.write(scrollback)` (ou être explicitement suspendu pendant ce
replay), tout en conservant le chemin nominal de frappe utilisateur ensuite. Test de
régression attendu dans `TerminalView.test.tsx` : un scrollback contenant des requêtes
terminal déclenche des réponses xterm simulées mais zéro `handle.write`; une saisie
`Hello` + Entrée après replay produit exactement les writes utilisateur attendus.
Aucun correctif backend n'a été appliqué : filtrer les réponses terminal dans
`write_terminal` casserait le protocole PTY normal et masquerait l'origine frontend.
Aucun fichier des projets Unity n'a été modifié.
## Validations DevBackend
- `cargo test -p infrastructure pty --lib` — vert, 26 tests passés, 352 filtrés.
- `cargo test -p application --test agent_lifecycle launch_same_node_is_idempotent_no_respawn` — vert, 1 passé.
- `cargo test -p application --test agent_lifecycle launch_existing_agent_with_no_node_is_background_noop` — vert, 1 passé.
- `cargo test -p application --test orchestrator_service agent_run_visible_same_cell_rebinds_existing_session` — vert, 1 passé.
- `npm test -- --run src/features/terminals/TerminalView.test.tsx` depuis `frontend/` — vert, 21 tests existants ; la couverture actuelle ne simule pas les réponses xterm émises pendant le replay et doit être complétée par DevFrontend.
Suite : DevFrontend implémente et teste la suspension du relais pendant le replay ; QA
rebuild l'AppImage puis reproduit sur SoundTool, UnityPlugin et IdeA, en contrôlant dans
`idea.log` qu'une saisie humaine ne produit qu'une seule séquence utilisateur et aucun
burst de réponses historiques à la réattache. Pour identifier le consommateur CPU hors
sandbox, QA peut utiliser `ps -eo pid,ppid,pcpu,comm,args --sort=-pcpu` puis corréler le
PID OpenCode/renderer avec l'heure du burst `pty-write`.
## Correctif DevFrontend — 2026-09-09
Le relais xterm → PTY est désormais activé selon le cycle de montage :
- ouverture fraîche : activation immédiate, afin de conserver le buffering des frappes
humaines pendant la résolution de l'opener ;
- réattache avec scrollback : aucun abonnement `term.onData` pendant
`term.write(scrollback)` ; activation seulement dans le callback de fin du replay,
puis adoption du handle ;
- réattache sans scrollback et fallback vers une ouverture fraîche : activation avant
adoption/ouverture selon le même invariant ;
- cleanup : disposal conditionnel de l'abonnement, puisqu'il peut ne pas encore exister
si la vue est démontée pendant le replay.
Le test de non-régression simule une requête de position curseur (`ESC[6n`) dans le
scrollback et une réponse xterm synthétique (`ESC[1;1R`) émise par `term.write`. Il
vérifie zéro appel à `handle.write` pendant le replay, puis exactement un appel contenant
`Hello\r` après la fin du replay.
Fichiers modifiés :
- `frontend/src/features/terminals/TerminalView.tsx`
- `frontend/src/features/terminals/TerminalView.scrollback.test.tsx`
- `.ideai/tickets/292/carnet.md`
Validations réelles :
- `git diff --check` — vert.
- `npm --prefix frontend test -- --run src/features/terminals/TerminalView.scrollback.test.tsx src/features/terminals/TerminalView.portal.test.tsx src/features/terminals/TerminalView.test.tsx` — vert, 3 fichiers et 27 tests passés. jsdom signale seulement son avertissement connu `HTMLCanvasElement.getContext()` non implémenté.
- `npm --prefix frontend run build` — vert (`tsc --noEmit` puis Vite, 515 modules transformés). Seul l'avertissement existant de chunk supérieur à 500 kB reste présent.
Reste à QA : rebuild de l'AppImage et reproduction hôte sur UnitySoundTool,
UnityPlugin et IdeA avec contrôle de l'absence de burst `pty-write` à la réattache.
## Validation QA — 2026-09-09
Verdict QA : VERT sur le contrat automatisé et l'artefact AppImage. Limite explicite :
la reproduction hôte complète par interaction graphique dans les trois projets n'a pas
pu être conduite depuis ce sandbox QA sans envoyer des frappes à l'aveugle dans
l'application visible.
Diff relu :
- `frontend/src/features/terminals/TerminalView.tsx` : l'abonnement `term.onData` est
désormais créé par `activateInput()`. Sur réattache avec scrollback, `term.write` reçoit
un callback final qui active seulement ensuite le relais xterm -> PTY et adopte le
handle. Le chemin ouverture fraîche garde l'activation immédiate pour conserver le
buffering des frappes humaines.
- `frontend/src/features/terminals/TerminalView.scrollback.test.tsx` : le stub xterm
émet une réponse synthétique `ESC[1;1R` pendant le replay de `ESC[6n`; le test vérifie
zéro écriture PTY pendant ce replay, puis une seule écriture `Hello\r` après activation.
Commandes réelles exécutées depuis `/home/anthony/Documents/Projects/IdeA` :
```bash
git status --short --branch
```
```text
## fix/292-tui-native-git-agents-loop
M .ideai/tickets/counter.json
M .ideai/tickets/index.json
M frontend/src/features/terminals/TerminalView.scrollback.test.tsx
M frontend/src/features/terminals/TerminalView.tsx
?? .ideai/tickets/292/
?? scripts/
```
```bash
git diff --check
```
```text
<aucune sortie, exit 0>
```
```bash
npm --prefix frontend test -- --run src/features/terminals/TerminalView.scrollback.test.tsx src/features/terminals/TerminalView.portal.test.tsx src/features/terminals/TerminalView.test.tsx
```
```text
Test Files 3 passed (3)
Tests 27 passed (27)
Duration 2.82s
```
La sortie contient aussi l'avertissement jsdom connu :
`Not implemented: HTMLCanvasElement's getContext() method: without installing the canvas npm package`.
```bash
npm --prefix frontend run build
```
```text
tsc --noEmit && vite build
515 modules transformed.
dist/assets/index-Cce2ycJb.js 1,261.08 kB
✓ built in 2.60s
```
Vite signale seulement l'avertissement existant de chunk supérieur à 500 kB.
Rebuild AppImage réel :
```bash
cd crates/app-tauri
APPIMAGE_EXTRACT_AND_RUN=1 NO_STRIP=1 ../../frontend/node_modules/.bin/tauri build --bundles appimage
```
```text
Running beforeBuildCommand `npm --prefix ../frontend run build:bundle`
Finished `release` profile [optimized] target(s) in 2m 26s
Built application at: /home/anthony/Documents/Projects/IdeA/target/release/app-tauri
Bundling IdeA_0.3.0_amd64.AppImage (/home/anthony/Documents/Projects/IdeA/target/release/bundle/appimage/IdeA_0.3.0_amd64.AppImage)
Finished 1 bundle at:
/home/anthony/Documents/Projects/IdeA/target/release/bundle/appimage/IdeA_0.3.0_amd64.AppImage
```
Vérification d'artefact :
```bash
stat -c '%n %s %Y %i' /home/anthony/Documents/Projects/IdeA/target/release/bundle/appimage/IdeA_0.3.0_amd64.AppImage /home/anthony/Documents/Projects/IdeA/.appimage-build/target/release/bundle/appimage/IdeA_0.3.0_amd64.AppImage
```
```text
/home/anthony/Documents/Projects/IdeA/target/release/bundle/appimage/IdeA_0.3.0_amd64.AppImage 119478776 1788956753 12345211
/home/anthony/Documents/Projects/IdeA/.appimage-build/target/release/bundle/appimage/IdeA_0.3.0_amd64.AppImage 119478776 1788956753 12345211
```
Les deux chemins sont le même artefact hardlinké, ce qui couvre les `opencode.json` des
agents Git affectés qui pointent vers `.appimage-build/.../IdeA_0.3.0_amd64.AppImage`.
```bash
sha256sum /home/anthony/Documents/Projects/IdeA/.appimage-build/target/release/bundle/appimage/IdeA_0.3.0_amd64.AppImage
```
```text
4165521e4248ec9f71af4ceb1c89d3aa54e8119a1ccf0f70d15268bdc67eaf94 /home/anthony/Documents/Projects/IdeA/.appimage-build/target/release/bundle/appimage/IdeA_0.3.0_amd64.AppImage
```
Contrôles hôte tentés :
```bash
env | sort | rg 'DISPLAY|WAYLAND|XDG_RUNTIME|IDEA|APPIMAGE|TAURI'
```
```text
APPIMAGE=/home/anthony/Documents/Projects/IdeA/.appimage-build/target/release/bundle/appimage/IdeA_0.3.0_amd64.AppImage
DISPLAY=:0
IDEA_MANAGED_TMP=/home/anthony/.local/share/app.idea.ide/managed-tmp/accb434c-d2d1-4c01-b928-72e738151fdc/data
QT_WAYLAND_RECONNECT=1
WAYLAND_DISPLAY=wayland-0
XDG_RUNTIME_DIR=/run/user/1000
```
```bash
xdotool search --name 'IdeA - Agents' getwindowgeometry %@
```
```text
Window 44040214
Position: 0,28 (screen: 0)
Geometry: 1920x1052
```
```bash
import -window 44040214 /home/anthony/.local/share/app.idea.ide/managed-tmp/accb434c-d2d1-4c01-b928-72e738151fdc/data/idea-agents-window-292.png
```
```text
import: missing an image filename `/home/anthony/.local/share/app.idea.ide/managed-tmp/accb434c-d2d1-4c01-b928-72e738151fdc/data/idea-agents-window-292.png' @ error/import.c/ImportImageCommand/1291.
```
```bash
xwd -id 44040214 -silent -out /home/anthony/.local/share/app.idea.ide/managed-tmp/accb434c-d2d1-4c01-b928-72e738151fdc/data/idea-agents-window-292.xwd && convert /home/anthony/.local/share/app.idea.ide/managed-tmp/accb434c-d2d1-4c01-b928-72e738151fdc/data/idea-agents-window-292.xwd /home/anthony/.local/share/app.idea.ide/managed-tmp/accb434c-d2d1-4c01-b928-72e738151fdc/data/idea-agents-window-292.png
```
```text
X Error of failed request: BadMatch (invalid parameter attributes)
Major opcode of failed request: 73 (X_GetImage)
```
```bash
APPIMAGE_EXTRACT_AND_RUN=1 /home/anthony/Documents/Projects/IdeA/.appimage-build/target/release/bundle/appimage/IdeA_0.3.0_amd64.AppImage --version
```
```text
(app-tauri:12): Gdk-WARNING **: The program 'app-tauri' received an X Window System error.
The error was 'BadAccess (attempt to access private resource denied)'.
```
```bash
ps -eo pid,ppid,pcpu,pmem,comm,args --sort=-pcpu | head -40
```
```text
PID PPID %CPU %MEM COMMAND COMMAND
1 0 20.0 0.0 codex codex-linux-sandbox ...
```
Le sandbox PID ne voit que ses propres processus ; il ne permet donc pas de mesurer
fiablement le CPU des processus hôtes IdeA/OpenCode.
Contrôle log :
```bash
tail -80 /home/anthony/.local/share/app.idea.ide/logs/idea.log
```
Le log actuel confirme surtout la signature pré-fix déjà collectée avant relance :
bursts `pty-write` de réponses synthétiques historiques (`\x1b[1;1R`, `\x1b[?1;2c`,
bulk writes) autour des sessions Git. Après le rebuild, aucun scénario graphique
nouveau n'a été exécuté depuis QA ; je ne conclus donc pas sur une absence live de burst
dans UnitySoundTool/UnityPlugin/IdeA.
Conclusion QA :
- VERT pour le correctif frontend ciblé : le test ajouté couvre la cause racine et
échouerait si `onData` restait actif pendant le replay.
- VERT pour les suites ciblées et le build frontend.
- VERT pour le rebuild AppImage avec `APPIMAGE_EXTRACT_AND_RUN=1 NO_STRIP=1`, artefact
disponible sur le chemin utilisé par les agents.
- Validation live hôte des trois Git TUI Native non conclue depuis ce sandbox faute de
pilotage UI fiable et de visibilité PID hôte. Une relance d'IdeA sur l'AppImage
rebuildée puis une saisie manuelle `Hello` dans IdeA, UnitySoundTool et UnityPlugin
reste le seul complément non automatisé.

View File

@ -0,0 +1,17 @@
---
id: "0889ead8-ddde-4655-a5cb-2a66531c3786"
number: 292
title: "Agents Git TUI Native bouclent sans réponse dans UnitySoundTool et UnityPlugin"
status: "qa"
priority: "high"
sprint: null
links: []
agentRefs: [{"agentId":"ab328d90-c307-4771-a3b6-6c56089c8506","role":"assigned"}]
attachments: []
createdBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
createdAt: 1788955001961
updatedAt: 1788956518862
version: 5
---
Symptôme rapporté le 2026-09-09 : dans les projets UnitySoundTool et UnityPlugin, l'agent Git lancé en TUI Native avec une commande simple comme "Hello" boucle, ne répond jamais et fait monter le CPU à 100%. L'agent Git du projet IdeA actuel, configuré de manière apparemment identique, fonctionne correctement. Investigation attendue : comparer les manifests/profils/runtime TUI Native de ces projets, identifier la différence effective, puis corriger côté runtime/config si IdeA provoque une boucle de lancement ou d'entrée PTY.

View File

@ -1,3 +1,3 @@
{
"nextNumber": 292
"nextNumber": 293
}

View File

@ -3993,6 +3993,22 @@
"agent_id": "a6c6ea12-bfc6-4bdc-8031-324102dfa34d"
},
"updatedAt": 1788940935288
},
{
"issueRef": "#292",
"path": "292",
"title": "Agents Git TUI Native bouclent sans réponse dans UnitySoundTool et UnityPlugin",
"status": "qa",
"priority": "high",
"sprint": null,
"assignedAgentIds": [
"ab328d90-c307-4771-a3b6-6c56089c8506"
],
"createdBy": {
"kind": "agent",
"agent_id": "a6c6ea12-bfc6-4bdc-8031-324102dfa34d"
},
"updatedAt": 1788956518862
}
]
}