Files
vmux/.planning/phases/02-daemon-et-i3-bridge/02-VERIFICATION.md
2026-03-23 19:20:03 +01:00

154 lines
12 KiB
Markdown

---
phase: 02-daemon-et-i3-bridge
verified: 2026-03-23T17:00:00Z
status: human_needed
score: 5/5 must-haves verified
re_verification: false
human_verification:
- test: "vmux list affiche les sessions avec workspace [ws:N]"
expected: "Chaque session Claude Code active est listee avec son numero de workspace i3"
why_human: "Necessite un environnement i3 + X11 actif avec des sessions Claude Code en cours"
- test: "vmux switch <query> bascule vers le bon workspace"
expected: "Le focus i3 se deplace vers le workspace de la session matchee"
why_human: "Necessite un environnement i3 actif et plusieurs sessions dans des workspaces differents"
- test: "Autostart daemon : vmux list depuis un terminal sans daemon actif"
expected: "Le daemon demarre automatiquement, la liste s'affiche sans erreur"
why_human: "Necessite de verifier le comportement de detachement du processus fils (Setsid)"
---
# Phase 02: Daemon et i3 Bridge — Rapport de verification
**Phase Goal:** L'utilisateur peut switcher vers n'importe quelle session Claude Code en une action via son workspace i3
**Verified:** 2026-03-23T17:00:00Z
**Status:** human_needed
**Re-verification:** Non (verification initiale)
## Criteres de succes (source ROADMAP.md)
1. vmuxd tourne en arriere-plan et maintient le registre des sessions a jour
2. Chaque session est associee a son workspace i3 (visible dans `vmux list`)
3. `vmux switch <session>` bascule vers le workspace i3 correspondant
4. L'utilisateur peut attribuer un label humain a une session (`vmux label <session> "review MR !456"`)
5. Chaque session en attente affiche le temps ecoule ("depuis 3 min")
## Verites observables
| # | Verite | Statut | Evidence |
| --- | ----------------------------------------------------------------------------------- | ---------- | --------------------------------------------------------------------------------- |
| 1 | Le daemon maintient un registre des sessions a jour (poll toutes les 5s) | VERIFIE | `daemon.go:246-258` poll loop + `daemon.go:192` scan initial synchrone |
| 2 | Le daemon ecoute sur un Unix socket et repond aux requetes JSON | VERIFIE | `daemon.go:198` `net.Listen("unix", ...)` + handlers list/label/switch/stop |
| 3 | Les labels sont persistes dans ~/.vmux/labels.json | VERIFIE | `daemon.go:131-143` `save()` avec `os.WriteFile` + `MkdirAll` |
| 4 | Le temps d'attente est tracke quand une session passe a NeedsInput | VERIFIE | `daemon.go:48-53` transition WaitingSince dans `Update()` |
| 5 | Un PID Claude Code est resolu vers son workspace i3 via la chaine PPID | VERIFIE | `workspace.go:51-64` `ResolveWorkspace` + max 20 niveaux |
| 6 | Le fuzzy match trouve une session par label, branche ou cwd | VERIFIE | `i3bridge.go:24-49` priorite label > GitBranch > Cwd, case-insensitive |
| 7 | Le switch vers un workspace i3 fonctionne via i3 IPC RunCommand | VERIFIE | `i3bridge.go:52-66` `SwitchToWorkspace` + `daemon.go:354-378` handler "switch" |
| 8 | vmux list affiche workspace, label et temps d'attente pour chaque session | VERIFIE | `display.go:74-88` affichage conditionnel [ws:N], label entre guillemets, "depuis" |
| 9 | vmux switch <query> bascule vers le workspace i3 de la session matchee | VERIFIE | `main.go:56-77` + wiring daemon.go switch handler |
| 10 | vmux label <session> <texte> attribue un label humain | VERIFIE | `main.go:79-101` + `daemon.go:331-352` avec fuzzy match |
| 11 | Le daemon demarre automatiquement si absent quand on lance une commande | VERIFIE | `client.go:46-84` `EnsureDaemon()` + spawn via `os.Executable() + "daemon"` |
**Score:** 5/5 criteres ROADMAP verifies (11/11 verites codees verifiees)
## Artefacts requis
| Artefact | Attendu | Statut | Details |
| ----------------- | -------------------------------------------------------- | -------- | ------------------------------------------------------------------------------ |
| `protocol.go` | Types Request, Response, SessionInfo pour IPC socket | VERIFIE | Request, Response, SessionInfo, SwitchArgs, LabelArgs — tous definis |
| `daemon.go` | SessionRegistry, LabelStore, boucle de poll, Unix socket | VERIFIE | 409 lignes, toutes structures et methodes presentes |
| `types.go` | Session enrichi avec Workspace, Label, WaitingSince | VERIFIE | Champs Workspace, Label, WaitingSince ajoutes |
| `workspace.go` | Resolution PID -> workspace via PPID chain + X11 | VERIFIE | ReadPPID, ResolveWorkspace, BuildTerminalWorkspaceMap, interfaces |
| `i3bridge.go` | Interface I3Client, fuzzy match, switch workspace | VERIFIE | FuzzyMatch, SwitchToWorkspace, I3Commander, RealI3Commander |
| `client.go` | Client Unix socket CLI -> daemon | VERIFIE | Client.Send(), EnsureDaemon() avec retry 50ms x 20 |
| `main.go` | Dispatch sous-commandes list/switch/label/stop/daemon | VERIFIE | case "list", "switch", "label", "stop", "daemon" tous implementes |
| `display.go` | Affichage enrichi avec workspace, label, temps d'attente | VERIFIE | DisplaySessionInfos avec [ws:N], label entre guillemets, "depuis X min" |
## Verification des liens cles
| De | Vers | Via | Statut | Details |
| ----------- | ------------- | -------------------------- | -------- | ---------------------------------------------------- |
| client.go | daemon.go | Unix socket ~/.vmux/vmux.sock | VERIFIE | `net.DialTimeout("unix", ...)` en lignes 24, 48, 76 |
| main.go | client.go | Dispatch sous-commandes | VERIFIE | `client.Send(...)` appele pour chaque sous-commande |
| daemon.go | i3bridge.go | FuzzyMatch + SwitchToWorkspace | VERIFIE | lignes 339, 361, 374 dans daemon.go |
| daemon.go | workspace.go | workspaceResolver dans poll loop | VERIFIE | `BuildTerminalWorkspaceMap` + `ResolveWorkspace` en lignes 180-184 |
| daemon.go | proc.go | FindClaudeProcesses dans scanOnce | VERIFIE | ligne 261 `FindClaudeProcesses(d.procDir)` |
## Trace de flux de donnees (Niveau 4)
| Artefact | Variable | Source | Produit des donnees reelles | Statut |
| ------------- | ----------------- | ----------------------------- | --------------------------- | -------- |
| display.go | sessions | daemon via socket JSON | Oui — sessions reelles de /proc + JSONL | FLUIDE |
| daemon.go | registry.sessions | scanOnce() -> FindClaudeProcesses | Oui — scan /proc reel | FLUIDE |
| daemon.go | workspace | workspaceResolver(pid) | Oui si X11 disponible, "" sinon | FLUIDE (degradation gracieuse) |
| client.go | Response | net.Conn JSON decode | Oui — reponse daemon | FLUIDE |
## Verification comportementale (Spot-checks)
| Comportement | Commande | Resultat | Statut |
| ----------------------- | ------------------------------------------------------ | ------------ | -------- |
| Tous les tests passent | `nix-shell -p go --run "go test -v -race ./..."` | PASS (100%) | PASS |
| Build sans erreur | `nix-shell -p go --run "go build -o /dev/null ./..."` | Build OK | PASS |
| go.i3wm.org/i3/v4 present | `grep "go.i3wm.org" go.mod` | v4.24.0 OK | PASS |
| vmux list en vrai | `./vmux list` | Necessite env i3 | SKIP (env) |
| vmux switch en vrai | `./vmux switch <query>` | Necessite env i3 | SKIP (env) |
## Couverture des requirements
| Requirement | Plan source | Description | Statut | Evidence |
| ----------- | ----------- | ------------------------------------------------------------------- | -------- | --------------------------------------------- |
| DISC-04 | 02-01, 02-03 | vmux permet d'associer un label humain a une session | SATISFAIT | LabelStore + daemon handler "label" + main.go case "label" |
| STATE-04 | 02-01, 02-03 | vmux affiche le temps ecoule depuis que la session attend | SATISFAIT | SessionRegistry.Update() WaitingSince + DisplaySessionInfos "depuis X min" |
| I3-01 | 02-02, 02-03 | vmux mappe chaque session a son workspace i3 | SATISFAIT | ResolveWorkspace + BuildTerminalWorkspaceMap + display [ws:N] |
| I3-02 | 02-02, 02-03 | vmux permet de switcher vers le workspace i3 d'une session en une action | SATISFAIT | FuzzyMatch + SwitchToWorkspace + daemon "switch" + main.go "switch" |
Tous les 4 requirements declares sont satisfaits. Aucun requirement orphelin detecte.
## Anti-patterns detectes
| Fichier | Ligne | Motif | Severite | Impact |
| ---------- | ----- | ------------------------ | -------- | ------------------------------------------------------ |
| (aucun) | - | - | - | Aucun stub, placeholder ou implementation vide detecte |
Analyse detaillee :
- Aucun `return null` / `return {}` / `return []` sans requete reelle
- Aucun TODO/FIXME/PLACEHOLDER
- Les fonctions `EnsureDaemon`, `SwitchToWorkspace`, `FuzzyMatch`, `DisplaySessionInfos` sont toutes pleinement implementees
- Le `workspaceResolver` nilable est un choix delibere de degradation gracieuse (i3/X11 absent), pas un stub
## Verification humaine requise
### 1. Workspace visible dans vmux list
**Test:** Lancer `./vmux list` sur une machine avec i3 + X11 actif et plusieurs sessions Claude Code dans des workspaces differents.
**Attendu:** Chaque session affiche `[ws:N]` avec le bon numero de workspace i3.
**Pourquoi humain:** La chaine PPID -> X11 _NET_WM_PID -> workspace necessite un environnement graphique reel. Les tests unitaires utilisent des mocks.
### 2. Switch effectif vers le workspace
**Test:** Lancer `./vmux switch <partie-du-nom>` depuis un workspace different de la cible.
**Attendu:** Le focus i3 bascule vers le workspace de la session matchee. La session correspond au query par label, branche ou cwd.
**Pourquoi humain:** `SwitchToWorkspace` appelle `i3.RunCommand` qui necessite un IPC socket i3 actif.
### 3. Autostart transparent
**Test:** Stopper le daemon (`vmux stop`), puis lancer `vmux list` depuis un terminal frais.
**Attendu:** Le daemon se lance en arriere-plan sans message d'erreur, la liste apparait apres ~1s max.
**Pourquoi humain:** Le comportement de detachement (Setsid via `sysattr_linux.go`) et le retry de 50ms x 20 sont difficiles a tester automatiquement sans piquer sur le timing reel.
## Resume
La phase 02 atteint son objectif : l'ensemble du code permettant a l'utilisateur de switcher vers n'importe quelle session Claude Code via son workspace i3 est present, substantiel, cable et passe 100% des tests automatises (incluant les tests avec -race).
Les 5 criteres de succes du ROADMAP sont tous implementes :
- Le daemon vmuxd est complet (registre, poll, socket, autostart)
- L'association session <-> workspace i3 est implementee via PPID chain + X11
- `vmux switch` est fonctionnel de bout en bout
- `vmux label` avec fuzzy match est operationnel
- L'affichage du temps d'attente "depuis X min" est implemente
Seule verification humaine manquante : comportement reel sur i3/X11 (inevitable, non testable automatiquement sans relancer i3).
---
_Verifie : 2026-03-23T17:00:00Z_
_Verificateur : Claude (gsd-verifier)_