Trois semaines après avoir dit que mon CLAUDE.md s'écrivait tout seul, il a ajouté 4 règles sans moi On April 28, the author published an article claiming their CLAUDE.md file "wrote itself" through incident-driven rule additions, and within three weeks, four new rules were added without direct author intervention. The new rules—covering cache authentication contracts, required name fields for registered students, and training contract formatting—emerged from real incidents like a security audit revealing a RBAC vulnerability and a data import bug causing missing student names. The author emphasizes these rules were not pre-written but captured as incidents occurred, demonstrating a doctrinal shift in how a solo developer manages an AI coding agent in production. Une thèse, trois semaines plus tard Le 28 avril, j'ai publié sur DEV.to un article qui affirmait quatre choses à propos d'un fichier CLAUDE.md — celui qui contraint l'agent de codage à chaque session — et qui finissait par cette phrase : « le CLAUDE.md n'est jamais fini, et c'est précisément pour ça qu'il marche » 4 incidents, 4 règles : comment mon CLAUDE.md s'est écrit tout seul https://dev.to/michelfaure/4-incidents-4-regles-comment-mon-claudemd-sest-ecrit-tout-seul-dpl . C'était une thèse, pas une métaphore. Trois semaines ont passé. Le fichier a ajouté quatre règles sans moi. Je veux dire par là que je ne les ai pas écrites le jour où je me suis assis pour écrire des règles. Je les ai accueillies les jours où un incident les avait produites, et où je n'avais plus qu'à les noter avant qu'elles s'évaporent dans la marche du projet. La différence, sur le papier, paraît mince. Dans la pratique d'un dev solo qui pilote un agent en production, elle est doctrinale. Une précision avant d'entrer dans la liste : le titre de cet article a failli dire « cinq règles ». live-snapshot-cache.md a été commité le 25 avril, trois jours avant la publication de l'article-pivot. Elle ne compte pas. Je préfère l'honnêteté du chiffre exact au confort de l'arrondi. Le bilan, mesuré par git Pas de récit possible sans la matière brute. Voici ce que git log --diff-filter=A --follow sur .claude/rules/ retourne entre le 28 avril 2026 publication de l'article-pivot et le 21 mai 2026 aujourd'hui — quatre fichiers nouveaux strictement post-publication. cache-auth-contract.md — committé le 2 mai. Né d'un audit de dette technique, pas d'un crash en prod. C'est un vendredi en fin d'après-midi. Niran est posé à deux bureaux de là, casque sur les oreilles, une boîte de burgers fermée dans l'angle. Je parcours docs/dette/AUDIT-2026-04-30.md section D-20 sur l'écran de droite, le code sur l'écran de gauche. En relisant getCachedFormateurs , je comprends que le cache unstable cache est mutualisé entre tous les utilisateurs — session non propagable. Si quelqu'un expose cette fonction via une route API sans guard, c'est une fuite RBAC silencieuse. Je lève la tête pour en parler à Niran. Il retire son casque, écoute, dit « Ah oui, ça mord. » Il remet le casque. La règle est rédigée ce soir-là. // .claude/rules/cache-auth-contract.md — anti-pattern à interdire // Faille : pas de guard export async function GET { const formateurs = await getCachedFormateurs return Response.json formateurs } // Correct export async function GET req: NextRequest { const supabase = await createSupabaseServer const { data: { user } } = await supabase.auth.getUser if user return new Response 'Unauthorized', { status: 401 } const profile = await getUserProfile user if canAccess profile, 'communication' return new Response 'Forbidden', { status: 403 } const formateurs = await getCachedFormateurs return Response.json formateurs } inscrit-nom-prenom-required.md — committé le 14 mai. « Hum, ça bug. » — Catherine, deux heures avant. « Mais c'est vite corrigé. » La sonde quotidienne sonde contacts orphelins inscrits a remonté un contact statut='inscrit' avec le prénom vide — l'enfant Loubna, importé d'un Airtable où le prénom vivait dans une colonne séparée non mappée. Le grep qui suit relève seize cas similaires. Ce qui aurait pété l'émargement régulier Cannot read properties of undefined tombe dans une CHECK constraint Postgres qui ferme la classe à la racine. -- .claude/rules/inscrit-nom-prenom-required.md CHECK statut < 'inscrit' OR nom IS NOT NULL AND nom < '' AND prenom IS NOT NULL AND prenom < '' Sans cette CHECK, la règle reste textuelle dans CLAUDE.md et l'import suivant ramènera un dix-septième cas avant la prochaine sonde. Avec, l'INSERT échoue, l'import remonte le problème à la source. contrat-formation.md — committé le 16 mai, dans le sillage d'ADR-0068. C'est la règle la plus longue, parce que le contrat de formation professionnelle est un Snapshot dont chaque colonne porte sa garantie d'immutabilité. motivation code , text version , cases cochees , pdf storage path — figés à la génération, jamais recalculés rétroactivement. Une évolution du contrat n'est jamais une réécriture du Snapshot, c'est un nouvel événement avec une nouvelle text version . La règle existe parce que l'audit Qualiopi trois ans repose entièrement sur l'immutabilité du PDF généré et de la signature stagiaire associée — un recalcul rétroactif suffirait à rendre le dossier indéfendable. hybrid-snapshot-live-reset.md — committé le 19 mai, deux jours avant cet article. Avant l'envoi des cinquante-trois SMS de Phase 2 réinscription, un audit pré-flight remonte qu'un token sur les cinquante-trois est consommé — créé en mode test le matin, cliqué, used at non null. Si le SMS Phase 2 part tel quel, le lien /r/