Introdução
Pedir código a uma IA com um prompt curto deixa muita coisa em aberto. O modelo precisa presumir o que ninguém escreveu, e o erro costuma aparecer só no fim, quando o código já está pronto. O Spec-Driven Development (SDD) tenta resolver isso escrevendo uma especificação antes do código.
Um exemplo de problema que só aparece depois está no meu projeto, o Brasileirão Pro Analytics. A primeira versão calculava as estatísticas dos times (posse, desarmes, gols) como acumulados da temporada inteira e usava esses valores para prever jogos da própria temporada. Na prática, o modelo "via" resultados que ainda não tinham acontecido, um caso de data leakage. Corrigi isso no commit b96e6ba, passando a calcular as features só com jogos anteriores a cada partida.
Neste artigo eu aplico o SDD em uma tarefa seguinte do mesmo projeto: transformar a temporada em parâmetro, para o código não depender de 2025 e 2026 escritos à mão. Depois comparo o resultado com o que a própria spec exigia. Os arquivos estão na branch experimento-sdd.
O que é Spec-Driven Development
SDD é escrever uma especificação antes de codar com IA e usar essa especificação como referência para a pessoa e para o agente. A Birgitta Böckeler, no site do Martin Fowler, separa três níveis de uso:
- spec-first: a spec é escrita antes e usada no fluxo de desenvolvimento com IA;
- spec-anchored: a spec é mantida depois que a tarefa termina, para evoluir e manter a funcionalidade;
- spec-as-source: a spec é o arquivo-fonte principal e a pessoa não mexe no código.
Ela também diferencia spec de memory bank. A spec descreve o comportamento de uma funcionalidade e vale para as tarefas que criam ou alteram essa funcionalidade. O memory bank reúne regras e descrições gerais do produto e da base de código, válidas para todas as sessões. No spec-kit, esse papel é da constitution, que guarda princípios de alto nível aplicados a toda mudança.
O texto do GitHub Blog (Den Delimarsky, 2 set. 2025) descreve o Spec Kit em quatro fases:
- specify: usuários, problema e critérios de sucesso, sem detalhe técnico;
- plan: stack, arquitetura e restrições;
- tasks: pedaços pequenos que dá para implementar e testar isoladamente;
- implement: o agente executa as tarefas e a pessoa revisa.
Na análise da Böckeler, o fluxo do spec-kit começa pela constitution, seguida de specify, plan e tasks.
A Thoughtworks colocou a técnica no anel Assess do Technology Radar de novembro de 2025, que significa que vale explorar para entender como ela afetará a organização. O Radar diz que os fluxos continuam elaborados e opinativos, que as ferramentas se comportam de forma bem diferente conforme o tamanho e o tipo da tarefa e que algumas geram arquivos de especificação longos e difíceis de revisar. A página do Radar indica que o item não está na edição atual, então a classificação vale para aquela edição.
O experimento
O Brasileirão Pro Analytics prevê o resultado de jogos do Campeonato Brasileiro. Ele lê os jogos de arquivos CSV, calcula as features usando só jogos anteriores a cada partida, treina uma regressão de Poisson com a temporada 2025 e testa com os jogos já realizados de 2026.
O ponto de partida foi o commit b9e399f. Nele, os anos 2025 e 2026 estavam escritos em src/features.py (valor padrão do argumento temporadas), em src/app.py e em src/avaliar_modelo.py. Os nomes dos arquivos já eram montados a partir do ano (partidas_{ano}.csv): o que estava fixo era o ano.
A tarefa foi esta: a temporada de treino e a de teste passam a ser parâmetros. Escolhi porque é pequena e tem critério de aceitação fácil de conferir.
Segui as fases do Spec Kit (constitution, specify, plan, tasks e implement). Os documentos ficaram em .spec/, uma pasta do próprio projeto, que não é a .specify/ usada pela CLI do Spec Kit. Em termos da Böckeler, foi um uso spec-first: as specs foram escritas antes da mudança e não foram atualizadas depois (as tarefas continuam sem marcação).
Passo a passo e artefatos
Constitution (.spec/constitution.md). Quatro regras: código compatível com Python 3.10+; zero data leakage, com features só a partir de eventos anteriores à rodada prevista; testes automatizados em /tests para novos métodos, lógicas de features ou mudanças de arquitetura; e README.md refletindo o estado atual e as limitações do modelo.
Specify (.spec/specify.md). Descreve o problema (anos fixos no código impedem usar 2027 sem editar vários lugares), o objetivo (receber ano de treino e de teste como parâmetros) e quatro critérios de aceite:
- os testes de
tests/test_features.pycontinuam passando; - a avaliação com 2025 e 2026 repete 48,0% de acurácia e 1,020 de log loss;
- o painel Streamlit renderiza como antes;
- nenhum ano sobra solto na lógica de carregamento de dados.
Plan (.spec/plan.md). Três mudanças: features.py passa a receber ano_treino e ano_teste; app.py ganha as constantes ANO_TREINO e ANO_TESTE; avaliar_modelo.py lê os anos de sys.argv, com 2025 e 2026 como padrão.
Tasks (.spec/tasks.md). Três tarefas, uma para cada arquivo do plano.
Implement (commit b21411b, 28/10/2026, 21:51). A mudança alterou src/app.py (8 linhas adicionadas, 4 removidas) e src/avaliar_modelo.py (15 adicionadas, 13 removidas). O features.py não mudou: o plano supunha chamadas de leitura com caminho fixo nesse arquivo, mas carregar_partidas já recebia temporadas e montava os nomes com o ano. Existe um único commit da implementação, então não há registro de erros ou correções no meio do caminho.
Verificação dos resultados
Comparei o commit com os critérios da spec e com as regras da constitution.
| Item | Resultado |
|---|---|
| Testes continuam passando | Sim: os 3 testes de tests/test_features.py passam |
| Mesmos resultados com 2025 e 2026 | Sim: python src/avaliar_modelo.py, com e sem os argumentos 2025 2026, repete 48,0% de acurácia e 1,0201 de log loss, com saída idêntica à de antes |
| Painel Streamlit renderiza como antes | Sim, aberto no navegador com streamlit run src/app.py (conferência manual, sem registro em experimento/) |
| Nenhum ano solto na lógica de carregamento | Parcial: features.py mantém temporadas=(2025, 2026) como padrão; app.py e avaliar_modelo.py mantêm 2025 e 2026 como padrão, como o plano previa |
| Constitution, regra 3: testes para o que é novo | Não: nenhum teste foi adicionado |
| Constitution, regra 4: README atualizado | Não: o README não menciona os argumentos de avaliar_modelo.py |
O arquivo experimento/depois_previsoes.txt é idêntico ao antes_previsoes.txt, mas esse teste não passa por app.py nem por avaliar_modelo.py, que são os arquivos alterados. O que valida a mudança é a comparação das métricas.
Outras temporadas (2027)
Não existe partidas_2027.csv no repositório, e ainda não há resultados de 2027. Em testes com arquivos criados só para esta verificação (nenhum está no repositório), o comportamento foi este:
- arquivo vazio: o
avaliar_modelo.pytermina comEmptyDataErrore o app mostra a mensagem de erro de leitura; - arquivo só com cabeçalho: os dois terminam com
ValueErrordoStandardScaler, por falta de amostras; - calendário com jogos sem placar: o app abre e mostra as previsões, mas exibe 0,0% de acurácia, que na verdade significa "sem jogos para avaliar"; o
avaliar_modelo.pyfalha pelo mesmoValueError.
O parâmetro funciona para anos que têm dados. O código ainda não trata uma temporada sem jogos realizados, e carregar um arquivo não valida o modelo: sem resultados não há acurácia nem log loss.
Tempo
O arquivo experimento/tempo.txt registra o início às 21:32, e o commit da implementação saiu às 21:51. Foram cerca de 20 minutos no total, com documentos, mudança no código e verificação. Não separei o tempo de cada etapa.
Benefícios e limitações
Os autores que li apontam estes benefícios. No texto do GitHub Blog:
- Menos adivinhação. Com um prompt vago o modelo presume muitos requisitos, e a spec reduz isso.
- O quê separado do como. A spec fixa a intenção, e o plano pode mudar sem reescrever tudo.
- Tarefas testáveis. Cada tarefa pequena pode ser implementada e testada isoladamente.
E estas limitações. Na análise da Böckeler:
- Tamanho do processo. O Kiro transformou um bug pequeno em 4 user stories e 16 critérios de aceitação. O spec-kit pareceu exagerado para uma funcionalidade de tamanho médio.
- Controle. O agente ignorou instruções e, em um caso, recriou classes que já existiam.
- Rigidez. Ela compara o spec-as-source com o MDD e teme herdar as desvantagens do MDD e dos LLMs, ou seja, a rigidez de um e a imprevisibilidade do outro.
O Radar da Thoughtworks acrescenta que podemos estar reaprendendo uma "lição amarga": escrever à mão regras detalhadas para a IA não escala.
No meu experimento, os critérios de aceite da spec funcionaram como lista de conferência. Compará-los com o commit mostrou lacunas que eu não tinha percebido: o padrão (2025, 2026) que continua em features.py, a falta de teste novo e de atualização do README, que eram regras da minha própria constitution, e o resultado do painel sem registro. Também mostrou que o plano descrevia o features.py de um jeito diferente do que ele era. A spec ajudou a achar esses problemas, mas depois da implementação, e não os evitou.
Sobre o tamanho do processo, foram quatro documentos curtos (40 linhas ao todo) para uma mudança em dois arquivos. É a proporção que a Böckeler questiona. Não comparei com um prompt direto.
Conclusão
Para uma funcionalidade pequena, como a parametrização de temporadas, o SDD me pareceu excessivo: quatro documentos para alterar dois arquivos. Essa é minha impressão, e ela se apoia em evidências limitadas. O tempo total foi de cerca de 20 minutos, sem divisão por etapa, e não repeti a tarefa com um prompt direto, então não posso dizer que o SDD foi mais lento ou menos eficiente do que essa alternativa.
O que a spec deu de concreto foi uma lista de critérios para conferir o resultado, e foi essa conferência que mostrou o que faltava. Minha hipótese é que o SDD compensa mais em mudanças com vários pontos de falha e critérios de aceitação mais amplos, como uma pipeline de web scraping ou a migração do banco de dados, e menos em refatorações pequenas, hotfixes ou na adição de um único parâmetro. Não testei esses cenários.
Este é um caso isolado (uma funcionalidade, um projeto) e não serve de regra geral. Os documentos, o código e os registros do experimento estão na branch experimento-sdd, para quem quiser conferir.
Referências
- BÖCKELER, Birgitta. Understanding Spec-Driven-Development: Kiro, spec-kit, and Tessl. martinfowler.com, 15 out. 2025.
- DELIMARSKY, Den. Spec-driven development with AI: Get started with a new open source toolkit. GitHub Blog, 2 set. 2025.
- THOUGHTWORKS. Spec-driven development. Technology Radar, edição de nov. 2025.
- GITHUB. Spec Kit. Repositório da ferramenta. Acesso em: 28 out. 2026.
- Projeto: Brasileirão Pro Analytics.

