Chapitres
Sur cette page
DOC-04 / Référence technique · Chapitre 01
Vue d'ensemble du harness agentique Synedre OS
Cette page introduit l'architecture du harness de Synedre OS en décrivant ses trois couches d'exécution (Nuxt mothership-app, Python synedre/, scripts bin/), leur articulation autour de la base PostgreSQL unique vaisseau_mere_ac, le cycle de vie d'une demande et les principes de gouvernance du système.
Vue d'ensemble — le dispositif agentique Synedre OS
Cette page est l'entrée du dossier de documentation sur le dispositif agentique. Elle pose le cadre : ce qu'est ce dispositif, comment ses trois couches s'articulent autour d'une base de données centrale, le cycle de vie complet d'une demande (email ou chat → classification → chantier → agents → automates → déploiement), et le glossaire des concepts cardinaux du système. Chaque sous-système dispose de sa page dédiée.
1. Ce qu'est le dispositif agentique
Le dispositif agentique est l'ensemble du mécanisme qui transforme une demande (un email forwardé, un message dans une console du hub, un déclencheur cron) en action exécutée et déployée (du code commité, une réponse préparée, un site mis à jour), sans état métier hors base de données.
Trois principes le structurent :
- Base de données en premier. La base PostgreSQL centrale est la seule source de vérité métier. Les fichiers de documentation ne portent que des runbooks, schémas d'architecture et doctrines. Tout référentiel (VPS, clients, chantiers, agents, cicatrices, runs) vit en table.
- Asymétrie ship/deploy. La commande
./deployest lancée par l'IA, systématiquement et sans demander (préprod, ou rebuild live du vaisseau-mère). La commande./ship(mise en production) est gatée par la flotte : un indicateur par VPS client détermine si l'IA ou le tick planifié peut shipper automatiquement, ou si l'opération est réservée à une validation manuelle. Le ship de nuit non surveillé exige en outre une preuve QA verte. - Gouvernance par garde-fous. Des hooks d'outillage (
PreToolUse,Stop, etc.), un scan antiviral obligatoire avant ouverture de pièce jointe, une façade email unique, une protection anti-fuite de secrets, et une procédure en 7 étapes de création de chantier. Toute violation constitue une dette d'architecture prioritaire.
Le dispositif sert un vaisseau-mère privé (le cockpit /hub/*), distinct des produits PaaS publics (CodeMyShop) et des tenants clients. Cette page ne couvre que le vaisseau-mère agentique.
2. Topologie
Trois couches d'exécution parlent toutes au même schéma de base de données, mais via des transports différents :
- Le cockpit (application Nuxt 4 standalone, Nitro) — l'interface
/hub/*. Accès à la base via un adaptateur dédié qui traduit à la volée les constructions SQL héritées vers PostgreSQL standard : placeholders positionnels, préfixe de schéma sur les tables du hub, gestion des conflits d'insertion, arithmétique d'intervalles, fonctions d'agrégation de date, alias camelCase. Certaines constructions plus avancées (ON DUPLICATE KEY UPDATE,LAST_INSERT_ID(),GROUP_CONCAT,FIND_IN_SET,DATE_FORMAT,CURDATE()) ne sont pas prises en charge automatiquement et doivent être portées manuellement. L'application est découpée en 27 couches modulaires. - La couche d'orchestration Python — plus de 200 façades couvrant l'orchestration Atlas, les automates, la mémoire, les audits, la gestion des emails et le déploiement. L'accès à la base de données s'effectue via l'exécution de commandes dans le container de base de données.
- Les scripts shell, Node et Python (
bin/) — wrappers de déploiement, spawn de terminaux, extraction de pièces jointes, sauvegardes, tests end-to-end. Le crontab Linux de la machine hôte ordonnance la majorité des automates (le scheduler intégré à Nitro est désactivé depuis mai 2026).
DEMANDE
email forwardé ───┐ ┌─── chat console /hub/runs
boîte agentique │ │ (scopé vaisseau-mère | tenant)
▼ ▼
┌───────────────────────────────────────────────────────┐
│ COUCHE PYTHON — orchestration, automates, mémoire │
│ classification Atlas, exécution de tâches, │
│ gestion email/deploy, invocation Claude headless │
│ via <pont-de-spawn> (node-pty, JAMAIS claude -p) │
└──────────────┬───────────────────────┬────────────────┘
exec container DB │ │ scp/docker cp + pm2/docker
▼ ▼
┌───────────────────────────┐ ┌──────────────────────────┐
│ POSTGRESQL (container DB)│ │ COCKPIT — mothership-app │
│ base de données centrale │◄──┤ interface /hub/* :3000 │
│ tables hub + tables sys │ │ adaptateur postgres-js │
│ (~271 tables + 18 vues) │ │ 27 couches modulaires │
└───────────────────────────┘ └──────────────────────────┘
▲
crontab Linux │ <orchestrateur-cron> → façades Python
(Nitro mort) │ bin/*.sh + bin/*.mjs (backups, scans, deploy)
│
┌──────────────┴────────────────────────────────────────┐
│ COUCHE bin/ + scripts/ (deploy, hooks, cron, tests) │
│ ./deploy / ./ship → scripts/deploy/ + lib de deploy │
│ hooks Claude Code : PreToolUse / Stop / … │
└─────────────────────────────────────────────────────────┘
Points de topologie à retenir d'emblée (détaillés dans la page sur la couche données) :
- Le nom du container de base de données, le nom de la base et le nom du schéma sont trois identifiants distincts — ne pas les confondre. Le port exposé sur la machine hôte diffère du port par défaut de PostgreSQL.
- Plusieurs tables apparentes sont en réalité des vues — héritage de la migration progressive du système (pattern Strangler Fig). La règle : lire via la vue, écrire dans la table physique sous-jacente.
- L'entité « chantier » est répartie sur deux familles de tables : les tables legacy et les tables cockpit. Les deux doivent rester cohérentes.
- Le cockpit est standalone : il n'étend plus le socle CodeMyShop. La sécurité réelle du hub repose sur l'infrastructure (tunnel SSH + knock-gate nginx) ; un middleware injecte automatiquement une session fondateur, de sorte que la vérification de session passe toujours côté vaisseau-mère.
3. Cycle de vie complet d'une demande
Le chemin canonique « email → action déployée ». Deux portes d'entrée alimentent le même moteur d'orchestration : le poll de la boîte agentique et la console scopée du hub.
(0) INGESTION
Alex forwarde un email vers la boîte agentique
│ cron */1 <poll-boite-agentique> (IMAP SEARCH UNSEEN)
▼
INSERT message email brut ──1:1──► message Atlas (status='received')
│
(0b) SCAN PIÈCE JOINTE (si présente — doctrine scan-first priorité absolue)
│ <scanner-pj> → ClamAV + heuristiques (agent Mitnick)
│ verdict ≠ clean ⇒ classification BLOQUÉE
▼
(1) CLASSIFICATION (LLM via façade fournisseur IA, enum strict, anti-injection)
<classificateur-atlas> → intention ∈
{run, chantier, question, noise, negociation, conseil}
│ matérialise au plus 1 ligne selon l'intention :
│ run / question / negociation / conseil
▼
(2) SPAWN + ORCHESTRATION (cron */5 + délai 120 s)
<orchestrateur-spawn>
│ verrou advisory PostgreSQL (anti-double-spawn)
│ spawn <pont-de-spawn> (node-pty, stream-json)
│ --no-session-persistence (isolation inter-runs)
│ --model sonnet --permission-mode bypassPermissions
│ --allowed-tools <CSV-outils> (optionnel — ex. QA read-only)
│ variables d'environnement de connexion DB injectées
│ --timeout-sec 2400 (défaut pont = 900 s)
│ ⚠️ ordre args : --add-dir AVANT les autres flags (varargs)
│ ⚠️ --allowed-tools varargs : sa valeur doit être suivie
│ d'un --flag, jamais du prompt final
│ ⚠️ fermer le flux de log APRÈS l'événement de sortie du pty
│ ⚠️ drainer stdout avant process.exit() (anti-troncature pipe)
│ prompt système Atlas = investigation + code + git commit, point
│ → Claude écrit /tmp/atlas-spawn-result-<ID>.json puis exit
▼
orchestrate_post_spawn()
├─ branche sans code (run/question/negociation)
│ → email récap → status='actioned'
└─ branche avec code (chantier) → ./deploy <tenant> --preprod
└─ QA 2 niveaux par route (<module-qa-post-deploy>) :
L1 HTTP (status + regex patterns d'erreur,
bypass knock-gate SSH optionnel)
L2 Playwright chromium headless
(console_error, page_error, screenshot)
Filtres : 401 + ERR_HTTP2 ignorés sur préprod
protégée par basic-auth
├─ OK → email récap → status='actioned'
└─ FAIL → re-spawn (max 3 itérations)
sinon escalade humaine
▼
(3) CHANTIER (si intention=chantier, voir page dédiée)
procédure 7 étapes : audit agents → lettre de mission
→ recrutement ≥ 2 agents → création atomique en base
│ INSERT chantier + travaux + tâches en transaction unique
▼
EXÉCUTION agents : worker de tâches (cron */1)
ou boucle ReAct (moteur de réflexes)
│ cascade tâche → travail → chantier
│ équipe QA si recrutée
▼
chantier → 'test' (préprod, review) ── manuel ──► ./ship → 'done'
▼
(4) APPRENTISSAGE (asynchrone)
cicatrice (échec/victoire) → réindexation pgvector
→ suggestion apprise → validation humaine /hub
→ règle dans memory/ ou doctrine → réflexe session suivante
Côté email sortant, rien ne part jamais au client directement : tout passe par la façade email client (mode --draft → copie de validation → --send après accord explicite). Atlas écrit au fondateur, jamais directement au demandeur.
L'ordonnancement repose sur le crontab Linux (le scheduler Nitro est désactivé) : le poll de la boîte agentique en */1 (poll + scan + classification dans le même tick), l'orchestrateur de spawn en */5 décalé de 120 secondes (pour passer après la classification), le worker de tâches en */1, plus les dizaines d'entrées cron actives couvrant les automates récurrents, workers et watchers.
Glossaire des noms cardinaux
| Nom | Définition |
|---|---|
| Atlas | L'orchestrateur principal. Un agent enregistré en base de données sans runtime propre : « être Atlas » consiste à lancer une session Claude Code avec le prompt système Atlas. Atlas pilote la classification des intentions, le spawn d'agents et l'orchestration post-spawn. |
| agent | Une persona (identité + cadre cognitif + périmètre métier) injectée dans le contexte d'un Claude pour exécuter une tâche. Trente agents actifs, répartis en quatre familles : direction, cadrage, exécution, validation. Un agent raisonne (pattern ReAct) — il n'exécute pas une routine figée. |
| automate | Un script déterministe qui exécute une routine ; peut faire appel à un LLM, mais son flux de contrôle est codé en dur. Opposé conceptuel de l'agent. |
| chantier | Une mission structurée multi-étapes. Unité de travail de plus haut niveau, créée atomiquement avec au moins un travail et une tâche. Hiérarchie : 1 chantier = N travaux = N tâches. |
| travail | Un lot granulaire d'un chantier (phase ou sous-objectif), avec son agent propriétaire, son périmètre et ses critères de sortie. Porte les cascades de statut et le pattern travail-bis (résolution d'un travail mis en pause). |
| tâche | L'unité atomique assignée à un agent, avec estimation de tokens et modèle recommandé. |
| run | Une exécution scopée pilotée par Atlas sur un périmètre (vaisseau-mère ou tenant), le périmètre chargeant le contexte (VPS, client, boîte mail). Déclenchée par un email entrant ou depuis la console. À distinguer de l'unité d'exécution déléguée à un agent, qui est un concept distinct. |
| cicatrice | Une leçon gravée issue d'une erreur ou d'un succès reproductible. Indexée en base vectorielle pour le rappel sémantique, scorée en importance — porte d'entrée de la boucle d'apprentissage. |
| orbite | Anneau d'organisation des agents (1, 2 ou 3). Notion double : la valeur numérique stockée en base ne correspond pas directement au rendu visuel du réacteur, qui recalcule l'anneau depuis le groupe fonctionnel de l'agent (direction = anneau 1, cadrage/exécution = anneau 2, validation = anneau 3). C'est le groupe fonctionnel qui fait foi. |
| façade | Un point d'entrée unique et obligatoire pour une capacité, rendant une opération non-contournable (envoi d'email, appel IA, scan de pièce jointe, accès base de données). Souvent doublée d'un hook qui bloque tout contournement. |
Autres termes utiles :
- knock-gate — porte nginx combinant cookie et slug en amont du hub, première ligne de défense avant authentification.
- node-pty — pseudo-TTY obligatoire pour spawner Claude de façon programmatique ; l'invocation en sous-processus direct est interdite.
- scan-first — doctrine : aucune pièce jointe n'est ouverte avant que le verdict
cleansoit rendu par le moteur antivirus. - travail-bis — travail portant une référence vers un travail mis en pause, permettant de le débloquer une fois le prérequis résolu.
Les frontières dures (non-négociables)
Les règles suivantes sont appliquées par l'ensemble du harness et ne souffrent aucune exception :
- Base de données unique — zéro contenu métier dans des fichiers de configuration versionnés ; toute donnée structurée réside exclusivement en base.
- Anti-fuite P0 — aucun secret en clair dans un fichier suivi par le gestionnaire de versions. Les secrets vivent hors dépôt et sont référencés uniquement par leur nom de variable (cinq niveaux d'exposition, détaillés dans la page déploiement).
- Scan antivirus avant ouverture — toute pièce jointe reste fermée tant que le verdict
cleann'a pas été rendu (voir la page inbox & email). - Zéro communication client par l'IA — la façade d'envoi d'email avec validation humaine préalable, ainsi que la prise de rendez-vous via Calendly, sont les seuls canaux autorisés (voir la page inbox & email).
- Procédure en sept étapes — aucun chantier ne peut être ouvert hors de la procédure
create_with_skeleton; au moins deux agents distincts sont requis pour un périmètre tenant (voir la page chantiers). - Commit en flux — aucun travail terminé ne peut rester non commité ; l'IA effectue le commit, l'opérateur humain ne tape jamais les commandes d'ajout et de commit manuellement. Un hook bloquant garantit cette règle.
Les autres pages du dossier
| Page | Sous-système couvert |
|---|---|
| La couche données | Base unique, préfixes de tables, adaptateur de compatibilité MySQL→PostgreSQL, classes d'entité Python, vues de compatibilité, internationalisation. |
| Le cœur agentique | Atlas, modèle d'agents, classification d'intention, spawn via pseudo-TTY, orchestration déploiement → QA → email, orbites, calibration. |
| Chantiers, travaux & tâches | Hiérarchie chantier/travail/tâche, création atomique par squelette, procédure en sept étapes, verrou multi-session, cascades de statut, travail-bis. |
| Automates, crons & runs | Façades déterministes, enveloppe cron, registre des automates, distinction run principal / unité déléguée à un agent, double scheduler. |
| Le Hub | Application Nuxt vaisseau-mère, modules et couches, pages du tableau de bord, endpoints, authentification knock-gate + auto-session, consoles. |
| Inbox, Atlas Inbox & email | Deux pipelines IMAP (hub vs Atlas), façade d'envoi, scan antivirus, politique zéro-comm-client. |
| Mémoire & apprentissage | Mémoire à trois niveaux (fichiers de contexte / base de connaissances / base vectorielle), rappel RAG, boucle cicatrices → suggestions → leçons, façade IA. |
| Déploiement & infrastructure | Asymétrie ./ship / ./deploy, dispatcher YAML, build-host + compression, auto-déploiement vaisseau-mère, inventaire VPS clients, secrets, commit avant déploiement. |
| Catalogue des façades & points d'entrée | Recensement des façades par famille, mode d'invocation (cron / CLI / skill / hook / bibliothèque), hooks recensés. |
| Skills, agents & hooks | Skills déclaratifs, sous-agents délégables, hooks de session (paramètres et permissions), variables d'environnement injectées. |