Chapitres

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

Skills, agents & hooks

Comment le harness câble skills, sous-agents délégables et hooks d'événements pour imposer la doctrine.

Vue d'ensemble

Le harness du vaisseau-mère est câblé autour d'un dossier .claude/. Trois mécaniques y coexistent : les skills (capacités invocables), les sous-agents délégables, et les hooks d'événements qui imposent la doctrine — commit-en-flux, garde-fous prod/email, injection mémoire.

                 .claude/
  utilisateur ──▶  settings.json (versionné)  +  settings.local.json (local)
  / Atlas              hooks PreToolUse / PostToolUse / Stop / UserPromptSubmit...

  skills/<nom>/SKILL.md  ──▶ invoqués via le tool Skill
  agents/<nickname>.md   ──▶ délégués via le tool Agent
       │                         │
       ▼                         ▼
  scripts/hook-*.sh        façades + injection mémoire
  (garde-fous, nudges)

Deux fichiers de réglages coexistent :

FichierVersionné gitContenu
.claude/settings.jsonouihooks PreToolUse/PostToolUse/Stop/UserPromptSubmit, env, permissions.defaultMode
.claude/settings.local.jsonnon (local)permissions.allow, hooks SessionStart/UserPromptSubmit/PreToolUse/PostToolUse, autoMode

Les deux jeux de hooks sont cumulatifs : pour un même événement (ex. PreToolUse matcher Bash), les commandes des deux fichiers s'exécutent. C'est pourquoi les garde-fous Python vivent dans le fichier local et les nudges shell dans le fichier versionné.

Les skills

Chaque skill est un dossier .claude/skills/<nom>/ contenant un SKILL.md — soit du markdown nu, soit avec un frontmatter --- description: ... ---. Un sous-dossier auto/ regroupe des skills internes au moteur, non destinés à l'invocation manuelle.

Catalogue par catégorie

CatégorieSkillRôle
Audit / santéauditAudit complet d'un site (healthcheck infra, pages publiques, SEO, perf, sécurité, DB) — score /100.
audit-hard-floorAnti-rot de la whitelist P0 immuable — vérifie que chaque path / section nommée existe encore.
audit-personasDrift des 30 personas vs stack actuelle ; snapshot dans sy_personas_drift_history.
statusCheck complet de l'état du système.
context-statusÉtat du contexte de la session courante.
Infra / hostsinfraAudit infra d'une machine hôte (dispo / charge / services / SSL / backups).
securityAudit sécurité d'une machine hôte (vaisseau-mère ou tenant).
backup-verifyVérifie fraîcheur + intégrité des backups locaux d'un hôte.
upgradeUpgrade APT non-interactif d'un hôte avec hold Docker.
botsAnalyse les hits de bots collectés côté serveur.
gscInterroge l'API Google Search Console (opportunités).
Chantier / pilotagechantierPilotage des chantiers (doctrine « 1 chantier = N travaux ») ; sources ps_ac_chantier + ps_ac_chantier_travail ; supporte new-skeleton (création atomique).
ideeCrée une idée de brainstorm (sy_brainstorm).
revueRevue de la Place des Armes (chaque agent se présente).
montessoriLeçon post-chantier via l'agent Montessori → draft dans le dossier d'inbox du Vault.
Email / inboxinboxLit / cherche les emails dans ps_ac_inbox_emails via la façade.
inbox-directFallback IMAP direct, lecture seule, n'écrit pas en DB.
inbox-findWrapper IMAP ergonomique — fetch + .eml, liste les pièces jointes sans extraire (scan-first).
scan-attachmentScan AV d'une pièce jointe avant ouverture — façade dédiée (agent Mitnick).
propal-verifQA d'une proposition commerciale email avant envoi (pool de 4 agents).
Mémoire / connaissancerecallRecall sémantique pgvector RAG sur la mémoire, le Vault et ps_ac_{cicatrices,doctrine,chantier} (embeddings 1024 dim, cosine).
zettelÉclate un document monolithique en notes atomiques pour le Vault Obsidian.
dictionnaireAjoute des termes au dictionnaire technique.
victoireGrave une victoire dans ps_ac_cicatrices (kind='victory').
refresh-personaRefresh d'une persona agent via LLM + diff 3-way + review (UPDATE sy_agents).
Finance / businessbankConsulte comptes / transactions via la façade bancaire.
bank-import-n26Import manuel de transactions bancaires (ps_ac_bank_transactions).
maltRécupère les conversations prospect de la plateforme freelance.
PublicationpublishPublie un article de blog sur le site vitrine.

Sources de vérité côté DB

Les skills ne stockent pas la donnée métier : ils tapent les tables PostgreSQL (schéma vaisseau_mere_ac). Tables citées explicitement dans les SKILL.md :

  • chantierps_ac_chantier, ps_ac_chantier_travail
  • recallps_ac_cicatrices, ps_ac_doctrine, ps_ac_chantier
  • victoireps_ac_cicatrices (kind='victory')
  • ideesy_brainstorm
  • audit-personassy_personas_drift_history
  • refresh-personasy_agents
  • inboxps_ac_inbox_emails
  • bank-import-n26ps_ac_bank_transactions

Un hook de pré-invocation lit sy_skill.size_bytes pour décider s'il faut suggérer un chargement paresseux (lazy-load à 3 niveaux) plutôt que d'injecter un gros SKILL.md en entier.

Les sous-agents

Sept fichiers <nickname>.md sont délégables via le tool Agent. Chaque fichier est généré depuis la DB par un script qui lit la vue ps_ac_agents et écrit entre des marqueurs AUTO-PERSONA-START / AUTO-PERSONA-END. La zone managée ne s'édite jamais à la main.

ps_ac_agents est une vue en lecture seule sur la table de base sy_agents (30 lignes). La source de vérité physique est donc sy_agents : refresh-persona y écrit, le générateur lit la vue — cohérent, aucune divergence à deux tables.

Frontmatter de chaque agent : name, description (critère de délégation), tools, model.

NicknameCodenameRôletools autorisésCadre cognitif
brunelinfraDevOps / Infrastructure (Docker, nginx, SSL, DNS, VPS)Bash, Read, Edit, Write, Grep, GlobCharge maximale
turingbackendBackend SRE (e-commerce headless, modules, Python, intégrité PG)Bash, Read, Edit, Write, Grep, GlobDéterminisme
eamesfrontendFrontend (Nuxt / Vue / Tailwind / Design System, pages du hub)Bash, Read, Edit, Write, Grep, GlobFonctionnalisme
lovelaceqaQA — dernier rempart prod, acceptance Playwright, régressionsBash, Read, Grep, Glob (pas d'écriture)Pré-mortem
mitnicksecuriteSécurité offensive/défensive, scan PJ, détection secrets, OWASPBash, Read, Grep, Glob (pas d'écriture)Attaquant
otletseo-techniqueSEO technique (JSON-LD, sitemap, CWV, 301, indexabilité IA)Bash, Read, Edit, Write, Grep, GlobMaillage
nightingaleclient-successCustomer Success — draft comm client, JAMAIS d'envoi directRead, Grep, Glob (lecture seule)Signaux vitaux

Observations vérifiables :

  • lovelace et mitnick n'ont pas Edit/Write (rôles de contrôle, pas de mutation).
  • nightingale n'a même pas Bash — strictement lecture, cohérent avec la règle « l'IA ne parle jamais directement aux clients ».
  • Drift connu : la zone managée peut afficher pour certains agents une stack DB historique (versions antérieures de Nuxt, ancien moteur SQL) alors que la zone manuelle parle de la stack actuelle. C'est précisément ce que traquent audit-personas / refresh-persona. Source de vérité = la table de base sy_agents, pas le .md.

Doctrine de délégation : Atlas s'auto-applique la doctrine chantier (≥ 2 agents distincts pour un scope tenant) et délègue via le tool Agent. Mitnick en scan-PJ est de l'outillage, pas un recrutement d'équipe.

Les hooks

Carte des événements

SessionStart        (local)    reset contexte + brief + injection cicatrices
UserPromptSubmit    json+local  sync schema DB  +  check emails
PreToolUse  Bash    json+local  nudges shell    +  garde-fous python
PreToolUse  Agent   json+local  reactor         +  injection cicatrices agent
PreToolUse  Skill   (json)      pre-invoke (suggère lazy-load si gros SKILL.md)
PreToolUse  Edit|Write (local)  injection cicatrices
PostToolUse Bash    (json)      react-log  +  deploy-preprod post-commit
PostToolUse Agent   (json)      reactor + react-log + telemetry agent
PostToolUse Edit|Write... (json) track-session-edits
PostToolUse ""      (local)     context-hook (compte tokens)
Stop                (json)      release-lock → cicatrice → uncommitted-warn → chantier-sync

SessionStart

Trois commandes (fichier local), chacune avec timeout court :

  1. Reset du compteur de contexte de la session.
  2. Brief de session : lit un rapport pré-calculé (ps_ac_audit_reports, type daily_meet, produit par une tâche planifiée) et l'enrichit en live (git, crontab, emails clients, backlog, cicatrice). SQL pipé via docker exec, sans dépendance npm.
  3. Injection des cicatrices pertinentes dans le contexte de démarrage.

Il n'y a pas de hook SessionStart dans le settings.json versionné — il vit uniquement dans le fichier local.

UserPromptSubmit

  • settings.json : synchronise le dump de schéma DB (.claude/db_schema.md).
  • fichier local : check des emails entrants (façade inbox, timeout court, échec silencieux et non bloquant).

PreToolUse — matcher Bash

settings.json (nudges, dans l'ordre d'exécution) :

ScriptEffet
check-db-mutation.shbloque une mutation DB (UPDATE/INSERT/ALTER … ps_ac_*) sans commit code aligné dans les 5 dernières minutes (équivalent runtime de « code AVANT db »).
hook-pre-deploy-autocommit.shauto-commit avant un ./deploy.
hook-chantier-skeleton-nudge.shwarn si INSERT SQL brut sur un chantier au lieu de la création atomique.
hook-pre-commit-transcript-scan.shscan anti-leak avant commit.

Un script d'audit d'auth back-office existe sur disque mais n'est référencé dans aucun settings*.json → script dormant, à ne pas croire actif.

Fichier local (garde-fous Python, exit 2 = bloquant) :

ScriptEffet
garde prod-writebloque toute commande Bash ciblant la prod d'un tenant (marqueurs hôte / base / domaine) avec un pattern d'écriture SQL → exige le passage par un script d'écriture prod sécurisé. Cicatrice d'un TRUNCATE accidentel. Anti-faux-positif : la preprod et les SELECT/SHOW non destructifs sont explicitement whitelistés, pour ne pas bloquer un smoke check.
garde façade emailbloque tout contournement de la façade email (clients SMTP/IMAP bruts, construction de messages hors façade). Seuls les scripts de façade autorisés peuvent envoyer/lire.
injection cicatrices Bashinjecte les cicatrices liées à la commande (timeout court).

PreToolUse — autres matchers

  • Agent : un reactor shell (json) + injection des cicatrices agent (local).
  • Skill : un pré-invoke non bloquant (exit 0 toujours), qui suggère un chargement paresseux si sy_skill.size_bytes dépasse un seuil.
  • Edit|Write (local) : injection cicatrices.

PostToolUse

  • Bash : log de réaction + hook de deploy auto après commit (asymétrie deploy auto / ship manuel). Le hook mappe les chemins touchés vers le site impacté. Pour les tenants c'est un deploy preprod ; pour le vaisseau-mère il n'y a pas de preprod — ./deploy = rebuild live, donc le terme « preprod » dans le nom du hook est trompeur dans ce cas. Skips : le hook saute le deploy si le message de commit contient [skip-deploy] / [no-deploy] ou commence par wip:, si le commit est pur docs/markdown/Vault (aucun fichier runtime touché), ou si le working tree est dirty post-commit.
  • Agent : reactor + react-log + télémétrie agent.
  • Edit|Write|MultiEdit|NotebookEdit : track-session-edits écrit la liste des fichiers édités par la session — base du Stop hook session-aware.
  • tous outils (local) : comptage tokens / contexte.

Stop — ordre d'exécution

1. release-chantier-lock   libère le lock chantier de la session
2. stop-cicatrice          rappel cicatrices SI mots-clés de clôture
                           (« clôture », « fin de session », « on ferme »…)
3. uncommitted-warn        BLOQUANT : refuse Stop si dirty (fichiers DE
                           cette session) → force commit-en-flux
4. chantier-sync           rappel synchro chantier ↔ hub DB

Mécaniques clés de l'avertissement uncommitted :

  • session-aware : filtre git status sur les fichiers listés par la session → N sessions Claude parallèles ne se bloquent pas mutuellement.
  • anti-boucle : si stop_hook_active=true (2e passe), passe en warning non bloquant au lieu de {"decision":"block"}.
  • worker early-return : un sous-claude spawné par le worker de tâches sort en exit 0 silencieux — il gère son propre cycle de commit.
  • exclusion de .claude/settings.json (le hook peut l'avoir édité).

Le hook stop-cicatrice est gardé par mot-clé du dernier message utilisateur, sinon silence ; quand déclenché, il liste les commits fix(*) / Cicatrice depuis la branche de preprod via stderr puis exit 2.

Convention worker-context

Une unique lib partagée sous scripts/lib/ est sourcée par les quatre hooks Stop ; ils sortent tôt quand la variable de contexte worker est positionnée (injectée par le spawner d'agents). Règle générale : un sous-claude spawné par le worker ne déclenche pas les hooks de session utilisateur (commit-en-flux, cicatrices de clôture).

Permissions & environnement

settings.json

"env":         { "CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "0", "CLAUDE_CODE_NO_FLICKER": "0" }
"permissions": { "defaultMode": "auto" }

defaultMode: auto = exécution sans prompt par défaut (cohérent avec la doctrine ./deploy autonome de l'IA).

settings.local.json

  • permissions.allow : une longue allowlist d'outils / commandes pré-approuvés ; permissions.deny absent.
  • env : vide.
  • autoMode : bloc structuré non standard décrivant une politique d'accès DB en langage naturel — allow (SQL lecture seule sur un environnement de staging), soft_deny (toute écriture sur la prod d'un tenant → confirmation explicite à chaque fois), et environment (rappel de ne pas confondre deux VPS d'un même tenant : prod vs staging).

Ce bloc autoMode est doublé au niveau exécutable par le garde-fou prod-write : la politique déclarative + le hook bloquant.

Anti-leak

Aucun secret en clair dans les hooks/skills/agents : les identifiants IMAP/SMTP sont référencés par nom de variable dans un fichier d'environnement gitignored, jamais en valeur. Le scan de transcript pré-commit et l'agent de sécurité (skill scan-attachment) sont les filets anti-leak / anti-malware.

Modèle de données

Récapitulatif des tables touchées (schéma vaisseau_mere_ac), avec leur producteur et leur consommateur :

TableProducteurConsommateur
sy_agents (base) / ps_ac_agents (vue)édition manuelle / refresh-personagénérateur de personas → .claude/agents/*.md
ps_ac_chantier, ps_ac_chantier_travailskill chantierhooks chantier-sync / lock
ps_ac_cicatricesskill victoire, hook stop-cicatricerecall, injection SessionStart / PreToolUse
ps_ac_audit_reports (daily_meet)tâche planifiée d'auditbrief de session (SessionStart)
sy_skill (size_bytes)indexation des skillshook pre-invoke skill
sy_personas_drift_historyaudit-personasreview drift
sy_brainstormideehub brainstorm
ps_ac_inbox_emailsfaçade inboxskill inbox
ps_ac_bank_transactionsbank-import-n26skill bank

Vérifié via information_schema : ps_ac_agents est une vue en lecture sur la table de base sy_agents. refresh-persona écrit sy_agents, le générateur lit la vue — cohérent, pas deux tables divergentes.