Export JSON workflows-n8n/chlova-alerts.v1.0.0.json (webhook → mail, formate par type d'alerte) + doc d'asset (palier privileged, rollback). ALERT_WEBHOOK_URL dans .env.example + compose (vide = log-only). need-review.md : alertes implémentées. Compose revalidé, 53 tests, 0 vuln. Palier de risque : privilégié (workflow envoie des mails) — désactivable via ALERT_WEBHOOK_URL vide ; non exécuté depuis le dépôt. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3.2 KiB
Cycle "need review" (Phase 2)
Pièce maîtresse. Tout asset/op privilégié est sous review avant exécution. Voir
docs/risk-tiers.md(paliers) etdocs/security.md(sécurité).
Asset & états
Un asset (table SQLite assets, src/gatekeeper/repository.ts) suit :
- PROVISOIRE : créé et exécutable, sursis de 7 jours (réservé au palier
reversible). - APPROUVÉ : review OK → permanent, plus d'alertes.
- REFUSÉ : review KO → désactivé.
- BLOQUÉ : sursis écoulé OU palier
privileged(aucun sursis) → non exécutable ; toute tentative lève une alerte.
Champs : id, type, version, risk_tier, status, created_at, expires_at, exec_count, commit_link, doc_link.
Règle de sursis (non négociable)
reversible→ PROVISOIRE 7 j (createAssetposeexpires_at = +7j).privileged→ BLOQUÉ immédiat, aucun sursis (expires_at = null).- Le LLM ne peut jamais reclasser un asset (
assertNoEscalation:privileged → reversibleinterdit). Le palier vient des annotations MCP.
Gatekeeper (src/gatekeeper/gatekeeper.ts)
Vérifie le statut avant chaque exécution (canExecute) :
- lecture seule → autorisée, sans asset ;
- privilégié inconnu → enregistré BLOQUÉ + exécution refusée + hook d'alerte ;
- privilégié APPROUVÉ → exécuté,
exec_countincrémenté ; - REFUSÉ / BLOQUÉ / sursis expiré → refusé.
Branché via GatekeeperGuard (interface Guard ; la boucle agent est inchangée).
Cron (src/gatekeeper/review.ts)
startExpiryCron passe horairement les PROVISOIRE échus en BLOQUÉ
(expireProvisional). runExpiryOnce = un passage (testable).
Review (humaine, hors LLM)
Commandes owner Telegram (src/surfaces/commands.ts) :
/pending, /approve <id>, /refuse <id>, /help. Le LLM n'y a pas accès :
seul l'humain change un statut.
Gate de phase
CHLOVA_PHASE (défaut 1). Phase 1 : aucun outil mutant exposé, ReadOnlyGuard.
Phase 2 : tous les outils exposés, GatekeeperGuard, cron + review actifs.
Passage à CHLOVA_PHASE=2 requis pour toute écriture (et PORTAINER_READ_ONLY
peut alors valoir false).
Rollback
- Repasser
CHLOVA_PHASE=1→ écriture désactivée, retour au cerveau read-only. git revertdu commit de l'asset fautif ; redeploy version N-1 (GitOps).- Un asset REFUSÉ reste tracé (audit) ; suppression via op SQL manuelle si besoin.
Alertes (Phase 3 — implémenté)
Stratégie anti-fatigue (src/alerts/) :
- tentative bloquée → alerte immédiate (
onBlockedAttempt) ; - 1ʳᵉ exécution d'un asset PROVISOIRE → alerte immédiate (
onFirstProvisionalExec) ; - digest quotidien + rappel J-1 →
startAlertScheduler(runAlertCycleOnce).
Transport : HttpAlertSender POST vers ALERT_WEBHOOK_URL (webhook n8n) ; sans
URL, NullAlertSender log-only (fail-safe). Best-effort : une panne d'alerte ne
casse jamais l'agent. Le mail est envoyé par le workflow
workflows-n8n/chlova-alerts.v1.0.0.json (doc : docs/assets/workflow-chlova-alerts.md).
Le payload ne contient aucun secret.
Reste à faire (Phase 4+)
- Auto-extension : CHLOVA génère commit + version + doc d'un asset avant de le passer en need-review (Phase 4).