OpenSpec Merge
Mescla várias pastas de capacidade relacionadas em openspec/specs/ em uma única
especificação de recurso principal, através de um fluxo de trabalho em duas fases
com aprovação humana. Nada em openspec/specs/<capacidade>/ é alterado até que um
humano tenha aprovado explicitamente a mesclagem.
Quando isso se aplica
O fluxo de trabalho de arquivamento do OpenSpec sincroniza deltas em
openspec/specs/<capacidade>/spec.md por alteração. Quando alterações relacionadas
são arquivadas sob nomes de capacidade diferentes (frequentemente porque foram
construídas em estágios, por exemplo user-show, user-detail,
user-permissions), você acaba com várias pastas de especificação descrevendo o
que é funcionalmente um único recurso. Esta skill mescla essas pastas em uma só,
usando uma área de staging que requer aprovação humana antes de qualquer coisa
real ser substituída.
As duas fases
- Fase A — Preparar: ler as especificações de origem, escrever um rascunho
mesclado em
openspec/specs/.merged-specs/<recurso>/spec.mdcomApproved-by-human: no. Nada mais muda. - Fase B — Aplicar: acionada quando o usuário alterar o frontmatter para
Approved-by-human: yes. Substitui as pastas de origem pelo conteúdo aprovado e remove o arquivo de staging.
Sempre detecte qual fase se aplica: se openspec/specs/.merged-specs/<recurso>/
já existir, verifique primeiro seu campo Approved-by-human em vez de
preparar do zero.
Fase A — Preparar
1. Identificar pastas candidatas
Liste openspec/specs/* e procure por pastas que:
- Compartilhem um prefixo de nome comum ou palavra de domínio (
user-show,user-detail,user-permissions) - Façam referência à mesma entidade/recurso em seus requisitos (mesmo modelo, mesmos endpoints de API, mesma página de interface)
- Tenham sido arquivadas próximas no tempo (verifique as datas em
openspec/changes/archive/)
Se o usuário nomeou pastas específicas explicitamente, use essas em vez de adivinhar.
Se houver mais de um agrupamento plausível, pare e pergunte ao usuário quais pastas pertencem juntas antes de preparar qualquer coisa.
2. Ler cada spec.md candidata por completo
Para cada pasta, leia todo o spec.md, não apenas os cabeçalhos. Anote nomes
de requisitos, cenários, marcadores de depreciação e qualquer coisa que pareça
modificar/substituir um requisito em outra pasta candidata.
3. Inferir o nome da capacidade alvo
Derive-o do prefixo comum ou substantivo de domínio compartilhado entre as pastas
candidatas (por exemplo user-show + user-detail + user-permissions → user, ou
user-management se soar mais natural).
- Prefixo/domínio comum claro → use-o, não precisa perguntar.
- Nenhum nome compartilhado óbvio (por exemplo
checkout-floweinvoice-exportrelacionados apenas por um vago tema "faturamento") → pergunte ao usuário o nome da capacidade alvo antes de prosseguir.
Informe o nome inferido explicitamente na sua saída para que o usuário possa substituí-lo.
4. Mesclar os requisitos
Regras, em ordem:
- União de requisitos ADICIONADOS: cada requisito distinto de cada pasta de origem é mantido.
- Requisitos conflitantes/duplicados (mesmo nome, ou mesmo comportamento descrito duas vezes): mantenha a versão mais completa/recente, mesclando detalhes não conflitantes em vez de descartar um silenciosamente.
- Requisitos REMOVIDOS/depreciados: exclua da especificação mesclada.
- Nunca invente requisitos. Sinalize ambiguidades ou contradições inline
(por exemplo
<!-- CONFLITO: fonte A diz X, fonte B diz Y — precisa de decisão humana -->) em vez de escolher silenciosamente. - Preserve o texto original do cenário quando possível; reescreva prosa apenas ao mesclar dois requisitos sobrepostos em um.
5. Escrever o arquivo de staging
Escreva em:
openspec/specs/.merged-specs/<nome-inferido>/spec.md
Com este frontmatter no topo:
---
Approved-by-human: no
merged-from:
- user-show
- user-detail
- user-permissions
---
Seguido pelo conteúdo da especificação mesclada.
6. Informe o usuário, brevemente
- Quais pastas de origem foram mescladas e o nome alvo inferido
- Quaisquer conflitos sinalizados inline que precisem de decisão
- Exatamente o que fazer a seguir: abrir
openspec/specs/.merged-specs/<nome-inferido>/spec.md, revisá-lo, editar se necessário, e definirApproved-by-human: yesno frontmatter quando estiver satisfeito - Que nada em
openspec/specs/<capacidade>/foi tocado ainda
Fase B — Aplicar
Acionamento: o usuário pede para aplicar/finalizar uma mesclagem, ou você percebe
que openspec/specs/.merged-specs/<recurso>/spec.md tem Approved-by-human: yes.
- Releia o arquivo de staging e confirme
Approved-by-human: yes. Se ainda forno, pare e informe o usuário que precisa de aprovação primeiro — não aplique. - Leia
merged-fromdo frontmatter para saber quais pastas de origem substituir. - Remova o frontmatter do conteúdo de staging (ambos os campos), deixando um
spec.mdlimpo, sem frontmatter. - Substitua as pastas de origem pelo resultado mesclado:
- Crie/sobrescreva
openspec/specs/<nome-inferido>/spec.mdcom o conteúdo sem frontmatter. - Remova as outras pastas de origem listadas em
merged-fromque não sejam o próprio nome alvo.
- Crie/sobrescreva
- Remova a pasta de staging
openspec/specs/.merged-specs/<recurso>/. - Confirme ao usuário o que foi substituído/removido, para que seja fácil verificar com git diff antes de confirmar.
Nunca execute o passo 4 sem que Approved-by-human: yes esteja já
presente no arquivo — não peça ao usuário para aprovar verbalmente no chat como
substituto; a aprovação deve ser o próprio campo frontmatter alterado.
Exemplo
Fase A — Entrada: openspec/specs/user-show/, openspec/specs/user-detail/,
openspec/specs/user-permissions/ — todas descrevendo aspectos diferentes do
mesmo recurso de perfil de usuário.
Saída: openspec/specs/.merged-specs/user/spec.md:
---
Approved-by-human: no
merged-from:
- user-show
- user-detail
- user-permissions
---
# User
## Requisito: ...
...
Mensagem ao usuário: mesclado de user-show, user-detail, user-permissions
para a capacidade inferida user (renomeie a pasta se preferir
user-management); nenhum conflito encontrado; revise
openspec/specs/.merged-specs/user/spec.md e defina
Approved-by-human: yes quando estiver pronto.
Fase B — Uma vez que o usuário defina Approved-by-human: yes e peça para aplicar:
openspec/specs/user/spec.md é criado/sobrescrito com o conteúdo mesclado
sem frontmatter, user-show/, user-detail/, user-permissions/ são removidos,
e openspec/specs/.merged-specs/user/ é excluído.