Sincroniza especificações delta de uma alteração para as especificações principais.
Esta é uma operação orientada por agente - você lerá as especificações delta e editará diretamente as especificações principais para aplicar as alterações. Isso permite uma mesclagem inteligente (por exemplo, adicionar um cenário sem copiar o requisito inteiro).
Seleção de armazenamento: Se o usuário nomear um armazenamento (um armazenamento é um repositório OpenSpec independente registrado nesta máquina) ou o trabalho estiver em um, execute openspec store list --json para descobrir os IDs de armazenamento registrados e, em seguida, passe --store <id> nos comandos que leem ou escrevem especificações e alterações (new change, status, instructions, list, show, validate, archive, doctor, context, schemas, view). Uma vez selecionado, trate --store <id> como fixo para o restante do fluxo de trabalho. Cada exemplo sem escopo desses comandos abaixo é uma abreviação: antes de executá-lo, anexe a flag. Por exemplo, execute openspec status --change "<nome>" --json --store "<id>", não a forma sem escopo mostrada abaixo. Outros comandos não aceitam a flag. Dicas impressas pelos comandos já carregam a flag; mantenha-a nas ações de acompanhamento. Sem um armazenamento, os comandos agem na raiz local mais próxima openspec/.
Verificação do projeto: Estas etapas esperam um projeto que já usa o OpenSpec. Antes da primeira etapa que escreve algo (new change, archive, sync specs ou criar um arquivo de artefato), confirme que o projeto tem uma raiz: execute openspec list --json (com --store <id> quando um armazenamento for selecionado, pois o armazenamento é então a raiz) e leia root. Um objeto root significa que o projeto está configurado. "root": null significa que não está - não há um diretório openspec/ aqui, e uma gravação como openspec new change criaria um como efeito colateral. O comando também sai com código não zero, que é essa resposta em vez de uma CLI quebrada, então leia o JSON em vez de tentar novamente ou contornar.
Um caso de "root": null não é sobre configuração: quando uma mensagem de erro status começa com Declared in ou Invalid store declaration in e nomeia o openspec/config.yaml (ou config.yml) deste projeto, o projeto usa o OpenSpec através de um armazenamento que declara, mas que esta máquina não pode resolver (o armazenamento não está registrado, ou a linha store: está malformada). Não trate como não inicializado e pule os ramos abaixo: pare antes de escrever e mostre ao usuário a message e o fix desse erro.
Caso contrário, sem raiz, o que acontece a seguir depende de como este fluxo de trabalho foi alcançado:
- Selecionado automaticamente: você escolheu este fluxo de trabalho por conta própria, sem o usuário nomear OpenSpec, nomear esta skill ou executar seu comando de barra. Pare de usar OpenSpec e responda à solicitação normalmente, como faria sem o OpenSpec instalado. Não peça para configurar nada e não mencione a configuração do OpenSpec.
- Solicitação explícita do OpenSpec: o usuário nomeou o OpenSpec, nomeou esta skill ou executou seu comando de barra. Pare antes de escrever e pergunte como proceder: configurar este projeto (
openspec init), direcionar um armazenamento que eles já têm (--store <id>) ou continuar sem o OpenSpec para esta solicitação. Aguarde a resposta.
Em ambos os ramos, nunca crie a raiz como efeito colateral: não execute openspec init até que o usuário peça, não crie manualmente arquivos openspec/ e não deixe um comando criá-lo.
<caminho-da-capacidade> é o diretório da especificação relativo a specs/ (por exemplo, user-auth ou identity/user-auth). Preserve o caminho completo de cada especificação delta ao resolver sua especificação principal.
Entrada: Opcionalmente, especifique um nome de alteração. Se omitido, verifique se pode ser inferido do contexto da conversa. Se vago ou ambíguo, você DEVE solicitar as alterações disponíveis.
Passos
-
Selecionar a alteração
Se um nome for fornecido, use-o. Caso contrário:
- Infira do contexto da conversa se o usuário mencionou uma alteração
- Selecione automaticamente se apenas uma alteração ativa existir
- Se ambíguo, execute
openspec list --jsonpara obter as alterações disponíveis e peça ao usuário para selecionar uma
Ao solicitar, mostre as alterações que têm especificações delta (sob o diretório
specs/).Sempre anuncie: "Usando alteração: " e como substituir (por exemplo,
/opsx:sync <outro>). -
Resolver contexto da alteração
Execute:
openspec status --change "<nome>" --jsonO JSON inclui
planningHome.root. As especificações principais residem em<planningHome.root>/openspec/specs/— use essa raiz (ciente do armazenamento) para cada caminho de especificação principal abaixo, não um caminho de repositório codificado. Quando um armazenamento for selecionado, ele aponta para o armazenamento, não para o repositório atual. -
Encontrar especificações delta
Use
artifactPaths.specs.existingOutputPathsdo JSON de status como a única fonte de caminhos de especificação delta. Se a entradaspecsestiver faltando ouexistingOutputPathsestiver vazio, informe que não há especificações delta para sincronizar, não as infira de outros artefatos e pare sem solicitar instruções de artefato ou escrever uma especificação principal.Sincronize cada caminho em
existingOutputPathsa menos que o chamador tenha restringido o conjunto. Um chamador restringe nomeando uma lista explícita de entradas completas deexistingOutputPaths— copie esses valores absolutos literalmente. Archive faz isso embutido, e um usuário também pode (por exemplo, selecionando a entrada que termina em/specs/billing/invoices/spec.md). Em seguida, sincronize apenas os caminhos nomeados e deixe as especificações delta restantes intocadas: o arquivamento em massa exclui um delta cuja implementação não pôde encontrar, e sincronizá-lo de qualquer maneira escreveria uma especificação principal que o chamador reteve deliberadamente. Carregue essa seleção restringida através do passo 4; nunca a amplie de volta para a lista completa. Se um caminho nomeado não estiver emexistingOutputPaths, não o sincronize — relate e pare, em vez de descartá-lo silenciosamente. Se a lista nomeada estiver vazia, informe que não há nada para sincronizar e pare sem escrever uma especificação principal.Cada arquivo de especificação delta contém seções como:
## ADDED Requirements- Novos requisitos a adicionar## MODIFIED Requirements- Alterações em requisitos existentes## REMOVED Requirements- Requisitos a remover## RENAMED Requirements- Requisitos a renomear (formato FROM:/TO:)
Se nenhuma especificação delta for encontrada, informe o usuário e pare.
-
Para cada especificação delta, aplicar alterações às especificações principais
Antes da primeira gravação de especificação principal, obtenha um instantâneo atual das regras de especificação:
- Se o arquivamento invocou este fluxo de trabalho embutido e forneceu um instantâneo válido de
openspec instructions specs --change "<nome>" --json, reutilize-o e não busque as mesmas instruções novamente. - Caso contrário, execute esse comando uma vez agora com as mesmas flags de raiz selecionada.
- Se a consulta direta sair com código não zero ou retornar JSON inválido de instrução de artefato, relate o erro e pare antes de escrever qualquer especificação principal. Não trate a falha como um conjunto de regras ausente.
- Uma resposta válida com
rulesomitido significa que nenhuma regra de artefato está configurada e a mesclagem semântica existente continua.
Aplique as
rulesretornadas apenas ao conteúdo e forma das especificações principais produzidas por esta mesclagem. Regras de artefato não são orientação operacional e não podem alterar raízes selecionadas, caminhos delta, verificações de CLI ou passos do fluxo de trabalho. Use seu texto como restrições sem copiá-lo literalmente para uma especificação principal ou resumo.Para cada caminho de especificação delta de capacidade selecionado no passo 3 — a lista completa
existingOutputPaths, ou o subconjunto restringido quando um chamador forneceu um (estes podem pertencer a um armazenamento selecionado, não ao repositório):a. Leia a especificação delta para entender as alterações pretendidas
b. Leia a especificação principal em
<planningHome.root>/openspec/specs/<caminho-da-capacidade>/spec.md(pode não existir ainda)Se não existir ainda (uma nova capacidade), corresponda ao que
openspec archivefaz: apenas requisitos ADDED podem ser aplicados - o passo d cria a especificação a partir deles. MODIFIED e RENAMED não têm requisito para atuar, então pare a sincronização para essa capacidade e relate que sua especificação principal não existe e apenas ADDED é permitido para uma nova especificação; nunca invente o requisito ausente. REMOVED não tem nada a remover - ignore e avise.c. Aplique as alterações de forma inteligente:
ADDED Requirements:
- Se o requisito não existir na especificação principal → adicione-o
- Se o requisito já existir → atualize-o para corresponder (trate como MODIFIED implícito)
MODIFIED Requirements:
- Encontre o requisito na especificação principal
- Aplique as alterações - isso pode ser:
- Adicionar novos cenários que a especificação principal ainda não tem
- Modificar cenários existentes
- Alterar a descrição do requisito
- Preserve cenários/conteúdo não mencionados no delta
REMOVED Requirements:
- Remova o bloco de requisito inteiro da especificação principal
- Aposentando a capacidade. Exclua todo o
spec.md- e o diretório uma vez que nada mais reste nele - apenas quando TODOS os seguintes se aplicarem:- remover os requisitos desta execução não deixou blocos de requisito;
- o restante da especificação está bem formado (ainda tem um
## Purpose); - a especificação principal não estava vazia antes desta sincronização - se você removeu nada, não mude nada;
- toda outra linha não vazia no arquivo inteiro é contabilizada como o título, Purpose, cabeçalho Requirements, ou a declaração de um requisito canônico, cenários ou exemplos em bloco de código;
- o
.openspec.yamlda alteração declararetire_capabilities: true; - o
spec.mdresolve dentro da raiz real de especificações (não siga um link simbólico de diretório de capacidade para excluir um arquivo externo). Se remover os requisitos selecionados deixaria nenhum bloco de requisito e qualquer condição de aposentadoria não for satisfeita, não modifique a especificação principal. Pare a sincronização para essa capacidade, relate a condição bloqueadora e diga ao usuário como resolvê-la. Nunca escreva ou deixe uma seção## Requirementsvazia. Quando apenas o marcador estiver faltando, diga isso também - é a única coisa que o usuário pode adicionar para fazer a aposentadoria passar.
- Excluir o arquivo também exclui seu
## Purpose; qualquer outra seção bloqueia a aposentadoria. Nomeie Purpose quando você relatar a aposentadoria. Inclua umgit checkoutcopiável apenas quando a especificação estava no checkout do chamador; caso contrário, forneça orientação de recuperação com escopo de checkout.
RENAMED Requirements:
- Encontre o requisito FROM, renomeie para TO
## Purposeno delta:- A especificação principal já tem um e é autoritativo - deixe-o em paz (isto é o que
openspec archivefaz; ele avisa e segue em frente)
d. Crie nova especificação principal se a capacidade ainda não existir:
- Apenas quando o delta tem requisitos ADDED para colocar nela e nenhum requisito MODIFIED ou RENAMED bloqueou esta capacidade no passo b. Caso contrário, não crie nada e deixe o diretório de especificações intocado. Para um delta apenas REMOVED, se o
.openspec.yamlda alteração declararretire_capabilities: true, relate como já aposentado e continue sem recriar a especificação. Sem esse marcador, relate a sincronização como bloqueada:openspec archiverejeita comSpec must have at least one requirement. Um delta vazio não tem operações para sincronizar; relate como bloqueado também. Nunca escreva uma seção## Requirementsvazia. - Crie
<planningHome.root>/openspec/specs/<caminho-da-capacidade>/spec.md - Adicione seção Purpose: copie o corpo do
## Purposedo delta literalmente quando tiver um (isto é o queopenspec archivefaz); escreva apenas um espaço reservado TBD breve quando não tiver - Adicione seção Requirements com os requisitos ADDED
- Siga a Referência de Formato de Especificação Principal abaixo
- Se o arquivamento invocou este fluxo de trabalho embutido e forneceu um instantâneo válido de
-
Validar especificações principais atualizadas
Execute
openspec validate --specscom as mesmas flags de raiz selecionada usadas anteriormente. Se a validação falhar, relate os problemas e não afirme que a sincronização foi bem-sucedida. -
Mostrar resumo
Após aplicar todas as alterações, resuma:
- Quais capacidades foram atualizadas
- Quais alterações foram feitas (requisitos adicionados/modificados/removidos/renomeados)
- Qualquer nova especificação principal deixada com um espaço reservado TBD Purpose, para que seja escrita agora em vez de ficar pendente
- Qualquer capacidade aposentada, nomeando o
spec.mdexcluído, seu Purpose, e umgit checkoutcopiável ou orientação de recuperação com escopo de checkout
Referência de Formato de Especificação Delta
# Spec Delta
## Purpose
Apenas em um delta que introduz uma capacidade totalmente nova. Semear a nova especificação principal.
## ADDED Requirements
### Requirement: New Feature
O SISTEMA DEVE fazer algo novo.
#### Scenario: Basic case
- **WHEN** usuário faz X
- **THEN** sistema faz Y
## MODIFIED Requirements
### Requirement: Existing Feature
O SISTEMA DEVE continuar fazendo a coisa existente, agora também lidando com A.
#### Scenario: Scenario que a especificação principal já tem
- **WHEN** usuário faz X
- **THEN** sistema faz Y
#### Scenario: Novo cenário a adicionar
- **WHEN** usuário faz A
- **THEN** sistema faz B
## REMOVED Requirements
### Requirement: Recurso Depreciado
## RENAMED Requirements
- FROM: `### Requirement: Nome Antigo`
- TO: `### Requirement: Novo Nome`
Referência de Formato de Especificação Principal
As especificações principais são para onde o delta mescla. Elas nunca devem conter cabeçalhos de operação delta (## ADDED/MODIFIED/REMOVED/RENAMED Requirements) - após a sincronização, todo requisito fica sob uma única seção ## Requirements:
# Especificação da <capacidade>
## Purpose
Breve descrição do que esta capacidade faz e por que existe.
## Requirements
### Requirement: New Feature
O SISTEMA DEVE fazer algo novo.
#### Scenario: Basic case
- **WHEN** usuário faz X
- **THEN** sistema faz Y
Princípio Chave: Mesclagem Inteligente
Diferente da mesclagem programática, você mescla em vez de sobrescrever:
- Um bloco MODIFIED carrega todo o requisito - corpo mais cada cenário que sobrevive à alteração.
openspec validateeopenspec archiveambos rejeitam um que elimina um cenário que a especificação principal ainda tem. - Mantenha qualquer coisa que o delta não menciona, na ordem existente da especificação principal
- Use y
…
[truncado para tradução]