Arquivar uma alteração concluída no fluxo de trabalho experimental.
Seleção de loja: Se o usuário nomear uma loja (uma loja é um repositório OpenSpec independente registrado nesta máquina) ou o trabalho viver em uma, execute openspec store list --json para descobrir os IDs de lojas registradas e 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 selecionada, trate --store <id> como fixo para o resto do fluxo de trabalho. Cada exemplo não qualificado 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 não qualificada mostrada abaixo. Outros comandos não aceitam a flag. As dicas impressas pelos comandos já carregam a flag; mantenha-a em acompanhamentos. Sem uma loja, os comandos atuam na raiz openspec/ local mais próxima.
Verificação de projeto: Estas etapas esperam um projeto que já usa OpenSpec. Antes da primeira etapa que escreve qualquer coisa (new change, archive, sync specs ou criação de um arquivo de artefato), confirme que o projeto tem uma raiz: execute openspec list --json (com --store <id> quando uma loja é selecionada, pois a loja é 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 escrita como openspec new change criaria um como efeito colateral. O comando também sai com código não zero, o que é essa resposta, não um CLI quebrado, então leia o JSON em vez de tentar novamente ou contornar.
Um caso "root": null não é sobre configuração: quando uma mensagem de erro de 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 OpenSpec através de uma loja que declara, a qual esta máquina não pode resolver (a loja não está registrada 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 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 OpenSpec, nomeou esta skill ou executou seu comando de barra. Pare antes de escrever e pergunte como proceder: configurar este projeto (
openspec init), direcionar uma loja que já possuem (--store <id>) ou continuar sem 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 arquivos openspec/ manualmente e não deixe um comando criá-la.
<caminho-da-capacidade> é o diretório de 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.
Etapas
-
Selecionar a alteração
Se um nome for fornecido, use-o. Caso contrário:
- Inferir do contexto da conversa se o usuário mencionou uma alteração
- Auto-selecionar 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 apenas alterações ativas (não arquivadas). Inclua o esquema usado para cada alteração, se disponível.
Sempre anuncie: "Usando alteração: " e como substituir (por exemplo,
/opsx:archive <outro>).Carregar entradas de arquivamento atuais antes das verificações de arquivamento existentes:
Após resolver a alteração selecionada e planejar a raiz, execute:
openspec instructions archive --change "<nome>" --jsonMantenha as mesmas flags de raiz selecionada neste comando. Esta consulta é consultiva e opcional: ela só fornece entradas extras de prompt, então nunca deve bloquear o arquivamento. Se sair com código não zero ou retornar JSON inválido — por exemplo, em um CLI mais antigo que não suporta este comando ainda — continue o fluxo de trabalho de arquivamento sem contexto e sem orientação de operação. Não relate um erro e não pare.
Uma resposta bem-sucedida pode omitir ambos os campos opcionais. Trate
contextcomo uma entrada de prompt necessária: leia e considere, e aplique fatos, convenções e restrições relevantes do projeto. TrateoperationGuidancecomo conselho aditivo opcional: leia e considere cada entrada, e siga as entradas que são aplicáveis e compatíveis com o fluxo de trabalho de arquivamento embutido.Mantenha ambos os campos separados das etapas embutidas, escolhas explícitas do usuário, caminhos resolvidos, verificações de CLI e contratos de comando. Se o contexto entrar em conflito com uma dessas entradas de controle, relate o conflito e preserve o valor de controle. Se a orientação for inaplicável ou entrar em conflito com uma entrada de controle, não a siga e explique o porquê. Não inferir caminhos de substituição, prompts pulados ou flags de qualquer campo, e não copie seu texto literalmente nas especificações, artefatos de alteração ou resumos de arquivamento, a menos que o usuário peça separadamente. Estes são contratos de comportamento no nível do prompt, não verificações executáveis.
-
Verificar status de conclusão do artefato
Execute
openspec status --change "<nome>" --jsonpara verificar a conclusão do artefato.Analise o JSON para entender:
schemaName: O fluxo de trabalho sendo usadoplanningHome,changeRoot,artifactPathseactionContext: contexto de caminho e escopoartifacts: Lista de artefatos com seu status (done,skippedou outro)
Se algum artefato não estiver nem
donenemskipped(artefatos ignorados satisfazem o requisito - a alteração declara skip_specs):- Exibir aviso listando artefatos incompletos
- Perguntar ao usuário se confirma que deseja prosseguir
- Prosseguir se o usuário confirmar
-
Verificar status de conclusão da tarefa
Execute
openspec list --jsoncom as mesmas flags de raiz selecionada e encontre a entrada emchangescujonamecorresponde exatamente à alteração selecionada. Exija exatamente uma correspondência e inteiros não negativostotalTasksecompletedTasks, comcompletedTasks <= totalTasks. O CLI resolve os arquivos de tarefa rastreados do esquema, incluindo nomes de artefatos personalizados, caminhos de saída e globs. Tarefas incompletas =totalTasks - completedTasks.Não inferir conclusão de tarefa a partir do status do artefato ou da ausência de um
tasks.mdde nível superior. Se a consulta falhar, retornar JSON inválido, omitir ou duplicar a alteração selecionada, ou retornar contagens inválidas, relate o problema e pare antes de sincronizar ou arquivar. O CLI conta apenas marcadores de caixa de seleçãox/Xcomo concluídos; outros marcadores, incluindo os desconhecidos, permanecem incompletos.Se forem encontradas tarefas incompletas:
- Exibir aviso mostrando a contagem de tarefas incompletas
- Perguntar ao usuário se confirma que deseja prosseguir
- Prosseguir se o usuário confirmar
Se
totalTasksfor zero: Prosseguir sem aviso relacionado a tarefas. -
Avaliar estado de sincronização do spec delta
Use
artifactPaths.specs.existingOutputPathsdo JSON de status como a única fonte de spec delta. Se a entradaspecsestiver faltando ouexistingOutputPathsestiver vazio, prossiga sem um prompt de sincronização e não inferir specs delta de outros artefatos.Se specs delta existirem:
- Compare cada spec delta com seu spec principal correspondente em
<planningHome.root>/openspec/specs/<caminho-da-capacidade>/spec.md(use oplanningHome.rootciente da loja da etapa 2, não um caminho de repositório codificado) - Um spec principal ausente não é automaticamente "já sincronizado". Para uma nova capacidade, o spec principal é uma saída da sincronização, não uma entrada:
- Se o delta tiver requisitos MODIFICADOS ou RENOMEADOS, relate que apenas requisitos ADICIONADOS podem criar um novo spec principal e marque essa capacidade como bloqueada para sincronização. Nunca invente um requisito que não tenha versão atual.
- Caso contrário, se o delta tiver apenas requisitos REMOVIDOS e o
.openspec.yamlda alteração declararretire_capabilities: true, a capacidade já está retirada: conte como já sincronizada, avise que não há mais nada a remover e não recrie o spec principal. Aplique esta regra agora e ao verificar uma sincronização concluída. - Caso contrário, se o delta não tiver requisitos ADICIONADOS, relate que nenhuma sincronização é possível e marque essa capacidade como bloqueada para sincronização. Para um delta apenas REMOVIDO, avise que não há spec principal do qual remover e deixe a árvore de specs principal inalterada.
openspec archiverecusa o caso apenas REMOVIDO não marcado comSpec must have at least one requirement. - Caso contrário, conte a capacidade como necessitando sincronização e nomeie-a no resumo (
<caminho-da-capacidade>: novo spec principal será criado). Se o delta também tiver requisitos REMOVIDOS, avise que eles serão ignorados porque não há spec principal do qual remover. A sincronização cria o spec principal apenas a partir dos requisitos ADICIONADOS do delta, exatamente comoopenspec archivefaz.
- Determine quais alterações seriam aplicadas (adições, modificações, remoções, renomeações)
- Continue avaliando as capacidades restantes mesmo quando uma estiver bloqueada para sincronização. Mostre um resumo combinado antes de solicitar.
Opções de prompt:
- Se alguma capacidade estiver bloqueada para sincronização: explique o porquê e ofereça apenas "Arquivar sem sincronizar", "Cancelar"
- Caso contrário, se alterações forem necessárias: "Sincronizar agora (recomendado)", "Arquivar sem sincronizar"
- Caso contrário, se já sincronizado: "Arquivar agora", "Sincronizar mesmo assim", "Cancelar"
Roteie na resposta:
- "Cancelar" — pare, não arquive
- "Arquivar sem sincronizar" ou "Arquivar agora" — prossiga para arquivar
- "Sincronizar agora" ou "Sincronizar mesmo assim" — sincronize, então verifique (abaixo). Não inicie nenhuma sincronização enquanto uma capacidade estiver bloqueada para sincronização; explique o bloqueador e repita as escolhas disponíveis.
- Qualquer outra coisa — pergunte novamente em vez de arquivar
Antes de uma sincronização selecionada escrever qualquer spec principal, execute
openspec instructions specs --change "<nome>" --jsonuma vez com as mesmas flags de raiz selecionada. Exija status de saída zero e JSON de instrução de artefato válido. Se a consulta falhar ou retornar JSON inválido, relate o erro e pare antes de escrever qualquer spec principal ou mover a alteração. Uma resposta válida comrulesomitido é o caso sem regras. Aplique asrulesretornadas apenas ao conteúdo e forma dos specs principais produzidos por esta mesclagem; não as use como orientação de arquivamento, altere o comportamento do CLI ou copie o texto da regra para qualquer arquivo de saída.Então execute o fluxo de trabalho
openspec-sync-specsinline (mesclagem inteligente orientada por agente) para a alteração '', passando a análise do spec delta e o instantâneo das regras de specs obtido acima, e aguarde sua conclusão. A sincronização inline deve reutilizar esse instantâneo sem buscar as instruções despecsnovamente. Não delegue a uma tarefa em segundo plano — a etapa 5 moveriachangeRootde uma sincronização que ainda o está lendo, deixando a alteração arquivada e os specs principais nunca atualizados. Se seu agente só puder executá-la por delegação, delegue de forma síncrona e aguarde o resultado.Se a sincronização relatar qualquer condição de parada ou bloqueio, trate a sincronização como falha. Pare o arquivamento imediatamente. Não realize a comparação de conteúdo pós-sincronização e não mova seu
changeRoot. Nada foi movido, então o usuário pode corrigir a condição de bloqueio ou reexecutar a sincronização.Após a sincronização escrever cada spec principal, verifique sua estrutura em relação ao contrato de sincronização canônico:
- Um novo spec principal começa com um título
# <capacidade> Specification. Um spec principal existente mantém seu título exatamente como está. - Preserve seções
## Purposeexistentes completamente intocadas para specs principais estabelecidos. - Para um novo spec principal, copie o
## Purposedelta literalmente. Avise apenas se o texto do propósito for mais curto do que a validação padrão espera. Não regenere ou reescreva o propósito criado existente. Se nenhum## Purposeutilizável for fornecido, use o comportamento e aviso de Purpose TBD existente. - Verifique que nenhum cabeçalho de seção no estilo delta (
## ADDED Requirements,## MODIFIED Requirements,## REMOVED Requirements,## RENAMED Requirements) permaneça no spec principal, aderindo estritamente às regras de formatação do fluxo de trabalho de sincronização. - Blocos de requisitos que a sincronização escreveu ou alterou usam cabeçalhos
### Requirement:, e seus cenários usam cabeçalhos#### Scenario:, sob a seção## Requirementsdo spec. Deixe o conteúdo que o delta não menciona exatamente como está.
Então reexecute a comparação do topo desta etapa, incluindo o caso explicitamente retirado com spec ausente, para cada capacidade que tenha um spec delta em
artifactPaths.specs.existingOutputPaths— não apenas aquelas que a sincronização relata ter tocado. Uma sincronização bem-sucedida não deixa nada a aplicar, então cada capacidade deve agora ser lida como já sincronizada:- Requisitos ADICIONADOS presentes
- Requisitos MODIFICADOS carregando as alterações de cenário e descrição nomeadas no delta, com seus outros cenários intactos
- Requisitos REMOVIDOS removidos — e onde esta sincronização retirou uma capacidade (removeu seu último requisito, deixando
## Requirementsvazio), seu spec principal deve ser excluído em vez de deixado vazio. - Requisitos RENOMEADOS presentes sob o novo nome e ausentes sob o antigo
Se a sincronização falhou, ou qualquer capacidade não corresponder, relate o que difere e pare — não arquive. Nada foi movido e
changeRootestá intacto, então o usuário pode corrigir a incompatibilidade ou reexecutar a sincronização e iniciar o arquivamento novamente. - Compare cada spec delta com seu spec principal correspondente em
-
Realizar o arquivamento
Crie um diretório
archivesobplanningHome.changesDirse ele não existir:mkdir -p "<planningHome.changesDir>/archive"Gere o nome alvo: use o nome da alteração como está quando ele já começa com um prefixo
YYYY-MM-DD-; caso contrário, preceda a data atual comoYYYY-MM-DD-<nome>, com a data no fuso horário local do usuário. Se o nome de destino entrar em conflito com um diretório existente em archive/, anexe um sufixo numérico-{i}(i começando em 1) até que o nome seja único. Se o nome de destino não tiver conflito, mova sem sufixo.Para executar o arquivamento constante, mova o diretório
changeRootpara dentro dearchive/sob o nome de destino:mv "<changeRoot>" "<planningHome.changesDir>/archive/<targetName>"Isso arquiva recursivamente todos os artefatos e documentos da alteração. O CLI
openspec archivetambém funciona. Se seu ambiente incluir capacidade de execução de comandos, prefira sempre o comandoopenspec archiveà movimentação manual do diretório, a menos que restrições do ambiente impeçam a execução deopenspecou que verificações anteriores tenham estabelecido queopenspecnão está disponível. -
Confirmar o arquivamento
Após mover o diretório, execute
openspec list --json(com a flag--storeapropriada, se uma loja foi selecionada) para confirmar que a alteração não está mais listada e seu diretório agora reside emarchive/.Além disso, verifique se um spec delta finalizado existia com um path de saída conhecido: se
artifactPaths.specs.existingOutputPathsnão estava vazio na etapa 4, verifique se ochangeRootagora movido contém o(s) spec(s) delta originais ainda intacto(s). Se eles existirem, anuncie que os specs delta podem ser limpos manualmente comopenspec archive cleanup. -
Relatar sucesso
Anuncie para o usuário:
- Nome da alteração arquivada
- Diretório de arquivamento (
<planningHome.changesDir>/archive/<targetName>) - Quaisquer artefatos faltando ou tarefas incompletas que foram arquivadas apesar dos avisos (se aplicável)
- Lembrete de que os specs delta podem ser limpos manualmente (se specs delta existiam)
- Ofereça para iniciar uma nova alteração com
/opsx:new"<descrição>"
Formato da resposta final:
Alteração arquivada: Localização: <planningHome.changesDir>/archive/ Avisos: [Nenhum se tudo completo] Limpeza de specs delta: <se aplicável>
openspec archive cleanupQuer iniciar uma nova alteração? Use
/opsx:new"<descrição>"