📋 A Lógica do SPEC Primeiro
Por que o documento de especificação precede qualquer linha de código — e como escrever um SPEC que realmente guia o build.
Um documento que define o sistema em texto antes de qualquer implementação — componentes, responsabilidades, invariantes e o critério de sucesso.
Sem SPEC, cada prompt reinventa a arquitetura. Com SPEC, cada prompt navega por um mapa já definido — bugs arquiteturais são encontrados antes de custar horas de código.
Especificação antes de implementação, componentes e responsabilidades, invariantes de segurança, decisões de design explícitas.
As três perguntas fundamentais: O quê o sistema faz (comportamento), Por quê cada decisão existe (justificativa), Como verificar que está correto (critério de aceitação).
Um SPEC que não responde estas três perguntas é incompleto. Prompts gerados a partir dele vão produzir código que funciona tecnicamente mas falha nos objetivos reais.
Comportamento esperado, justificativa de design, critério de aceitação, testabilidade por definição.
Invariantes são propriedades que o sistema nunca pode violar — independente do estado, carga ou falha. Declará-las no SPEC força cada prompt a respeitá-las.
Sem invariantes explícitos, o prompt 5 pode quebrar silenciosamente uma garantia que o prompt 2 estabeleceu. Descobrir isso tarde custa muito mais que escrever o SPEC.
Invariantes de segurança, fail-open, escrita atômica, idempotência, propriedades inegociáveis do sistema.
README explica como usar. Comentário explica como funciona. SPEC define o que deve ser — antes que exista. São três camadas de documentação com propósitos distintos.
Confundir os três leva a documentação no lugar errado. Colocar invariantes em comentários garante que sejam ignorados. SPEC é contrato, não documentação.
SPEC como contrato, README como guia de uso, comentário como explicação local, separação de responsabilidades de documentação.
Um template de seis seções — objetivo, componentes, invariantes, interface pública, sequência de build e critérios de aceitação — que pode ser preenchido em menos de meia hora para projetos médios.
SPEC não precisa ser um documento extenso para ser útil. Um template estruturado garante que as perguntas certas sejam respondidas sem gastar tempo em seções desnecessárias.
Template de SPEC, seis seções essenciais, proporcionalidade entre tamanho do SPEC e do projeto, completude mínima.
A prática de usar os critérios de aceitação do SPEC como checklist após cada prompt — confirmando que a entrega cumpre o contrato antes de avançar para a próxima camada.
O SPEC sem verificação é decorativo. Usá-lo como checklist transforma cada prompt em um passo verificado — e detecta desvios cedo, quando ainda são fáceis de corrigir.
Checklist de aceitação, verificação por prompt, SPEC como contrato ativo, detecção precoce de desvios.
🏗️ A Sequência Obrigatória
A ordem correta de construção — esqueleto, estado, lógica, segurança — e o que acontece quando você pula etapas.
Criar primeiro a estrutura de arquivos, interfaces e pontos de integração — sem implementar nenhuma lógica real. O scaffold define o contrato externo do sistema.
Implementar lógica antes de ter estrutura leva a reescritas completas quando a arquitetura se mostra inadequada. Scaffold primeiro garante que o contrato externo está correto antes do custo da implementação.
Plugin scaffold, estrutura de arquivos, interfaces vazias, contrato externo, fail-open por padrão.
Implementar a representação e transições de estado antes de qualquer lógica de negócio. O sistema precisa saber em qual fase está antes de poder agir corretamente.
Lógica de negócio implementada sem estado explícito inevitavelmente cria estado implícito — variáveis globais, flags, condições aninhadas que tornam o sistema impossível de raciocinar.
State machine, representação de estado, transições explícitas, estado persistido, estado implícito vs. explícito.
A terceira camada que implementa o comportamento real do sistema — só depois que o scaffold e a máquina de estados estão verificados e funcionando.
Lógica implementada sobre fundação instável herda todos os bugs da fundação. Ao verificar cada camada antes de avançar, a lógica de negócio pode ser testada de forma isolada.
Camadas verificadas, lógica de negócio isolada, dependências de camadas, testabilidade por isolamento.
O safety pass final que reforça todas as primitivas de segurança — fail-open, escrita atômica, CAS, lockfiles — sobre um sistema funcionalmente correto.
Adicionar segurança em um sistema com bugs de lógica mascara os bugs — o sistema fica "seguro" mas incorreto. Segurança sobre lógica verificada garante que as primitivas protegem o comportamento correto.
Safety pass, primitivas de segurança, hardening sobre lógica correta, segurança como camada final.
Os padrões de falha recorrentes quando a sequência é ignorada: estado implícito que corrompe, lógica que não sabe sua fase, segurança que protege o comportamento errado.
Reconhecer estes padrões de falha permite diagnóstico rápido quando algo dá errado. A maioria dos bugs de LLM coding vem de sequência incorreta, não de código ruim.
Padrões de falha por sequência, estado implícito, bugs de fase, segurança sobre lógica incorreta.
O processo de mapear seu projeto nas quatro camadas da sequência e quebrar cada camada em prompts atômicos — cada um com entrada clara, saída verificável e critério de avanço.
A maior dificuldade de LLM coding não é escrever prompts — é decidir quantos prompts fazer e em qual ordem. Este processo elimina essa dificuldade com uma estrutura repetível.
Mapeamento de camadas, granularidade de prompts, dependências entre prompts, critério de avanço.
🛡️ Fail-Open e os Padrões de Segurança
As seis primitivas de segurança que todo plugin precisa — e como verificar se o seu projeto as implementa corretamente.
A propriedade que garante: quando um hook ou plugin falha por qualquer razão, o sistema host (Claude Code) continua operando normalmente — sem bloquear, sem travar, sem perder trabalho.
Um plugin que bloqueia o fluxo de trabalho quando falha é mais prejudicial que não existir. Fail-open é a primeira garantia de segurança — sem ela, as outras não importam.
Fail-open vs. fail-closed, try/catch em todo código de hook, exit codes seguros, degradação graciosa.
A técnica de escrever em arquivo temporário e fazer rename atômico — garantindo que o arquivo de destino nunca fica em estado parcialmente escrito, mesmo com interrupção no meio.
Escrever diretamente no arquivo de estado deixa uma janela onde interrupção (kill, crash, timeout) corrompe o arquivo. Estado corrompido pode ser permanente — sem recovery.
Write-then-rename, arquivo temporário, atomicidade do rename no POSIX, janela de corrupção, recovery.
A operação que lê o estado atual, verifica que ainda é o esperado, e só então aplica a modificação — rejeitando a operação se o estado mudou entretanto.
Em hooks concorrentes (múltiplas instâncias de Claude Code), sem CAS dois processos podem ler o mesmo estado e ambos acreditar que são os donos de uma transição — corrompendo o estado.
Compare-and-swap, versioning de estado, condição de corrida, conflito de escrita, transição segura.
Usar criação atômica de arquivo (mkdir ou open com O_EXCL) como mutex — garantindo que apenas um processo executa uma seção crítica ao mesmo tempo, sem dependência de banco de dados ou serviço externo.
Plugins shell não têm acesso a mutexes de sistema operacional convenientes. Lockfiles são a solução portátil e sem dependências — mas precisam de cleanup garantido para não travar.
Lockfile como mutex, criação atômica de arquivo, cleanup em EXIT trap, stale lock detection.
A combinação de `set -euo pipefail` e `trap ... ERR` que garante que qualquer comando que falha em um shell script seja capturado — sem a falha silenciosa que é o padrão em bash.
Bash por padrão ignora erros de comandos individuais e continua executando. Um plugin que executa com estado inconsistente porque um comando falhou silenciosamente é difícil de debugar.
set -euo pipefail, ERR trap, EXIT trap, falha silenciosa, pipelines e exit codes.
A lista de verificação com as seis primitivas que todo plugin deve implementar: fail-open, escrita atômica, CAS, lockfile com cleanup, ERR trap e idempotência.
Sem um checklist explícito, é fácil implementar cinco primitivas e esquecer a sexta. O checklist transforma segurança de conhecimento tácito em verificação mecânica — aplicável a qualquer projeto.
Checklist de primitivas, segurança como verificação mecânica, idempotência, completude das garantias.
🎯 Quebrar em Prompts Incrementais
Como dividir qualquer projeto em prompts atômicos — cada um com entrada verificável, saída verificável e critério de avanço claro.
Cada prompt deve entregar exatamente uma camada do sistema — completa, testável e com critério de aceitação claro — antes que o próximo prompt seja executado.
Prompts que entregam múltiplas camadas ao mesmo tempo tornam impossível determinar qual camada causou um bug. Atomicidade de entrega é o que torna o diagnóstico de falhas possível.
Prompt atômico, camada verificável, critério de aceitação por prompt, diagnóstico de falha isolado.
O prompt certo é aquele cuja entrega pode ser verificada em menos de 5 minutos e que não depende de mais de 2 prompts anteriores para fazer sentido.
Prompts muito grandes criam múltiplos pontos de falha não isoláveis. Prompts muito pequenos criam overhead de verificação e aumentam o risco de incoerência entre entregas adjacentes.
Granularidade de prompt, tempo de verificação, profundidade de dependência, coerência entre prompts.
O conjunto de pré-condições que cada prompt assume — arquivos presentes, interfaces implementadas, comportamentos verificados — e que devem ser explicitados no prompt.
Dependências implícitas criam falhas misteriosas quando o prompt anterior não entregou exatamente o que o próximo esperava. Torná-las explícitas transforma dependências em contratos verificáveis.
Pré-condições de prompt, dependências explícitas, contratos de interface, verificação de pré-condição antes de executar.
O conjunto mínimo de testes que confirma que a entrega do prompt atual satisfaz seus critérios de aceitação e não quebrou o que prompts anteriores entregaram.
Avançar sem verificar é acumular dívida técnica invisível. A verificação entre prompts é o momento em que cada camada é declarada sólida — e o custo de corrigir ainda é baixo.
Gate de verificação, critérios de aceitação, testes de não-regressão, dívida técnica por pulo de verificação.
O protocolo de diagnóstico e regressão quando uma entrega não passa a verificação — identificar em qual camada a falha ocorreu, reverter apenas essa camada e re-executar com contexto adicional.
Sem protocolo de regressão, uma falha no prompt 6 leva a reescrever tudo do prompt 3. Com protocolo correto, a regressão é cirúrgica — preservando o trabalho verificado.
Diagnóstico de falha, regressão por camada, contexto de diagnóstico, re-execução com informação adicional.
Um template de cinco seções para cada prompt: contexto do projeto, estado atual verificado, entrega esperada, invariantes a respeitar e critério de aceitação.
Prompts sem estrutura levam o modelo a fazer suposições sobre o que é esperado. O template elimina ambiguidade e garante que contexto, restrições e critérios estejam sempre presentes.
Template de prompt, cinco seções obrigatórias, contexto explícito, invariantes como restrições, critério de aceitação como contrato.
🧪 Testando Camada por Camada
Por que testar primitivos isolados antes de compor — e como estruturar platform tests, smoke tests e E2E sintético.
A prática de verificar cada primitiva (escrita atômica, CAS, lockfile, ERR trap) de forma independente antes de integrá-las — garantindo que o primitivo funciona antes de depender dele.
Bugs em primitivos compostos são difíceis de diagnosticar porque múltiplos componentes interagem. Testar isolado identifica exatamente qual primitivo falhou — sem interferência dos outros.
Teste de primitivo isolado, composição sobre primitivos verificados, diagnóstico por isolamento.
Testes que verificam as capacidades do ambiente de execução antes do build principal — versão de shell, disponibilidade de comandos, permissões de filesystem e comportamento de atomicidade.
Assumir que o ambiente suporta uma operação e descobrir que não no meio do build é custoso. Platform tests identificam incompatibilidades antes que se tornem bugs difíceis de reproduzir.
Platform tests, capability detection, pré-condições de ambiente, compatibilidade de shell.
O conjunto mínimo de testes que confirma que a camada entregue não está obviamente quebrada — sem cobrir edge cases, apenas o happy path principal.
Smoke tests são rápidos de escrever e executar — e eliminam os erros mais grosseiros antes que você avance. São o gate mínimo entre prompts, não o gate completo.
Smoke test vs. teste completo, happy path, gate mínimo, velocidade de verificação.
Testes end-to-end que simulam o fluxo real do sistema usando fixtures e stubs controlados — sem depender do serviço externo real para verificação.
E2E com dependências reais são lentos, frágeis e custosos. E2E sintético tem a cobertura do fluxo completo com a velocidade e determinismo dos testes unitários.
E2E sintético, fixture e stub, simulação de dependências, cobertura de fluxo, determinismo.
O protocolo de diagnóstico quando um teste falha no prompt N: identificar se a falha é da camada N ou de uma camada anterior, e como replicar a falha em isolamento para corrigir.
Sem protocolo sistemático, a resposta a uma falha é reescrever tudo. Com protocolo, cada falha tem um procedimento de diagnóstico que preserva o trabalho verificado.
Diagnóstico de falha em sequência, bisect de camada, replicação em isolamento, preservação de trabalho verificado.
A prática de re-executar os testes de camadas anteriores após cada novo prompt — garantindo que a nova camada não quebrou comportamentos já verificados.
O modelo pode resolver a tarefa do prompt 7 de uma forma que invalida uma suposição do prompt 3. Sem regressão, este bug só é descoberto em produção — ou nunca.
Regressão entre prompts, suite de não-regressão, suposições implícitas, detecção de quebra retroativa.
🚀 Do Zero ao SPEC — Seu Próximo Projeto
Exercício guiado completo: do projeto escolhido ao SPEC escrito, sequência de prompts definida e checklist de pré-build preenchido.
Os critérios que tornam um projeto adequado para aplicar o método pela primeira vez: escopo delimitado, comportamento verificável, um único ponto de integração e ausência de dependências externas complexas.
Aplicar o método pela primeira vez em um projeto excessivamente complexo mistura a curva de aprendizado do método com a complexidade do domínio — dificultando separar o que é dificuldade do método e o que é dificuldade do problema.
Critérios de projeto adequado, escopo delimitado, verificabilidade, ponto único de integração, complexidade gerenciável.
Um exercício prático de 30 minutos onde você preenche o template de SPEC para o seu projeto — respondendo as três perguntas fundamentais e declarando os invariantes de segurança.
Conhecer o template é necessário mas não suficiente. Preencher o template para o seu projeto específico é quando você descobre onde as perguntas são difíceis — e onde ainda não tem clareza suficiente.
Exercício guiado, template preenchido, dificuldades reveladas, clareza de requisitos, SPEC como ferramenta de descoberta.
O processo de transformar o SPEC em uma sequência de 4-8 prompts — mapeando cada seção do SPEC para uma ou mais camadas, e cada camada para um prompt atômico com critério de aceitação.
O SPEC diz o quê construir. A sequência de prompts diz em qual ordem e como verificar. Transformar SPEC em sequência é a habilidade central do método — e a mais difícil de dominar sem prática.
Mapeamento SPEC para prompts, sequência incremental, granularidade de camadas, critério de aceitação por prompt.
A análise de quais das seis primitivas de segurança são relevantes para o seu projeto específico — e em qual camada da sequência cada uma deve ser adicionada.
Nem todo projeto precisa das seis primitivas com a mesma intensidade. Identificar as primitivas relevantes evita over-engineering e garante que as críticas não sejam esquecidas.
Análise de primitivas relevantes, risk assessment, primitivas críticas vs. opcionais, posicionamento na sequência.
O exercício de definir, para cada prompt da sua sequência, os testes concretos que confirmam a aceitação — antes de executar o prompt, para que os critérios não sejam ajustados para encobrir falhas.
Critérios de aceitação definidos depois da entrega tendem a se ajustar ao que foi entregue. Definir antes força clareza sobre o que realmente é necessário — e detecta requisitos ambíguos antes que virem bugs.
Critérios de aceitação antecipados, testes concretos, gates de avanço, requisitos explícitos.
A lista de verificação final antes de iniciar o build: SPEC completo, sequência definida, primitivas de segurança mapeadas, critérios de aceitação escritos e ambiente de teste preparado.
O checklist de pré-build é o que separa um build planejado de uma série de tentativas. Confirmar cada item antes do primeiro prompt reduz drasticamente a probabilidade de reescritas completas.
Checklist de pré-build, prontidão para build, ambiente de teste, SPEC completo, sequência verificada.