Spec-Driven Development
Especificar é reduzir ambiguidades sobre o que será construído, para quem e como será aceito. Uma boa spec não precisa antecipar cada linha de código, mas precisa conectar necessidade, comportamento e evidência. Nesta semana você organizará PRD, histórias, contratos, plano e testes em um fluxo coerente.
O caso é importar pedidos e apresentar rejeições ao operador. A funcionalidade toca interface, serviço e persistência, oferecendo dependências reais para decompor. Você aprenderá a detectar discrepâncias antes de chamar uma implementação de concluída.
JavaScriptAPIsProgramaçãoAo terminar esta aula
- Specs conectam necessidade e verificação.
- Dependências definem paralelismo seguro.
- Discrepâncias são comparadas, não escondidas.
Antes de continuar: Laboratório: Skills, scripts, progressive disclosure
PRD, requisitos e user stories
FundamentosUm PRD registra problema, público, objetivo, escopo e critérios de sucesso do produto. Para importação, o problema pode ser retrabalho causado por linhas inválidas sem explicação. A solução precisa mostrar rejeições e permitir correção, mas não necessariamente criar um editor completo de planilhas. Distinguir objetivo de solução evita transformar uma necessidade pequena em um sistema amplo. Registre também o que está fora do escopo para controlar dependências e revisão.
↗ Product requirements document↗ Spec Kit specification template
User stories descrevem uma necessidade do ponto de vista de quem usa: como operador, quero saber quais linhas falharam para corrigir o arquivo. A história não substitui detalhes de comportamento. Requisitos explicam limites de arquivo, formatos, autorização e resultado quando parte das linhas falha. Se isso ficar implícito, interface e serviço podem implementar políticas incompatíveis. Critérios de sucesso do produto, como reduzir retrabalho, precisam de medição definida; não invente um percentual de melhoria antes de avaliar o uso real.
↗ Product requirements document↗ Spec Kit specification template
Acceptance criteria e specs funcional e técnica
FundamentosAcceptance criteria são condições verificáveis que permitem aceitar a entrega. “Importação funciona” é vago. “Ao enviar arquivo com uma linha negativa, o sistema rejeita essa linha e mostra número e motivo, sem expor dados de outra conta” é observável. Inclua caso nominal, fronteiras e falhas relevantes. A spec funcional explica o comportamento para o usuário; a técnica descreve arquitetura, dados, contratos e restrições que permitem implementá-lo. Elas se conectam, mas não têm o mesmo público ou finalidade.
Uma spec técnica pode definir endpoint, idempotência de lote e armazenamento do relatório. Não enterre uma regra de negócio apenas em um detalhe de código. Se a política é aceitar linhas válidas mesmo quando outras falham, isso pertence ao comportamento do produto e ao contrato. Exemplos concretos de entrada e saída ajudam a revelar inconsistência. Templates de ferramentas são pontos de partida, não prova de completude. Adapte seções ao risco e mantenha rastreabilidade entre requisito e verificação.
Contratos e schemas como fronteiras
FundamentosUm contrato de API descreve operações, entradas, saídas e erros. OpenAPI organiza esse contrato para interfaces HTTP; JSON Schema descreve estruturas de dados. Defina campo obrigatório, unidade monetária e código de rejeição. O frontend não deve interpretar frases livres para saber se uma linha é inválida. Um código estável como VALOR_NEGATIVO permite apresentação e teste, enquanto a mensagem explica o motivo ao operador.
Schema não valida sozinho autorização ou semântica completa. O serviço recebe o escopo do contexto confiável e verifica cada lote. Exemplos devem incluir rejeição parcial e repetição da mesma intenção. Uma alteração de contrato precisa considerar consumidores, como visto na semana de skills. Evite gerar cliente e servidor a partir de uma spec que ainda contém contradições: automação replica o contrato, inclusive seus erros. Revise unidades, estados e tratamento de falhas antes de produzir código derivado.
Task breakdown, dependências e implementation plan
FundamentosDivida trabalho por resultados verificáveis: contrato de importação, validação, persistência do lote, interface de rejeições e E2E. Um dependency graph mostra o que precisa existir antes de outra etapa. A interface pode usar um mock do contrato enquanto o serviço é implementado, mas a integração precisa validar a equivalência. Tarefas independentes podem ocorrer em paralelo quando suas fronteiras estão claras. Não distribua a mesma função entre agentes sem coordenação.
↗ Spec Kit tasks template↗ GitHub Spec Kit↗ Effective harnesses for long-running agents
O implementation plan informa sequência, arquivos relevantes, verificação e riscos por etapa. Não é apenas uma lista de substantivos como “backend, frontend, testes”. Cada tarefa precisa de entrada, saída e critério de conclusão. Inclua checkpoints para confirmar contrato antes de expandir implementação. O plano pode mudar quando novas evidências revelam uma restrição, mas a mudança precisa atualizar requisitos e aceitação. Completar tarefas antigas de um plano desatualizado não significa completar o produto pretendido.
↗ Spec Kit tasks template↗ GitHub Spec Kit↗ Effective harnesses for long-running agents
Discrepancy analysis e E2E
FundamentosDiscrepancy analysis compara intenção especificada, implementação e evidência. Pode encontrar requisito não implementado, comportamento extra ou verificação insuficiente. Para importação, o serviço pode devolver motivos corretos, mas a interface mostrar apenas “erro”; o requisito de correção pelo operador ainda falha. Use uma matriz que conecte critério, componente e teste, evitando considerar cobertura de linhas como substituto de comportamento.
↗ Playwright Best Practices↗ Effective harnesses for long-running agents
E2E com Playwright pode enviar um arquivo e observar o resultado visível. Use dados controlados e testes independentes, com seletores ligados à experiência do usuário. Não teste detalhes internos desnecessários nem dependa de uma ordem acidental de execução. Um E2E aprovado prova o cenário exercitado, não todos os arquivos possíveis. Combine com testes de regra e contrato. Ao concluir, registre discrepâncias resolvidas e conhecidas, explicando impacto e próximo passo, em vez de declarar completude apenas porque o plano possui todas as caixas marcadas.
↗ Playwright Best Practices↗ Effective harnesses for long-running agents
Exemplo comentado e limites
FundamentosA matriz mostra que dois critérios implementados não compensam o terceiro pendente. A importação ainda não está concluída conforme o contrato, embora a validação local possa funcionar. O programa usa estados fictícios para ensinar rastreabilidade; feito precisa corresponder a evidência real no projeto.
const criterios = [
{id:"AC1",descricao:"Linha negativa rejeitada",verificacao:"teste-validacao",feito:true},
{id:"AC2",descricao:"Motivo visível ao operador",verificacao:"e2e-interface",feito:false},
{id:"AC3",descricao:"Escopo autorizado",verificacao:"teste-integracao",feito:true}
];
console.log({concluido:criterios.every(x=>x.feito),
pendencias:criterios.filter(x=>!x.feito).map(x=>x.id)});O campo verificacao indica a natureza da evidência, não um resultado executado. Em uma entrega real, acrescente referência ao comando, artefato ou teste observado. Um critério de interface não deveria ser marcado apenas porque o serviço devolve um código correto. A fronteira entre componentes é justamente onde discrepâncias aparecem.
Exercício aplicado
Especifique importação parcial de pedidos com rejeição visível e vincule cada critério a uma verificação.
- Tente definir comportamento e tradeoff de importação.
- Escreva exemplos e schemas coerentes.
- Decomponha tarefas com checkpoints.
- Avalie jornada e registre discrepâncias com evidência.
Abrir resolução comentada
A solução começa pelo PRD e inclui uma história de correção de erros. Define importação parcial, contrato de motivos e autorização. O plano permite frontend trabalhar com mock versionado, mas exige integração final e E2E para o fluxo do operador.
A conclusão depende de todos os critérios pertinentes verificados. Se o cenário de interface falha, revise a implementação ou o requisito explicitamente; não reclassifique o critério como opcional depois de ver o resultado. O relatório registra o que falta e o impacto no uso.
A resolução mantém necessidade, contrato e teste ligados. Um plano bom termina com comportamento demonstrado para o operador; não basta cumprir uma lista de alterações internas.
A solução contém PRD, contrato, tarefas com dependências e uma fatia funcional local de validação e apresentação de rejeições. Os asserts verificam regra, escopo, versão do contrato e número/motivo. A matriz liga os critérios à evidência realmente executada e mantém E2E de interface como pendência explícita. Essa resolução não chama uma apresentação textual de teste de navegador: a feature integrada só é concluída quando upload, interface e Playwright forem executados no projeto-alvo.
import assert from "node:assert/strict";
const prd={problema:"Operador não sabe corrigir linhas rejeitadas",usuario:"operador autorizado",
objetivo:"Apresentar número e motivo",escopo:"importação parcial",foraEscopo:["editor completo de planilha"]};
const contrato={versao:1,entrada:{id:"string",valor:"inteiro em centavos"},
saida:{aceitas:"lista",rejeitadas:"linha, codigo, motivo"},escopo:"contexto autenticado"};
function importar(linhas,ctx){const aceitas=[],rejeitadas=[];
linhas.forEach((l,i)=>{if(l.tenant!==ctx.tenant)rejeitadas.push({linha:i+1,codigo:"ESCOPO_INVALIDO",motivo:"Escopo não autorizado"});
else if(!Number.isSafeInteger(l.valor)||l.valor<0)rejeitadas.push({linha:i+1,codigo:"VALOR_INVALIDO",motivo:"Valor deve ser inteiro não negativo"});
else aceitas.push({id:l.id,valor:l.valor});});return {versao:1,aceitas,rejeitadas};}
function renderizar(resultado){return "Rejeições: "+resultado.rejeitadas.map(x=>"Linha "+x.linha+": "+x.motivo).join("; ");}
const resultado=importar([{tenant:"A",id:"p1",valor:100},{tenant:"A",id:"p2",valor:-1},
{tenant:"B",id:"p3",valor:100}],{tenant:"A"});
assert.equal(resultado.aceitas.length,1);assert.equal(resultado.rejeitadas[0].linha,2);
assert.ok(renderizar(resultado).includes("Linha 2: Valor deve ser inteiro não negativo"));
assert.ok(!resultado.aceitas.some(x=>x.id==="p3"));assert.equal(resultado.versao,contrato.versao);
const criterios=[{id:"AC1",entrada:"linha negativa",resultado:"rejeição com motivo",evidencia:"assert local do serviço"},
{id:"AC2",entrada:"resultado com rejeição",resultado:"número e motivo visíveis",evidencia:"assert de apresentação textual",
pendencia:"E2E da interface real não executado"},
{id:"AC3",entrada:"outro tenant",resultado:"escopo rejeitado",evidencia:"assert local de contexto"}];
const tarefas=[{id:"contrato",depende:[],saida:"schema e exemplos"},{id:"servico",depende:["contrato"],saida:"validação"},
{id:"interface",depende:["contrato"],saida:"apresentação"},{id:"e2e",depende:["servico","interface"],saida:"jornada verificada"}];
assert.ok(tarefas.every(t=>t.depende.every(id=>tarefas.some(x=>x.id===id))));
assert.ok(criterios.every(c=>c.evidencia||c.pendencia));
console.log({status:"verificações locais aprovadas",prd,contrato,resultado,criterios,tarefas,
discrepancia:"apresentação local existe; upload e E2E no produto continuam pendentes"});Como conferir seu resultado
- Critérios têm entradas e resultados observáveis.
- Mocks respeitam contrato versionado.
- Cada conclusão aponta evidência ou pendência.
Aplique em um problema novo
Primeiro resolva sem consultar a resposta. Explique suas decisões e guarde a evidência. A conclusão de leitura é independente desta autoavaliação.
Confira seus pré-requisitos
- Escrever comportamento observável.
- Relacionar contrato e dependências.
Importação parcial tem rejeições no serviço, mas UI mostra só erro. Está concluída? Defina dependências.
Conferir raciocínio e critérios de domínio
Operador precisa identificar linha/motivo; história não terminou.
Contrato com índice/motivo permite mock frontend e integração.
E2E da jornada precisa evidência; não tornar critério opcional após falha.
Evidências para autoavaliação ou revisão por pares
- Necessidade: Operador precisa identificar linha/motivo; história não terminou.
- Contrato: Contrato com índice/motivo permite mock frontend e integração.
- Aceitação: E2E da jornada precisa evidência; não tornar critério opcional após falha.
Um erro frequente
Testes internos concluem a história.
A história inclui critérios da jornada, além dos testes internos.
Teste sua compreensão
Responda com suas palavras antes de abrir o comentário. Saber explicar uma decisão é parte do domínio.
1. User story substitui contrato técnico?
Não.
Ela comunica necessidade, enquanto contratos especificam fronteiras e dados.
2. Task concluída prova requisito aceito?
Não.
É necessário ligar implementação à verificação do critério.
3. E2E aprovado prova todos os arquivos possíveis?
Seu progresso fica salvo neste navegador. Concluir a leitura não substitui demonstrar o domínio nos exercícios.
Referências e aprofundamento
Documentação oficial e trabalhos originais. As referências registram o escopo e as limitações para você conferir o que sustentam.
- Product requirements document
Atlassian • consulta: 2026-10-06
FundamentosObjetivos, escopo, requisitos e comunicação de decisões em PRD.
Limites: Formato sugerido pelo fornecedor; adaptar ao produto e evitar burocracia desnecessária.
- Spec Kit specification template
GitHub • consulta: 2026-10-06
FundamentosUser stories, acceptance scenarios, requisitos e critérios verificáveis.
Limites: Template no ramo main; adaptar ao projeto, sem confundir template com especificação concluída.
- Playwright Best Practices
Microsoft / Playwright • consulta: 2026-10-06
FundamentosTestes E2E de comportamento visível, isolamento, locators e assertions confiáveis.
Limites: Documentação dinâmica; fixar a versão usada no laboratório e conferir compatibilidade antes de executar.
- GitHub Spec Kit
GitHub • consulta: 2026-10-06
FundamentosFluxo requirements → specification → technical plan → tasks → implement/converge; consistência e checklists.
Limites: Ferramenta concreta para ensinar SDD, não padrão universal; comandos atuais podem diferir de tutoriais antigos.
- OpenAPI Specification 3.1.1
OpenAPI Initiative • consulta: 2026-10-06
FundamentosContrato HTTP, schemas, operações, parâmetros e respostas.
Limites: Versão fixada 3.1.1; suporte das ferramentas a JSON Schema/OpenAPI deve ser verificado.
- Structured model outputs
OpenAI • consulta: 2026-10-06
OpenAIJSON Schema, saída estruturada, strict mode e distinção entre resposta estruturada e function calling.
Limites: Suporte a subconjunto JSON Schema e modelos específicos; JSON válido não garante verdade factual ou regra de negócio.
- Spec Kit tasks template
GitHub • consulta: 2026-10-06
FundamentosQuebra de tarefas, dependências, ordenação e execução paralela quando aplicável.
Limites: Dependency graph explícito do curso é representação editorial derivada das dependências do plano.
- Effective harnesses for long-running agents
Anthropic • consulta: 2026-10-06
AgentesHarness, artefatos persistentes, progresso incremental, recuperação e testes de aplicação.
Limites: Relato de engenharia; harness mínimo e gates do curso são síntese pedagógica, não implementação fornecida completa.