Constructeur d'agents IA d'entreprise (Samassé AI)
Un agent d'entreprise n'est pas « un prompt + une API ». C'est un programme qui lit du texte non
fiable, connaît le métier d'un client précis, et peut agir dans son système. Ce skill produit donc
d'abord un document — la carte d'identité de l'agent — puis un squelette qui la respecte,
puis les preuves qu'on remet avec la facture.
Trois principes tiennent tout le reste :
- aucun agent sans entretien. Le skill commence par l'onboarding des 4 C et refuse de générer
quoi que ce soit tant qu'un C est vide ou que deux réponses se contredisent.
- aucun C sans preuve. Chaque case fermée à l'entretien devient un test, une garde dans le code,
ou une ligne dans
docs/LIMITES.md.
- la limite se dit. Une livraison sans ligne « Limites » est refusée par ce skill. Ce qui n'a pas
été testé chez le fournisseur réel, ce qui reste à écrire, ce qui dépend du compte du client : ça
s'écrit, ça ne se devine pas.
Ce que je produis
| Livrable |
Contenu |
agent.json + agent.yaml |
la spec des cinq axes, versionnée, rejouable par l'entretien |
docs/IDENTITE.md … docs/CONSEQUENCES.md |
la carte d'identité relue avec le client (six pages) |
docs/CONTRAT-DE-REFUS.md |
ce qu'il refuse, ce qu'il ne fait jamais, comment on l'arrête |
docs/COMMANDES.md · docs/SCORES.md · docs/LIVRABLES.md |
les trois pages qui se relisent après coup : la table des commandes, le barème avec ses poids, la liste des fichiers livrés par commande |
| le squelette TypeScript |
src/ en sept couches, un test par C, npm run check vert — 49 fichiers à la sortie du gabarit |
src/channels/telegram.ts |
la seule surface de commande : long polling getUpdates, liste blanche d'identifiants dans .env, réponses coupées à 4096, approbations par oui <jeton> |
src/commands/ |
un fichier = une commande métier : registre.ts (définition typée, approbation collée au constructeur), catalogue.ts (la projection de la spec), executer.ts (une commande, un livrable, un bloc d'écran de six à douze lignes) |
src/subagents/ |
orchestrateur.ts (jusqu'à cinq ouvriers en parallèle), ouvriers.ts (un module par agent déclaré), bareme.ts (score à poids lus dans la spec, échelle de paliers unique) |
src/livrables/ |
marque.ts (white-label : un brand.json posé à côté de .env fait la marque, sans retoucher le code) + rapport.ts (nom de fichier TYPE-OBJET-AAAA-MM-JJ.md, avertissement posé sur les domaines qui engagent) |
scripts/install.sh · scripts/uninstall.sh · brand.example.json |
l'installation qui se vérifie elle-même (compte ses contrôles, sort en erreur sinon) et le désinstallation qui dit ce qu'elle laisse |
scripts/check_invariants.py |
les vingt gardes de l'agent, chez le client, sans nous |
docs/LIMITES.md |
ce qui n'est pas prouvé — la page qui évite le litige |
Les sept scripts
| Script |
Rôle |
Codes |
scripts/gen_questionnaire.py |
génère le questionnaire client depuis onboard.QUESTIONS (le document ne peut plus être en retard sur l'entretien) ; --check compare sans écrire |
0 aligné · 1 en retard |
scripts/onboard.py |
l'entretien (41 questions, 5 pauses) ou la réponse à un questionnaire ; --profil marketing (ou geo-seo, sales, legal) repart d'un patron de dépôt au lieu de la page blanche ; écrit la spec et les dix pages |
0 propre · 1 réponses à compléter · 78 spec refusée (dont un canal entrant non admis) |
scripts/scaffold.py |
le squelette à partir de la spec : 49 fichiers, src/ en sept couches, un test par C, les gardes copiées chez le client |
0 · 1 spec absente ou non concordante |
scripts/check_invariants.py |
les vingt gardes, dans le projet livré (--json pour les machines) |
0 · 1 liste de correctifs · 78 dossier sans agent |
scripts/reinvalider_gardes.py |
re-invalide les gardes : muter une seule garantie à la fois dans l'exemple, vérifier que la garde tombe, restaurer par copie. Sans ce script, une garde qui ne tombe plus reste dans la doc comme une décoration |
0 toutes les gardes mordent · 1 au moins une garde décorative |
scripts/check_skill.py |
vérifie l'atelier lui-même : hygiène, chemins cités réels, chiffres recomptés à la source, 4 profils passés au contrôle client, exemple identique octet pour octet à la sortie du gabarit, et le gabarit doit refuser une spec dont la conversation entre par un autre canal |
0 · 1 écarts listés · 78 atelier introuvable |
scripts/detect_drift.py |
compare un agent livré à la capture du skill (assets/skill_state.json) et dit si la méthode a bougé ; --capture après une entrée validée |
0 rien à intégrer · 1 signaux porteurs · 2 pas un agent |
Le questionnaire à envoyer au client (remplissable sans nous) : assets/templates/questionnaire.md.
La spec de référence, valide au spec.check() : assets/templates/agent.json.
Un exemple complet est livré avec le skill : exemples/atlas-marketing (agent rédactionnel et
calendrier pour un studio de marketing, parti du profil marketing) — spec, dix pages de docs,
49 fichiers de squelette, 14 commandes, 5 sous-agents, 4 outils, 22 tests, 20/20 invariants et
tsc --noEmit à zéro erreur. C'est le niveau attendu d'une sortie de gabarit : pas une cible à rattraper.
Déroulé
Étape 0 — Lire les dépôts de référence (avant de poser la première question)
Quatre dépôts sont livrés avec le skill, sous depots/ : geo-seo-claude, ai-marketing-claude,
ai-sales-team-claude et le dépôt de revue juridique. Ils ne sont pas une inspiration : ce sont les
patrons de nos agents générés, et un skill qui ne les a pas lus à jour régénère des squelettes qui
ressemblent à un demo et non à un livrable. Ordre de lecture (détail et justifications :
depots/README.md, synthèse exploitable : references/patrons.md, douze patrons) :
depots/*/README.md des quatre dépôts — ce que chacun prétend livrer, en une page ;
- le
package.json / SKILL.md de chacun — quelles commandes existent vraiment, et leurs arguments ;
- la definition des commandes (
commands/*.md chez eux) — une commande = un livrable nommé ;
- le bloc terminal de chaque commande — court, six à douze lignes, le détail va au fichier ;
- les sous-agents et leur barème — parallélisme, score à poids, échelle de paliers A+ à D ;
- les portes chiffrées (plafond de pages, délai par page, pause entre appels, concurrence, doublons) ;
- l'installateur et la marque (white-label) — comment ils se vérifient eux-mêmes.
On ne copie pas : leurs prompts métier, leurs noms de tiers, leurs exemples chiffrés, leurs secrets
d'exemple, et le vocabulaire d'un secteur plaqué sur un autre — la liste tient sur une page de
depots/README.md. Quand un dépôt bouge (nouvelle commande, nouveau patron de score), on relit, on
ajoute la garde correspondante, puis on régénère l'exemple.
Étape 1 — L'entretien (obligatoire, ~45 min avec le client)
python3 scripts/onboard.py --interview --out ../mon-agent # a l'ecran, une pause par C
python3 scripts/onboard.py --answers reponses.json --out ../mon-agent # questionnaire rempli a l'equipe
python3 scripts/onboard.py --check ../mon-agent # relit une spec existante (reprise, recette)
Quarante-et-une questions, cinq pauses (10 · 10 · 10 · 6 · 5), un défaut pour chacune — détail et contradictions refusées :
references/onboarding.md. Repartir d'un profil de dépôt (--profil marketing) n'est pas un raccourci :
le profil apporte la surface et le barème, l'entretien garde les questions d'identité, de secrets, de
rétention et d'approbation — les quatre choses que les dépôts ne couvrent pas. L'entretien ne demande aucune valeur de secret : seulement des noms de
variables ; le script refuse une spec où une valeur apparaît (sk-…, gsh_…, GOCSPX-…, un token
Telegram, un JSON web token).
Étape 2 — Le squelette
python3 scripts/scaffold.py --spec ../mon-agent --out ../mon-agent
cd ../mon-agent && npm install && npm run check
Il compile, il a un test par C, ses vingt invariants passent, et ses outils disent « à écrire »
plutôt qu'un faux résultat. C'est voulu : le socle est commun à tous les clients, le métier s'écrit
dans src/tools/metier.ts et dans la spec — pas en forkant le noyau.
Étape 3 — Le métier (le vrai travail)
Pour chaque outil déclaré : un corps, un test, une phrase dans docs/CAPACITE.md qui dit quand le
modèle doit l'appeler. Pour chaque canal voulu : un module dans src/channels/, jamais dans core/.
Plan fichier par fichier et décisions de structure : references/blueprint.md.
Étape 4 — Prouver, sinon ce n'est pas livré
npm run check # typecheck + un test par C + les 20 invariants
python3 scripts/check_invariants.py .
Puis les vingt cas de recette écrits par le client (dont trois hors périmètre, trois sans réponse
dans ses sources, une tentative d'injection) : references/verification.md. On compte les succès et on
liste les échecs dans le PV. Un agent à 17/20 avec les trois cas écrits vaut mieux qu'un 20/20 dont on
a retiré les cas qui gênent.
Étape 5 — Livrer et rester joignable
Runbook (démarrer, couper en trois secondes, purger une personne, changer de modèle), PV de recette en
six lignes, et ce qui est facturé comment : references/delivery.md. Le devis d'un agent de base tient
en une ligne : 4 à 6 jours ; un agent élaboré se décompose à la ligne, après l'entretien, jamais avant.
Les cinq axes, et ce qu'ils empêchent
| Axe |
Question |
Artefact |
Ce qui casse sans lui |
| Contexte |
De quoi il parle, pour qui, avec quel vocabulaire, qu'est-ce qui est vrai ? |
CONTEXTE.md + lexique + sources |
il invente, parle le mauvais métier, confond deux clients |
| Connexion |
Par où il entre et sort, à quels systèmes il touche, avec quels secrets ? |
CONNEXION.md + inventaire de secrets + rétention |
un tuyau non déclaré devient une porte ; un secret non inventorié finit dans un journal |
| Capacité |
Quels outils, quelles compétences, quels modèles, quelles limites ? |
CAPACITE.md + registre typé |
il promet ce qu'il ne peut pas faire, ou fait plus qu'il ne devrait |
| Cadence |
Quand il se réveille, à quelle fréquence, jusqu'à quel budget ? |
CADENCE.md + quatre plafonds chiffrés |
un agent proactif sans plafond est une facture sans fin et du spam |
| Conséquences |
Qu'est-ce qui est irréversible, qui approuve, comment on annule, combien de temps on garde ? |
CONSEQUENCES.md + contrat de refus |
une action non désirée, non annulable, non journalisée — la fin d'un contrat |
Conséquences est notre ajout aux quatre C : ils décrivent ce que l'agent reçoit et ce qu'il fait, pas
ce que ses actes coûtent. En entreprise, la question du client n'est jamais « est-il intelligent ? »
mais « que se passe-t-il quand il se trompe ? ». Détail et contre-exemples : references/4c.md.
Ce qui ne doit jamais bouger
| Invariant |
Pourquoi |
python3 scripts/onboard.py --check passe avant toute génération |
un C vide ne se corrige pas dans le code plus tard ; il se corrige dans la facture |
| Liste blanche avant tout appel au modèle, et refus générique au tiers |
sinon n'importe qui pilote l'agent au nom du client et vide le quota |
process.env lu dans config.ts uniquement |
validation et masquage des secrets n'ont qu'un point |
Aucun eval, new Function, vm ; child_process seulement pour un binaire métier marqué, avec environnement filtré |
le modèle ne choisit jamais le code exécuté |
| Outils en liste close, arguments validés, champs inconnus refusés |
une injection lue dans un document ne devient pas un argv |
Toute écriture = dangerous + requiresApproval, vérifié dans le constructeur du registre |
aucun appelant ne peut oublier le garde-fou |
| La conversation entre et sort par Telegram seul ; pas de WhatsApp, pas de portail, pas de boîte mail ; le terminal n'est pas une surface humaine |
un canal de plus, c'est une identité à vérifier, un plafond à payer et une porte de plus dans le réseau du client |
| Les plafonds de cadence sont dans la spec et lus par la config |
un plafond écrit mais non lu est une intention, pas une limite |
| Sorties d'outils encadrées comme données non fiables ; refus expliqué à l'utilisateur |
un fichier lu ne devient pas une consigne ; un silence se lit comme une panne du client |
| Aucun secret dans le dépôt ni les journaux ; rétention chiffrée et purgeable |
le message d'erreur du fournisseur contient la requête, donc la donnée |
| Chaque modèle épinglé est vérifié contre l'inventaire du compte au démarrage |
un nom recopié d'une doc produit un 400 opaque chez le client, un lundi |
docs/LIMITES.md existe, et nomme ce qui reste non prouvé |
une limite annoncée se planifie ; une limite cachée se plaide |
Ces douze règles, les sept venues des dépôts et la garde de surface sont vérifiées par
scripts/check_invariants.py (codes 0 propre, 1 liste des correctifs, 78 dossier sans spec) —
vingt gardes :
| # |
Garde |
Ce qu'elle empêche |
| 13 |
commands-routed |
une commande déclarée dans la spec et absente du menu : le client paie une capacité qu'il ne verra jamais |
| 14 |
score-weights-read |
un poids recopié dans le code de calcul à côté du poids de la spec : deux barèmes, deux notes pour un même travail |
| 15 |
subagent-modules-exist |
un sous-agent annoncé et sans module : l'orchestrateur le compte comme couverture nulle, et le score baisse sans que personne ne sache pourquoi |
| 16 |
quality-gates-read |
une porte écrite dans la spec que config.ts ne relit pas : un plafond qui n'est pas lu est une intention, pas une limite |
| 17 |
deliverable-named |
une sortie qui n'atterrit dans aucun fichier nommé : rien à rouvrir deux semaines plus tard, rien à facturer |
| 18 |
disclaimer-on-sensitive |
un livrable à valeur juridique, médicale ou financière sans avertissement en tête : le client le découvre après coup |
| 19 |
install-verifies |
un installateur qui compte ses échecs mais ne sort jamais en erreur : il déclare une installation prête pendant qu'elle est cassée |
| 20 |
canaux-clos |
une surface humaine rouverte n'importe où : un canal entrant ou sortant hors Telegram dans la spec, un module de canal qui réapparaît dans src/channels/, un secret WhatsApp revenu dans .env.example, le terminal qui redevient la conversation, ou un createServer qui traîne dans src/ |
Une règle qui ne peut plus échouer est une préférence. Chaque garde ajoutée est re-invalidée par
mutation — python3 scripts/reinvalider_gardes.py muter une garantie à la fois et exige que la garde
tombe, puis restaure par copie (jamais par remplacement de texte : un replace non conditionnel sur :
a déjà détruit un install.sh généré). Une garde qui ne mord pas ne rentre pas dans le skill.
Refus du skill (à assumer devant le client)
| Demande |
Réponse |
| « un outil qui envoie n'importe quelle requête à l'API du fournisseur » |
non : des opérations enregistrées et typées, sinon on a rouvert un shell |
| « écrire sans confirmation, pour aller plus vite » |
non : requiresApproval est dans le constructeur du registre |
| « journalise les conversations, ça servira » |
non : on journalise des compteurs, pas du contenu privé |
| « entraîne un modèle sur nos données » |
pas chez nous, et c'est écrit ; si le client le décide, la spec le porte avec son accord |
| « reprends l'agent qu'un autre a livré » |
d'abord un audit (20 invariants, --check sur la spec), et l'audit dit souvent « à refaire » |
| « ajoute-moi un portail web / une entrée e-mail » |
non : la conversation entre par Telegram. Un portail, c'est un port écouté et une session à sécuriser ; un e-mail entrant, c'est une identité qu'on ne peut pas vérifier. Si le besoin est réel, ça s'arbitre à l'atelier (nouvelle garde, nouveau profil), pas dans un dépôt client |
| « chiffre avant l'entretien » |
non : le périmètre se fixe aux étapes 0 et 1, le chiffrage après |
| « prends l'agent d'un concurrent et change le logo » |
non : on relit les dépôts, on écrit nos propres gabarits, et la licence du tiers est vérifiée avant (MIT ici, recopiée dans depots/README.md) |
Étendre et faire évoluer
Canaux, fournisseurs, hébergement chez le client, voix et appels, données sensibles :
references/extending.md. Les douze patrons des dépôts et l'endroit exact où chacun atterrit chez nous :
references/patrons.md. Sécurité en détail (modèle de menace, onze règles) : references/security.md.
Le skill suit le projet : une règle fausse est remplacée, pas doublée ; chaque évolution retenue prend
une entrée de CHANGELOG.md avec sa preuve (commande exécutée, résultat brut), et un bump de version
selon qu'elle touche un chiffre (patch), une capacité (minor) ou la philosophie (major).
1---2name: agent-ia-entreprise3description: Créer un agent IA d'entreprise de zéro, à partir d'un entretien obligatoire (l'onboarding des 4 C : Contexte, Connexion, Capacité, Cadence — plus Conséquences), puis générer un squelette robuste qui compile, se teste et tient ses propres invariants. La surface humaine est fermée par l'atelier : la conversation entre par Telegram seul (long polling, aucun port écouté), sort par Telegram et, si le client : ni portail, ni messagerie, ni WhatsApp (sorti de la méthode en v1.3.0) ; le terminal reste un outil de recette sous `RECETTE=1`. Utiliser ce skill pour concevoir un agent métier pour un client (support, marketing, devis, recouvrement, reporting, onboarding RH interne), pour produire un « agent de base » non personnalisé servant de socle à plusieurs clients, pour personnaliser ou configurer un agent existant selon ces cinq axes, pour auditer la sécurité et le périmètre d'un agent vendu par un tiers, ou pour chiffrer et livrer un agent avec un procès-verbal de recette. Déclencher aussi sur les formulations indi4license: MIT5---67# Constructeur d'agents IA d'entreprise (Samassé AI)89Un agent d'entreprise n'est pas « un prompt + une API ». C'est un **programme qui lit du texte non10fiable, connaît le métier d'un client précis, et peut agir dans son système**. Ce skill produit donc11d'abord un **document** — la carte d'identité de l'agent — puis un **squelette qui la respecte**,12puis les **preuves** qu'on remet avec la facture.1314Trois principes tiennent tout le reste :15161. **aucun agent sans entretien.** Le skill commence par l'onboarding des 4 C et refuse de générer17 quoi que ce soit tant qu'un C est vide ou que deux réponses se contredisent.182. **aucun C sans preuve.** Chaque case fermée à l'entretien devient un test, une garde dans le code,19 ou une ligne dans `docs/LIMITES.md`.203. **la limite se dit.** Une livraison sans ligne « Limites » est refusée par ce skill. Ce qui n'a pas21 été testé chez le fournisseur réel, ce qui reste à écrire, ce qui dépend du compte du client : ça22 s'écrit, ça ne se devine pas.2324## Ce que je produis2526| Livrable | Contenu |27|---|---|28| `agent.json` + `agent.yaml` | la spec des cinq axes, versionnée, rejouable par l'entretien |29| `docs/IDENTITE.md` … `docs/CONSEQUENCES.md` | la carte d'identité relue avec le client (six pages) |30| `docs/CONTRAT-DE-REFUS.md` | ce qu'il refuse, ce qu'il ne fait jamais, comment on l'arrête |31| `docs/COMMANDES.md` · `docs/SCORES.md` · `docs/LIVRABLES.md` | les trois pages qui se relisent après coup : la table des commandes, le barème avec ses poids, la liste des fichiers livrés par commande |32| le squelette TypeScript | `src/` en sept couches, un test par C, `npm run check` vert — **49 fichiers** à la sortie du gabarit |33| `src/channels/telegram.ts` | **la seule surface de commande** : long polling `getUpdates`, liste blanche d'identifiants dans `.env`, réponses coupées à 4096, approbations par `oui <jeton>` |34| `src/commands/` | un fichier = une commande métier : `registre.ts` (définition typée, approbation collée au constructeur), `catalogue.ts` (la projection de la spec), `executer.ts` (une commande, un livrable, un bloc d'écran de six à douze lignes) |35| `src/subagents/` | `orchestrateur.ts` (jusqu'à cinq ouvriers en parallèle), `ouvriers.ts` (un module par agent déclaré), `bareme.ts` (score à poids lus dans la spec, échelle de paliers unique) |36| `src/livrables/` | `marque.ts` (white-label : un `brand.json` posé à côté de `.env` fait la marque, sans retoucher le code) + `rapport.ts` (nom de fichier `TYPE-OBJET-AAAA-MM-JJ.md`, avertissement posé sur les domaines qui engagent) |37| `scripts/install.sh` · `scripts/uninstall.sh` · `brand.example.json` | l'installation qui **se vérifie elle-même** (compte ses contrôles, sort en erreur sinon) et le désinstallation qui dit ce qu'elle laisse |38| `scripts/check_invariants.py` | les vingt gardes de l'agent, chez le client, sans nous |39| `docs/LIMITES.md` | ce qui n'est **pas** prouvé — la page qui évite le litige |4041## Les sept scripts4243| Script | Rôle | Codes |44|---|---|---|45| `scripts/gen_questionnaire.py` | **génère** le questionnaire client depuis `onboard.QUESTIONS` (le document ne peut plus être en retard sur l'entretien) ; `--check` compare sans écrire | `0` aligné · `1` en retard |46| `scripts/onboard.py` | l'entretien (41 questions, 5 pauses) ou la réponse à un questionnaire ; `--profil marketing` (ou `geo-seo`, `sales`, `legal`) repart d'un patron de dépôt au lieu de la page blanche ; écrit la spec et les dix pages | `0` propre · `1` réponses à compléter · `78` spec refusée (dont un canal entrant non admis) |47| `scripts/scaffold.py` | le squelette à partir de la spec : 49 fichiers, `src/` en sept couches, un test par C, les gardes copiées chez le client | `0` · `1` spec absente ou non concordante |48| `scripts/check_invariants.py` | les vingt gardes, dans le projet livré (`--json` pour les machines) | `0` · `1` liste de correctifs · `78` dossier sans agent |49| `scripts/reinvalider_gardes.py` | **re-invalide les gardes** : muter une seule garantie à la fois dans l'exemple, vérifier que la garde tombe, restaurer par copie. Sans ce script, une garde qui ne tombe plus reste dans la doc comme une décoration | `0` toutes les gardes mordent · `1` au moins une garde décorative |50| `scripts/check_skill.py` | vérifie l'atelier lui-même : hygiène, chemins cités réels, **chiffres recomptés à la source**, 4 profils passés au contrôle client, exemple identique octet pour octet à la sortie du gabarit, **et le gabarit doit refuser une spec dont la conversation entre par un autre canal** | `0` · `1` écarts listés · `78` atelier introuvable |51| `scripts/detect_drift.py` | compare un agent livré à la capture du skill (`assets/skill_state.json`) et dit si la méthode a bougé ; `--capture` après une entrée validée | `0` rien à intégrer · `1` signaux porteurs · `2` pas un agent |5253Le questionnaire à envoyer au client (remplissable sans nous) : `assets/templates/questionnaire.md`.54La spec de référence, valide au `spec.check()` : `assets/templates/agent.json`.5556Un exemple complet est livré avec le skill : `exemples/atlas-marketing` (agent rédactionnel et57calendrier pour un studio de marketing, parti du profil `marketing`) — spec, dix pages de docs,5849 fichiers de squelette, 14 commandes, 5 sous-agents, 4 outils, 22 tests, **20/20 invariants** et59`tsc --noEmit` à zéro erreur. C'est le niveau attendu d'une sortie de gabarit : pas une cible à rattraper.6061## Déroulé6263### Étape 0 — Lire les dépôts de référence (avant de poser la première question)6465Quatre dépôts sont livrés avec le skill, sous `depots/` : `geo-seo-claude`, `ai-marketing-claude`,66`ai-sales-team-claude` et le dépôt de revue juridique. Ils ne sont pas une inspiration : **ce sont les67patrons de nos agents générés**, et un skill qui ne les a pas lus à jour régénère des squelettes qui68ressemblent à un demo et non à un livrable. Ordre de lecture (détail et justifications :69`depots/README.md`, synthèse exploitable : `references/patrons.md`, douze patrons) :70711. `depots/*/README.md` des quatre dépôts — ce que chacun prétend livrer, en une page ;722. le `package.json` / `SKILL.md` de chacun — quelles commandes existent vraiment, et leurs arguments ;733. la definition des commandes (`commands/*.md` chez eux) — **une commande = un livrable nommé** ;744. le bloc terminal de chaque commande — court, six à douze lignes, le détail va au fichier ;755. les sous-agents et leur barème — parallélisme, score à poids, échelle de paliers A+ à D ;766. les portes chiffrées (plafond de pages, délai par page, pause entre appels, concurrence, doublons) ;777. l'installateur et la marque (white-label) — comment ils se vérifient eux-mêmes.7879On **ne copie pas** : leurs prompts métier, leurs noms de tiers, leurs exemples chiffrés, leurs secrets80d'exemple, et le vocabulaire d'un secteur plaqué sur un autre — la liste tient sur une page de81`depots/README.md`. Quand un dépôt bouge (nouvelle commande, nouveau patron de score), on relit, on82ajoute la garde correspondante, puis on régénère l'exemple.8384### Étape 1 — L'entretien (obligatoire, ~45 min avec le client)8586```bash87python3 scripts/onboard.py --interview --out ../mon-agent # a l'ecran, une pause par C88python3 scripts/onboard.py --answers reponses.json --out ../mon-agent # questionnaire rempli a l'equipe89python3 scripts/onboard.py --check ../mon-agent # relit une spec existante (reprise, recette)90```9192Quarante-et-une questions, cinq pauses (10 · 10 · 10 · 6 · 5), un défaut pour chacune — détail et contradictions refusées :93`references/onboarding.md`. Repartir d'un profil de dépôt (`--profil marketing`) n'est pas un raccourci :94le profil apporte la surface et le barème, l'entretien garde les questions d'identité, de secrets, de95rétention et d'approbation — les quatre choses que les dépôts ne couvrent pas. L'entretien **ne demande aucune valeur de secret** : seulement des noms de96variables ; le script refuse une spec où une valeur apparaît (`sk-…`, `gsh_…`, `GOCSPX-…`, un token97Telegram, un JSON web token).9899### Étape 2 — Le squelette100101```bash102python3 scripts/scaffold.py --spec ../mon-agent --out ../mon-agent103cd ../mon-agent && npm install && npm run check104```105106Il compile, il a un test par C, ses vingt invariants passent, et **ses outils disent « à écrire »**107plutôt qu'un faux résultat. C'est voulu : le socle est commun à tous les clients, le métier s'écrit108dans `src/tools/metier.ts` et dans la spec — pas en forkant le noyau.109110### Étape 3 — Le métier (le vrai travail)111112Pour chaque outil déclaré : un corps, un test, une phrase dans `docs/CAPACITE.md` qui dit **quand** le113modèle doit l'appeler. Pour chaque canal voulu : un module dans `src/channels/`, jamais dans `core/`.114Plan fichier par fichier et décisions de structure : `references/blueprint.md`.115116### Étape 4 — Prouver, sinon ce n'est pas livré117118```bash119npm run check # typecheck + un test par C + les 20 invariants120python3 scripts/check_invariants.py .121```122123Puis les **vingt cas de recette écrits par le client** (dont trois hors périmètre, trois sans réponse124dans ses sources, une tentative d'injection) : `references/verification.md`. On compte les succès et on125liste les échecs dans le PV. Un agent à 17/20 avec les trois cas écrits vaut mieux qu'un 20/20 dont on126a retiré les cas qui gênent.127128### Étape 5 — Livrer et rester joignable129130Runbook (démarrer, couper en trois secondes, purger une personne, changer de modèle), PV de recette en131six lignes, et ce qui est facturé comment : `references/delivery.md`. Le devis d'un agent de base tient132en une ligne : **4 à 6 jours** ; un agent élaboré se décompose à la ligne, après l'entretien, jamais avant.133134## Les cinq axes, et ce qu'ils empêchent135136| Axe | Question | Artefact | Ce qui casse sans lui |137|---|---|---|---|138| Contexte | De quoi il parle, pour qui, avec quel vocabulaire, qu'est-ce qui est vrai ? | `CONTEXTE.md` + lexique + sources | il invente, parle le mauvais métier, confond deux clients |139| Connexion | Par où il entre et sort, à quels systèmes il touche, avec quels secrets ? | `CONNEXION.md` + inventaire de secrets + rétention | un tuyau non déclaré devient une porte ; un secret non inventorié finit dans un journal |140| Capacité | Quels outils, quelles compétences, quels modèles, quelles limites ? | `CAPACITE.md` + registre typé | il promet ce qu'il ne peut pas faire, ou fait plus qu'il ne devrait |141| Cadence | Quand il se réveille, à quelle fréquence, jusqu'à quel budget ? | `CADENCE.md` + quatre plafonds chiffrés | un agent proactif sans plafond est une facture sans fin et du spam |142| **Conséquences** | Qu'est-ce qui est irréversible, qui approuve, comment on annule, combien de temps on garde ? | `CONSEQUENCES.md` + contrat de refus | une action non désirée, non annulable, non journalisée — la fin d'un contrat |143144`Conséquences` est notre ajout aux quatre C : ils décrivent ce que l'agent reçoit et ce qu'il fait, pas145ce que ses actes coûtent. En entreprise, la question du client n'est jamais « est-il intelligent ? »146mais « que se passe-t-il quand il se trompe ? ». Détail et contre-exemples : `references/4c.md`.147148## Ce qui ne doit jamais bouger149150| Invariant | Pourquoi |151|---|---|152| `python3 scripts/onboard.py --check` passe avant toute génération | un C vide ne se corrige pas dans le code plus tard ; il se corrige dans la facture |153| Liste blanche avant tout appel au modèle, et refus générique au tiers | sinon n'importe qui pilote l'agent au nom du client et vide le quota |154| `process.env` lu dans `config.ts` uniquement | validation et masquage des secrets n'ont qu'un point |155| Aucun `eval`, `new Function`, `vm` ; `child_process` seulement pour un binaire métier marqué, avec environnement filtré | le modèle ne choisit jamais le code exécuté |156| Outils en liste close, arguments validés, champs inconnus refusés | une injection lue dans un document ne devient pas un argv |157| Toute écriture = `dangerous` + `requiresApproval`, vérifié dans le **constructeur** du registre | aucun appelant ne peut oublier le garde-fou |158| La conversation **entre et sort par Telegram seul** ; pas de WhatsApp, pas de portail, pas de boîte mail ; le terminal n'est pas une surface humaine | un canal de plus, c'est une identité à vérifier, un plafond à payer et une porte de plus dans le réseau du client |159| Les plafonds de cadence sont dans la spec **et** lus par la config | un plafond écrit mais non lu est une intention, pas une limite |160| Sorties d'outils encadrées comme données non fiables ; refus expliqué à l'utilisateur | un fichier lu ne devient pas une consigne ; un silence se lit comme une panne du client |161| Aucun secret dans le dépôt ni les journaux ; rétention chiffrée et purgeable | le message d'erreur du fournisseur contient la requête, donc la donnée |162| Chaque modèle épinglé est vérifié contre l'inventaire du compte au démarrage | un nom recopié d'une doc produit un 400 opaque chez le client, un lundi |163| `docs/LIMITES.md` existe, et nomme ce qui reste non prouvé | une limite annoncée se planifie ; une limite cachée se plaide |164165Ces douze règles, les sept venues des dépôts et la garde de surface sont vérifiées par166`scripts/check_invariants.py` (codes `0` propre, `1` liste des correctifs, `78` dossier sans spec) —167**vingt gardes** :168169| # | Garde | Ce qu'elle empêche |170|---|---|---|171| 13 | `commands-routed` | une commande déclarée dans la spec et absente du menu : le client paie une capacité qu'il ne verra jamais |172| 14 | `score-weights-read` | un poids recopié dans le code de calcul à côté du poids de la spec : deux barèmes, deux notes pour un même travail |173| 15 | `subagent-modules-exist` | un sous-agent annoncé et sans module : l'orchestrateur le compte comme couverture nulle, et le score baisse sans que personne ne sache pourquoi |174| 16 | `quality-gates-read` | une porte écrite dans la spec que `config.ts` ne relit pas : un plafond qui n'est pas lu est une intention, pas une limite |175| 17 | `deliverable-named` | une sortie qui n'atterrit dans aucun fichier nommé : rien à rouvrir deux semaines plus tard, rien à facturer |176| 18 | `disclaimer-on-sensitive` | un livrable à valeur juridique, médicale ou financière sans avertissement en tête : le client le découvre après coup |177| 19 | `install-verifies` | un installateur qui compte ses échecs mais ne sort jamais en erreur : il déclare une installation prête pendant qu'elle est cassée |178| 20 | `canaux-clos` | une surface humaine rouverte n'importe où : un canal entrant ou sortant hors Telegram dans la spec, un module de canal qui réapparaît dans `src/channels/`, un secret WhatsApp revenu dans `.env.example`, le terminal qui redevient la conversation, ou un `createServer` qui traîne dans `src/` |179180Une règle qui ne peut plus échouer est une préférence. Chaque garde ajoutée est **re-invalidée par181mutation** — `python3 scripts/reinvalider_gardes.py` muter une garantie à la fois et exige que la garde182tombe, puis restaure par copie (jamais par remplacement de texte : un `replace` non conditionnel sur `:`183a déjà détruit un `install.sh` généré). Une garde qui ne mord pas ne rentre pas dans le skill.184185## Refus du skill (à assumer devant le client)186187| Demande | Réponse |188|---|---|189| « un outil qui envoie n'importe quelle requête à l'API du fournisseur » | non : des opérations enregistrées et typées, sinon on a rouvert un shell |190| « écrire sans confirmation, pour aller plus vite » | non : `requiresApproval` est dans le constructeur du registre |191| « journalise les conversations, ça servira » | non : on journalise des compteurs, pas du contenu privé |192| « entraîne un modèle sur nos données » | pas chez nous, et c'est écrit ; si le client le décide, la spec le porte avec son accord |193| « reprends l'agent qu'un autre a livré » | d'abord un audit (20 invariants, `--check` sur la spec), et l'audit dit souvent « à refaire » |194| « ajoute-moi un portail web / une entrée e-mail » | non : la conversation entre par Telegram. Un portail, c'est un port écouté et une session à sécuriser ; un e-mail entrant, c'est une identité qu'on ne peut pas vérifier. Si le besoin est réel, ça s'arbitre à l'atelier (nouvelle garde, nouveau profil), pas dans un dépôt client |195| « chiffre avant l'entretien » | non : le périmètre se fixe aux étapes 0 et 1, le chiffrage après |196| « prends l'agent d'un concurrent et change le logo » | non : on relit les dépôts, on écrit nos propres gabarits, et la licence du tiers est vérifiée avant (MIT ici, recopiée dans `depots/README.md`) |197198## Étendre et faire évoluer199200Canaux, fournisseurs, hébergement chez le client, voix et appels, données sensibles :201`references/extending.md`. Les douze patrons des dépôts et l'endroit exact où chacun atterrit chez nous :202`references/patrons.md`. Sécurité en détail (modèle de menace, onze règles) : `references/security.md`.203Le skill suit le projet : une règle fausse est **remplacée**, pas doublée ; chaque évolution retenue prend204une entrée de `CHANGELOG.md` avec sa preuve (commande exécutée, résultat brut), et un bump de version205selon qu'elle touche un chiffre (patch), une capacité (minor) ou la philosophie (major).