Retour au blog

Le developpement pilote par les specs avec Claude Code

Le developpement pilote par les specs avec Claude Code

Le developpeur qui tape "add user authentication" dans Claude Code obtient un resultat different a chaque fois. Peut-etre du JWT. Peut-etre des cookies de session. Peut-etre un flux OAuth2 complet avec refresh tokens et PKCE. L'agent ne sait pas ce que vous voulez parce que vous ne le lui avez pas dit. Vous lui avez donne une direction, pas une destination.

Les developpeurs que je vois obtenir des resultats coherents et livrables de Claude Code partagent une habitude : ils ecrivent une spec avant de confier du travail a l'agent. Pas un roman. Pas un ticket Jira avec trois phrases de contexte. Un document concret qui definit a quoi ressemble "termine" avant que quiconque ecrive une ligne de code.

Ce n'est pas une sagesse nouvelle. Le developpement spec-first precede l'IA de plusieurs decennies. Mais avec les agents, le cout de sauter la spec est plus eleve et le benefice d'en ecrire une est plus grand. Un developpeur humain peut s'arreter en pleine implementation et demander "attends, tu voulais dire l'auth par mot de passe ou le SSO ?" Un agent en choisira un silencieusement et continuera. Le temps que vous remarquiez, il a construit la mauvaise chose, et vous avez passe 20 minutes a relire du code qui doit etre jete.

Cet article parcourt le cycle de vie pilote par les specs que j'utilise avec Claude Code chaque jour : comment ecrire des specs contre lesquelles les agents peuvent executer, le checkpoint plan-avant-le-code qui attrape les malentendus tot, et un protocole de verification plus rigoureux que "ca compile."

Pourquoi "construis-le" echoue avec les agents

Soyons precis sur le mode d'echec. Quand vous donnez a Claude Code une instruction vague, trois choses tournent mal :

Des hypotheses silencieuses. L'agent comble chaque lacune de votre spec avec ses propres hypotheses. Parfois elles sont raisonnables. Parfois non. Vous ne saurez pas dans quelle categorie vous etes jusqu'a la lecture du resultat. Avec des instructions vagues, vous finissez par lire le resultat plus attentivement que le temps qu'il vous aurait fallu pour ecrire une spec.

Des resultats non reproductibles. Executez le meme prompt vague deux fois et vous obtenez deux implementations differentes. Pas juste des noms de variables ou du formatage differents. Des decisions architecturales differentes. Des bibliotheques differentes. Des strategies de gestion d'erreurs differentes. Si vous ne pouvez pas reproduire le resultat, vous ne pouvez pas construire un processus fiable autour.

La revue devient le goulot d'etranglement. Quand l'agent prend toutes les decisions, vous devez verifier toutes les decisions. Un diff de 400 lignes ou vous comprenez chaque choix prend 5 minutes de revue. Un diff de 400 lignes ou l'agent a choisi le schema de base de donnees, la forme de l'API, les codes d'erreur et la logique de validation prend 30 minutes parce que vous reconstruisez la spec a partir de l'implementation.

La solution n'est pas de meilleurs prompts. C'est de concentrer en amont les decisions qui comptent dans un document contre lequel l'agent peut executer.

Le cycle de vie pilote par les specs

Le workflow comporte cinq phases. Chacune a une condition d'entree claire et une condition de sortie claire.

Phase 1 : Brainstorming. Vous explorez l'espace du probleme. Quelles sont les contraintes ? Quelles approches existent ? Qu'avez-vous deja essaye ? C'est la ou vous pensez a voix haute, seul ou avec Claude Code en mode conversationnel. La condition de sortie : vous avez une approche preferee et vous comprenez les compromis.

Phase 2 : Revue. Vous mettez l'approche a l'epreuve. Qu'est-ce qui pourrait mal tourner ? Quels cas limites existent ? Est-ce que ca entre en conflit avec quelque chose deja dans le codebase ? Si vous travaillez avec plusieurs agents, c'est la qu'un agent d'architecture ou un second avis est precieux. La condition de sortie : vous etes confiant que l'approche est solide.

Phase 3 : Spec. Vous ecrivez ce que vous avez decide. Enonce du probleme, approche proposee, fichiers a modifier, criteres d'acceptation verifiables mecaniquement et un plan de test. C'est le contrat. La condition de sortie : quelqu'un (humain ou agent) pourrait lire cette spec et savoir exactement quoi construire et comment le verifier.

Phase 4 : Implementation. L'agent execute contre la spec. Pas contre une idee vague. Contre un document concret avec des criteres testables. La condition de sortie : l'agent affirme avoir termine et a publie des preuves de verification.

Phase 5 : Verification. Vous (ou un agent QA) confirmez que l'implementation correspond a la spec. Pas "est-ce que ca a l'air correct" mais "est-ce que ca satisfait chaque critere d'acceptation." La condition de sortie : chaque critere est verifie, et ceux qui echouent retournent a la Phase 4.

L'idee cle : les phases 1-3 sont peu couteuses. Elles prennent 10-20 minutes pour une fonctionnalite de taille moyenne. La phase 4 prend le temps que necessite l'implementation. La phase 5 prend 5-10 minutes. Sauter les phases 1-3 ne fait pas gagner 10-20 minutes. Ca vous coute le temps de relire, deboguer et refaire du travail qui partait dans la mauvaise direction.

A quoi ressemble une bonne spec pour agent

Voici un vrai template de spec. Pas une user story. Pas un document de requirements produit. Un document de travail qui dit a un agent exactement quoi construire.

## Problem
The filter bar resets when switching workspaces. Users lose their
filter state and have to re-apply filters every time they switch.

## Approach
Persist filter state per-workspace in localStorage. Key the stored
state by workspace database path so filters don't bleed across
workspaces.

## Files to Modify
- lib/local-storage.ts: Add getWorkspaceFilters / setWorkspaceFilters
- components/filter-bar.tsx: Read initial state from localStorage,
  write on every change
- hooks/use-workspace.ts: Trigger filter restore on workspace switch

## Acceptance Criteria
1. Select workspace A, set filters to status=open + type=bug
2. Switch to workspace B. Filters reset to defaults.
3. Switch back to workspace A. Filters restore to status=open + type=bug.
4. Close the browser tab, reopen. Filters for the active workspace
   are still applied.
5. bd list --status=open --type=bug output matches the filtered table.

## Out of Scope
- Server-side filter persistence
- Filter presets / saved filter combinations
- URL-based filter state (query params)

## Test Plan
- Unit test: getWorkspaceFilters returns stored value for matching
  workspace path
- Unit test: setWorkspaceFilters writes correct key format
- Manual test: steps 1-5 from acceptance criteria above

Remarquez ce que cette spec contient et ne contient pas. Elle n'explique pas comment fonctionne localStorage. Claude Code le sait. Elle ne justifie pas pourquoi nous avons choisi localStorage plutot que les URL params. Ca s'est passe pendant le brainstorming. Elle liste chaque fichier que l'agent doit toucher, ce qui signifie que si l'agent commence a modifier des fichiers hors de cette liste, c'est un signal d'alerte. Elle inclut une section hors-perimetre, qui empeche l'agent de faire du gold plating.

Les criteres d'acceptation sont la partie la plus importante. Chacun est une action concrete avec un resultat observable. Pas "les filtres doivent persister." C'est ambigu. "Basculer vers le workspace A, verifier que les filtres sont status=open + type=bug" est testable. Un agent peut executer ca. Un reviseur QA peut le verifier.

Le pattern plan-avant-le-code

Voici un protocole qui attrape la majorite des erreurs d'implementation avant qu'elles ne deviennent du code : exiger que l'agent publie son plan d'implementation avant d'ecrire quoi que ce soit.

En pratique, ca ressemble a un commentaire structure sur la tache. Avant que l'agent n'ouvre un fichier, il ecrit exactement ce qu'il compte faire.

PLAN: Persist filter state per-workspace using localStorage.

1. Add workspace-scoped storage helpers to lib/local-storage.ts:
   - getWorkspaceFilters(dbPath: string): FilterState | null
   - setWorkspaceFilters(dbPath: string, filters: FilterState): void
   - Key format: "beadbox:filters:{dbPath}"

2. Update components/filter-bar.tsx:
   - On mount, read stored filters for current workspace
   - On every filter change, write to localStorage
   - Accept databasePath as prop (currently not passed)

3. Update hooks/use-workspace.ts:
   - On workspace switch, emit event that filter-bar listens for
   - Filter-bar reads new workspace's stored filters on event

4. Threading databasePath:
   - filter-bar needs databasePath from the workspace context
   - Will add it to the WorkspaceProvider context value

Files: lib/local-storage.ts, components/filter-bar.tsx,
       hooks/use-workspace.ts, components/workspace-provider.tsx

Test: Unit tests for storage helpers, manual test of all 5
acceptance criteria.

Ca prend environ 30 secondes a l'agent. Ca vous prend environ 2 minutes a lire. Et dans ces 2 minutes, vous pouvez detecter des problemes qui prendraient 20 minutes a corriger apres l'implementation :

  • L'agent touche-t-il des fichiers hors de la spec ? (Ajouter workspace-provider.tsx n'etait pas dans la spec. C'est acceptable ou c'est du scope creep ?)
  • L'approche a-t-elle du sens ? (Utiliser un event emitter pour les changements de workspace est peut-etre surdimensionne. Un simple changement de prop pourrait suffire.)
  • Manque-t-il des etapes ? (Qu'en est-il du nettoyage des anciennes entrees localStorage quand un workspace est supprime ?)

Le plan est un checkpoint. S'il parait correct, dites a l'agent de continuer. S'il parait incorrect, corrigez le plan. Dans les deux cas, vous avez investi 2 minutes au lieu de 20.

C'est le probleme que Beadbox resout.

Visibilite en temps reel sur ce que fait toute votre flotte d'agents.

Essayez-le gratuitement pendant la beta →

La verification n'est pas "ca compile"

Le mode d'echec le plus courant que je vois avec Claude Code n'est pas que les agents ecrivent du mauvais code. C'est que personne n'a verifie le resultat contre la spec.

L'agent dit "DONE." Le developpeur survole le diff, trouve ca raisonnable et merge. Deux jours plus tard, quelqu'un decouvre que la fonctionnalite ne gere pas le cas limite numero 3 des criteres d'acceptation. Vous etes maintenant en train de deboguer en production au lieu de l'avoir attrape lors de l'etape de verification de 5 minutes.

La verification signifie verifier mecaniquement chaque critere d'acceptation. Pas "ca semble marcher." Pas "les tests passent" (les tests peuvent etre faux ou incomplets). Chaque critere de la spec recoit une verification concrete.

Voici a quoi ressemble un rapport d'achevement correct :

DONE: Filter bar now persists selected filters across workspace
switches using per-workspace localStorage.

Changes:
- lib/local-storage.ts: Added getWorkspaceFilters/setWorkspaceFilters
  with key format "beadbox:filters:{dbPath}"
- components/filter-bar.tsx: Reads stored filters on mount, writes
  on change. Accepts databasePath prop.
- hooks/use-workspace.ts: Triggers filter restore on workspace switch
  via callback prop.

QA Verification:
1. Open http://localhost:41420, select workspace A
2. Set filters to status=open, type=bug
3. Switch to workspace B via header dropdown
4. Switch back to workspace A
5. Verify filters are still status=open, type=bug
   -> Confirmed: filters restore correctly
6. Close tab, reopen. Filters persist.
   -> Confirmed: localStorage key present, filters applied on mount
7. Run: bd list --status=open --type=bug
   -> Output matches filtered table contents (14 beads)

Acceptance criteria:
- [x] Filters persist across workspace switches (steps 2-5)
- [x] Filters survive browser restart (step 6)
- [x] Filtered view matches bd CLI output (step 7)
- [x] Filters don't bleed between workspaces (step 3: workspace B
      shows defaults)

Unit tests: 3 added (storage read/write/key format). All passing.

Commit: a1b2c3d

La difference entre ceci et "DONE: Fixed the filter bar" est la difference entre un passage QA de 5 minutes et une investigation de 30 minutes. Chaque affirmation dans le commentaire DONE est etayee par une verification specifique. Chaque critere d'acceptation est mappe a une etape de verification. Le reviseur sait exactement ce qui a ete construit, comment ca a ete verifie et ou chercher si quelque chose semble anormal.

Beads comme conteneur de specs

Le cycle de vie que je viens de decrire a besoin d'un endroit ou vivre. La spec, le commentaire du plan, l'implementation, le rapport d'achevement, les resultats de verification. Le tout, attache a une tache, au meme endroit.

C'est le probleme que resout beads. Beads est un issue tracker open-source et local-first concu pour exactement ce workflow. Chaque "bead" est une tache avec une description (votre spec), un fil de commentaires (plans et rapports d'achevement), un statut (open, in_progress, ready_for_qa, closed) et des metadonnees comme la priorite, les dependances et les assignations.

Voici a quoi ressemble le cycle de vie pilote par les specs en pratique avec le CLI bd :

Creer le bead avec votre spec :

bd create --title "Persist filter state across workspace switches" \
  --description "## Problem
The filter bar resets when switching workspaces...

## Acceptance Criteria
1. Select workspace A, set filters...
2. Switch to workspace B..." \
  --type feature --priority p2

L'agent reclame le travail et publie un plan :

bd update bb-a1b2 --claim --actor eng1
bd comments add bb-a1b2 --author eng1 "PLAN: Persist filter state
per-workspace using localStorage.

1. Add workspace-scoped storage helpers...
2. Update filter-bar component...
3. ..."

L'agent termine le travail et publie un rapport :

bd comments add bb-a1b2 --author eng1 "DONE: Filter bar now persists
selected filters across workspace switches.

QA Verification:
1. Open http://localhost:41420...

Acceptance criteria:
- [x] Filters persist across workspace switches
- [x] Filters survive browser restart
...

Commit: a1b2c3d"

bd update bb-a1b2 --status ready_for_qa

Le QA prend le relais et verifie :

bd show bb-a1b2  # Lire la spec et le commentaire DONE
# Executer les etapes de verification
bd comments add bb-a1b2 --author qa1 "QA PASS: All 5 acceptance
criteria verified. Filters persist, restore, and match bd CLI output."

L'ensemble du cycle de vie est dans le bead. La spec est la description. Le plan est un commentaire. Le rapport d'achevement est un commentaire. Le resultat QA est un commentaire. Dans six mois, si quelqu'un demande "comment fonctionne la persistance des filtres et pourquoi avons-nous choisi localStorage plutot que les URL params ?", la reponse est dans le fil de commentaires du bead.

Quand vous faites passer une seule spec par ce pipeline, un terminal et bd show suffisent. Mais ce workflow montre sa vraie valeur quand vous executez plusieurs specs en parallele.

Faire evoluer le developpement pilote par les specs

Imaginez le scenario reel : vous avez trois agents Claude Code, chacun implementant une spec differente. L'Agent A construit une fonctionnalite de persistance des filtres. L'Agent B ajoute un nouveau endpoint API pour les statistiques de workspace. L'Agent C corrige un bug de reconnexion WebSocket. Chacun est quelque part dans le cycle de vie pilote par les specs.

Dans le terminal, vous devriez executer bd list pour voir tous les beads actifs, puis bd show sur chacun pour verifier son statut et lire le dernier commentaire. Ca fait six commandes pour obtenir un apercu de trois flux de travail en parallele. Multipliez ca par cinq ou dix agents et vous passez plus de temps a verifier les statuts qu'a relire les plans.

C'est la que Beadbox entre en jeu. Beadbox est un tableau de bord en temps reel qui vous montre l'etat de chaque bead dans votre workspace. Quelles specs sont ouvertes et attendent un agent. Lesquelles ont des plans publies qui necessitent votre revue. Lesquelles sont en cours. Lesquelles sont pretes pour la verification QA. Le tout se met a jour en direct pendant que les agents ecrivent des commentaires et changent les statuts via le CLI bd.

Vous n'avez pas besoin de Beadbox pour faire du developpement pilote par les specs. Le CLI gere l'ensemble du cycle de vie. Mais quand vous executez plusieurs workflows spec-driven en parallele, pouvoir voir le pipeline d'un coup d'oeil plutot que de consulter le statut de chaque agent individuellement change la vitesse a laquelle vous pouvez relire les plans, debloquer les agents et reperer le travail qui stagne.

Beadbox est gratuit pendant la beta, et le CLI beads sur lequel il fonctionne est open-source.

Ce qui reste vrai quel que soit l'outillage

Que vous utilisiez beads, GitHub Issues, Linear ou de simples fichiers texte, le pattern pilote par les specs fonctionne parce qu'il traite une asymetrie fondamentale dans la facon dont les agents operent : ils sont rapides a l'execution et mauvais au jugement. Chaque minute passee a ecrire une spec claire fait economiser plusieurs minutes a relire du resultat incorrect, deboguer des hypotheses silencieuses et refaire du travail qui a derive.

Les principes :

  1. Definissez "termine" avant "commencer." Les criteres d'acceptation ne sont pas optionnels. Ils sont la seule chose qui rend la verification possible.

  2. Les plans sont des checkpoints, pas de la bureaucratie. Un commentaire de plan de 30 secondes fait economiser des reecritures de 20 minutes. Relisez le plan, pas le code.

  3. La verification est un protocole, pas une impression. "Ca me parait bien" n'est pas une verification. Associer chaque critere d'acceptation a une verification concrete, ca c'est de la verification.

  4. La spec est la seule source de verite. Quand l'implementation et la spec ne concordent pas, c'est l'implementation qui a tort. Cette regle existe parce que les agents ne remettront pas en question un mauvais plan. Ils l'executeront fidelement et produiront un resultat fidelement incorrect.

  5. Les limites de perimetre empechent la derive. Une liste explicite de fichiers a modifier et une section hors-perimetre empechent l'agent d'"ameliorer" des choses que vous ne lui avez pas demande d'ameliorer.

L'investissement est faible : 10-20 minutes a ecrire une spec pour une fonctionnalite dont l'implementation prend une heure. Le retour est important : des resultats coherents, un output verifiable et un enregistrement permanent de ce qui a ete construit et pourquoi.

Si vous construisez des workflows comme ceux-ci, mettez une etoile sur Beadbox sur GitHub.

Like what you read?

Beadbox is a real-time dashboard for AI agent coordination. Free during the beta.

Share