feat(lifecycle): validate shared symlinks at daemon startup (A2)

Wire symlinks.ValidateAll into the lifecycle manager so the daemon
refuses to start if any configured account is missing one of the
shared-state symlinks or if a link diverges from the canonical target.

Previously, a missing link on a freshly deployed VM would silently
create a divergent state tree per account (duplicate JSONL transcripts,
broken undo history) — exactly the failure mode the symlinks package
(A1) was introduced to prevent.

The check runs once at startup before EnsureAllSessions, guarding a
single well-defined invariant: "every account home shares the same
projects/, file-history/ and session-env/ roots". No auto-heal on
divergence — we fail fast with an explicit error so the operator fixes
it manually rather than one account's state being overwritten.

Part of Phase 1 Chantier A — Failover robuste.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ubuntu 2026-04-16 19:03:43 +00:00
parent 91091d7abf
commit e16e3526a0
3 changed files with 68 additions and 1 deletions

View file

@ -1,4 +1,31 @@
# Version actuelle : 0.3.5
# Version actuelle : 0.3.6
## [0.3.6] - 2026-04-16
**Type:** Patch — Phase 1 / Chantier A2 : validation des symlinks au startup
### Ajouté
- `Manager.ValidateSharedSymlinks()` : nouvelle méthode dans
`internal/lifecycle` qui agrège les `Home` de tous les comptes
configurés et délègue à `symlinks.ValidateAll`. Échoue dur si un
compte n'a pas de `home` défini ou si un lien est absent/divergent.
- `cmd/claude-failover/main.go` appelle cette validation **avant**
`EnsureAllSessions()` : un état partagé cassé ne laissera plus le
daemon démarrer et divergér silencieusement.
### Rationale
- Un opérateur qui copie la config sur une nouvelle VM ne peut plus
oublier les liens — le daemon refuse de démarrer jusqu'à ce qu'ils
soient corrects.
- Pas d'auto-heal sur divergence : on préfère un message d'erreur
explicite à un `rm -f` silencieux qui détruirait l'autre compte.
### Tests
- ✅ `go test ./...` : tous les packages PASS (incluant
`internal/lifecycle` et `internal/symlinks`).
### Fichiers modifiés
- `cmd/claude-failover/main.go` (+9)
- `internal/lifecycle/manager.go` (+31)
## [0.3.5] - 2026-04-16
**Type:** Patch — Phase 1 / Chantier A1 : package `internal/symlinks`