Aller au contenu

Hooks déterministes

Quatre scripts PowerShell dans scripts/ s'interposent aux moments critiques de chaque session. Ils constituent la couche déterministe qui garantit que l'état de la spirale (spiral-state.md), la traçabilité des outils, et les règles de vocabulaire sont toujours respectés — indépendamment de la volonté ou de la vigilance de l'agent IA.

Principe

Les hooks sont non-négociables : ils s'exécutent à des événements fixes, lisent stdin en JSON, et peuvent soit enrichir le contexte (SessionStart), soit refuser une action (PreToolUse), soit écrire un artefact (PreCompact, Stop). Ils ne contiennent aucune intelligence — uniquement des règles.

Vue d'ensemble

Hook Événement Rôle principal Peut bloquer ?
hook-session-start.ps1 SessionStart Injecter spiral-state.md comme contexte système Non
hook-pretooluse.ps1 PreToolUse Logger chaque usage outil + lint vocabulaire CODIR Oui
hook-precompact.ps1 PreCompact Sauvegarder spiral-state.md avant compaction Non
hook-stop.ps1 Stop Créer le fichier session + gate traçabilité spirale Non

hook-session-start.ps1

Événement : démarrage d'une session Claude Code.

Entrée : JSON depuis stdin (objet session).

Action :

  1. Lit .product/spiral-state.md s'il existe.
  2. Émet un JSON hookSpecificOutput contenant un additionalContext avec le contenu de spiral-state.md encadré par === ETAT SPIRAL === / === FIN ETAT SPIRAL ===.

Effet : l'agent IA reçoit, dès son premier tour, l'état explicite de la spirale (où nous en sommes, quelle porte est active, quels objets sont LIVING). Pas de devinette possible.

hook-pretooluse.ps1

Événement : avant chaque appel d'outil par l'agent (Edit, Write, Bash…).

Entrée : JSON incluant tool_name, tool_input, sessionId.

Actions :

  1. Log JSONL : append dans .product/.events/.tools/YYYY-MM-DD.jsonl d'une ligne {ts, tool, sessionId, input}. Trace exhaustive de tout usage outil de la journée.
  2. Lint vocabulaire CODIR : si l'outil édite un fichier .html, scan du contenu nouvellement écrit (newString ou content). Liste de termes interdits :
  3. \bEHS\b, \bLBC\b → vocabulaire interne du kernel, à remplacer par vocabulaire CODIR
  4. \binvariant\b → technique, remplacer par « critère »
  5. \bKR[0-9]?\b → jargon OKR, remplacer par « résultat clé »
  6. \bEpic Hypothesis\b → jargon SAFe, à traduire

Si un terme interdit est détecté, le hook émet une décision deny avec la raison → l'outil est refusé, l'agent reçoit le message d'erreur et doit réécrire avec le vocabulaire approprié.

Effet : impossible d'infiltrer du jargon interne dans un livrable destiné au COMEX. La règle est mécanique, pas contractuelle.

hook-precompact.ps1

Événement : juste avant une compaction du contexte (automatique ou manuelle).

Entrée : JSON incluant sessionId, trigger.

Action :

  1. Cherche le fichier session du jour dans .product/.events/.
  2. S'il n'existe pas, en crée un (YYYY-MM-DD-HH-mm-session-autocompact.md).
  3. Y append un bloc ## Snapshot PreCompact — <timestamp> contenant un dump markdown complet de spiral-state.md.

Effet : aucune compaction ne peut effacer la mémoire de la spirale. L'état est toujours sauvegardé dans un fichier humain-lisible, versionné, consultable.

hook-stop.ps1

Événement : fin de session (arrêt du processus Claude Code).

Entrée : JSON incluant sessionId, stop_hook_active.

Actions :

  1. Anti-boucle : si stop_hook_active === true, sortie immédiate (évite la réentrance).
  2. Création du fichier session : si aucun YYYY-MM-DD-*.md n'existe encore dans .product/.events/, crée un fichier avec en-tête + zones vides pour prompt et décisions.
  3. Gate traçabilité spirale : vérifie la date de dernière modification de .product/spiral-state.md.
  4. Si pas modifié aujourd'hui → émet un systemMessage : « TRACABILITE : spiral-state.md n'a pas été mis à jour aujourd'hui. »
  5. Si absent → émet un systemMessage alertant de sa création nécessaire.

Effet : impossible de clore une journée de travail sans que la spirale soit mise à jour, sans laisser de trace. Le rappel est visible à la fermeture, pas après.

Configuration

Les hooks sont déclarés dans .claude/settings.json du projet consommateur (ou dans .claude/settings.local.json pour un paramétrage utilisateur). Exemple :

{
  "hooks": {
    "SessionStart": ["pwsh -File .sdeg/scripts/hook-session-start.ps1"],
    "PreToolUse":   ["pwsh -File .sdeg/scripts/hook-pretooluse.ps1"],
    "PreCompact":   ["pwsh -File .sdeg/scripts/hook-precompact.ps1"],
    "Stop":         ["pwsh -File .sdeg/scripts/hook-stop.ps1"]
  }
}

Décisions liées

Voir aussi : Invariant sécurité · Stack technique.