Files
arboretum/spikes/s1-resume/VERDICT.md
Johan LEROY c98f619b25 Spike S1: resume/fork/liveness — GO; flood: pause/resume — GO
Demonstrated on CLI 2.1.173: resuming a live session interleaves both
TUIs into one transcript (no lock, no warning) — liveness detection via
registry pid+procStart is mandatory; --fork-session is safe on live
sessions; --resume must run in the session's original cwd ("No
conversation found" otherwise); registry files are cleaned on graceful
exit AND SIGTERM, may be GC'd later after SIGKILL — never reason on
file presence. ANSI-stripped TUI text loses spaces (cursor-positioned
painting) — confirms @xterm/headless for screen parsing.
Flood: 21 MB through node-pty with 10s pause => 0 bytes leaked, no
loss, 4.7 ms echo after flood.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 17:47:05 +02:00

3.4 KiB
Raw Blame History

Spike S1 — resume / fork / vivacité — VERDICT : GO

Exécuté le 2026-06-11 (CLI claude 2.1.173, repos jetables /tmp/spike-s1-*). Scripts : harness.mjs + run.mjs, captures brutes et results.json dans captures/ (non versionnés).

Faits démontrés

# Scénario Résultat
1 claude --resume <id> pendant que la session est vivante Aucun verrou, aucun avertissement. B s'ouvre sur le même sessionId, les deux process s'inscrivent au registre avec le même sessionId, et les messages des deux TUI s'entrelacent dans le même transcript (ALPHA/BRAVO/CHARLIE dans un seul fichier). Corruption logique confirmée → le daemon DOIT détecter la vivacité avant tout resume.
2 --resume <id> --fork-session sur session vivante Sûr. Nouveau sessionId, nouveau fichier contenant la copie de l'historique + ses propres messages ; l'original n'est pas pollué. C'est l'opération à proposer pour une session vivante (« Dupliquer »).
3 kill -9 puis détection Le fichier registre reste (stale) immédiatement après ; pid mort + procStart discordant le détectent à coup sûr. --resume après mort : même sessionId, continuation propre dans le même fichier, 0 parentUuid cassé.
4 resume depuis un autre cwd Échec explicite : « No conversation found with session ID » — le CLI cherche la session dans le dossier projet dérivé du cwd courant. → Le daemon doit toujours lancer --resume dans le cwd d'origine de la session (champ cwd du JSONL), comme prévu au design.
5 sortie gracieuse (/exit) Exit code 0, fichier registre nettoyé.
6 SIGTERM Fichier registre nettoyé aussi (handler du CLI).
7 GC des stale Le fichier stale du kill -9 a été nettoyé plus tard par une autre instance du CLI → ne jamais raisonner sur la présence/absence du fichier, toujours valider pid+procStart à la lecture.

Enseignements supplémentaires pour le claude-adapter

  • Le strip ANSI naïf mange les espaces : le TUI peint le texte par déplacements de curseur (« Isthisaprojectyoucreated… »). Toute détection sur texte brut doit matcher sur une version sans espaces ; la reconstruction d'écran fiable passe par @xterm/headless (confirme la reco du design moteur).
  • Trust dialog (nouveau dossier) : précède l'inscription au registre, texte « Quick safety check: Is this a project you created or one you trust? », options 1. Yes, I trust this folder / 2. No, exit, « Enter to confirm · Esc to cancel ». Entrée valide l'option par défaut → géré.
  • Le registre s'écrit ~immédiatement après le trust ; waitReady = poll du registre par pid est une primitive fiable de readiness.
  • Les réponses des sessions -n/spawnées apparaissent bien dans ~/.claude/projects/<munge(cwd)>/<sid>.jsonl en continu (flush par tour).

Décisions actées pour P1/P3

  1. Politique de reprise (inchangée vs design) : vivante → Observer/Dupliquer uniquement ; morte → resume direct ; incertain → traiter comme vivante.
  2. --resume toujours exécuté dans le cwd d'origine lu dans le JSONL.
  3. isLive() = pid+procStart à chaque lecture du registre, jamais de cache de présence de fichier.
  4. La machine à états peut compter sur le nettoyage du registre aux sorties propres (exit//exit/SIGTERM) et sur la détection procStart pour les morts brutales.