Cours 11

Astuce — savoir ceci suffit pour commander

L’application a explosé. La connexion qui fonctionnait hier ne fonctionne plus. Le paiement est débité deux fois. Plus on touche au code, plus d’autres parties se cassent. Demander à l’IA de “corriger” empire les choses.

Ne pas tout refaire. Refaire depuis zéro — dans 3 mois, ça explose au même endroit. Verrouiller l’état actuel en premier.

Trois outils structurels existent :

  • codistill — Diagnostic. Extrait automatiquement les endpoints API, le schéma DB et les flux d’authentification du code existant.
  • huma — Verrouillage. Pose des tests de régression sur tous les endpoints pour protéger le comportement actuel.
  • yongol — Transition. Génère un nouveau backend depuis le SSOT, et prouve le comportement identique avec les tests existants.

On progresse de gauche à droite. Diagnostiquer avec codistill, verrouiller avec huma, transitionner avec yongol quand on est prêt.

A l’agent : “Lance codist scan pour extraire la liste des endpoints, le schéma DB et les flux d’authentification de ce projet.”

L’état actuel apparaît. On voit combien d’endpoints sur 25 sont vivants et combien sont morts.

A l’agent : “Lance huma verify pour vérifier l’état de tous les endpoints, et écris un test Hurl pour chacun qui est vivant.”

C’est le test de régression. On verrouille ce qui fonctionne maintenant. Tant que ces tests passent, l’agent peut modifier le code sans casser le comportement existant.

A l’agent : “Corrige maintenant le bug de connexion. Mais tous les tests Hurl doivent passer.”

On corrige le bug sans casser autre chose. On répare avec le cliquet enclenché.


Expérience rapide

Même sans application cassée, on peut expérimenter. Vivre le processus “construire → casser → sauver” en 3 minutes.

Étape 1 — Construire l’application

Dans Claude Code :

“Crée une API simple de liste de tâches. 5 endpoints : lister les tâches, ajouter une tâche, modifier une tâche, supprimer une tâche, marquer une tâche comme terminée. Lance le serveur.”

Étape 2 — Diagnostiquer avec codist

“Lance codist scan pour extraire la liste des endpoints de ce projet.”

codist extrait automatiquement le chemin, la méthode et les paramètres des 5 endpoints. C’est la carte actuelle.

Étape 3 — Verrouiller avec huma

“Lance huma verify, et écris des tests Hurl pour tous les endpoints.”

Un fichier Hurl est créé pour chacun des 5 endpoints. Le comportement actuel est verrouillé.

Étape 4 — Casser intentionnellement

“Change le format de réponse de l’endpoint de modification de tâche. Renomme le champ title en name.”

Après le changement :

“Lance les tests Hurl.”

Les tests échouent. “title attendu mais name reçu.” La dérive est détectée. Le cliquet fonctionne.

Étape 5 — Réparer avec le cliquet enclenché

“Corrige pour que tous les tests Hurl passent. Mais la nouvelle fonctionnalité utilisant le champ name doit aussi être maintenue.”

L’agent maintient la compatibilité ascendante lors de la correction. Si Hurl passe, le comportement existant est préservé.

C’est la version réduite de codistill → huma → réparation. Sur une vraie application cassée, ce processus se répète sur 25, 50, 200 endpoints — le principe reste identique.


Pourquoi commander ainsi

Introduction : la vraie raison pour laquelle votre application a explosé

En 2025, la base de données de 170 applications créées avec Lovable a été exposée en entier sur internet. Emails, clés API, informations de paiement. La cause n’était pas un bug dans le code. L’IA avait créé les applications sans politique de sécurité, et personne n’avait vérifié.

En janvier 2026, 1,5 million de tokens API ont fuité depuis Moltbook, le réseau social IA. Même cause. L’IA a construit, les humains n’ont pas vérifié.

Ce n’est pas l’histoire de quelqu’un d’autre. Quiconque a construit une application avec le vibe coding est assis sur la même structure.

“Crée la connexion” — 30 secondes. “Ajoute le paiement” — 2 minutes. “Ajoute un tableau de bord admin” — 5 minutes. Trois mois plus tard, l’IA “nettoie” la logique de paiement en changeant le calcul des remises, une nouvelle fonctionnalité casse l’authentification, et une page qui fonctionnait hier retourne une erreur 500 aujourd’hui.

On se retrouve face à deux choix :

  1. Tout refaire
  2. Sauver

Refaire, on aurait pu le faire il y a 3 mois. Le problème, c’est que refaire répète les mêmes schémas. La dérive n’est pas un problème de code — c’est un problème de structure.

Il faut apprendre à sauver.


Autorescousse du naufragé — 5 étapes

Sauver une application cassée, c’est comme gérer une urgence en montagne. Ne pas courir. Identifier sa position actuelle, sécuriser, avancer pas à pas.


Étape 1. Diagnostic — qu’est-ce qui est encore vivant ?

La première chose à faire n’est pas de corriger le code. C’est d’évaluer l’état actuel.

A l'agent : "Scanne tous les endpoints API de ce projet.
Envoie des requêtes réelles à chaque endpoint
et enregistre les codes de statut de réponse.
Présente les résultats dans un tableau : chemin, méthode, code statut, temps de réponse."

Si 18 des 25 endpoints retournent 200, 4 retournent 401, et 3 retournent 500 — c’est la carte actuelle. Commencer les réparations sans carte revient à casser d’autres parties en corrigeant.

codist scan de codistill automatise ce travail. Il extrait les endpoints, les modèles de données et les flux d’authentification du code existant.


Étape 2. Verrouillage — protéger d’abord ce qui vit

Après le diagnostic, verrouiller les endpoints vivants.

A l'agent : "Écris des tests Hurl pour chacun
des 18 endpoints retournant 200.
Prends la réponse actuelle comme valeur attendue.
Pour ceux qui nécessitent une authentification, exécute d'abord
la séquence de connexion pour obtenir le token."

Ces 18 fichiers Hurl sont le filet de sécurité. Quelle que soit la modification effectuée, si ces tests passent, le comportement existant est préservé.

huma verify de huma structure ce processus. Il suit l’état par endpoint et détermine PASS/IMPROVE/FAIL.

Important : le verrouillage partiel ne suffit pas. Si on ne verrouille que 10 des 18 endpoints, les 8 restants peuvent se casser pendant les réparations sans qu’on le sache. Le verrouillage intégral est le principe.


Étape 3. Réparation — corriger avec le cliquet enclenché

Avec le filet de sécurité en place, on peut corriger les bugs.

A l'agent : "Trouve et corrige la cause de l'échec de connexion.
Mais tous les tests Hurl doivent passer.
Si un seul échoue, annule la modification."

C’est l’application pratique du Ratchet Pattern appris au Cours 6. Corriger sans casser. Lancer Hurl après chaque réparation. Si ça passe, passer au bug suivant. Si ça échoue, revenir en arrière.

Les 3 endpoints retournant une erreur 500 se réparent de la même manière. Après la réparation, on ajoute de nouveaux tests Hurl. Le cliquet est serré d’un cran supplémentaire.


Étape 4. Extraction — sortir la logique de la boîte noire

C’est le point central. La cause racine de l’explosion d’une application est généralement là.

Si on utilise Supabase :

  • Les politiques RLS sont dans le tableau de bord seulement, pas dans le code
  • La logique métier est cachée dans les Edge Functions
  • La logique d’authentification est liée à Supabase Auth

Si on utilise Firebase :

  • Les Security Rules sont dans la console seulement
  • La logique est dispersée dans les Cloud Functions

Quel que soit le BaaS utilisé, la structure est la même. La logique métier est hors de la base de code.

A l'agent : "Extrais toutes les politiques RLS depuis le tableau de bord Supabase.
Enregistre les politiques SELECT, INSERT, UPDATE, DELETE
de chaque table dans des fichiers SQL. Commit dans git."
A l'agent : "Analyse la logique métier des Edge Functions.
Documente quelles fonctions implémentent quelles règles métier."

Il s’agit de sortir la logique de la boîte noire vers la base de code. Une fois sortie, l’agent peut la lire, la tester et la verrouiller avec le cliquet.

codist ddl de codistill extrait le DDL de la DB existante. codist scan extrait le SSOT depuis le code. C’est l’outil pour passer de la boîte noire à la couche déclarative.


Étape 5. Transition — seulement quand on est prêt

Après les étapes 1 à 4, l’application est dans cet état :

  • Tous les endpoints ont des tests de régression Hurl
  • Les bugs sont réparés
  • La logique de la boîte noire est documentée dans la base de code
  • Le cliquet est enclenché : les nouvelles modifications ne cassent pas le comportement existant

Dans cet état, on décide de la transition. De Supabase vers un backend propre, de Deno vers Go, peu importe.

Le filet de sécurité de la transition, ce sont les tests Hurl écrits à l’étape 2. On lance les mêmes Hurl sur le nouveau serveur — si tout passe, c’est prouvé que le comportement est identique au legacy.

A l'agent : "Génère un backend Go+Gin avec yongol generate.
Fais passer tous les tests Hurl existants."

La transition est l’étape 5, pas l’étape 1. Tenter la transition à l’étape 1 mène à l’échec. Leçon confirmée lors des onboardings post-incident.


Comment sortir de Supabase

Le cas le plus fréquent du Cours 11 est Supabase. On commence avec le vibe coding, on mise tout sur Supabase, et ça explose 3 mois après.

Ordre pour en sortir :

1. Garder la DB et poser seulement le cliquet

On garde le PostgreSQL de Supabase tel quel. Changer la DB, c’est pour la fin.

codist ddl → extraire le DDL des tables existantes
huma verify → évaluer l'état des endpoints
hurl → verrouiller intégralement les API vivantes

2. Migrer la logique vers le code

Politiques RLS → fichiers Rego. Edge Functions → annotations SSaC. Du tableau de bord vers la base de code.

3. Séparer l’authentification

Supabase Auth est la dernière chose à détacher. Comme les hachages de mots de passe de auth.users ne peuvent pas être extraits, si on est en phase initiale (sans clients), transitionner immédiatement ; si des clients existent, opérer une période de double authentification.

4. Lancer le nouveau serveur et valider avec Hurl

yongol generate → générer le backend Go+Gin
lancer tous les Hurl → prouver le comportement identique au legacy

Si tous les Hurl passent, basculer le trafic.


Pourquoi ne pas tout refaire

“On ne peut pas juste tout refaire ?”

Non. Trois raisons :

1. Le même schéma se répète

La dérive est un problème de structure, pas de code. Refaire sans cliquet — ça explose au même endroit dans 3 mois.

2. La connaissance est enfouie dans le legacy

Les règles métier accumulées en 3 mois de vibe coding sont dans le code. Refaire implique de les reconstruire de mémoire. La mémoire se trompe.

3. Il peut déjà y avoir des clients

Il y a un moment où le prototype devient production. Si même 1 utilisateur existe, “tout refaire” s’accompagne de migration de données, de transition d’authentification et de temps d’arrêt.

Apprendre à sauver est plus précieux qu’apprendre à refaire. Parce que le legacy existe toujours, et tout nouveau code devient legacy en 6 mois.


La relation entre les Cours 1 à 10 et le Cours 11

CoursComment bien construire depuis le débutCours 11 : comment sauver ce qui est cassé
Cours 3 HurlDéclarer le contrat APIVerrouiller le comportement existant avec des tests de régression
Cours 4 yongolGénérer depuis le SSOTExtraire le SSOT du code existant
Cours 6 RatchetPasse, verrouilleRéparer sans casser
Cours 8 filefuncStructurer le codeNettoyer le code legacy
Cours 10 DDLDéclarer le schémaExtraire le DDL de la DB existante

Mêmes outils, direction inverse. Si les Cours 1 à 10 allaient “de haut en bas” (déclaration → génération), le Cours 11 va “de bas en haut” (code existant → extraction → déclaration).

codistill est l’outil qui automatise ce “de bas en haut”. Il extrait le SSOT du code existant.


Du naufragé au sauveteur

Après ce processus, on dispose de deux capacités :

  1. Construire depuis le début (Cours 1 à 10) — déclarer, valider, verrouiller, pérenniser
  2. Sauver ce qui est cassé (Cours 11) — diagnostiquer, verrouiller, réparer, extraire, transitionner

La majorité du code dans le monde est du legacy. Les projets construits depuis zéro sont rares. La capacité à sauver est plus souvent utilisée.

Le vibe coding n’est pas terminé. On a appris à tenir les rênes.


Articles connexes


Cours complet Reins Engineering

CoursTitre
Cours 1Comment commander l’IA
Cours 2Comment ne pas faire confiance à l’IA
Cours 3L’application incassable
Cours 4Les décisions hors du code
Cours 5L’IA bridée
Cours 6Passé, verrouillé
Cours 7Retourner la flatterie
Cours 8L’usine des agents
Cours 9L’automatisation au-delà du code
Cours 10La loi des données
Cours 11Sauver une application brisée par le vibe coding

Sources

  • Feathers, M. (2004). Working Effectively with Legacy Code. Prentice Hall. — Characterization testing의 원전. 레거시 코드에 테스트를 감싸서 현재 동작을 잠그는 기법. 11강 2단계의 이론적 기초.
  • CVE-2025-48757 (2025). Lovable 생성 앱 170+ RLS 누락으로 Supabase DB 노출. ameeba.com
  • OG William (2026). “Moltbook Hack: Supabase Vibe Coding.” 1.5M API 토큰 노출. blog.ogwilliam.com
  • Cursino, D. et al. (2026). “Speed at the Cost of Quality? The Impact of AI Coding on Software.” MSR 2026. arxiv.org/abs/2511.04427 — Cursor 도입 후 코드 복잡도 41.6% 영구 증가. 바이브 코딩이 터지는 정량적 근거.
  • Liu, Z. et al. (2026). “Debt Behind the AI Boom: A Large-Scale Empirical Study of AI-Generated Code in the Wild.” arxiv.org/abs/2603.28592 — 6,299개 리포지토리, 302,600건 AI 커밋 분석. 미해결 기술 부채가 2025년 초 수백 건에서 2026년 2월 110,000건 이상으로 급증.
  • Storey, M.-A. (2026). “From Technical Debt to Cognitive and Intent Debt.” arxiv.org/abs/2603.22106 — 드리프트의 근본 원인을 “인지 부채”(공유 이해 침식)와 “의도 부채”(근거의 미외부화)로 이론화.
  • Nguyen, H. et al. (2025). “Vibe Coding in Practice: Flow, Technical Debt, and Guidelines for Sustainable Use.” arxiv.org/abs/2512.11922 — 바이브 코딩의 flow-debt 트레이드오프를 문서화한 최초의 학술 논문.
  • Cloud Security Alliance (2026). “Vibe Coding Security Crisis: Credential Sprawl and SDLC Debt.” labs.cloudsecurityalliance.org — AI 생성 코드의 45%가 OWASP Top 10 취약점 포함. AI 커밋의 시크릿 노출률 2배.
  • GitClear (2025). “AI Copilot Code Quality 2025.” gitclear.com — 2.11억 라인 분석. 코드 중복 4배 증가, 리팩토링 비율 25% → 10% 감소.
  • Encore (2026). “Backend as a Service (BaaS) in 2026: Providers, Tradeoffs, and Migration Paths.” encore.dev — BaaS 이탈은 포팅이 아니라 백엔드 재작성.