O desenvolvedor que digita "add user authentication" no Claude Code recebe um resultado diferente toda vez. Talvez JWT. Talvez cookies de sessao. Talvez um fluxo OAuth2 completo com refresh tokens e PKCE. O agente nao sabe o que voce quer porque voce nao disse. Voce deu uma direcao, nao um destino.
Os desenvolvedores que vejo obtendo resultados consistentes e prontos para entrega do Claude Code compartilham um habito: escrevem uma especificacao antes de passar trabalho para o agente. Nao um romance. Nao um ticket do Jira com tres frases de contexto. Um documento concreto que define como "pronto" se parece antes que alguem escreva uma linha de codigo.
Isso nao e sabedoria nova. Desenvolvimento spec-first precede a IA por decadas. Mas com agentes, o custo de pular a spec e maior e o beneficio de escrever uma e maior. Um desenvolvedor humano pode parar no meio da implementacao e perguntar "espera, voce quis dizer autenticacao por senha ou SSO?" Um agente vai escolher um silenciosamente e seguir em frente. Quando voce perceber, ele construiu a coisa errada, e voce gastou 20 minutos revisando codigo que precisa ser descartado.
Este artigo percorre o ciclo de vida orientado por specs que uso com Claude Code todos os dias: como escrever especificacoes contra as quais agentes podem executar, o checkpoint de plano-antes-do-codigo que pega mal-entendidos cedo, e um protocolo de verificacao mais rigoroso que "compila."
Por que "so construa" falha com agentes
Vamos ser especificos sobre o modo de falha. Quando voce da ao Claude Code uma instrucao vaga, tres coisas dao errado:
Suposicoes silenciosas. O agente preenche cada lacuna na sua spec com suas proprias suposicoes. As vezes sao razoaveis. As vezes nao. Voce nao sabera em qual categoria esta ate ler o output. Com instrucoes vagas, voce acaba lendo o output com mais cuidado do que teria gasto escrevendo uma spec.
Resultados nao reproduziveis. Execute o mesmo prompt vago duas vezes e voce obtem duas implementacoes diferentes. Nao apenas nomes de variaveis ou formatacao diferentes. Decisoes arquiteturais diferentes. Bibliotecas diferentes. Estrategias de tratamento de erros diferentes. Se voce nao pode reproduzir o output, nao pode construir um processo confiavel ao redor dele.
Revisao se torna o gargalo. Quando o agente toma todas as decisoes, voce precisa verificar todas as decisoes. Um diff de 400 linhas onde voce entende cada escolha leva 5 minutos de revisao. Um diff de 400 linhas onde o agente escolheu o schema do banco, a forma da API, os codigos de erro e a logica de validacao leva 30 minutos porque voce esta reconstruindo a spec a partir da implementacao.
A solucao nao sao prompts melhores. E antecipar as decisoes que importam em um documento contra o qual o agente pode executar.
O ciclo de vida orientado por especificacoes
O fluxo de trabalho tem cinco fases. Cada uma tem uma condicao de entrada clara e uma condicao de saida clara.
Fase 1: Brainstorming. Voce explora o espaco do problema. Quais sao as restricoes? Quais abordagens existem? O que voce tentou antes? Aqui e onde voce pensa em voz alta, sozinho ou com Claude Code em modo conversacional. Condicao de saida: voce tem uma abordagem preferida e entende os tradeoffs.
Fase 2: Revisao. Voce testa a abordagem sob pressao. O que pode dar errado? Quais casos extremos existem? Isso conflita com algo ja no codebase? Se voce trabalha com multiplos agentes, aqui um agente de arquitetura ou segunda opiniao e valioso. Condicao de saida: voce esta confiante de que a abordagem e solida.
Fase 3: Spec. Voce escreve o que decidiu. Declaracao do problema, abordagem proposta, arquivos a modificar, criterios de aceitacao verificaveis mecanicamente e um plano de testes. Este e o contrato. Condicao de saida: alguem (humano ou agente) poderia ler esta spec e saber exatamente o que construir e como verificar.
Fase 4: Implementacao. O agente executa contra a spec. Nao contra uma ideia vaga. Contra um documento concreto com criterios testaveis. Condicao de saida: o agente afirma ter concluido e postou evidencias de verificacao.
Fase 5: Verificacao. Voce (ou um agente de QA) confirma que a implementacao corresponde a spec. Nao "parece certo" mas "satisfaz cada criterio de aceitacao." Condicao de saida: cada criterio esta verificado, e os que falharam voltam para a Fase 4.
O insight chave: as fases 1-3 sao baratas. Levam 10-20 minutos para uma funcionalidade de porte medio. A fase 4 leva o tempo que a implementacao necessitar. A fase 5 leva 5-10 minutos. Pular as fases 1-3 nao economiza 10-20 minutos. Custa o tempo para revisar, depurar e refazer trabalho que foi na direcao errada.
Como e uma boa spec para agentes
Aqui esta um template de spec real. Nao e uma user story. Nao e um documento de requisitos de produto. E um documento de trabalho que diz a um agente exatamente o que construir.
## 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
Note o que esta spec contem e o que nao contem. Nao explica como localStorage funciona. Claude Code sabe disso. Nao justifica por que escolhemos localStorage em vez de URL params. Isso aconteceu na fase de brainstorming. Lista cada arquivo que o agente deve tocar, o que significa que se o agente comecar a modificar arquivos fora desta lista, isso e um sinal de alerta. Inclui uma secao de fora do escopo, que impede o agente de fazer gold plating.
Os criterios de aceitacao sao a parte mais importante. Cada um e uma acao concreta com um resultado observavel. Nao "filtros devem persistir." Isso e ambiguo. "Mude para o workspace A, verifique que os filtros sao status=open + type=bug" e testavel. Um agente pode executar isso. Um revisor de QA pode verificar.
O padrao plano-antes-do-codigo
Aqui esta um protocolo que pega a maioria dos erros de implementacao antes que se tornem codigo: exigir que o agente poste seu plano de implementacao antes de escrever qualquer coisa.
Na pratica, parece um comentario estruturado na tarefa. Antes do agente abrir qualquer arquivo, ele escreve exatamente o que pretende fazer.
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.
O agente leva cerca de 30 segundos para produzir isso. Voce leva cerca de 2 minutos para ler. E nesses 2 minutos, voce pode detectar problemas que levariam 20 minutos para corrigir apos a implementacao:
- O agente esta tocando arquivos fora da spec? (Adicionar workspace-provider.tsx nao estava na spec. Isso esta ok ou e scope creep?)
- A abordagem faz sentido? (Usar um event emitter para mudancas de workspace pode ser overengineering. Uma mudanca de prop mais simples pode funcionar.)
- Faltam etapas? (E quanto a limpeza de entradas antigas no localStorage quando um workspace e removido?)
O plano e um checkpoint. Se parece correto, diga ao agente para prosseguir. Se parece errado, corrija o plano. De qualquer forma, voce investiu 2 minutos em vez de 20.
