kwa/ workflows
Instructions, règles, skills, agents, hooks, MCP, permissions, plugins

Les briques

Un agent de code se règle avec une poignée de briques. Elles ne se ressemblent pas : certaines sont du texte que le modèle lit et peut oublier, d'autres sont exécutées par l'outil et tiennent quoi qu'il arrive. Chaque fiche dit pourquoi la brique existe, quand s'en servir, où elle vit, et montre un vrai fichier.

Lu par le modèle, ou exécuté par l'outil

suggéré Le modèle lit

Du texte qui entre dans sa fenêtre de contexte. Il le suit presque toujours, mais peut l'oublier ou s'en écarter.

imposé L'outil exécute

Claude Code (ou Kwa) l'applique avant ou après chaque action, sans demander l'avis du modèle.

barrière Un troisième cas : le bac à sable, où c'est le système d'exploitation qui contraint la commande elle-même, quoi qu'elle dise. Une brique « mixte » a les deux premiers : un sous-agent suit son texte, mais ne peut utiliser que les outils permis. Un plugin vaut ce qu'il contient. Page écrite pour Claude Code ; Codex lit le même AGENTS.md, et ses autres emplacements sont dans le README de Kwa.

Le trajet d'une commande

L'agent veut lancer git commit. Voici, dans l'ordre, ce qui peut l'arrêter. Chaque étape est une brique.

  1. Le modèle décideguidé par les instructions, les règles et la skill en cours
  2. Hooks PreToolUsetous en parallèle ; un refus arrête tout (hook, gardes de Kwa)
  3. Permissionsdeny, puis ask, puis allow, puis le mode de la session (permission)
  4. Bac à sablela commande tourne dans les limites du système (bac à sable)
  5. Hooks PostToolUseformater, vérifier : l'action a déjà eu lieu
  6. Le résultat revientdans la fenêtre de contexte : le modèle le lit et continue

Hors de la machine, la protection de branche de GitHub refuse encore une fusion sans relecture : le dernier filet, et le plus solide.

Laquelle choisir ?

Choisissez un besoin, puis faites votre pronostic parmi les briques : la page corrige, avec la raison.

Interdire quelque chose : trois façons

BesoinLe plus simple
Une commande ou un fichier toujours interdit, quelle que soit la situationPermission deny : une ligne dans settings.json
Un refus qui dépend du contexte : la branche, le contenu du fichier, l'heureHook : un script calcule la décision
Un refus propre au projet, avec la raison expliquée à l'agent, sous Claude Code comme sous CodexPolitique Kwa : les gardes de Kwa l'appliquent

Où tout cela vit

Un projet qui utilise toutes les briques. Rien n'est obligatoire : la plupart des projets commencent par AGENTS.md et une ou deux règles.

mon-projet/
├── AGENTS.md                      instructions, lues à chaque session
├── CLAUDE.md                      @AGENTS.md (un pointeur)
├── .mcp.json                      serveurs MCP du projet
└── .claude/
    ├── settings.json              permissions et hooks (partagés)
    ├── settings.local.json        vos réglages à vous (hors git)
    ├── rules/                     règles par sujet
    │   └── composants.md
    ├── skills/                    procédures
    │   └── release-notes/
    │       ├── SKILL.md
    │       └── modele.md          annexe, lue au besoin
    ├── agents/                    sous-agents
    │   └── security-reviewer.md
    ├── hooks/                     scripts des hooks
    │   ├── no-commit-on-main.py
    │   └── format.ts
    └── kwa.policy.json            avec Kwa : la politique du projet

~/.claude/                         les mêmes dossiers, pour tous vos projets
├── CLAUDE.md   ├── rules/   ├── skills/   ├── agents/   └── settings.json

La fenêtre de contexte, au fil d'une session

Ce que chaque brique fait entrer dans la fenêtre, et ce qui en sort à la compaction. Avancez pas à pas.

  1. Démarrage
  2. Lecture de src/Button.tsx
  3. Appel de /release-notes
  4. Relecture par un sous-agent
  5. Après /compact

  • chargé au démarrage
  • règle
  • skill
  • le travail de la session

Portées : qui l'emporte

Une brique peut exister chez vous, dans le projet, dans un plugin ou être imposée par l'organisation. Quand elle existe deux fois, la règle n'est pas la même partout.

BriqueOù elle peut vivreEn cas de doublon
Instructionsgéré (organisation) · ~/.claude/CLAUDE.md · CLAUDE.md du projet · CLAUDE.local.mdRien n'écrase rien : tout est mis bout à bout. Deux consignes contraires ? Le modèle suit l'une ou l'autre : à éviter.
Règle~/.claude/rules/ · .claude/rules/Les deux sont chargées, les vôtres d'abord ; aucune n'annule l'autre.
Skillorganisation · ~/.claude/skills/ · .claude/skills/ · pluginMême nom : organisation, puis la vôtre, puis celle du projet. Celles d'un plugin ont leur préfixe, donc pas de conflit.
Sous-agentgéré · --agents · .claude/agents/ · ~/.claude/agents/ · pluginMême nom : géré, puis la ligne de commande, puis le projet, puis le vôtre, puis le plugin.
Hookréglages personnels, du projet, locaux, gérés · plugin · en-tête d'une skill ou d'un agentTous s'additionnent et tournent en parallèle. Un hook identique dans deux fichiers de réglages ne tourne qu'une fois ; la copie d'un plugin ou d'une skill tourne en plus.
Serveur MCPplugin · ~/.claude.json (vous) · .mcp.json (projet) · localMême nom : local, puis projet, puis le vôtre, puis le plugin. L'entrée gagnante est prise entière, sans mélange.
Permission~/.claude/settings.json · .claude/settings.json · .claude/settings.local.json · ligne de commande · géréLes listes s'additionnent ; un deny venu de n'importe où bloque un allow d'ailleurs.
Pluginvous (user) · projet · local · géréActivé ou non : local, puis projet, puis le vôtre ; l'organisation peut l'imposer.

Instructions (AGENTS.md)

Ce que l'agent doit savoir sur le projet, à chaque session.

suggéré
Pourquoi
Une session repart de zéro. Ce fichier transmet ce que l'agent ne peut pas deviner en lisant le code : les commandes de vérification, les pièges, les interdits.
Quand l'utiliser
Un fait valable partout et tout le temps : comment lancer les tests, le port du serveur, la convention de branche.
Quand ce n'est pas le bon outil
Une consigne qui ne concerne qu'une partie du code (une règle), une procédure longue (une skill), une interdiction qui doit tenir (un hook).
Qui le déclenche
Personne : il est chargé au démarrage de chaque session.
Où il vit
AGENTS.md à la racine ; CLAUDE.md pour Claude Code, qui peut n'être qu'un pointeur.
Ce qu'il coûte au contexte
Toujours dans la fenêtre : restez court.
Sous Codex
AGENTS.md du projet, et ~/.codex/AGENTS.md ; du dossier racine au dossier courant, le plus proche pèse le plus.
Vérifier que ça marche
/context dans une session : AGENTS.md (ou CLAUDE.md) dans la liste des fichiers de mémoire chargés.
# AGENTS.md

Application web (Next.js, pnpm). Répondre en français.

## Vérifier avant de dire « fait »
- `npx tsc --noEmit` puis `pnpm test` : citer le résultat.
- `pnpm lint` signale à tort les fichiers générés : lancer `pnpm lint src`.

## Pièges
- Le serveur de développement écoute sur le port 4000, fixé dans `.env.example`.
- Après un changement de schéma : `pnpm db:migrate:create <nom>` puis `pnpm db:migrate`.

## Interdit
- Pas de commit sur main : une branche par sujet, une PR par branche.

Dans Kwa : le bloc que Kwa gère dans AGENTS.md

Règle (.claude/rules/)

Une consigne rangée par sujet, chargée quand elle sert.

suggéré
Pourquoi
Quand AGENTS.md grossit, tout y est lu à chaque fois. Une règle isole un sujet ; avec paths, elle n'entre dans le contexte que quand l'agent touche un fichier concerné.
Quand l'utiliser
Une convention propre à un dossier ou à un type de fichier : les composants React, les migrations, l'API.
Quand ce n'est pas le bon outil
Un fait général (AGENTS.md) ou une étape à exécuter dans l'ordre (une skill).
Qui le déclenche
Personne : chargée au démarrage, ou quand l'agent lit, écrit ou modifie un fichier qui correspond à paths (après une compaction, elle revient au prochain fichier concerné).
Où il vit
.claude/rules/*.md dans le projet, ~/.claude/rules/ pour vous.
Ce qu'il coûte au contexte
Au démarrage sans paths ; seulement au besoin avec.
Sous Codex
pas d'équivalent : un AGENTS.md par sous-dossier joue ce rôle.
Vérifier que ça marche
/context, puis demander à l'agent de modifier un fichier .tsx : la règle apparaît dans le contexte après la lecture du fichier.
---
paths:
  - "src/**/*.tsx"
---

# Composants React

- Tester avec Testing Library, jamais avec Enzyme.
- Un composant par fichier, nommé comme le fichier.
- Pas de style en ligne : les classes du design system.
  • --- … --- l'en-tête, en YAML : des paires « clé: valeur » que l'outil lit, le modèle ne les voit pas comme du texte.
  • paths les fichiers concernés. ** veut dire « dans tous les sous-dossiers », *.tsx « tout fichier qui finit par .tsx ». Sans paths, la règle est lue à chaque session, comme AGENTS.md : on la range à part seulement pour garder AGENTS.md court.

Dans Kwa : une règle commune de Kwa, rappelée au démarrage

Skill (SKILL.md)

Une procédure que l'agent suit quand la situation correspond.

suggéré
Pourquoi
Une tâche qui revient se fait toujours de la même façon. La skill l'écrit une fois ; seule sa description reste dans le contexte, le corps n'est lu qu'à l'appel.
Quand l'utiliser
Une procédure à étapes, déclenchée par une demande : rédiger des notes de version, livrer une PR, déboguer.
Quand ce n'est pas le bon outil
Un fait à connaître en permanence (AGENTS.md) ou une contrainte qui doit tenir même si l'agent l'oublie (un hook).
Qui le déclenche
Le modèle, quand la description correspond à la demande ; ou vous, en tapant /release-notes.
Où il vit
.claude/skills/<nom>/SKILL.md, ses annexes à côté ; ~/.claude/skills/ pour vous ; ou un plugin.
Ce qu'il coûte au contexte
La description (1 536 caractères au plus) dès le démarrage. Une fois appelée, le corps reste dans la conversation jusqu'à la fin ; après une compaction, les skills appelées sont réattachées (5 000 jetons chacune, 25 000 au total), mais la liste des descriptions ne revient pas : l'agent ne pense plus tout seul aux skills qu'il n'a pas encore utilisées. Vous pouvez toujours la lancer avec /nom.
Sous Codex
.agents/skills/<nom>/SKILL.md ou ~/.agents/skills/, même format ; on l'appelle avec $nom.
Vérifier que ça marche
/skills, puis taper /release-notes : la skill dans la liste ; à l'appel, l'agent suit ses étapes.
Les pièges
  • Un champ mal orthographié dans l'en-tête est ignoré sans erreur.
  • Une skill personnelle (~/.claude/skills/) l'emporte sur une skill du projet qui porte le même nom.
  • disable-model-invocation: true la réserve à vous : utile pour ce qui a des effets (déployer, publier).
---
name: release-notes
description: Rédiger les notes de version à partir des PR fusionnées. À utiliser quand l'utilisateur demande « les notes de version », « le changelog » ou « qu'est-ce qui part en prod ».
---

# Notes de version

1. Lister les PR fusionnées depuis la dernière étiquette :
   `gh pr list --state merged --search "merged:>=<date>"`.
2. Les classer : nouveautés, corrections, technique.
3. Une ligne par PR, au présent, sans jargon interne.
4. Suivre le gabarit de `modele.md` (dans ce dossier).
  • name le nom de la commande : /release-notes. Dans un plugin, il prend le préfixe du plugin (/kwa:tdd) ; sous Codex, on tape $ au lieu de /.
  • description la seule partie toujours chargée. Le modèle la compare à votre demande pour décider d'appeler la skill : dites quand l'utiliser, avec les mots que l'on emploie vraiment.
  • modele.md une annexe : lue seulement si la skill en a besoin, donc gratuite le reste du temps.

Dans Kwa : /kwa:tdd, le test d'abord

Sous-agent (.claude/agents/)

Un second collaborateur, avec sa propre fenêtre de contexte.

mixte
Pourquoi
Lire trente fichiers remplit la fenêtre de l'agent principal. Un sous-agent le fait à part et ne rend qu'un résumé. Il peut aussi avoir moins d'outils : un relecteur qui ne peut pas écrire relit mieux.
Quand l'utiliser
Un travail de lecture volumineux, une relecture indépendante, plusieurs tâches en parallèle.
Quand ce n'est pas le bon outil
Une petite tâche : le brief et le résumé coûtent plus que de la faire dans la session.
Qui le déclenche
Le modèle, ou une skill qui le lance ; vous, en le nommant : tapez @ et choisissez-le, ou écrivez @agent-security-reviewer relis mon diff.
Où il vit
.claude/agents/<nom>.md ; ~/.claude/agents/ pour vous ; ou un plugin.
Ce qu'il coûte au contexte
Sa propre fenêtre, où il relit les fichiers d'instructions ; seul son résumé revient. La description de chaque sous-agent reste dans la fenêtre principale.
Sous Codex
un fichier TOML dans .codex/agents/ ou ~/.codex/agents/ (name, description, developer_instructions).
Vérifier que ça marche
écrire @agent-security-reviewer relis mon diff : l'agent lance le sous-agent, qui travaille à part puis rend son résumé.
---
name: security-reviewer
description: Relit un diff sous l'angle de la sécurité (entrées non validées, secrets, droits). À utiliser avant une PR qui touche l'authentification, les paiements ou les données personnelles.
tools: Read, Grep, Glob
model: sonnet
---

Tu relis un changement sans le modifier. Pour chaque constat : le fichier et la
ligne, ce qui peut arriver, comment le reproduire, la gravité. Si rien ne pose
problème, dis-le en une phrase : n'invente pas de constat.
  • tools les seuls outils qu'il aura : ici lire et chercher, pas écrire. C'est l'outil qui l'applique : la partie imposée d'un sous-agent. Le reste du fichier est du texte qu'il suit.
  • model le modèle qui le fait tourner : sonnet, opus, haiku, ou inherit pour celui de la session. Absent, Claude Code choisit selon ses réglages, en général celui de la session.
  • le texte sous l'en-tête ses consignes. Il ne voit rien de votre conversation : seulement la tâche que l'agent principal lui donne. Sans Bash, il ne lance pas git diff : le diff lui est fourni dans la demande (le relecteur de Kwa a Bash, en lecture seule, gardé par un hook).

Dans Kwa : kwa:reviewer, le relecteur en lecture seule

Hook

Un script que l'outil exécute à un moment précis, sans demander au modèle.

imposé
Pourquoi
Une instruction peut être oubliée. Un hook ne dépend pas du modèle : Claude Code l'exécute, toujours, avant ou après un outil, au démarrage, à la fin d'une réponse. Mais il juge un texte : une commande formulée autrement peut lui échapper. C'est un filet contre l'erreur ; une vraie barrière, c'est le bac à sable ou la protection de branche.
Quand l'utiliser
Refuser une action (commit sur main, lecture d'un secret), formater après une écriture, réinjecter du contexte au démarrage.
Quand ce n'est pas le bon outil
Une décision qui demande du jugement : un hook lit du texte, il ne comprend pas l'intention.
Qui le déclenche
Claude Code, à l'événement choisi (PreToolUse, PostToolUse, SessionStart, Stop…).
Où il vit
Déclaré dans .claude/settings.json ; le script où vous voulez, souvent .claude/hooks/. Python, TypeScript, bash : n'importe quel langage qui lit l'entrée standard.
Ce qu'il coûte au contexte
Aucun, sauf ce qu'il renvoie à l'agent.
Sous Codex
.codex/hooks.json, ~/.codex/hooks.json ou des tables [hooks] dans config.toml. Des événements de même nom (PreToolUse, PostToolUse, Stop, SessionStart…), mais une douzaine au lieu d'une trentaine. Les hooks du projet ne se chargent que si le projet est approuvé, et chaque hook doit être validé dans /hooks, puis revalidé s'il change.
Vérifier que ça marche
/hooks, puis demander un commit sur main : le hook dans la liste ; le commit est refusé avec la raison du script.
Les pièges
Sortie du scriptAvant l'outil (PreToolUse)Après (PostToolUse)Fin de réponse (Stop)
0 sans rienpas d'avisrienl'agent s'arrête
0 et un JSONla décision du JSON (deny, ask, allow)un retour pour l'agentpeut demander de continuer
2refus, la sortie d'erreur part à l'agenttrop tard : l'outil a déjà tournél'agent repart travailler
1 ou autreerreur sans effet : l'action continue
  • Tous les hooks d'un même événement tournent en parallèle, sans ordre : deux formateurs sur le même fichier se marchent dessus.
  • Un hook Stop qui refuse toujours fait boucler l'agent : testez stop_hook_active ; Claude Code rend la main après 8 relances d'affilée.
  • Un hook peut être déclaré ailleurs : réglages personnels ou locaux, plugin, en-tête d'une skill ou d'un agent. /hooks les montre tous.
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "python3 \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/no-commit-on-main.py"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "npx tsx \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/format.ts"
          }
        ]
      }
    ]
  }
}
  • PreToolUse, PostToolUse l'événement : avant ou après un outil. Il en existe une trentaine (démarrage, fin de réponse…).
  • matcher le nom de l'outil visé : Bash (le terminal), Edit|Write (l'un ou l'autre).
  • type: command le hook est un programme à lancer ; command est sa ligne de commande.
  • $CLAUDE_PROJECT_DIR la racine du projet, remplie par Claude Code : le chemin marche quel que soit le dossier courant.

Dans Kwa : guard-git, le garde de git de Kwa

Serveur MCP

Des outils et des données branchés sur l'agent : une doc, un navigateur, une base.

suggéré
Pourquoi
L'agent ne voit que son dépôt. Un serveur MCP lui ajoute des outils, que le modèle découvre et décide d'appeler : chercher dans une doc à jour, piloter un navigateur, lire une base.
Quand l'utiliser
Un accès à un service ou à des données hors du dépôt.
Quand ce n'est pas le bon outil
Une procédure (une skill) ; un serveur que vous ne connaissez pas : il agit avec vos droits. En session interactive, Claude Code demande avant d'utiliser les serveurs d'un .mcp.json ; en claude -p et dans le SDK, il les charge sans demander.
Qui le déclenche
Le modèle, qui appelle ses outils (mcp__context7__…).
Où il vit
.mcp.json à la racine du projet (partagé) ; claude mcp add l'ajoute pour ce projet et vous seul, --scope user pour tous vos projets.
Ce qu'il coûte au contexte
Les noms des outils ; leurs définitions à la demande.
Sous Codex
une table [mcp_servers.<nom>] dans ~/.codex/config.toml, ou codex mcp add.
Vérifier que ça marche
/mcp : le serveur connecté et ses outils.
Les pièges
  • Un même serveur déclaré à plusieurs endroits : la définition locale gagne, puis celle du projet, puis la vôtre, puis celle d'un plugin.
  • Un dépôt cloné peut apporter un .mcp.json : en claude -p ou en CI, il est chargé sans demander. disabledMcpjsonServers en exclut un.
{
  "mcpServers": {
    "context7": {
      "type": "http",
      "url": "https://mcp.context7.com/mcp",
      "headers": {
        "Authorization": "Bearer ${CONTEXT7_API_KEY}"
      }
    },
    "base": {
      "type": "stdio",
      "command": "npx",
      "args": [
        "-y",
        "@bytebase/dbhub"
      ],
      "env": {
        "DSN": "${DB_URL}"
      }
    }
  }
}
  • type: http un service distant, joint par une adresse ; headers porte l'authentification.
  • type: stdio un programme lancé sur votre machine (npx -y le télécharge puis le lance), qui parle par l'entrée et la sortie standard.
  • ${CONTEXT7_API_KEY} une variable d'environnement : la clé n'est jamais écrite dans le fichier, qui peut donc être versionné.
  • DSN le nom de variable que ce serveur attend pour la base : chaque serveur documente les siens.

Pas à pas : parcours 2, étapes 7 et 8 : MCP, Context7, Playwright, Graphify

Permission

Ce que l'agent a le droit de faire, décidé hors de son texte.

imposé
Pourquoi
Évite de valider chaque commande à la main, et ferme ce qui ne doit jamais se faire. Claude Code l'applique avant l'outil, quoi qu'en pense le modèle.
Quand l'utiliser
Autoriser les commandes sûres et fréquentes, demander avant un push, refuser un fichier de secrets.
Quand ce n'est pas le bon outil
Une règle qui dépend du contexte (la branche, le contenu) : un hook la calcule, une permission ne voit que la commande.
Qui le déclenche
Claude Code, avant chaque outil : deny, puis ask, puis allow.
Où il vit
.claude/settings.json (partagé), .claude/settings.local.json (vous seul), ~/.claude/settings.json.
Ce qu'il coûte au contexte
Aucun.
Sous Codex
approval_policy dans config.toml, et des règles de commandes prefix_rule(…) dans .codex/rules/*.rules.
Vérifier que ça marche
/permissions : vos règles, rangées par portée (projet, local, personnel).
Les pièges
  • Un deny de n'importe quel fichier de réglages l'emporte sur un allow d'un autre.
  • Une règle Bash lit la commande écrite : bash -c '…' ou un chemin complet passent à côté. Pour une vraie limite, le bac à sable.
{
  "permissions": {
    "allow": [
      "Bash(pnpm test *)",
      "Bash(git status)"
    ],
    "ask": [
      "Bash(git push *)"
    ],
    "deny": [
      "Read(.env)",
      "Read(secrets/**)",
      "Bash(rm -rf *)",
      "mcp__playwright__browser_run_code_unsafe"
    ]
  }
}
  • Bash(pnpm test *) la commande pnpm test, seule ou suivie d'arguments (l'étoile).
  • Read(.env) un nom de fichier seul vaut à toute profondeur (comme dans un .gitignore) ; ./.env ne viserait que le dossier courant. .env.local demande sa propre ligne.
  • Bash(rm -rf *) un filet : rm -fr ou /bin/rm passent à côté. Une règle Bash lit le texte de la commande.
  • deny, ask, allow évaluées dans cet ordre : un refus l'emporte toujours, même sur une autorisation plus précise, et vaut aussi pour chaque morceau d'une commande composée.

Pas à pas : parcours 2, étape 9 : permissions et réglages

Bac à sable

Une limite posée par le système d'exploitation autour des commandes shell.

barrière
Pourquoi
Une permission ou un hook lisent le texte d'une commande ; une commande écrite autrement leur échappe. Le bac à sable, lui, contraint le processus lui-même : les fichiers qu'il peut écrire, les sites qu'il peut joindre, quoi que la commande dise.
Quand l'utiliser
Laisser l'agent lancer des commandes sans confirmation, sur un projet où une fuite ou une suppression coûterait cher.
Quand ce n'est pas le bon outil
Les outils de fichiers (Read, Edit), les serveurs MCP et les hooks : ils tournent hors du bac à sable et suivent les permissions. Et Windows natif : il faut WSL2.
Qui le déclenche
Le système d'exploitation, pendant chaque commande shell de l'agent, et pour les processus qu'elle lance.
Où il vit
/sandbox dans une session, ou sandbox.enabled dans settings.json. Désactivé par défaut.
Ce qu'il coûte au contexte
Aucun.
Sous Codex
sandbox_mode dans config.toml : read-only, workspace-write ou danger-full-access.
Vérifier que ça marche
/sandbox, puis demander à l'agent « curl https://example.com » : le bac à sable actif ; en mode Manuel (default, celui où l'outil vous demande avant d'agir), une demande d'autorisation pour example.com s'affiche ; en dontAsk ou avec strictAllowlist, un refus net.
{
  "sandbox": {
    "enabled": true,
    "allowUnsandboxedCommands": false,
    "network": {
      "allowedDomains": [
        "registry.npmjs.org"
      ]
    },
    "filesystem": {
      "allowWrite": [
        "/tmp/build"
      ]
    }
  }
}
  • allowUnsandboxedCommands: false sans cela, Claude peut demander à relancer une commande hors du bac à sable quand elle échoue.
  • network.allowedDomains les sites que le shell joint sans demander ; la liste part vide. Pour un autre site, le mode de permission de la session décide : une demande s'affiche en mode Manuel (default), acceptEdits ou plan ; le site est refusé en dontAsk, et en auto sauf si la commande l'a déclaré et que le classifieur l'a validé ; la connexion passe sans demande en bypassPermissions. Pour un refus net partout, network.strictAllowlist: true, à mettre dans vos réglages personnels (il est ignoré dans ceux du projet).
  • filesystem.allowWrite les dossiers où écrire, en plus du projet.

Pas à pas : Imposé ou suggéré : où le bac à sable se place

Plugin

Un paquet de skills, d'agents, de hooks et de serveurs, installé une fois par machine.

selon le contenu
Pourquoi
Copier les mêmes fichiers dans dix dépôts, c'est dix copies qui divergent. Un plugin les regroupe, se met à jour d'un coup, et le projet ne garde que sa configuration.
Quand l'utiliser
Partager une méthode entre plusieurs projets ou plusieurs personnes.
Quand ce n'est pas le bon outil
Un réglage propre à un seul projet : il reste dans le dépôt. À savoir : ses skills prennent son préfixe (/mon-plugin:release-notes) ; ses hooks désignent leurs scripts par ${CLAUDE_PLUGIN_ROOT}, pas $CLAUDE_PROJECT_DIR ; un CLAUDE.md placé dans un plugin n'est pas lu. claude plugin validate vérifie le tout.
Qui le déclenche
Vous : /plugin install ; le projet peut le proposer à l'équipe dans settings.json.
Où il vit
un dépôt Git, la marketplace/plugin install sur votre machineactivé dans le projet par settings.json
Ce qu'il coûte au contexte
Celui de ce qu'il contient.
Sous Codex
des plugins Codex existent aussi (skills, serveurs MCP, hooks), installés depuis /plugins.
Vérifier que ça marche
/plugin : le plugin installé et activé ; ses skills dans /skills.
mon-plugin/
├── .claude-plugin/
│   └── plugin.json          le manifeste : nom, version, où sont les hooks
├── skills/
│   └── release-notes/SKILL.md
├── agents/
│   └── security-reviewer.md
├── hooks/hooks.json         les hooks, au format du bloc hooks de settings.json
└── .mcp.json                facultatif : les serveurs MCP

Dans Kwa : le manifeste du plugin Kwa

Politique Kwa

Ce qui change d'un projet à l'autre, lu par les gardes et les skills de Kwa.

imposé (par les gardes)
Pourquoi
Les gardes sont les mêmes partout ; les commandes interdites, les vérifications et les environnements, non. La politique les décrit, sans toucher aux scripts.
Quand l'utiliser
Interdire une commande propre au projet, déclarer les vérifications, choisir les modules.
Quand ce n'est pas le bon outil
Une règle valable pour tous les projets : elle va dans Kwa lui-même.
Qui le déclenche
Les gardes de Kwa, à chaque outil surveillé ; les skills, quand elles en ont besoin.
Où il vit
.claude/kwa.policy.json, créé par kwa init, puis propriété du projet.
Ce qu'il coûte au contexte
Aucun.
Sous Codex
la même politique : Kwa la traduit en hooks et en règles de commandes pour Codex.
Vérifier que ça marche
kwa doctor . dans le terminal : « cible conforme », ou la liste de ce qui manque.
{
  "kwa": 1,
  "modules": [
    "core",
    "craft",
    "issue-flow"
  ],
  "bash": {
    "deny": [
      {
        "id": "deploy-prod",
        "reason": "La production part par la PR, pas par ce script.",
        "all": [
          "npm run deploy:prod"
        ]
      }
    ]
  },
  "verify": {
    "commands": [
      "pnpm typecheck",
      "pnpm test"
    ]
  }
}
  • bash.deny une commande que les gardes de Kwa refusent, avec la raison donnée à l'agent. Le même refus vaut sous Codex.
  • verify.commands les vérifications que les skills de Kwa lancent avant de dire « fait ».

Dans Kwa : une politique complète d'exemple