Chapitres

DOC-05 / Référence technique · Chapitre 01

Vue d'ensemble du harness

Le dispositif qui transforme une demande en action déployée, autour d'une base unique.

Cette page pose le cadre du harness agentique de Synedre OS : ce qu'il est, comment ses trois couches s'articulent autour de la base de données unique, le cycle de vie complet d'une demande (de l'email ou du chat jusqu'au déploiement), et le glossaire des noms cardinaux du système. Chaque sous-système dispose ensuite de sa propre page.

Ce qu'est le harness

Le « harness » est l'ensemble du dispositif qui transforme une demande — un email transféré, 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 rédigée pour le Fondateur, un site mis à jour. Le tout sans état métier hors de la base de données.

Trois principes le structurent :

  • DB-first. La base PostgreSQL est la seule source de vérité métier. Les fichiers .md ne portent que runbooks, schémas d'architecture et doctrines. Tout référentiel — VPS, clients, chantiers, agents, cicatrices, runs — vit en table.
  • Asymétrie ship / deploy. ./deploy est lancé par l'intelligence, systématiquement et sans demander (préprod, ou rebuild en place du vaisseau-mère). ./ship est un geste manuel exclusif du Fondateur (production). L'intelligence ne tape jamais ./ship.
  • Gouvernance par garde-fous. Hooks de l'agent de code (avant chaque outil, à l'arrêt de session…), scan antivirus obligatoire avant ouverture de pièce jointe, façade email unique, anti-fuite de secrets, procédure de création de chantier en sept étapes. Toute violation devient une dette d'architecture P0.

Le harness sert un vaisseau-mère privé — le cockpit /hub/* hébergé en local sur la machine hôte — distinct des produits PaaS publics (CodeMyShop OSS) et des tenants clients qui vivent ailleurs dans le dépôt. Cette page ne couvre que le vaisseau-mère agentique.

Topologie réelle

Trois couches d'exécution parlent toutes au même schéma PostgreSQL, mais par des transports différents :

  • Couche Nuxt — l'application Nuxt 4 standalone (runtime Nitro), le cockpit /hub/*. Accès DB via un pool postgres-js avec un adaptateur qui traduit à la volée le SQL legacy MySQL vers PostgreSQL. Découpée en une vingtaine de layers Nuxt.
  • Couche Python (synedre/) — plusieurs centaines de façades Python (orchestration de l'orchestrateur, automates, mémoire, audits, email, deploy…). Accès DB via un sous-processus psql exécuté dans le container PostgreSQL.
  • Couche scripts (bin/) — scripts shell / Node / Python (wrappers de deploy, spawn de l'agent en pseudo-TTY, extraction de pièces jointes, backups, tests E2E), plus le crontab Linux qui ordonnance la majorité des automates.
                      DEMANDE
   email transféré ───┐        ┌─── chat console /hub/runs
                      │        │    (scopé mothership|tenant)
                      ▼        ▼
        ┌───────────────────────────────────────────────┐
        │  COUCHE PYTHON   synedre/*.py                   │
        │  Orchestrateur : poll / classify / spawn        │
        │  exécution : worker de tâches, ReAct            │
        │  mémoire / audits / email / deploy : ac_*.py    │
        │  invocation Claude headless = node-pty          │
        └────────────┬──────────────────────┬─────────────┘
        docker psql  │                       │ copie + pm2/docker
                     ▼                       ▼
        ┌─────────────────────────┐  ┌──────────────────────────┐
        │  POSTGRESQL             │  │  COUCHE NUXT mothership    │
        │  schéma vaisseau_mere_ac│◄─┤  cockpit /hub/*            │
        │  ps_ac_* / sy_* / ps_*  │  │  postgres-js + adaptateur  │
        │  + vues                 │  │  ~20 layers                │
        └─────────────────────────┘  └──────────────────────────┘
                     ▲
        crontab      │  wrapper de cron → ac_*.py
                     │  bin/*.sh + bin/*.mjs (backups, scans, deploy)
                     │
        ┌────────────┴──────────────────────────────────┐
        │  COUCHE bin/ + scripts/ (deploy, hooks, cron)  │
        │  ./deploy / ./ship → scripts/deploy/*           │
        │  hooks avant-outil / arrêt-session              │
        └─────────────────────────────────────────────────┘

Pièges de topologie à retenir d'emblée (détaillés dans le chapitre sur la couche données) :

  • Le container PostgreSQL et la base portent des noms distincts, et le schéma n'est pas public mais un schéma dédié. À garder en tête pour toute requête.
  • Plusieurs tables ps_ac_* sont en réalité des vues pointant sur des tables physiques sy_* — un héritage de la migration Strangler Fig. On lit via la vue, on écrit dans la table sy_* physique.
  • Une seule entité « chantier » est répartie sur les deux préfixes : des tables ps_ac_chantier* (legacy) et des tables sy_* (cockpit).
  • Le vaisseau-mère est standalone : il n'étend plus le cœur OSS. La sécurité réelle du hub est l'infra (tunnel SSH + knock-gate nginx) ; un middleware auto-injecte une session de Fondateur, si bien que le contrôle de session côté serveur passe toujours.

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
    Un email est transféré vers la boîte agentique
       │  cron : poll IMAP (recherche des non-lus)
       ▼
    INSERT message brut ──1:1──► email agentique (status='received')
       │
(0b) SCAN PIÈCE JOINTE (doctrine scan-first, P0)
       │  ClamAV + heuristiques (agent Mitnick)
       │  verdict ≠ clean ⇒ classification BLOQUÉE
       ▼
(1) CLASSIFY  (LLM via façade IA, enum strict, anti-injection)
    intent ∈ {run, chantier, question, bruit, négociation, conseil}
       │  matérialise au plus 1 ligne : run / question /
       │  négociation / conseil  (chantier = drafting en aval)
       ▼
(2) SPAWN + ORCHESTRATION  (cron, après le classify)
       │  verrou applicatif PG (anti-double-spawn)
       │  spawn de Claude headless via node-pty (stream-json)
       │  prompt système : INVESTIGATION + CODE + commit, point
       │  → l'agent écrit un résultat puis quitte
       ▼
    orchestration post-spawn
       ├─ branche sans code (run/question/négo) → email récap → 'actioned'
       └─ branche code (chantier) → ./deploy  --preprod
              └─ QA navigateur par route
                    ├─ OK   → email récap au Fondateur → 'actioned'
                    └─ FAIL → re-spawn (max 3 itérations) sinon escalade
       ▼
(3) CHANTIER (si intent=chantier)
    procédure 7 étapes : audit agents → lettre de mission → recrutement ≥2 agents
       │  création du squelette = INSERT atomique
       │     chantier + travail + tâche(s)
       ▼
    EXÉCUTION agents : exécution déléguée (worker) ou ReAct
       │  cascade tâche→travail→chantier (max 1 cran) ; QA si recrutée
       ▼
    chantier → 'test' (préprod, review du Fondateur) ── manuel ──► ./ship → 'done'
       ▼
(4) APPRENTISSAGE (asynchrone)
    cicatrice (échec/victoire) → réindexation pgvector → suggestion →
    validation humaine → règle → réflexe de la session suivante

Côté email sortant, rien ne part jamais au client directement : tout passe par la façade d'envoi (--draft → copie de validation au Fondateur → --send après accord explicite). L'orchestrateur écrit au Fondateur, jamais au demandeur.

L'ordonnancement repose sur le crontab Linux : poll de la boîte (poll + scan + classify dans le même tick), spawn décalé pour passer après le classify, worker de tâches en continu, plus la cinquantaine d'automates récurrents.

Glossaire des noms cardinaux

NomDéfinitionSupport physique
AtlasL'orchestrateur. Un agent enregistré en base, sans runtime propre : « être Atlas » = lancer l'agent de code avec le prompt système d'Atlas. Pilote la classification, le spawn et l'orchestration post-spawn.façades synedre/ac_atlas_*.py + spawn node-pty
agentUne persona (identité + cadre cognitif + scope métier) injectée dans le contexte d'un Claude pour exécuter une tâche. Trente agents actifs, en quatre familles : direction, cadrage, exécution, validation. Un agent pense (ReAct), il n'exécute pas une routine figée.table sy_agents (vue ps_ac_agents)
automateUn script déterministe qui exécute une routine ; il peut appeler un LLM mais son flux de contrôle est codé en dur. Opposé conceptuel de l'agent.registre sy_automates ; journal sy_automate_logs
chantierUne mission structurée multi-étapes. Unité de travail de plus haut niveau. Créé atomiquement avec ≥1 travail et ≥1 tâche. Hiérarchie : 1 chantier = N travaux = N tâches.ps_ac_chantier
travailUn lot granulaire d'un chantier (phase / sous-objectif), avec son agent owner, son périmètre et ses critères de sortie. Porte les cascades de statut et le pattern travail-bis.ps_ac_chantier_travail
tâcheL'unité atomique assignée à un agent, avec estimation de tokens et modèle recommandé.sy_chantier_tache
runUne exécution scopée pilotée par Atlas sur un périmètre (mothership ou tenant), le périmètre chargeant le contexte (VPS, client, boîte mail). Déclenché par email ou par chat. À ne pas confondre avec l'unité d'exécution déléguée à un agent.sy_run ; console /hub/runs
cicatriceUne leçon gravée d'une erreur (kind='failure') ou d'un succès reproductible (kind='victory'). Indexée en pgvector pour le recall, scorée en importance, porte d'entrée de la boucle d'apprentissage.ps_ac_cicatrices + embeddings
orbiteAnneau d'organisation des agents (1/2/3). Notion double : la colonne numérique ne mappe pas 1:1 sur le rendu visuel, qui recalcule l'anneau depuis la famille (direction=1, cadrage/exécution=2, validation=3). C'est la famille qui fait foi.colonne orbite + group_name
façadeUn point d'entrée unique obligatoire pour une capacité, qui rend une opération non-contournable (email, IA, scan de pièce jointe, accès DB). Souvent doublée d'un hook qui bloque le bypass.synedre/ac_*.py + hooks avant-outil

Autres termes utiles : knock-gate (gate nginx cookie + slug en amont du hub), node-pty (pseudo-TTY obligatoire pour spawner Claude programmatiquement), scan-first (aucune pièce jointe ouverte avant verdict clean), travail-bis (travail portant un lien de résolution pour débloquer un travail en pause).

Les frontières dures (non-négociables)

Rappel condensé des règles que tout le harness fait respecter :

  • DB unique — zéro contenu métier dans les .json / .ts / .md ; tout dans le schéma dédié.
  • Anti-fuite P0 — aucun secret en clair dans un fichier suivi par git ; les secrets vivent hors du dépôt, référencés par nom de variable seulement.
  • Scan antivirus avant ouverture — pièce jointe non ouverte tant que le verdict clean n'est pas rendu.
  • Zéro communication client par l'intelligence — façade email + show-before-send + prise de RDV par lien dédié uniquement.
  • Procédure 7 étapes — aucun chantier hors de la création de squelette, ≥2 agents distincts pour un scope tenant.
  • Commit-en-flux — aucun travail terminé non commité ; l'intelligence commit, le Fondateur ne tape jamais git add / commit ; hook d'arrêt de session bloquant.