Files
IdeA/.ideai/tickets/2/issue.md
Blomios 8e481aed69 chore(ideai): état d'orchestration du sprint #13 (transport HTTP/WS + surface web)
Versionne l'état runtime IdeA produit pendant le sprint #13 : store de
tickets (dont les nouveaux #55 à #67), compteur et index, notes de mémoire
projet des lots F0 à F5, et journal des tâches de fond.

Séparé du code applicatif conformément à la convention du dépôt
(cf. ad1f225, a244f32) : métadonnée d'orchestration last-writer-wins,
sans impact sur le build.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 10:32:39 +02:00

3.2 KiB

id, number, title, status, priority, sprint, links, agentRefs, createdBy, updatedBy, createdAt, updatedAt, version
id number title status priority sprint links agentRefs createdBy updatedBy createdAt updatedAt version
0a492d45-e195-4df7-a2ad-65649372abf0 2 Tâches de fond — dette A : découpler fin de process et flux output PTY (PtyPort::wait/try_wait) closed low e28a4d53-8bd2-446a-b0ac-2a017373b8b2
agentId role
a6ced819-b893-4213-b003-9e9dc79b9641 assigned
kind agent_id
agent a6ced819-b893-4213-b003-9e9dc79b9641
kind agent_id
agent a6ced819-b893-4213-b003-9e9dc79b9641
1783082860742 1784065385002 6

Ticket #2 — Tâches de fond : découpler fin de process et flux output PTY.

REQUALIFIÉ (2026-07-14) : le hub broadcast PTY existe désormais (crates/infrastructure/src/pty/mod.rs), donc l'ancienne contrainte « pas de broadcast multi-consommateur » est OBSOLÈTE. Le volet « tee live UI » est sorti en sous-ticket B/F séparé (voir lien blocks). La dette restante ici est purement backend.

Constat : CommandBackgroundRunner détecte encore la fin d'une tâche en drainant PtyPort::subscribe_output jusqu'à EOF (crates/infrastructure/src/background_task/runner.rs:187), ce qui couple la lifecycle du process à la consommation de sortie et empêche un tee sans casser la détection.

Attendu :

  • Ajouter au port figé PtyPort (crates/domain/src/ports.rs:952) deux opérations explicites :
    • async fn wait(&self, handle: &PtyHandle) -> Result<ExitStatus, PtyError> (attend la fin naturelle + status ; documenter l'idempotence : premier wait consomme, suivants retournent le status mémorisé).
    • fn try_wait(&self, handle: &PtyHandle) -> Result<Option<ExitStatus>, PtyError> (non bloquant : Ok(None) si vivant, Ok(Some(status)) si terminé).
  • kill reste « forcer l'arrêt puis retourner status » ; si déjà terminé, retourne le status mémorisé. NotFound si handle inconnu/purgé. L'exit status est mémorisé dans le registre live tant que la session existe (cohérence wait/try_wait/kill).
  • Implémenter dans PortablePtyAdapter (état d'exit partagé, attendre le child sans dépendre du reader EOF, éviter double wait/kill) et dans tous les fakes de test.
  • Migrer le runner : remplacer l'attente EOF (runner.rs:187) par une attente sur pty.wait(&handle), concurrencée avec cancel/deadline. La sortie de completion reste prise depuis le scrollback borné ; le runner n'a plus besoin de subscribe_output pour savoir si le process est fini.

Impact contractuel : port figé modifié → changement source-breaking intra-workspace (tous les adapters/fakes ajoutent wait/try_wait), mais PAS de breaking IPC/front, pas de migration de données.

Lots : B1 wait/try_wait au port + fakes ; B2 impl PortablePtyAdapter ; B3 migrer CommandBackgroundRunner vers wait ; B4 tests. Taille M.

QA (point de vérité) :

  • Fake PtyPort dont l'output n'est jamais drainé (ou consommé par 2 subscribers) mais wait résout → le runner complète quand même.
  • Fake avec subscriber UI actif + runner → completion via wait, pas via EOF.
  • Deadline : si wait ne résout pas avant deadline → runner retourne Expired et tue/cleanup correctement.
  • Cancel : cancel gagne même si l'output continue.
  • Portable PTY réel : commande courte (echo hi) → completion exit 0 sans dépendre d'un drain output.