feat(symlinks): add shared-state symlink manager (A1)

Adds internal/symlinks package that encodes in code the convention
previously maintained by hand on the VM: every Claude account home
must expose `session-env`, `file-history` and `projects` as symlinks
to a single shared target, so account failover does not create
divergent state (duplicate JSONL transcripts, broken undo history).

- EnsureForAccount(home, required) creates missing links and target
  directories, refuses to auto-correct a divergent link (risks data
  loss), and errors when a regular file sits where the link belongs.
- ValidateAll(homes, required) aggregates errors across both accounts
  so the operator sees every problem at once rather than fixing one
  per restart cycle.
- RequiredShared exposes the production defaults so lifecycle and
  switcher (A2/A3) can depend on it directly.

9/9 unit tests green.

Part of Phase 1 Chantier A — Failover robuste.
This commit is contained in:
Ubuntu 2026-04-16 18:55:32 +00:00
parent 4cbdcf143a
commit 91091d7abf
4 changed files with 414 additions and 4 deletions

View file

@ -1,4 +1,30 @@
# Version actuelle : 0.3.4
# Version actuelle : 0.3.5
## [0.3.5] - 2026-04-16
**Type:** Patch — Phase 1 / Chantier A1 : package `internal/symlinks`
### Ajouté
- `internal/symlinks/shared.go` : `EnsureForAccount` + `ValidateAll` qui
encodent en code la convention des 3 symlinks partagés par compte
(`session-env`, `file-history`, `projects`). Jusqu'à aujourd'hui ces
liens étaient maintenus à la main et leur absence silencieuse cassait
le failover (JSONL dupliqués, undo désynchronisé).
- Tests unitaires couvrant : création missing, idempotence, divergence
(refus d'auto-correction pour éviter la perte de données), fichier
régulier à la place du lien, home vide, agrégation d'erreurs multi-comptes.
### Rationale
- Un déploiement sur une nouvelle VM ne peut plus omettre les liens.
- Divergent link → erreur explicite, jamais de correction silencieuse.
- Préparation des tâches A2 (ValidateAll au startup) et A3 (EnsureForAccount
post-flipSymlink dans le switcher).
### Tests
- ✅ `go test ./internal/symlinks/...` : 9/9 PASS
### Fichiers ajoutés
- `internal/symlinks/shared.go`
- `internal/symlinks/shared_test.go`
## [0.3.4] - 2026-04-16
**Type:** Patch — Dispatcher ne route JAMAIS vers les sessions dédiées