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.
4.1 KiB
4.1 KiB
Travaux en Cours - claude-failover
Dernière mise à jour
2026-04-16 19:00:00
Version Actuelle
0.3.5 (en cours de progression vers 0.4.0)
Demande Actuelle
Phase 1 / Chantier A — Failover robuste (spec dans ccl-platform/phases/phase1/A-failover.md).
Rendre le failover compte1 ↔ compte2 déterministe en intégrant dans le code les fixes manuels
(symlinks partagés), en ajoutant un registre UUID fiable, et en durcissant tmux send-keys.
Branche : feat/phase1-A-failover-robust.
Sous-tâches Chantier A
- A1 —
internal/symlinks/shared.go(+ tests) — v0.3.5 - A2 —
lifecycle/manager.go:ValidateAllau startup - A3 —
switcher/account_switcher.go:EnsureForAccountpost-flip - A4 —
internal/registry/uuid_registry.go(+ tests) - A5 —
internal/tmux/send.goavec retry exponentiel (+ tests) - A6 — Capture UUID 200 → 500 lignes
- A7 —
scripts/test-failover.shdans ccl-platform + scripts associés
Étapes Complétées
- v0.2.1 — Cooldown post-swap + log forensique (trigger_session, pattern, snippet)
- v0.2.2 — Confirmation 2-polls pour les hits sans reset time
- v0.2.3 — Veto 5xx (
api_error/overloaded_error/internal server error) et retrait du pattern générique"rate limit"(remplacé parrate_limit_error) - Documentation :
docs/architecture.md§2.2.1 "False-positive protection" - Tests unitaires exhaustifs (14 cas pour
isQuotaExhausteddont les 3 veto 5xx) - Déploiement prod :
/usr/local/bin/claude-failover+ service redémarré - Push sur Forgejo
origin/main(commits7c5f838et62e98cb)
Prochaines Étapes
préserver les sessions dédiées lors d'un swap légitime— fait en v0.3.0 viasaveDedicatedUUIDs+relaunchDedicatedSessions.- Optionnel : telegram alert quand
SwapRequestedest émis pour que l'opérateur soit au courant sans lire les logs. Lenotifier.Telegramexiste déjà — il suffit de câbler. - Optionnel : exposer
/quota/statusviainternal/apiavec les champslast_swap_at,suspected_hit_at,cooldown_remainingpour le dashboard.
Contexte Important
- Symptôme en prod (2026-04-15) : daemon faisait des swaps compte1↔compte2
en boucle (intervalle descendant à 1 min), tuant les sessions interactives
ccl-1 et ccl-2 en permanence.
reset=""sur tous les events. - Cause racine identifiée via le log forensique v0.2.1 : les 500 d'Anthropic
contenaient le texte "rate limit" dans leur payload. Snippet capturé :
API Error: 500 {"type":"error","error":{"type":"api_error",...}}. Le monitor les confondait avec de vrais 429. - Config
reactivate_cooldown: "5m"existait déjà dans config.yaml mais n'était consommée que par le dispatcher — pas par le monitor. v0.2.1 a branché le monitor dessus. - Comptes disponibles :
compte1(Claude Max),compte2(Claude Team). Symlink actuel :~/.claude → .claude-compte2. - Sessions tmux gérées : pool autonome
ccl-auto-*(min=2, max=10) + dédiéesccl-1-conformvault,ccl-2-scanyze.
Fichiers Modifiés (cette série de fixes)
internal/quota/monitor.go— quotaPatterns, serverErrorPatterns, suspectedHitAt, cooldowninternal/quota/monitor_test.go— 14 sous-tests isQuotaExhausted + 3 tests pollinternal/state/state.go— LastSwapAt/From/To + RecordSwap + LastSwapInfointernal/switcher/account_switcher.go— appelstate.RecordSwap()après swapdocs/architecture.md— §2.2.1 False-positive protectionVERSION.md— changelog 0.2.1 → 0.2.3
Bugs Connus
- Sessions dédiées tuées lors d'un swap légitime : comportement documenté et voulu (respawn sur le nouveau compte), mais coupe brutalement le travail interactif en cours. Voir Prochaines Étapes.
Historique des Demandes (Récentes)
| Date | Version | Demande | Status |
|---|---|---|---|
| 2026-04-15 | 0.2.1 | Casser le ping-pong + logs forensiques | Terminé |
| 2026-04-15 | 0.2.2 | Confirmation 2-polls pour absorber les flashes | Terminé |
| 2026-04-15 | 0.2.3 | Veto 5xx + patterns stricts (root cause) | Terminé |