Como escrever uma especificação que o Claude Code consiga seguir de ponta a ponta

Uma especificação para Claude Code é o contrato que impede o agente de decidir sozinho no meio do caminho. O mínimo que funciona são seis seções: objetivo em uma frase verificável, escopo com caminhos de arquivo citados, o que está fora do escopo, restrições concretas o bastante para checar, formato de saída e o check que o próprio Claude roda. A documentação oficial reforça isso: instruções precisas, arquivos referenciados, padrões de exemplo apontados e sempre um meio de verificação. Antes de liberar a execução, rode a spec no modo plano e ajuste a spec, nunca o plano
O agente entregou, rodou de primeira e não é nada do que você pediu
Quem já viu isso sabe que quase nunca é burrice do modelo: é buraco no pedido. Onde a sua descrição fica vaga, o agente não trava, ele DECIDE. Escolhe pasta, escolhe biblioteca, escolhe o formato do retorno e segue feliz
A spec é o contrato que fecha esses buracos antes de a primeira linha ser escrita. E ela não precisa ser um documento gigante, precisa ser curta e checável. Bora ver a estrutura mínima?
O que ter antes de escrever a spec
Duas coisas, só
A primeira é um CLAUDE.md na raiz do projeto. Ele é o arquivo markdown de contexto persistente que o Claude Code lê no início de cada sessão. Se você quiser ver o que já existe, o comando /memory lista o CLAUDE.md, o CLAUDE.local.md e os outros arquivos de memória nos escopos de usuário e de projeto; selecionar um abre no editor, e selecionar um que ainda não existe cria o arquivo antes
A segunda é a noção de modo plano, que é onde você vai testar a spec no fim do post
O que é do CLAUDE.md e o que é da spec:
Essa divisão é o que evita você escrever a mesma coisa duas vezes
O CLAUDE.md carrega o contexto do projeto inteiro, aquilo que vale em toda sessão: stack, convenções, regras que não mudam por feature. A spec carrega o contexto específico da feature que está sendo construída agora
Regra prática que uso: se a informação continuar verdadeira depois que a feature estiver pronta, ela é do CLAUDE.md. Se ela morre junto com a entrega, é da spec
Domine o Claude Code do básico ao avançado
Você vai aprender a criar sistemas completos com Claude Code, sem precisar ser programador. Inscreva-se para ter acesso a um desconto de lançamento e bônus especiais!
Como escrever a spec passo a passo
Seis seções. Nem uma a mais
A documentação oficial de boas práticas é direta nesse ponto: quanto mais precisas as instruções, menos correções; referencie arquivos específicos, mencione restrições e aponte padrões de exemplo
- Objetivo em uma frase verificável
Uma frase. Que descreva o estado final e não a sensação
## Objetivo
O usuário logado consegue exportar suas notas em CSV clicando no botão "Exportar" da tela de listagem, e o download dispara no navegadorO erro comum deste passo: escrever "melhorar a exportação de notas". Melhorar quanto? Terminou quando? Se você não consegue responder "pronto é quando X acontece", o agente também não vai conseguir
- Escopo com arquivos e caminhos citados
Aqui é onde a maioria das specs morre. "A tela de notas" não é um endereço, é uma vibe
## Escopo
- `src/app/notas/page.tsx`: adicionar o botão "Exportar"
- `src/app/api/notas/export/route.ts`: criar o endpoint GET
- Siga o padrão de autenticação e de resposta que já existe em `src/app/api/notas/route.ts`Repare na terceira linha: ela aponta um padrão de exemplo. É exatamente o que a documentação recomenda, e é o que impede o agente de inventar um jeito novo de fazer o que o projeto já fazia
O erro comum deste passo: descrever o comportamento e esquecer o endereço. Aí o agente cria o arquivo onde ELE acha bonito
- O que está fora do escopo
Essa seção parece boba até a primeira vez que o agente refatora meio módulo sem ninguém pedir
## Fora do escopo
- Não alterar o schema do banco
- Não mexer em endpoints que não estejam no escopo
- Não renomear nem reorganizar arquivos existentes
- Não instalar dependência novaO erro comum deste passo: achar que "não pedi" equivale a "não faça". Não equivale. Silêncio, para um agente, é espaço livre
- Restrições concretas o bastante para verificar
A documentação oficial dá o exemplo perfeito: escreva Use 2-space indentation em vez de Format code properly
A régua é essa: dá pra alguém olhar o resultado e dizer sim ou não sem discutir? Então é restrição. Se dá pra discutir, ainda é opinião
## Restrições
- Use 2-space indentation
- Nada de biblioteca nova: monte o CSV com o que já está no projeto
- Toda rota nova valida a sessão antes de responder
- Mensagens de erro em portuguêsO erro comum deste passo: encher de adjetivo. "Código limpo", "performático", "seguro". Isso não é restrição, é torcida
- Formato de saída esperado
Duas saídas moram aqui: a do produto e a da conversa
## Formato de saída
- CSV com cabeçalho: id,titulo,criado_em
- Uma nota por linha, datas em ISO 8601
- Ao terminar, responda com: arquivos alterados, decisões que precisou tomar e o comando pra testarAquele último item vale ouro. Ele te dá o rastro do que o agente escolheu por conta própria, que é justamente o que você vai querer virar linha nova da spec depois
O erro comum deste passo: definir o formato do dado e esquecer o formato do relato. Sem relato, você audita lendo o diff inteiro
- O check que o próprio Claude roda
A recomendação oficial é direta: sempre forneça verificação (testes, scripts, screenshots). Se não dá pra verificar, não dê como pronto. E o ponto fino é esse: o check tem que ser algo que ELE mesmo consiga rodar
## Verificação
- Rode `npm test -- notas-export` e mostre a saída
- Rode `npm run lint` nos arquivos alterados
- Se algum check falhar, corrija e rode de novo antes de dizer que terminouO erro comum deste passo: colocar como verificação algo que só você consegue fazer, tipo "conferir na homologação". Isso não é check do agente, é tarefa sua
Onde a spec falha e o agente inventa a decisão
Quatro sintomas que se repetem, e o buraco exato de cada um
Sintoma: ele criou o arquivo numa pasta nova
O buraco: você não apontou padrão de exemplo. O agente não tinha referência de onde coisas parecidas moram, então escolheu uma convenção qualquer (normalmente uma boa, só que não a sua)
Como prevenir: no escopo, cite um arquivo existente que resolve um problema parecido e mande seguir aquele padrão
Sintoma: ele refatorou o que ninguém pediu
O buraco: faltou a seção de fora do escopo. Ele viu código que dava pra melhorar e melhorou, porque nada dizia o contrário
Como prevenir: escreva o "não faça" com a mesma seriedade do "faça". Uma linha proibindo renomeação já resolve metade dos casos
Sintoma: ele deu como pronto sem provar
O buraco: faltou verificação. Sem um check rodável, "pronto" vira opinião do modelo sobre o próprio trabalho
Como prevenir: toda spec fecha com um comando. Teste, script, o que for, desde que ele possa executar e te mostrar a saída
Sintoma: ele escolheu uma biblioteca sozinho
O buraco: faltou restrição. Instalar dependência é uma decisão de arquitetura, e você deixou ela em aberto
Como prevenir: diga explicitamente o que pode e o que não pode entrar no projeto. "Sem dependência nova" é uma frase curta que evita PR gigante
Como validar a spec no modo plano antes de deixar o Claude codificar
O modo plano é o ensaio: o Claude lê arquivos e propõe um plano, mas não faz edições até você aprovar (as edições ficam bloqueadas, exceto em sessões com bypass permissions disponível)
Use ele como espelho da spec
- Entre no modo plano
Aperte Shift+Tab até a barra de status mostrar ⏸ plan mode on, ou já abra a sessão assim:
claude --permission-mode planDurante a sessão, o Shift+Tab cicla default → acceptEdits → plan. Ou seja, se você passar do ponto, é só continuar ciclando
- Ou acione só pra um prompt
Se você não quer trocar o modo da sessão inteira, prefixe o prompt com /plan e o plano vale só ali
- Cole a spec e leia o plano como espelho
Aqui é o pulo do gato: você não está lendo o plano pra ver se ele é bom, está lendo pra ver se ele é O QUE A SPEC DIZ. Se o plano tem um passo que a spec não pediu, sua spec estava aberta demais naquele ponto
O erro comum deste passo: aprovar porque "tá bom assim". Plano bom com spec vaga significa que você teve sorte, não que o contrato ficou fechado
- Se aparecer ambiguidade, abra o plano e edite à mão
Ctrl+G abre o plano proposto no seu editor de texto padrão pra edição direta, antes de o Claude prosseguir. Serve pra ajuste cirúrgico: você tira a ambiguidade e destrava a execução de agora, sem começar tudo de novo
Só que essa edição vive na rodada de hoje. A spec continua com o mesmo buraco, e na próxima sessão o agente vai decidir aquele mesmo ponto do mesmo jeito
Então trate como duas tarefas, não como uma escolha: edita o plano pra seguir agora, e leva a MESMA correção pra spec, senão o buraco volta. Se der pra rodar de novo com a spec ajustada, melhor ainda: você confere se o plano sai igual ao que queria
- Aprove e deixe rodar
Sai-se do modo plano aprovando o plano ou apertando Shift+Tab (esse segundo caminho sai sem aprovar). Depois disso o Claude codifica verificando contra o plano
Onde cada pedaço do contexto deve morar
Spec não é o único lugar de guardar contexto, e enfiar tudo nela é o jeito rápido de deixar o arquivo ilegível
| Tipo de informação | Onde mora | Por quê |
|---|---|---|
| Regra do projeto inteiro | CLAUDE.md na raiz | Lido no início de cada sessão |
| Regra só de uma parte do código | Regras com escopo por caminho | Carrega a instrução só quando o Claude trabalha com arquivos que casam com o padrão |
| Procedimento que você repete | .claude/skills/<nome>/SKILL.md | Vira comando /nome, invocável quando precisar |
| Leitura grande de apoio | Subagente | Roda em janela de contexto própria |
| Contexto da feature atual | Spec | Descartável, morre com a entrega |
Sobre a hierarquia: o Claude Code carrega todo CLAUDE.md do diretório de trabalho e de cada diretório pai no lançamento, e carrega o arquivo de cada subdiretório sob demanda, quando lê arquivos dali. Então dá pra ter contexto por área do repo sem inchar a raiz
Cuidado com o truque dos imports:
Muita gente quebra o CLAUDE.md em vários arquivos com imports @path achando que está economizando contexto
Não está. Dividir em imports @path ajuda na ORGANIZAÇÃO, mas não reduz contexto, porque os arquivos importados carregam no lançamento. Quem economiza de verdade são as regras com escopo por caminho, que só entram quando o arquivo casa com o padrão
Skill é pra procedimento, não pra conhecimento solto:
O formato recomendado é .claude/skills/<nome>/SKILL.md, com frontmatter YAML entre marcadores ---, e ele fica invocável por /nome. O formato legado .claude/commands/*.md continua funcionando, e ali o nome do arquivo vira o nome do comando
A lógica de escrever regras de breakpoint em skill é a mesma da spec: instrução concreta o bastante pra checar. Se você já brincou com o Superpowers do Claude Code, é o mesmo raciocínio levado pro nível do fluxo de trabalho
E onde tudo isso vive:
O escopo de projeto fica no repositório, em .claude/ (ou na raiz, no caso de CLAUDE.md, .mcp.json e .worktreeinclude). O escopo global fica em ~/.claude/ e vale pra todos os projetos
A memória automática por projeto fica em ~/.claude/projects/<project>/memory/, com o MEMORY.md como índice conciso carregado em toda sessão. Dá pra mudar o local com autoMemoryDirectory no settings.json, passando caminho absoluto ou começando com ~/
Quando a leitura é grande demais:
Cada subagente roda na própria janela de contexto, com system prompt próprio, acesso a ferramentas específico e permissões independentes. Pra sessão principal volta só o resumo e um pequeno trailer de metadados
É o jeito de investigar um módulo inteiro sem entupir a conversa onde a feature está sendo construída. E se a sessão principal esticar demais, /compact substitui a conversa por um resumo estruturado, enquanto /autocompact com uma contagem de tokens (tipo /autocompact 500k) define o quanto a janela enche antes da passagem automática
O que aconteceu quando escrevi um pedido único e bem delimitado
No vídeo abaixo eu testo essa ideia no extremo: um pedido único e descritivo pra um SaaS inteiro (um gerador de slogans com IA, com autenticação) e o agente conduzindo a construção dali em diante
O detalhe que fez diferença foi não descrever só a funcionalidade. Eu coloquei no pedido questões de segurança e regras de negócio que considero importantes, que é basicamente a seção de restrições da spec vestida de prompt
Antes de escrever código, veio um planejamento. Eu li, conferi se estava tudo certo e só então aprovei pra seguir
E aí apareceu a prova viva do post: no meio da execução o agente PAROU pra perguntar decisões que o pedido não tinha definido, tipo onde salvar a chave de API e se o preenchimento seria manual. Aquilo era buraco de spec aparecendo em tempo real. Quando o pedido é bem delimitado, ele pergunta; quando é vago, ele chuta
O resultado do pedido único foram 4 páginas, além de autenticação, integração com banco de dados e integração com IA. No painel de uso, aquela execução ficou em torno de 11 a 12 centavos de dólar (uma execução de teste anterior tinha custado 3 centavos, e eu tinha colocado 2 dólares de crédito antes de começar). No fim, o agente ainda entregou as instruções de como rodar, como testar e o aviso de que faltava preencher a chave no arquivo de ambiente
Depois do projeto pronto, pedi ao próprio modelo pra gerar um arquivo de documentação na raiz, listando exatamente o que ele precisava conter: visão geral, stack, estrutura de pastas, banco de dados, autenticação, como rodar, convenções e regras importantes. A ideia é camada de segurança: o próximo agente cria funcionalidade nova sem destruir o que já existe
Confesso o pecado: o certo seria ler o documento gerado e conferir se faltou complementar alguma coisa, e eu segui adiante assumindo que estava correto haha. Mas o teste seguinte deu bom, troquei de agente e pedi pra ele explicar o projeto usando só aquele arquivo e os arquivos do repositório, e a explicação voltou coerente com o que tinha sido construído. Rodei o fluxo na aplicação (criar conta, login, gerar slogan) e funcionou, apesar do projeto ser simples
A lição é essa: o que o agente entrega de ponta a ponta depende diretamente de quão delimitado foi o pedido
Conclusão
Spec curta e verificável vale mais que documento longo e bonito
As seis seções são objetivo em uma frase verificável, escopo com caminhos, fora do escopo, restrições concretas o bastante pra checar, formato de saída e o check que o próprio Claude roda. Se alguma delas está vazia, é ali que ele vai decidir sozinho
O próximo passo é bem prático: pegue a próxima feature, escreva a spec nessas seis seções, rode no modo plano e leia o plano como espelho. Achou divergência? Ajusta o plano pra destravar a rodada de hoje se precisar, mas leva a correção pra SPEC também, e roda de novo até o plano sair igual ao que você queria
Depois disso é só aprovar e deixar ele trabalhar =)
até o próximo post!
Perguntas frequentes
Como eu testo a spec antes de deixar o Claude Code executar de verdade?
É pra isso que existe o modo plano: você entra nele apertando Shift+Tab até a barra de status mostrar ‘plan mode on’, ou já inicia a sessão com claude –permission-mode plan. Nesse modo o Claude lê os arquivos do projeto e propõe um plano baseado na sua especificação para Claude Code, mas não edita nada até você aprovar. Se o plano bateu com o que a spec pedia, beleza; se não bateu, o buraco ficou óbvio antes de qualquer linha de código mudar.
Dá pra ativar o modo plano só num prompt específico, sem mudar a sessão inteira?
Dá sim. Basta prefixar o prompt com /plan que só aquela mensagem entra em modo plano, sem precisar alternar a sessão toda com Shift+Tab. É útil quando você quer testar um trecho da spec isolado, sem sair do fluxo normal de edição.
Como eu edito o plano que o Claude Code propôs antes de ele sair executando?
Ctrl+G abre o plano proposto no editor de texto padrão, e dá pra editar direto ali antes de mandar seguir. Só que essa edição vale pra execução de agora: se a ambiguidade veio de um buraco na spec, leve a mesma correção pra spec também, senão o mesmo ponto volta em aberto na próxima sessão.
O que acontece se eu sair do modo plano sem aprovar o que o Claude propôs?
Você sai apertando Shift+Tab de novo, e isso encerra o modo plano sem aprovar nada. Ele só passa a codificar depois que o plano é aprovado, e aí verifica o trabalho contra o que ficou combinado na spec.
Preciso reescrever o CLAUDE.md toda vez que eu crio uma spec nova?
Não. O CLAUDE.md carrega o contexto do projeto inteiro, que continua valendo em toda sessão, então ele fica parado. A spec é o que muda a cada feature: se a informação some depois que a entrega termina, ela nasce e morre na spec, não no CLAUDE.md.
Quebrar o CLAUDE.md em vários arquivos com imports @path economiza contexto?
Não economiza. Dividir em imports @path ajuda na organização, mas não reduz contexto, porque os arquivos importados carregam no lançamento junto com o principal. Quem economiza de verdade são as regras com escopo por caminho, que carregam a instrução só quando o Claude trabalha com arquivos que casam com o padrão.
Formações
Formação Vibe Coding
Do Prompt ao Produto: Crie Software Real com IA
- 474 aulas
- 20 projetos
- 39h 27min
Blog | Mais populares

As diferenças de var, let e const

Como fazer redirecionamento com PHP
Neste artigo você vai aprender a como fazer redirecionamento com PHP, utilizaremos abordagens fáceis de entender e de aplicar Fala programador(a), beleza? Bora aprender mais […]

ChatGPT: o que é, como usar, dicas e como acessar login
ChatGPT é uma ferramenta de processamento de linguagem natural (NLP) baseada na arquitetura GPT-3.5, desenvolvida pela OpenAI. Sua criação representa um marco significativo no campo […]
