56e948c976
Table assets sur node:sqlite (Node 24, zéro dep native) : CRUD, listByStatus, incrementExec, setRiskTier anti-escalade, expireProvisional (cron PROVISOIRE→BLOQUÉ). 6 tests. Bump Node 24 (sqlite stable), Dockerfile 24.13 + copie tsconfig.build.json. 0 vuln. Palier de risque : reversible (persistance d'état, aucune mutation d'infra). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
orchestrator — backend CHLOVA
Le cerveau : LLM en boucle tool-calling. Phase 1 = lecture seule. Seule
surface exposée de la stack (voir ../CLAUDE.md, ../docs/architecture.md).
Stack
Node 22, TypeScript (ESM, NodeNext, strict), Fastify, MCP SDK officiel, pino
(audit), zod (config), Vitest (tests). Toutes deps épinglées ; npm audit
doit rester à 0 vuln.
Démarrage (dev)
cp ../.env.example ../.env # renseigner les secrets (jamais commités)
npm install
npm run dev # tsx watch
npm run typecheck
npm test
Modules
| Fichier | Rôle |
|---|---|
src/config.ts |
Config fail-closed (zod). Refuse de démarrer si secret manquant. assertReadOnlyPhase() verrouille la lecture seule P1. redactedConfig() masque les secrets. |
src/audit/log.ts |
Logger pino + journal d'audit des exécutions d'outils. |
src/index.ts |
Bootstrap : config → verrou RO → logger → (P1) MCP + agent + Telegram. Healthcheck interne. |
src/llm/ |
Client Ollama + boucle agent (v0.6.0). |
src/mcp/ |
Registry MCP + readonly-filter (v0.7.0). |
src/gatekeeper/ |
Paliers de risque + table assets (interfaces P1, câblé P2). |
src/surfaces/ |
Surface Telegram (v0.8.0). |
Sécurité
- Secrets par référence uniquement, jamais loggés (
redactedConfig+ redact pino). - Phase 1 :
PORTAINER_READ_ONLY=falsefait échouer le démarrage. - Aucun port publié (Telegram long-polling) ; Fastify n'écoute qu'en interne.
Palier de risque
reversible (lecture seule). Aucune capacité d'écriture branchée en Phase 1.