Skip to content

spec-driven ​

Os artefatos do fluxo de trabalho padrão: sua ordem, seus formatos e a pasta de alteração que eles produzem.

spec-driven é o esquema padrão integrado do OpenSpec. schema.yaml define os campos que ele define.

Artefatos ​

O fluxo de trabalho elabora quatro artefatos:

ArtefatoArquivoFinalidade
proposalproposal.mdPor que a alteração é necessária
specsspecs/<capability-path>/spec.md, um por capacidadeQuais comportamentos mudam
designdesign.mdComo construí-lo
taskstasks.mdA checklist de implementação

Ordem de elaboração ​

text
             ┌─ specs ──┐
proposal ────┤          ├── tasks ── apply
             └─ design ─┘

A proposal vem primeiro. Specs e design seguem em qualquer ordem, e tasks precisa de ambos. A implementação (apply) começa assim que o tasks.md está pronto.

Dois artefatos podem ser omitidos:

  • design: quando nenhuma das suas condições se aplica, o agente o deixa de fora e elabora tasks mesmo assim.
  • specs: defina skip_specs: true no .openspec.yaml da alteração.

Exemplo de pasta de alteração ​

Uma alteração chamada add-user-auth, com todos os artefatos elaborados:

text
openspec/changes/add-user-auth/
├── .openspec.yaml      metadados da alteração, escrito quando a alteração é criada
├── proposal.md
├── specs/
│   └── user-auth/
│       └── spec.md     um spec delta por capacidade
├── design.md
└── tasks.md

proposal.md ​

Estabelece por que a alteração é necessária.

Estrutura ​

O template que o agente recebe como formato de saída (templates/proposal.md):

md
# Proposta

## Por quê

<!-- Explique a motivação para esta alteração. Que problema isso resolve? Por que agora? -->

## O Que Muda

<!-- Descreva o que será alterado. Seja específico sobre novas capacidades, modificações ou remoções. -->

## Capacidades

### Novas Capacidades
<!-- Capacidades sendo introduzidas. Nomeie cada capacidade para um comportamento de sistema
     coeso que possa abrigar requisitos relacionados conforme o sistema evolui. Não nomeie
     tarefas de implementação ou seções da proposta. Evite nomes genéricos abrangentes. Use
     kebab-case para segmentos de caminho que você introduzir (por exemplo, user-auth ou identity/user-auth)
     que sigam a organização de specs existente do projeto. Cada uma cria
     specs/<capability-path>/spec.md. -->
- `<capability-path>`: <descrição breve do que essa capacidade abrange>

### Capacidades Modificadas
<!-- Capacidades existentes cujos REQUISITOS estão mudando (não apenas implementação).
     Liste aqui apenas se o comportamento no nível do spec muda. Cada uma precisa de um arquivo de spec delta.
     Use o caminho existente exato sob openspec/specs/. Deixe vazio se não houver mudança de requisito.
     Uma alteração sem nenhuma capacidade (refatoração pura, ferramentação, docs)
     deve definir `skip_specs: true` em seu .openspec.yaml - openspec validate rejeita
     uma alteração de delta zero sem esse marcador. Não invente um requisito apenas para
     satisfazer a validação. -->
- `<existing-capability-path>`: <qual requisito está mudando>

## Impacto

<!-- Código afetado, APIs, dependências, sistemas -->

Instruções ​

A instrução enviada ao agente quando ele elabora este artefato (de schema.yaml):

md
Crie o documento de proposta que estabelece POR QUE esta alteração é necessária.

Seções:
- **Por quê**: 1-2 frases sobre o problema ou oportunidade. Que problema isso resolve? Por que agora?
- **O Que Muda**: Lista de alterações em marcadores. Seja específico sobre novas capacidades, modificações ou remoções. Marque alterações que quebram compatibilidade com **BREAKING**.
- **Capacidades**: Identifique quais specs serão criados ou modificados:
  - **Novas Capacidades**: Liste as capacidades sendo introduzidas. Cada uma se torna um novo `specs/<capability-path>/spec.md`. Nomeie cada capacidade para um comportamento de sistema duradouro (por exemplo, `user-auth`), não o trabalho nesta alteração (por exemplo, `add-login-endpoint`). Escolha um limite coeso que possa abrigar requisitos relacionados conforme o sistema evolui; evite capacidades genéricas abrangentes. Use kebab-case para segmentos de caminho que você introduzir (por exemplo, `user-auth` ou `identity/user-auth`) e siga a organização de specs existente do projeto.
  - **Capacidades Modificadas**: Liste as capacidades existentes cujos REQUISITOS estão mudando. Inclua apenas se o comportamento no nível do spec mudar (não apenas detalhes de implementação). Cada uma precisa de um arquivo de spec delta. Use o caminho existente exato sob `openspec/specs/`. Deixe vazio se não houver mudança de requisito.
- **Impacto**: Código afetado, APIs, dependências ou sistemas.

IMPORTANTE: A seção de Capacidades é crítica. Ela cria o contrato entre
as fases de proposta e specs. Pesquise os specs existentes antes de preencher isso:
execute `openspec list --specs` para o inventário de capacidades do projeto, depois
`openspec show "<spec-id>" --type spec --json --no-scenarios` para quaisquer que
pareçam relacionados - isso retorna o propósito e os textos de requisitos de uma
capacidade sem trazer arquivos de spec inteiros para o contexto. Anexe `--store "<id>"`
aos dois comandos apenas para um repositório independente registrado, e mantenha `--type
spec`: uma alteração e um spec compartilhando um nome é, caso contrário, um erro de
item ambíguo. `openspec list` sem `--specs` lista alterações em andamento, não
specs - nunca mostra o que o projeto já abrange. Reutilize o caminho exato de uma
capacidade existente em vez de introduzir um nome quase duplicado.
A leitura filtrada é apenas uma visão geral. Antes de decidir o que já está
abordado ou o que deve mudar, leia cada spec relevante na íntegra, incluindo
cenários, com `openspec show "<spec-id>" --type spec` (mesma regra de `--store`).
Cada capacidade listada aqui precisará de um arquivo de spec correspondente.

Toda alteração deve declarar pelo menos uma capacidade (nova ou
modificada) ou explicitamente optar por não ter specs: `openspec validate` rejeita uma
alteração com zero deltas a menos que o `.openspec.yaml` da alteração defina
`skip_specs: true`. Use `skip_specs: true` apenas quando não há mudança de
comportamento no nível do spec (refatoração pura, ferramentação, docs) - specs descrevem
comportamento, então se o comportamento não muda, nenhum spec deve mudar também.
Não invente um requisito apenas para satisfazer a validação.

Mantenha conciso (1-2 páginas). Foque no "porquê" não no "como" -
detalhes de implementação pertencem ao design.md.

Esta é a fundação - specs, design e tasks todos se baseiam nisso.

Specs delta (spec.md) ​

Define qual comportamento muda, com um spec delta por capacidade que a proposta lista.

Cada spec delta é o spec.md dentro da pasta de sua capacidade. openspec validate e openspec archive rejeitam seções delta escritas em qualquer outro arquivo sob specs/, como specs/user-auth.md, porque o archive nunca os mescla.

Estrutura ​

O template que o agente recebe como formato de saída (templates/spec.md):

md
# Spec Delta

## Propósito
<!-- Apenas novas capacidades: uma ou duas frases (50+ caracteres) sobre para que essa capacidade serve. Exclua esta seção para uma capacidade existente. -->

## Requisitos ADICIONADOS

### Requisito: <!-- nome do requisito -->
<!-- texto do requisito -->

#### Cenário: <!-- nome do cenário -->
- **QUANDO** <!-- condição -->
- **ENTÃO** <!-- resultado esperado -->

Instruções ​

A instrução enviada ao agente quando ele elabora este artefato (de schema.yaml):

md
Crie arquivos de especificação que definam O QUE o sistema deve fazer.

Um spec é um contrato de comportamento, não um plano de implementação.

Bom conteúdo para spec:
- Comportamento observável no qual usuários ou sistemas downstream confiam
- Entradas, saídas e condições de erro
- Restrições externas (segurança, privacidade, confiabilidade, compatibilidade)
- Cenários que podem ser testados ou explicitamente validados

Evite em specs:
- Nomes internos de classes/funções
- Escolhas de bibliotecas ou frameworks
- Detalhes de implementação passo a passo
- Planos de execução detalhados (esses pertencem ao design.md ou tasks.md)

Teste rápido: se a implementação pode mudar sem alterar o comportamento
visível externamente, provavelmente não pertence ao spec.

Crie um arquivo de spec por capacidade listada na seção de Capacidades da proposta.
`<capability-path>` é o diretório do spec relativo a `specs/` (por exemplo,
`user-auth` ou `identity/user-auth`). Preserve o caminho completo:
- Novas capacidades: use o caminho exato da proposta em `specs/<capability-path>/spec.md`. Qualquer segmento de caminho introduzido recentemente na proposta deve estar em kebab-case. Siga a organização existente do projeto; não adicione um novo nível de domínio quando o projeto usa um layout plano.
- Capacidades modificadas: use o caminho existente exato de `openspec/specs/<capability-path>/` ao criar o delta em `specs/<capability-path>/spec.md`. Execute `openspec list --specs` para confirmar esse caminho antes de escrever o delta, anexando `--store "<id>"` apenas para um repositório independente registrado - um caminho com erro de digitação ou inventado aponta para uma capacidade que não existe em vez da que você pretendia. Não mova ou renomeie a capacidade.

Escreva os arquivos de spec um de cada vez, para que o usuário veja o progresso e
uma execução interrompida mantenha os arquivos que já foram escritos:
- Antes de escrever qualquer coisa, compare as capacidades que a proposta lista
  com os arquivos `specs/<capability-path>/spec.md` que já existem,
  e comece com a primeira capacidade que não tem arquivo. Não reescreva
  um arquivo existente a menos que o usuário peça.
- Antes de cada arquivo, diga em uma linha qual capacidade você está escrevendo.
- Escreva cada arquivo assim que tiver elaborado o rascunho. Não planeje todos os arquivos
  antes de escrever o primeiro.
- Pare quando cada capacidade que a proposta lista tiver seu arquivo.

Deve haver pelo menos um arquivo de spec a menos que o `.openspec.yaml` da alteração
defina `skip_specs: true` (sem mudança de comportamento no nível do spec) - `openspec validate`
rejeita uma alteração de delta zero sem esse marcador. Se a proposta não lista
nenhuma capacidade e `skip_specs` não está definido, revise a proposta primeiro.

Operações delta (use cabeçalhos ##):
- **Requisitos ADICIONADOS**: Novas capacidades
- **Requisitos MODIFICADOS**: Comportamento alterado - DEVE incluir conteúdo atualizado completo
- **Requisitos REMOVIDOS**: Funcionalidades obsoletas - DEVE incluir **Motivo** e **Migração**
- **Requisitos RENOMEADOS**: Apenas mudanças de nome - use formato DE:/PARA:

Requisitos de formato:
- Cada requisito: `### Requisito: <nome>` seguido de descrição
- Use SHALL/MUST (DEVE/DEVER) para requisitos normativos (evite should/may)
- Cada cenário: `#### Cenário: <nome>` com formato QUANDO/ENTÃO
- **CRÍTICO**: Cenários DEVEM usar exatamente 4 hashtags (`####`). Usar 3 hashtags ou marcadores falhará silenciosamente.
- Todo requisito DEVE ter pelo menos um cenário.
- Todo cenário DEVE ter um passo QUANDO/DADO (seu gatilho) e um passo ENTÃO (seu resultado). Um cenário com apenas linhas AND ou prosa simples ainda conta como cenário, mas `openspec validate` o sinaliza como aviso: a validação normal ainda passa, mas `openspec validate --strict` falha com ele.
- Mantenha a descrição de cada requisito (o texto entre `### Requisito:` e seu primeiro cenário) com 500 caracteres ou menos. `openspec validate` sinaliza descrições mais longas em requisitos ADICIONADOS e no spec principal. Isso é um aviso: a validação normal ainda passa, mas `openspec validate --strict` falha com ele. Ao escrever um novo requisito, declare um comportamento por requisito: mova exemplos e casos extremos para cenários, e divida um requisito que abrange vários comportamentos em blocos `### Requisito:` separados, cada um com seus próprios cenários. Sob MODIFICADOS, mantenha o bloco de requisito existente inteiro; nunca divida, corte ou reescreva texto existente apenas para atender ao comprimento. Divida um requisito longo existente apenas quando o usuário pedir, em uma alteração feita para esse fim: sob MODIFICADOS, mantenha seu cabeçalho e todos os cenários e corte sua descrição para um comportamento sem alterar seu significado, depois adicione cada comportamento que você removeu como seu próprio requisito ADICIONADO com seus próprios cenários.

Apenas novas capacidades: a primeira seção do spec delta é `## Propósito` -
uma ou duas frases (50+ caracteres, ou `openspec validate --strict`
o reporta como muito breve) descrevendo para que a capacidade serve. O archive
o copia para o spec principal que cria; sem ele, o novo spec principal
fica com um placeholder `TBD ... Update Purpose after archive` para preencher
manualmente. NÃO adicione `## Propósito` a um delta para uma capacidade existente -
esse spec já tem um e o do delta é ignorado. Para alterar o Propósito de
uma capacidade existente - incluindo um placeholder `TBD` remanescente -
edite `<planningHome.root>/openspec/specs/<capability-path>/spec.md`
diretamente. `planningHome.root` vem da resposta `openspec instructions ...
--json`. Sempre use-o em vez de um caminho relativo ao repositório: ele
resolve para o repositório sempre que a alteração vive em um - seja isso
proveniente de `--store`, um ponteiro `store:` do projeto, ou um repositório
padrão global - e para o repositório atual caso contrário. Não tente descobrir
qual caso se aplica; o campo já tem a resposta.

Fluxo de trabalho para requisitos MODIFICADOS:
1. Localize o requisito existente em `<planningHome.root>/openspec/specs/<capability-path>/spec.md` (a mesma raiz com reconhecimento de repositório acima)
2. Copie o bloco INTEIRO do requisito (de `### Requisito:` por todos os cenários)
3. Cole sob `## Requisitos MODIFICADOS` e edite para refletir o novo comportamento
4. Garanta que o texto do cabeçalho corresponda exatamente (sem distinção de espaços em branco)

Armadilha comum: Usar MODIFICADOS com conteúdo parcial perde detalhes no momento do archive.
Se estiver adicionando novas preocupações sem alterar o comportamento existente, use ADICIONADOS.

Exemplo (uma nova capacidade, então sua primeira seção é `## Propósito`):
```
# Spec Delta

## Propósito

Permite que os usuários extraiam seus dados do produto em um formato portátil.

## Requisitos ADICIONADOS

### Requisito: Usuário pode exportar dados
O sistema DEVE permitir que os usuários exportem seus dados no formato CSV.

#### Cenário: Exportação bem-sucedida
- **QUANDO** o usuário clica no botão "Export"
- **ENTÃO** o sistema faz o download de um arquivo CSV com todos os dados do usuário

## Requisitos REMOVIDOS

### Requisito: Exportação legada
**Motivo**: Substituído pelo novo sistema de exportação
**Migração**: Use o novo endpoint de exportação em /api/v2/export
```

Especificações devem ser testáveis - cada cenário é um caso de teste potencial.

design.md ​

Explica como implementar a mudança. Elaborado apenas quando a mudança necessita de um.

Estrutura ​

O modelo que o agente recebe como formato de saída (templates/design.md):

md
# Design

## Contexto

<!-- Estado atual e restrições que moldam a abordagem. Veja proposal.md para a motivação - não a repita -->

## Objetivos / Não-Objetivos

**Objetivos:**
<!-- O que este design visa alcançar -->

**Não-Objetivos:**
<!-- O que está explicitamente fora do escopo -->

## Decisões

<!-- Principais decisões de design com justificativa e alternativas consideradas -->

## Riscos / Compensações

<!-- Riscos e compensações conhecidos -->

Instruções ​

A instrução enviada ao agente quando ele elabora este artefato (de schema.yaml):

md
Crie o documento de design que explica COMO implementar a mudança.

Quando incluir design.md (crie apenas se algum dos casos se aplicar):
- Mudança transversal (múltiplos serviços/módulos) ou novo padrão arquitetural
- Nova dependência externa ou mudanças significativas no modelo de dados
- Complexidade de segurança, desempenho ou migração
- Ambiguidade que se beneficia de decisões técnicas antes da codificação

Seções:
- **Contexto**: Apenas o estado atual e as restrições necessárias para explicar a abordagem. Referencie a proposta para a motivação em vez de repeti-la (ex: "Veja proposal.md - Por quê").
- **Objetivos / Não-Objetivos**: O que este design alcança e exclui explicitamente. Não repita o escopo da proposta - adicione apenas limites em nível de design.
- **Decisões**: Principais escolhas técnicas com justificativa (por que X em vez de Y?). Inclua alternativas consideradas para cada decisão.
- **Riscos / Compensações**: Limitações conhecidas, coisas que podem dar errado. Formato: [Risco] → Mitigação
- **Plano de Migração**: Passos para implantação, estratégia de rollback (se aplicável)
- **Questões Abertas**: Incógnitas que podem ser respondidas posteriormente sem
  alterar as especificações, a abordagem ou a decomposição de tarefas. Omita se não houver.

Questões abertas são para incógnitas genuinamente adiáveis, não decisões que
você pulou. Se uma questão mudaria as especificações, a abordagem escolhida ou
a decomposição de tarefas, resolva-a agora - pergunte ao usuário em vez de adivinhar.

Foque na arquitetura e na abordagem, não na implementação linha por linha.
A proposta cobre o porquê e o quê; o design cobre o como. Referencie a
proposta para a motivação e, uma vez escritas, as especificações para os requisitos -
se uma seção apenas as repetiria, aponte para elas em vez disso.

Bons documentos de design explicam o "porquê" por trás das decisões técnicas.

tasks.md ​

Divide a implementação em tarefas verificáveis. Aplicar acompanha o progresso aqui.

Estrutura ​

O modelo que o agente recebe como formato de saída (templates/tasks.md):

md
# Tarefas

## 1. <!-- Nome do Grupo de Tarefas -->

- [ ] 1.1 <!-- Descrição da tarefa -->
- [ ] 1.2 <!-- Descrição da tarefa -->

## 2. <!-- Nome do Grupo de Tarefas -->

- [ ] 2.1 <!-- Descrição da tarefa -->
- [ ] 2.2 <!-- Descrição da tarefa -->

Instruções ​

A instrução enviada ao agente quando ele elabora este artefato (de schema.yaml):

md
Crie a lista de tarefas que divide o trabalho de implementação.

Antes de escrever as tarefas, verifique o design.md para Questões Abertas. Se alguma delas
mudaria o que será construído, resolva-as com o usuário primeiro - não
incorpore uma suposição não declarada na lista de tarefas.

**IMPORTANTE: Siga o modelo abaixo para tarefas rastreadas.** A fase de aplicação analisa o
formato de checkbox para acompanhar o progresso. Uma caixa contendo apenas `x` conta como concluída,
maiúsculo ou minúsculo e com qualquer espaçamento, então `- [ x]` também é concluído. Todo
outro marcador, incluindo `- [~]`, `- [-]` e um `- []` vazio, é considerado
não concluído. Uma linha sem checkbox não é rastreada de forma alguma.

Diretrizes:
- Agrupe tarefas rastreadas relacionadas sob títulos ## numerados
- Cada tarefa rastreada DEVE ser um checkbox: `- [ ] X.Y Descrição da tarefa`
- As tarefas devem ser pequenas o suficiente para serem concluídas em uma sessão
- Ordene as tarefas por dependência (o que deve ser feito primeiro?)
- Acompanhe o trabalho de implementação e verificação que pode ser concluído antes
  do arquivamento. Se o fluxo de trabalho solicitado incluir arquivamento ou trabalho que exija
  que esta mudança seja arquivada, preserve essas etapas como marcadores simples em uma
  seção opcional `## Continuidade do fluxo de trabalho` no final de tasks.md. Esses
  marcadores são informações de referência fora do progresso de tarefas rastreadas.
- Cada tarefa DEVE declarar como verificar a conclusão (um teste, comando,
  comportamento observável ou artefato entregue). Coloque a verificação na
  descrição do checkbox dessa tarefa. Use uma tarefa de verificação separada apenas
  quando ela verifica integração mais ampla ou comportamento do sistema que abrange
  múltiplas tarefas de implementação.
- Cada grupo de tarefas DEVE implementar os testes e a documentação que seu próprio trabalho
  exige. NÃO acumule testes ou documentação em um grupo final -
  quando um grupo tardio exercita o trabalho de um grupo anterior, as falhas
  retroagem por todos os grupos intermediários e forçam retrabalho. Um grupo
  cujo trabalho não exija nenhum dos dois, como scaffolding ou configuração de dependências,
  não carrega nenhum. Um grupo final é apenas para verificações de integração, não para
  os testes e docs que um grupo anterior devia.

Exemplo:
```
# Tarefas

## 1. Configuração

- [ ] 1.1 Criar nova estrutura de módulo e verificar se os arquivos esperados estão presentes
- [ ] 1.2 Adicionar dependências ao package.json e verificar se a instalação do pacote é bem-sucedida

## 2. Implementação Principal

- [ ] 2.1 Implementar função de exportação de dados e verificar se o teste de exportação passa
- [ ] 2.2 Adicionar utilitários de formatação CSV e verificar se os testes unitários cobrem aspas e delimitadores
- [ ] 2.3 Documentar a API de exportação em docs/export.md e verificar se o comando documentado executa como escrito
```

Quando aplicável, anexe a continuidade do fluxo de trabalho como marcadores simples, por exemplo:
```
## Continuidade do fluxo de trabalho

- Arquivar a mudança após satisfazer os requisitos de revisão do projeto.
- Verificar o resultado arquivado.
```

Referencie as especificações para o que precisa ser construído, o design para como construí-lo.

Aplicar ​

A transição do planejamento para a implementação. Aplicar é a fase que trabalha através do tasks.md, não um artefato.

  • Inicia: assim que o tasks.md existir e listar pelo menos uma tarefa.
  • Acompanha: os checkboxes no tasks.md. Marcá-los é o registro de progresso.
  • Termina: todos os checkboxes marcados. O OpenSpec então sugere arquivar a mudança.

Configurações ​

As configurações de aplicação (de schema.yaml):

yaml
apply:
  requires: [tasks]
  tracks: tasks.md
  # instruction: mostrada abaixo

Instruções ​

A instrução enviada ao agente quando a implementação começa (de schema.yaml):

md
Leia os arquivos de contexto, trabalhe nas tarefas pendentes, marque como concluídas conforme avança.
Pare se encontrar bloqueadores ou precisar de esclarecimentos.

schema.yaml ​

O schema.yaml completo, com corpos de instrução omitidos. Cada um é mostrado integralmente em sua seção acima.

yaml
name: spec-driven
version: 1
description: Default OpenSpec workflow - proposal → specs → design → tasks
artifacts:
  - id: proposal
    generates: proposal.md
    description: Initial proposal document outlining the change
    template: proposal.md
    # instruction: shown in full under proposal.md above
    requires: []

  - id: specs
    generates: "specs/**/*.md"
    description: Detailed specifications for the change
    template: spec.md
    # instruction: shown in full under Delta specs above
    requires:
      - proposal

  - id: design
    generates: design.md
    description: Technical design document with implementation details
    template: design.md
    # instruction: shown in full under design.md above
    requires:
      - proposal

  - id: tasks
    generates: tasks.md
    description: Implementation checklist with trackable tasks
    template: tasks.md
    # instruction: shown in full under tasks.md above
    requires:
      - specs
      - design

apply:
  requires: [tasks]
  tracks: tasks.md
  # instruction: shown in full under Apply above