Files
chlova/docs/need-review.md
T
Kantin-Petit 2bfa58f440 feat: outil propose_asset + auto-extension exposée, fin Phase 5 v1 (v0.27.0)
Outil local sanctionné chlova.propose_asset : l'agent propose un asset →
write+commit+version+doc → need-review (privilégié = BLOQUÉ). Notion
ToolSpec.sanctioned (autorisé par gatekeeper, audité). Flag
CHLOVA_AUTOEXT_ENABLED (off défaut) + CHLOVA_REPO_ROOT. Prompt impose un
palier honnête. 75 tests, 0 vuln, compose OK.

Palier de risque : privilégié (l'agent écrit+commit) — derrière flag +
Phase 2 ; l'asset produit n'est jamais exécuté, il reste sous review.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 06:38:45 +02:00

81 lines
4.0 KiB
Markdown

# 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) et `docs/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 (`createAsset` pose `expires_at = +7j`).
- `privileged`**BLOQUÉ immédiat, aucun sursis** (`expires_at = null`).
- Le LLM ne peut jamais reclasser un asset (`assertNoEscalation` :
`privileged → reversible` interdit). 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_count` incré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 revert` du 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.
## Auto-extension (Phase 5 — implémenté)
Quand aucune capacité n'existe, l'agent appelle l'outil **sanctionné**
`chlova.propose_asset` (`src/autoext/`) qui :
1. écrit l'artefact (workflow/outil) + sa doc (gabarit) dans le dépôt ;
2. **commit + versionne** (commit ciblé, jamais `git add -A`) ;
3. enregistre l'asset en need-review (privilégié → **BLOQUÉ**, aucun sursis) ;
4. émet l'alerte `asset_created` (version + commit + doc).
L'asset n'est **jamais exécuté** par ce canal : il attend la review (/approve).
Un outil sanctionné est autorisé par le gatekeeper mais **audité** ; il ne touche
pas l'infra. Désactivé par défaut (`CHLOVA_AUTOEXT_ENABLED=false`) ; requiert un
dépôt git monté (`CHLOVA_REPO_ROOT`). Le LLM ne peut pas sous-classer un asset
privilégié (palier honnête imposé par le prompt + non négociable côté review).
## Reste à faire (Phase 6+)
- Voix : STT + wake-word + TTS dans l'UI (API déjà prête).