From 2375374f2fd72328c5284c1f914da87c96d25e48 Mon Sep 17 00:00:00 2001 From: Pierre Martin Date: Mon, 23 Mar 2026 19:20:03 +0100 Subject: [PATCH] docs(phase-02): complete phase execution --- .planning/STATE.md | 12 +- .../02-daemon-et-i3-bridge/02-VERIFICATION.md | 153 ++++++++++++++++++ 2 files changed, 159 insertions(+), 6 deletions(-) create mode 100644 .planning/phases/02-daemon-et-i3-bridge/02-VERIFICATION.md diff --git a/.planning/STATE.md b/.planning/STATE.md index e411e2e..d8d16af 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -2,14 +2,14 @@ gsd_state_version: 1.0 milestone: v1.0 milestone_name: milestone -status: Ready to execute +status: Ready to plan stopped_at: Completed 02-02-PLAN.md -last_updated: "2026-03-23T16:47:11.294Z" +last_updated: "2026-03-23T18:19:56.401Z" progress: total_phases: 4 - completed_phases: 1 + completed_phases: 2 total_plans: 5 - completed_plans: 4 + completed_plans: 5 --- # Project State @@ -23,8 +23,8 @@ See: .planning/PROJECT.md (updated 2026-03-23) ## Current Position -Phase: 02 (daemon-et-i3-bridge) — EXECUTING -Plan: 3 of 3 +Phase: 3 +Plan: Not started ## Performance Metrics diff --git a/.planning/phases/02-daemon-et-i3-bridge/02-VERIFICATION.md b/.planning/phases/02-daemon-et-i3-bridge/02-VERIFICATION.md new file mode 100644 index 0000000..5baa461 --- /dev/null +++ b/.planning/phases/02-daemon-et-i3-bridge/02-VERIFICATION.md @@ -0,0 +1,153 @@ +--- +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 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 ` bascule vers le workspace i3 correspondant +4. L'utilisateur peut attribuer un label humain a une session (`vmux label "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 bascule vers le workspace i3 de la session matchee | VERIFIE | `main.go:56-77` + wiring daemon.go switch handler | +| 10 | vmux label 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 ` | 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 ` 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)_