# 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.
