Contexte : test grandeur nature de la skill
vibe-skill(Claude Code délègue à Mistral Vibe) sur un vrai projet Next.js en clean architecture. 6 runs sur la création d'un outil de redimensionnement d'images, capturés dans~/.local/share/delegate-runs.jsonl(raw data Vibe) + tokens Claude lus depuis le transcript de la session.Méthodo : 4 variants pour séparer les biais (brief / pas de brief / Claude-only / Vibe nu).
Reproductibilité : prompts Vibe complets dispo sur demande. Coûts Vibe extraits directement du log
delegate-runs.jsonl(Mistral, autoritatif). Coûts Claude estimés depuis les usage tokens du transcript (cache_creation + cache_read + output × pricing Anthropic public). Ordres de grandeur, pas chiffres laboratoire.Patches livrés en local sur l'install de la skill (non versionnés upstream pour l'instant) : (1) auto-détection d'un fichier
<PROJET>-CONVENTIONS.mdà la racine du workdir, intégré dans le prompt Vibe avant délégation ; (2) remplacement descriptpar un wrapper Pythonpty.fork()pour gérer les environnements où stdin est un socket (cas observé en Run #5).
| Variant | Description | Mesure quoi ? |
|---|---|---|
| A : Vibe briefe par Claude | Cette session. Claude redige un prompt detaille et reference HUB-CONVENTIONS.md. |
Plafond de performance Vibe avec aide maximale |
| B : Vibe sans brief | Session fresh. User demande la tache sans pointer HUB-CONVENTIONS.md. Claude-fresh decide. |
Capacite de Vibe a se debrouiller, et capacite du fichier conventions a etre auto-decouvert |
| C : Claude-only | Pas de Vibe. Claude code directement avec Edit/Write. | Baseline qualite/temps pour comparer |
| D : Vibe prompt minimal | Session fresh. User invoque /vibe avec instruction ultra-courte ("ajoute X"). |
Mesure la valeur du brief detaille |
- Setup : A (Vibe briefe par Claude)
- Date : 2026-05-15
- Scope : 2 fichiers neufs (page.tsx + ImageResizerTool.tsx) + 1 edit (home page card)
- Prompt size : ~60 lignes (
/tmp/vibe-pilot-image-resizer.txt) - Cost : $0.044 / 19.3s / 24.8k tokens Mistral
- Verdict : pass
- Manual fixes post-run : 0 LOC
- Conformance HUB-CONVENTIONS.md : oui (couleur cyan, placement card, no em-dash, @/ paths, "use client", named export)
- Relances : 1 seule
- Claude estimate : ~5 min, ~8k tokens (lecture refs + ecriture + verif)
- Ratio : Vibe ~2x moins cher, ~10x plus rapide qu'en faisant moi-meme
- Notes : exit code 1 trompeur (sandbox bloque
mkdir, Vibe a route surwrite_file). Toujours lire le diff, jamais se fier a l'exit code seul.
- Setup : A (Vibe briefe par Claude)
- Date : 2026-05-15
- Scope : 1 nouveau fichier
ImageDropZone.tsx(137 LOC) + editImageResizerTool.tsx(29 LOC modifiees) - Template ref :
src/ui/features/skeletonify/ImageDropZone.tsx(103 LOC) - Prompt size : ~70 lignes (
/tmp/vibe-pilot-dropzone.txt) - Cost : $0.044 / 23.1s / 24.9k tokens Mistral
- Verdict : pass with minor notes
- Manual fixes post-run : 0 LOC critique (2 micro-issues a corriger plus tard, pas bloquantes)
- Conformance HUB-CONVENTIONS.md : oui : "use client" L1, named export, props inline, cyan partout, no em-dash, no accents code-adjacent, useCallback handlers, useRef input, @/ paths corrects, relative pour same-folder
- Relances : 1 seule
- Claude estimate : ~12 min, ~12k tokens (lire template skeletonify + ecrire 137 LOC + cabler + verifier)
- Ratio : Vibe ~2x moins cher, ~30x plus rapide que moi a la main
- Micro-issues detectees (Vibe ne les a pas vues) :
file.type.match(accept)L35 utilise regex au lieu destartsWith("image/"). Accidentellement OK pour"image/*", fragile sinon.handleInputChangenesetError(null)pas avant validation. Si user pick mauvais puis bon fichier, erreur reste affichee.
- Notes : exit code 1 toujours trompeur (sandbox bloque bash). Meme cost que run #1 (~$0.044) malgre prompt plus court : le gros du cout est dans la lecture des refs. Une optimisation possible : passer les refs en pre-compute si Vibe re-lit les memes fichiers.
- Setup : B (Vibe sans brief)
- Date : 2026-05-15
- Scope : 1 nouveau fichier
PresetSelector.tsx(99 LOC) : wire-in PAS fait - Vibe cost : $0.031 / 15.8s / 20.2k tokens Mistral / 4 tool calls
- Claude-fresh tokens : ~12.8k (orchestration : recon + prompt + review + fixes + report)
- Verdict : fix-needed (2 vrais bugs Vibe corriges par Claude-fresh post-run)
- Bugs Vibe (corriges manuellement par Claude-fresh) :
use clientecrit SANS guillemets : fichier n'aurait pas parse en build- ASCII
xau lieu de×(U+00D7) malgre instruction explicite dans le prompt
- Conformance HUB-CONVENTIONS.md : partielle
- ✅ Couleur cyan respectee (inferee depuis
ImageResizerTool.tsx) - ✅ Named export, "use client" (apres fix), TS strict
- ❌
HUB-CONVENTIONS.mdnon decouvert par Claude-fresh : n'est pas inspecte sans pointage explicite - ❌ Autres outils (skeletonify, video-gen) non inspectes comme templates
- ✅ Couleur cyan respectee (inferee depuis
- Tache completee ? Non : composant cree mais pas integre dans
ImageResizerTool.tsx. Claude-fresh a interprete "ajoute" = "cree", pas "cree + cable". A demande en fin de session si il fallait wire-in. - Comparaison directe vs Run #2 :
| Dimension | Run #2 (A) | Run #3 (B) | Delta |
|---|---|---|---|
| Vibe cost | $0.044 | $0.031 | -30% (lit moins de refs) |
| Manual fixes | 0 LOC | 2 LOC (vrais bugs) | +2 fixes |
| Conformance | Full | Partielle | Conventions subtiles ratees |
| Task done end-to-end | Oui | Non (wire-in manque) | Gap de scope |
- 3 enseignements :
HUB-CONVENTIONS.mddoit etre rendu auto-decouvrable (via reference dansCLAUDE.mdprojet)- L'absorption de convention par lecture de fichier existant marche pour le visible (couleur), pas pour le subtil (U+00D7, structure)
- Vibe peut sortir du code qui ne compile pas (le
use clientsans guillemets) : review humaine non negociable
- Setup : C (Claude code directement, pas de Vibe)
- Date : 2026-05-15
- Pre-condition cle :
CLAUDE.mdpatche avec sectionHUB:conventions-refpointant versHUB-CONVENTIONS.md - Scope : 1 nouveau fichier
src/infrastructure/adapters/image-resizer/canvasResize.ts(55 LOC) - Vibe : non utilise (variant C respecte)
- Claude tokens : 22 input + 4.4k output + 72k cache_creation + 557k cache_read
- Claude cost estime : ~$1.58 (output dominant + cache write substantiel)
- Wall-clock duration : 2 min 42 s
- Verdict : pass (qualite superieure aux runs Vibe)
- Manual fixes post-run : 0 LOC
- Conformance HUB-CONVENTIONS.md : ✅ full
HUB-CONVENTIONS.mddecouvert automatiquement (le patch CLAUDE.md a fonctionne du premier coup)- Adapters refs (skeletonify, gif-generator) inspectes comme templates
- Couche clean-archi correcte (infrastructure/adapters)
- Pas de tiret cadratin, pas d'accents code-adjacent
- Qualite code (au-dessus des runs Vibe) :
OffscreenCanvas+ fallback DOM (worker-compatible)imageSmoothingQuality: "high"bitmap.close()en finally (resource cleanup, souvent oublie)- Validation des dimensions + erreurs claires
- Interface
ResizeDimensionsexportee (typage propre)
- Vibe spontane ? Non : malgre la section VIBE:eval-start dans CLAUDE.md disant "considerer Vibe", Claude-fresh a juge la tache assez ciblee pour la faire directement. Bon jugement (la fonction fait 55 LOC, pile au seuil).
- Comparaison cross-run :
| Run | Setup | Vibe $ | Claude $ approx | Total $ | Fix LOC | Qualite | Wall-clock |
|---|---|---|---|---|---|---|---|
| #1 | A | $0.044 | ~$0.05 | ~$0.10 | 0 | full | 19s + ~3min |
| #2 | A | $0.044 | ~$0.08 | ~$0.12 | 0 | full | 23s + ~5min |
| #3 | B | $0.031 | ~$0.30 | ~$0.33 | 2 | partial | 15s + ~10min |
| #4 | C | $0 | ~$1.58 | ~$1.58 | 0 | full+ | ~2m42s |
- Enseignement strategique : Claude-only coute ~10x plus cher mais sort une qualite legerement superieure. Vibe gagne en cost/qualite quand le scope est cadre et la review humaine est faite. Le seuil de bascule semble etre vers la complexite algorithmique : tache "structurale" (composant UI, scaffold) → Vibe ; tache avec edge cases techniques (resource management, fallbacks) → Claude direct.
- Setup : D (Vibe prompt minimal) : dérapé en variant C accidentel suite a crash Vibe
- Date : 2026-05-15
- Scope : 1 nouveau hook
src/ui/hooks/useImageResize.ts(78 LOC) - Vibe attempt : $0.031 / 0.3s / 0 tool calls / exit 1 : CRASH TTY
- Vibe error :
tcgetattr/ioctl: Operation not supported on socket:scriptn'a pas pu allouer un pseudo-TTY dans le shell de la session Claude Code fresh - Claude tokens orchestration : 27 input + 14.4k output + 141k cache_creation + 767k cache_read
- Claude cost approx : ~$4.35 (le plus eleve de tous les runs)
- Total cost : ~$4.38 (Vibe paye + Claude paye, pire scenario)
- Wall-clock : 3m 40s
- Verdict : pass with minor (Claude-only fallback, qualite ok)
- Manual fixes : 0 LOC (Claude-fresh a ecrit le fichier direct)
- Micro-issue detectee : pas de cleanup
useEffectcontre unmount → setState sur composant demonte possible. LerunIdRefprotege contre les races inter-rerun mais pas contre l'unmount. - Conformance HUB-CONVENTIONS.md : ✅ full (decouverte via patch CLAUDE.md, conventions respectees)
3 enseignements critiques :
-
Le variant D "Vibe minimal" est presque inatteignable dans la pratique. La skill + le patch CLAUDE.md transforment automatiquement une instruction nue en brief detaille. Claude-fresh fait 5 reads, construit un prompt de 3000+ chars avant de lancer Vibe. Pour vraiment tester "Vibe nu", il faudrait bypass Claude entierement (ex: lancer
vibe-delegatedirect en bash). -
Vibe a un probleme d'environnement TTY dans Claude Code :
scriptne peut pas allouer pseudo-TTY dans le shell bash de Claude Code. Vibe marche depuis un vrai terminal mais peut crash en session Claude. Bug a investiguer. Workaround : utiliser un vrai terminal pour /vibe, ou patchervibe-delegatepour detecter et fallback. -
Cost explosion quand Vibe crash mid-flow : Vibe failed ($0.031) + Claude full effort + diagnostic + fallback = ~$4.38. Le pire scenario possible : payer 2x pour le meme boulot. Le ratio cost(Vibe-fail+Claude-fallback) / cost(Vibe-success) est ~40x.
| Run | Setup | Verdict | Cost | Fix LOC | Conformance | Time saved vs Claude |
|---|---|---|---|---|---|---|
| #1 | A | pass | $0.044 | 0 | oui | ~5min |
| #2 | A | pass+ | $0.044 | 0 | oui | ~12min |
| #3 | B | fix-needed | $0.031 | 2 | partielle | ~10min |
| #4 | C | pass+ | $1.58 | 0 | full | ~2m42s |
| #5 | D→C* | pass | $4.38 | 0 | full | ~3m40s |
| #6 | A-post-fix | pass | $0.05 | 0 | full | ~25s + ~30s review |
* Run #5 a derape : Vibe a crash TTY → Claude-fresh a fallback en variant C. Donnees comptees pour C.
- Setup : A-post-fix : session fresh + skill
vibepatchee (Step 1b auto-discovery) + wrapper PTY corrige (run-in-pty) - Date : 2026-05-15
- Scope : 1 nouveau fichier
src/ui/features/image-resizer/ProgressBar.tsx(31 LOC) - User prompt :
/vibe crée un composant ProgressBar pour Image Resizer dans src/ui/features/image-resizer/ProgressBar.tsx. Props : {value: number, label?: string} où value va de 0 à 100. Barre cyan animée façon Tailwind, label centré au-dessus, pourcentage à droite. ~40 LOC. - Vibe run : 13.5s / 6 tool calls / exit 0 / $0.034 / 1 file changed
- Claude orchestration : recon (3 bash) + brief Vibe + verify grep = ~$0.02 estime
- Total cost : ~$0.05
- Verdict : pass, conformance full, 0 fix manuel
- Comportement Claude-fresh post-patches :
- ✅ A immediatement cherche
*CONVENTIONS.mdau workdir (Step 1b auto-execution) - ✅ A grep le code existant pour la couleur signature
- ✅ A redige un brief Vibe avec
STEP 1 : Read HUB-CONVENTIONS.mdau top (template du Step 3 mis a jour) - ✅ A pointe
PresetSelectorcomme template sibling - ✅ A verifie le diff post-run via grep (em-dash, conformance)
- ✅ A immediatement cherche
- Comportement Vibe :
- ✅ Pas de TTY crash (vs Run #5 mort en 0.3s)
- ✅ Exit 0 (premier de tout le pilote avec
accept-edits) - ✅ Style aligne sur HUB-CONVENTIONS (double quotes, semicolons) : contraste avec Run #3 (single quotes, no semicolons)
- ✅ Ajout d'un detail UX non demande mais judicieux :
tabular-numspour percentage stable
- Comparaison cross-run cle :
| Metric | Run #5 (avant fix) | Run #6 (apres fix) | Delta |
|---|---|---|---|
| Vibe exit code | 1 (crash 0.3s) | 0 (13.5s normal) | TTY crash resolu |
| Vibe tool calls | 0 | 6 | Vibe peut maintenant travailler |
| Total cost | $4.38 | $0.05 | /88x moins cher |
| Fix manuel | 0 LOC (Claude fallback) | 0 LOC (Vibe a livre) | Effort Claude divise par >10 |
- Conclusion : les 2 patches (
Step 1bSKILL.md +run-in-ptyPTY runner) ont collapse les pires scenarios vers le sweet spot. Le pattern variant A est maintenant viable en session fresh sans intervention de Claude au-dela de l'orchestration normale du skill.
-
Vibe est-il rentable en variant A ? → Oui clairement. 2/2 runs pass, 0 fix, cost moyen $0.11. Pattern viable pour scaffold cadre + composants UI structurels.
-
Le brief
HUB-CONVENTIONS.mdapporte-t-il une vraie valeur ? → Oui essentielle. Run #2 (A, briefe) full conformance / 0 fix vs Run #3 (B, sans brief auto-decouverte) partial conformance / 2 fixes. Le brief est ce qui sauve la qualite. -
La capacite de Vibe a se passer du brief est-elle suffisante ? → Non. Sans pointage explicite, Vibe rate les conventions subtiles (Run #3 :
use clientsans guillemets, separateurxau lieu de×). -
Quel est le break-even cost/qualite vs Claude direct ? → Vibe-briefe : $0.10-0.12 / pass full. Claude-direct : $1.58 / pass full+. Vibe ~15x moins cher pour qualite quasi-egale sur tache structurelle. Sur tache algorithmique (edge cases), Claude direct gagne en finesse.
| Type de tache | Outil recommande | Justification |
|---|---|---|
| Scaffold de composant UI (placeholder, structure) | Vibe briefe (variant A) | Conventions absorbees via brief, cout x10-15 moins eleve, qualite equivalente |
| Ajout sous-composant structurel (DropZone, Selector) | Vibe briefe (variant A) | Scope cadre = sweet spot Vibe |
| Service / adapter avec edge cases (Canvas, FFmpeg) | Claude direct (variant C) | Resource management, fallbacks, gestion d'erreur fine |
| Hook React avec async/race conditions | Claude direct ou Vibe briefe + review serree | Demande vigilance |
| Modification ciblee (<10 LOC) | Claude direct toujours | Overhead Vibe non amorti |
| Refactor / rename | Claude direct toujours | Vibe perd le contexte chaine |
TTY crash en environnement Claude Code→ RESOLU 2026-05-15 par~/.pai/skills/vibe/tools/run-in-pty(wrapper Pythonpty.fork()) remplacantscript. Validation : Run #6 a tourne 13.5s exit 0 en session fresh (vs Run #5 mort 0.3s).- Exit code 1 trompeur → PARTIELLEMENT RESOLU. Run #6 a sorti exit 0 avec
accept-edits. Le patternTool execution not permittedsurbashreste possible quand Vibe tente d'utiliserbash(ex: mkdir) : toujours review le diff. → RESOLU 2026-05-15 par : (a) patchHUB-CONVENTIONS.mdn'est PAS auto-decouvertCLAUDE.mdprojet (HUB:conventions-refsection), et (b) Step 1b dans~/.pai/skills/vibe/SKILL.md(detection systematique avant brief Vibe). Validation : Run #6 a auto-decouvert le fichier en session fresh.
| Run | Vibe $ | Claude $ approx | Total $ |
|---|---|---|---|
| #1 | 0.044 | 0.05 | 0.10 |
| #2 | 0.044 | 0.08 | 0.12 |
| #3 | 0.031 | 0.30 | 0.33 |
| #4 | 0 | 1.58 | 1.58 |
| #5 | 0.031 | 4.35 | 4.38 |
| #6 | 0.034 | 0.02 | 0.05 |
| Total | 0.19 | 6.38 | ~$6.57 |
- Adopter variant A comme pattern par defaut pour scaffolds et composants UI dans le HUB.
- Patcher la skill
vibepour ajouter auto-detection d'un<projet>-CONVENTIONS.mdau workdir racine et l'inclure systematiquement dans le prompt. - Investiguer le TTY issue dans Claude Code (probablement fallback
expectouptydansvibe-delegate). - Tenir
HUB-CONVENTIONS.mda jour a chaque evolution de pattern significative. - Etendre le pattern a d'autres projets apres correction du TTY issue (Origo, SSP, etc.).