Aller au contenu
learn

6. Se l'approprier — règles, vérification, installation d'équipe

Code : code/slashforge/check.sh, dont la sortie l06_verify_glob est vérifiée par la CI sous Linux, Windows et macOS, et lab/run.sh pour l’unique exécution du modèle, e5b dans le journal.

Setup (leçon 3) écrit une première version de chacun. Ensuite, ils sont à toi et tu les modifies :

Fichier Chargé Pour
CLAUDE.md à chaque session ce qu’est le projet, et les commandes : build, test, lint
.claude/rules/*.md au démarrage de la session, ou seulement quand un fichier correspondant est lu si la règle a paths: les conventions d’une zone du code
.claude/skills/<name>/SKILL.md quand on l’invoque, ou quand Claude le juge pertinent une recette : « ajouter un endpoint ici »

C’est la ligne du milieu qu’il faut retenir. Une règle avec paths: dans son frontmatter ne coûte rien tant que Claude ne lit pas un fichier qui lui correspond ; c’est ainsi qu’un grand dépôt garde des instructions courtes. La documentation du répertoire .claude ajoute la mise en garde qui vaut pour les trois : “Like CLAUDE.md, rules are guidance Claude reads, not configuration Claude Code enforces. For guaranteed behavior use hooks or permissions.”

La première ligne compte pour SlashForge en particulier. La phase 6 de /slashforge:code commence par vérifier que “lint, test, and build commands are defined in CLAUDE.md. If any are missing, ask the user for them before continuing.” C’est ton contrat de vérification : ce que nomme CLAUDE.md est ce que le workflow exécute avant d’annoncer un succès. /init a écrit une section Commands à la leçon 3 ; setup pose la question.

Relance setup après une nouvelle version de SlashForge, et il doit décider quels fichiers il a le droit d’écraser. forge-instructions.md fait porter à chaque fichier qu’il génère un marqueur, generated_by: slashforge@4.4.3 dans le frontmatter, ou un commentaire HTML sur la première ligne de CLAUDE.md, et applique trois cas à la nouvelle exécution :

  • le marqueur correspond à la version actuelle du kit : le fichier peut être rafraîchi ;
  • le marqueur vient d’une version plus ancienne : “Propose a refresh; ask the user before overwriting” ;
  • le marqueur est “missing or edited” : le fichier est “user-owned. Edit to fill gaps only; do not overwrite”.

C’est l’en-tête // <auto-generated> d’un fichier de designer .NET, avec la classe partielle comme porte de sortie. Ici, la porte de sortie consiste à modifier le marqueur, ou à le supprimer, et le fichier devient le tien. C’est le modèle qui applique ces règles à la nouvelle exécution : ce sont donc des instructions, pas un mécanisme ; le cours n’a pas relancé setup pour les tester.

Le kit donne au modèle deux guides sur les skills, et ils ne sont pas d’accord.

forge-instructions.md forge-skills.md
Où va un skill .claude/skills/*.md “each skill is a directory containing a SKILL.md entrypoint, not a flat .md file”
Quelle longueur il peut avoir “Every .md file — including this one — must stay under 200 lines”, parmi les “Golden Rules (always enforced)” “Keep SKILL.md under 500 lines”

Claude Code donne raison au second sur la première ligne : sa documentation des skills indique chaque emplacement sous la forme .claude/skills/<skill-name>/SKILL.md. Un fichier à plat dans skills/ ne figure pas dans ce tableau. Sur la seconde ligne, les deux limites sont propres au kit ; la documentation de Claude Code prend 200 lignes comme cible pour CLAUDE.md.

Une étape de vérification qui ne voit pas les skills

Section intitulée « Une étape de vérification qui ne voit pas les skills »

Setup se termine par une étape de vérification, dans forge-instructions.md :

Fenêtre de terminal
# No file exceeds 200 lines
wc -l CLAUDE.md .claude/**/*.md

En bash, ** ne veut dire « à n’importe quelle profondeur » que si l’option globstar est activée, et elle est désactivée par défaut. Sans elle, .claude/**/*.md équivaut à .claude/*/*.md : un seul dossier de profondeur. check.sh construit un dépôt comme le demande forge-skills.md — une règle, un skill dans son propre dossier, long de 300 lignes — et lance la commande :

# the files, as find sees them
6 .claude/rules/api.md
300 .claude/skills/add-endpoint/SKILL.md
1 CLAUDE.md
# the files the verify step counts: wc -l CLAUDE.md .claude/**/*.md, in bash without globstar
1 CLAUDE.md
6 .claude/rules/api.md

Le skill est à deux dossiers de profondeur, donc la vérification ne le voit jamais, et un skill de 300 lignes passe une règle de 200 lignes. Le /bin/bash 3.2 de macOS n’a pas du tout globstar. zsh est différent : là, **/ est récursif par défaut, donc la même ligne fonctionne dans un shell zsh — la vérification réussit ou échoue selon le shell qui l’exécute. Une vérification qui ne peut pas échouer dans le cas pour lequel elle existe est pire que pas de vérification du tout, parce qu’elle est déclarée faite. find CLAUDE.md .claude -name '*.md' | xargs wc -l voit tous les fichiers.

Une installation d’équipe, et quelle copie s’exécute

Section intitulée « Une installation d’équipe, et quelle copie s’exécute »

--project (leçon 1) écrit le kit dans le .claude/ du dépôt, avec des chemins relatifs, pour qu’une équipe puisse le commiter : tous ceux qui clonent obtiennent /slashforge:code à la même version. Sauf si quelqu’un a aussi installé SlashForge globalement, dans ~/.claude/.

La règle de Claude Code pour deux skills ou commandes du même nom est “Enterprise over personal, and personal over project.” Le labo l’a testée avec la plus petite commande possible, /lab:which, présente deux fois : dans le commands/lab/which.md personnel du labo, qui répond GLOBAL, et dans le .claude/commands/lab/which.md du dépôt, qui répond PROJECT. L’hypothèse, écrite avant l’exécution à partir de cette phrase, était GLOBAL.

subtype: success
turns: 1
cost: 0.0896938 USD (as computed by Claude Code)
RESULT: "GLOBAL"

C’est la copie personnelle qui s’exécute. Pour une équipe, cela veut dire que la version commitée n’est celle qui s’exécute que pour les personnes qui n’ont pas installé le kit elles-mêmes : un coéquipier avec une installation globale plus ancienne exécute son /slashforge:code, avec les points de contrôle et les guides de sa version, sans le moindre avertissement. slashforge status et slashforge status --project indiquent les deux installations séparément, donc la vérification ne coûte pas cher. Choisis un seul mode pour l’équipe, et si c’est le mode projet, désinstalle l’installation globale.

Une remarque sur le coût, tirée de la même exécution : la première tentative, avec un plafond de 0.10 USD, a été arrêtée avec error_max_budget_usd à 0.103 USD — pour une réponse de huit tokens. Le plafond fonctionne sous une connexion par abonnement, mais il est vérifié après chaque appel, si bien qu’une exécution peut se terminer légèrement au-dessus ; et avec ce modèle, une session coûte environ 0.09 USD avant de faire quoi que ce soit, essentiellement l’écriture du cache de prompt.

  • CLAUDE.md contient les commandes qu’exécute la phase 6 de SlashForge ; les règles avec paths: ne se chargent que pour les fichiers correspondants ; les skills sont des dossiers avec un SKILL.md.
  • Les fichiers générés par setup portent un marqueur generated_by ; un fichier dont le marqueur manque ou a été modifié est traité comme le tien à une nouvelle exécution.
  • Les deux guides du kit ne sont pas d’accord sur l’emplacement des skills ni sur leur longueur maximale ; la documentation de Claude Code exige la forme en dossier.
  • Le wc -l .claude/**/*.md de l’étape de vérification ne regarde pas dans les dossiers de skills dans le mode par défaut de bash : un skill de 300 lignes passe.
  • Quand une commande existe dans ~/.claude et dans le projet, c’est la copie personnelle qui s’exécute. Une installation d’équipe ne tient que pour les coéquipiers qui n’en ont pas de globale.
  1. Réécris l’étape de vérification pour qu’elle échoue, avec un code de sortie non nul, quand un fichier sous .claude/ ou CLAUDE.md dépasse 200 lignes, d’une façon qui fonctionne en bash 3.2.
  2. Tu veux que /slashforge:code exécute le npm run lint:strict de ton équipe en phase 6. Où le mets-tu, et que se passe-t-il si tu ne le fais pas ?
  3. Un coéquipier dit que le kit commité « ne marche pas » et décrit des points de contrôle que la 4.4.3 n’a pas. Que lui demandes-tu de lancer ?
Solution
  1. Par exemple :

    Fenêtre de terminal
    find CLAUDE.md .claude -name '*.md' -exec wc -l {} + \
    | awk '$2 != "total" && $1 > 200 { print; bad = 1 } END { exit bad }'

    find parcourt toutes les profondeurs sans option de shell, et awk affiche les fichiers en cause et fixe le code de sortie.

  2. Dans la section Commands de CLAUDE.md, comme commande de lint. La phase 6 lit les commandes dans CLAUDE.md ; si le lint, les tests ou le build manquent, le workflow s’arrête et les demande — ou, sans interface, l’exécution se termine là.

  3. npx slashforge status et npx slashforge status --project : la première montre une installation globale et sa version. S’il y en a une, c’est elle qui s’exécute ; npx slashforge uninstall la retire, et la copie commitée du projet prend le relais.