test-driven-development (obra/superpowers)
Implementa recursos e correções com test-first, escrevendo primeiro o teste que falha.
superpowers test-driven-development: faz o agente escrever o teste primeiro, e custa cerca de 1.6x os tokens
Codex CLI · gpt-6-astra
24.0 / 30
Ganho sobre sem skill: +1.00 · Recomendado · 18 execuções
Recomendado: o total 24.0/30 é pelo menos 22, a qualidade da saída 5.0 é pelo menos 3.5 e o ganho +1.00 é pelo menos +1.0.
SOTA
AprovadoTestado com Codex.
Cobre Codex, Claude Code
Codex CLI 0.166 (nível SOTA): 18 execuções avaliadas. Uma aprovação aqui também vale para o Claude Code pela nossa regra de níveis; ela não diz nada sobre o segundo nível.
Notas
Cada dimensão vai de 0 a 5, e as seis somam o total de 30. 5 é melhor em todas as dimensões. Custo 5 significa barato e rápido. Instalação 5 significa fácil.
- Confiabilidade do acionamento
- 5.0
- Ganho sobre sem skill
- 3.0
- Qualidade da saída
- 5.0
- Custo de tokens e tempo
- 2.0
- Instalação e portabilidade
- 4.0
- Segurança
- 5.0
Revisão de segurança
SeguroVarredura estática: 0 CRÍTICO / 0 ALTO / 0 MÉDIO. Revisão manual: seguro para executar em sandbox sem rede (nenhum achado). Uma varredura limpa não prova que a skill é segura.
Instalar
npx skills@latest add obra/superpowers --skill test-driven-development
Commit fixado: 2ce8aa15d05bd57213e6f746f953aafb7ded7a8b
Testado: 2026-11-02
O que testamos
- Implementar uma função a partir de uma spec precisa — Implemente slugify(text, max_length=None) em slug.py (Python 3, apenas biblioteca padrão). Spec: deixe o texto em minúsculas; substitua cada sequência de caracteres que não sejam letras ASCII ou dígitos por um único '-'; remova '-' do início e do fim; um resultado vazio se torna 'n…
- Implementar uma pequena classe com estado — Escreva ratelimiter.py (Python 3, apenas biblioteca padrão) com a classe RateLimiter(limit, window_seconds, clock=time.monotonic): um limitador de janela deslizante por chave. allow(key) retorna True e registra a chamada se menos de limit chamadas foram registradas na última…
- Corrigir um bug de arredondamento — Clientes dizem que cart_total em cart.py às vezes fica um centavo fora em relação ao nosso sistema contábil, que arredonda valores com fração de meio para cima até o centavo a cada etapa (total de cada linha, subtotal com desconto e imposto). Por exemplo, cart_total([(1.005, 1)]) deveria retornar 1.09 e…
Prós
- Eleva a nota média de 4.0 para 5.0 em relação ao grupo sem skill (+1.00).
- A skill foi acionada sem ser nomeada: o arquivo da skill foi lido em 6/6 execuções de tratamento.
- Supera uma versão de uma frase da própria regra em +0.33.
- Qualidade absoluta alta com a skill: 5.0 de 5.
Contras
- Usa 1.65x os tokens do grupo sem skill.
- Ressalva do teste: o braço de uma frase (6 execuções) foi adicionado depois, em uma máquina diferente dos braços de controle e tratamento.
- n=2 por tarefa por braço; diferenças abaixo de cerca de 1 ponto são ruído.
Avaliação
Codex CLI 0.166 (gpt-6-astra, raciocínio baixo) em uma máquina de teste Mac, com um projeto temporário novo e HOME/TMPDIR/caches temporários a cada execução, skill instalada (tratamento) ou ausente (grupo de controle) ou ausente com o requisito central da skill comprimido em uma frase anexada ao prompt (grupo prompt de uma frase), 2 execuções por grupo por tarefa, rede desligada, gravações em /tmp bloqueadas. Os prompts nunca mencionam a skill. A pontuação é programática (testes ocultos / detecção de problemas plantados / checagens de restrição / render+OCR quando relevante), de 0 a 5 por execução. Nenhum juiz LLM atribuiu nenhuma nota.
Comparação entre os braços
| Braço | Nota média (0-5) | Tokens por execução |
|---|---|---|
| Sem a skill | 4.0 | 65k |
| Prompt de uma frase | 4.67 | 127k |
| Com a skill | 5.0 | 108k |
Medido com Codex CLI em 18 execuções, com pontuação por verificações baseadas em regras e sem juiz LLM. Total 24.0 / 30, veredito Recomendado.
Divulgação: O braço de uma frase (6 execuções) foi adicionado depois, em uma máquina diferente da dos braços de controle e de tratamento.
Veredicto: Recomendado (24.0 / 30). Fonte: obra/superpowers, skills/test-driven-development, fixado no commit 2ce8aa1. Instalação: npx skills@latest add obra/superpowers --skill test-driven-development. Licença: MIT (LICENSE do repositório).
O que é
A skill test-driven-development do obra/superpowers. A descrição dela diz: "Use quando estiver implementando qualquer recurso ou correção de bug, antes de escrever o código de implementação". Cerca de 1.500 palavras de Markdown (a "lei de ferro" red-green-refactor, uma tabela de desculpas para pular o teste, uma checklist de verificação) mais um arquivo extra sobre como escrever bons testes. Nenhum script.
Como testamos
Codex CLI 0.166 (gpt-6-astra, raciocínio baixo) em uma máquina de teste Mac, com um projeto temporário novo e HOME/TMPDIR/caches temporários a cada execução, skill instalada (tratamento), ausente (controle) ou ausente com o requisito central da skill comprimido em uma frase anexada ao prompt (grupo de uma frase), 2 execuções por grupo por tarefa, rede desligada, gravações em /tmp bloqueadas. Os prompts nunca mencionam a skill.
- Implementar uma função a partir de uma especificação precisa — Implemente
slugify(text, max_length=None)em slug.py (Python 3, somente biblioteca padrão). Especificação: converta o texto para minúsculas; substitua cada sequência de caracteres que não sejam letras ASCII ou dígitos por um único "-"; remova "-" do início e do fim; um resultado vazio se torna "n… - Implementar uma pequena classe com estado — Escreva ratelimiter.py (Python 3, somente biblioteca padrão) com a classe
RateLimiter(limit, window_seconds, clock=time.monotonic): um limitador de janela deslizante por chave.allow(key)retorna True e registra a chamada se menos delimitchamadas foram registradas na última… - Corrigir um bug de arredondamento — Clientes dizem que
cart_totalem cart.py às vezes fica um centavo errado em comparação com nosso sistema contábil, que arredonda meio para cima até o centavo em cada etapa (total de cada linha, subtotal com desconto e imposto). Por exemplo, cart_total([(1.005, 1)]) deveria retornar 1.09 e…
A pontuação é programática (testes ocultos / identificação de problemas plantados / verificações de restrições / renderização + OCR quando aplicável), de 0 a 5 por execução. Nenhum juiz LLM decidiu qualquer pontuação.
Resultados
A frase única dada ao terceiro grupo: "Siga red-green-refactor estrito: escreva um teste que falha primeiro e veja-o falhar pelo motivo certo, escreva a implementação mínima para passá-lo e depois refatore; nenhum código de produção sem um teste que falhe antes."
| Tarefa | Pontuação do controle | Uma frase | Com a skill | Tokens do controle | Tokens de uma frase | Tokens com a skill | Skill lida |
|---|---|---|---|---|---|---|---|
| t1-slugify | 4.0 | 5.0 | 5.0 | 62k | 134k | 108k | 2/2 |
| t2-ratelimiter | 4.0 | 5.0 | 5.0 | 63k | 147k | 97k | 2/2 |
| t3-cart-bugfix | 4.0 | 4.0 | 5.0 | 69k | 97k | 116k | 2/2 |
Pontuação média: 4.0 sem a skill vs. 5.0 com a skill (delta +1.0). Tokens por execução: 65k vs. 108k (1.65x); tempo 55s vs. 51s. Grupo de uma frase: 4.67 (ganho da skill sobre a frase única: +0.33; ganho da própria frase única sobre sem skill: +0.67); 127k tokens por execução no grupo de uma frase, então a skill custa 0.85x a frase única.
O que aconteceu
- A correção foi idêntica: as suítes de teste ocultas passaram em todas as 12 execuções dos dois grupos (12/12, 10/10 e 11/11 testes). Nessas tarefas pequenas, a skill não altera se o código funciona.
- O que ela altera é a ordem do trabalho. Em todas as 6 execuções de tratamento, o arquivo de teste foi escrito em uma etapa anterior à implementação; em todas as 6 execuções de controle, o agente escreveu testes e implementação no mesmo patch (ou corrigiu o bug primeiro e adicionou o teste depois, na tarefa do carrinho). Na execução de tratamento que lemos por completo (slugify), o agente escreveu o teste, rodou para vê-lo falhar e depois escreveu o código.
- Ela é acionada só pela descrição: o arquivo da skill foi lido em 6/6 execuções de tratamento, embora nenhum prompt mencionasse TDD.
- Custa mais: cerca de 1.65x os tokens por execução (107k vs. 65k) com tempo de relógio semelhante (51 s vs. 55 s), porque o agente lê a skill e seu arquivo complementar e roda o ciclo várias vezes.
- Versão de uma frase (red-green-refactor estrito, nenhum código de produção sem um teste que falhe): média 4.67, entre o controle (4.0) e a skill (5.0), com 127k tokens por execução contra 65k do controle (2.0x) e 108k da skill (1.2x a skill).
- Os testes foram escritos antes da implementação em 0 de 6 execuções de controle, 4 de 6 de uma frase e 6 de 6 da skill; as duas execuções de uma frase que não fizeram isso são da tarefa de correção do carrinho. O grupo da skill é o único que fez isso todas as vezes, e fez com menos comandos (10 por execução) do que a frase única (19).
Pontuação por dimensão
| Dimensão | Pontuação | Por quê |
|---|---|---|
| 1_output_quality | 5.0 | Pontuação média de 5.00/5 com a skill (verificações programáticas; consulte a tabela por tarefa). |
| 2_lift_vs_no_skill | 3.0 | +1.00 ponto vs. 4.00 sem a skill (n=2 por tarefa; abaixo de ~1 ponto é ruído). |
| 3_trigger | 5.0 | Arquivo da skill lido em 6/6 execuções com a skill. |
| 4_instructions_portability | 4 | |
| 5_efficiency | 2 | 1.65x tokens (108k vs. 65k por execução) e 0.93x tempo (51s vs. 55s). |
| 6_safety_hygiene | 5 |
Limites deste teste
- Os testes ocultos passam em ambos os grupos (efeito teto), então o ganho medido é a verificação de processo (teste escrito antes da implementação), que calculamos a partir do log de eventos, não uma diferença de resultado.
- As tarefas são pequenas, exercícios Python de um único arquivo; repositórios maiores, outras linguagens e a qualidade dos testes (por exemplo, teste de mutação) não foram testados.
- n = 2 por grupo por tarefa: diferenças abaixo de cerca de 1 ponto são ruído.
- A pontuação por regras mede o que as verificações conseguem ver; não julga bom gosto nem se o resultado é o melhor possível.
Segurança
Consulte security.md. Scan: 0 CRITICAL / 0 HIGH / 0 MEDIUM. Veredicto: segura para execução (sandbox sem rede). Um scan limpo não prova que uma skill é segura.
Conclusão
A skill faz o que diz: o grupo da skill foi o único que escreveu o teste que falha primeiro em todas as execuções (6/6, contra 0/6 do controle e 4/6 da versão de uma frase), com 1.7x os tokens do controle e 0.85x os da versão de uma frase. A correção final nessas tarefas pequenas foi a mesma em todos os grupos, então o ganho é o processo, não o código.
Transcrição
Log de execuções: test-driven-development (Codex CLI, network off, per-run temp HOME/TMPDIR, one row per graded run.) Colunas: tarefa, grupo-execução, nota (0-5), tokens, segundos, verificações aprovadas, arquivos da skill abertos pelo agente. t1-slugify control-1: nota 4.0, tokens 62017, s 55.5, verificações 2/3, nada aberto t1-slugify control-2: nota 4.0, tokens 62139, s 53.8, verificações 2/3, nada aberto t1-slugify oneliner-1: nota 5.0, tokens 135535, s 52.9, verificações 3/3, nada aberto t1-slugify oneliner-2: nota 5.0, tokens 134448, s 46.7, verificações 3/3, nada aberto t1-slugify treatment-1: nota 5.0, tokens 118034, s 56.3, verificações 3/3, abriu test-driven-development t1-slugify treatment-2: nota 5.0, tokens 97974, s 48.3, verificações 3/3, abriu test-driven-development t2-ratelimiter control-1: nota 4.0, tokens 63363, s 46.1, verificações 2/3, nada aberto t2-ratelimiter control-2: nota 4.0, tokens 63431, s 98.9, verificações 2/3, nada aberto t2-ratelimiter oneliner-1: nota 5.0, tokens 140042, s 60.8, verificações 3/3, nada aberto
18 execuções, 3 artefatos
Resultado de exemplo
SOTA · With the skill: test_slug.py (t1-slugify, run 1, Codex)
import unittest from slug import slugify class SlugifyTests(unittest.TestCase): def test_normalizes_text(self): cases = [ ('Hello, World!', 'hello-world'), (' --ABC__123\t\nxyz!! ', 'abc-123-xyz'), ('café déjà vu 12٣', 'caf-d-j-vu'), ('İ X', 'i-x'), ('already-a-slug', 'already-a-slug'), ] for text, expected in cases: with self.subTest(text=text): self.assertEqual(slugify(text), expected) def test_empty_result_uses_fallback(self): for text in ('', '--- !\t', '中文', '😀'): with self.subTest(text=text): self.assertEqual(slugify(text), 'n-a') def test_length_limits_respect_word_boundaries(self): cases = [ ('Hello, World!', 8, 'hello'), ('Hello, World!', 11, 'hello-world'), ('Hello, World!', 20, 'hello-world'), ('Hello, World!', 5, 'hello'), ('Hello, World!', 6, 'hello'), ('one two three', 7, 'one-two'), ('one two three', 9, 'one-two'), ('Supercalifragilistic', 5, 'super'), ('Supercalifragilistic next', 5, 'super'), ('abc', 1, 'a'), ('abc', 0, ''), ('!!!', 1, 'n'), ('!!!', 2, 'n'), ('!!!', 3, 'n-a'), ] for text, limit, expected in cases: with self.subTest(text=text, limit=limit): self.assertEqual(slugify(text, limit), expected) def test_explicit_none_leaves_length_unlimited(self): self.assertEqual(slugify('Hello, World!', None), 'hello-world') if __name__ == '__main__': unittest.main()