marcioaltoe/arquivar-especificacao

Arquiva uma especificação concluída — verifica se toda tarefa foi concluída, o QA foi aprovado e as referências indexadas são autocontidas, então escreve <slug>.md na raiz de arquivamento resolvida (<spec-root>/_archived/, ou docs/history/specs/ para a raiz docs/specs embutida) e remove a pasta da Especificação, que permanece no Git na source_revision do registro. Executa automaticamente ao final de uma Roundfix Spec Run após aprovação no QA, ou sempre que o usuário pedir para arquivar uma especificação.

O que é arquivar-especificacao?

Esta skill automatiza o arquivamento de especificações concluídas em ambientes como Claude Code, Cursor, Codex e outras ferramentas de agente de IA, garantindo que o processo siga verificações rigorosas de conclusão, aprovação de QA e autocontenção de referências. Ela suporta arquivamento normal, override de QA e cancelamento de especificação, movendo o registro resumido para uma raiz de arquivamento (como `_archived/` ou `docs/history/specs/`) e removendo a pasta original da especificação, que permanece no Git na revisão de origem. A skill verifica três pré-condições principais com comandos shell: todas as tarefas obrigatórias concluídas, QA aprovado (com validação estruturada do relatório mais recente) e a especificação autocontida (sem links para `_inbox/` ou `findings/`, com índice válido). Inclui também um relink automático de arquivos de referência e tratamento especial para merges squash, declarações de QA e linhas bloqueadas por ambiente ou autorização. Ideal para equipes que usam sistemas baseados em especificações e precisam de um arquivamento confiável e rastreável.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/marcioaltoe/roundfix/tree/HEAD/skills/archive-spec

Installed? Explore more Programação e Desenvolvimento skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Arquivar Especificação

Arquive uma especificação concluída escrevendo <slug>.md na raiz de arquivamento resolvida e removendo <resolved-spec-root>/<slug>/, que permanece no Git na source_revision do registro. A origem é a Raiz de Especificação configurada; o destino é sua raiz de arquivamento resolvida — docs/history/specs/ para a raiz docs/specs embutida, ou <spec-root>/_archived/ para uma raiz externa ou não padrão, correspondendo ao destino roundfix archive. Um arquivamento normal significa implementado, verificado e autocontido — toda tarefa concluída, QA aprovado quando o Grafo de Tarefas cria uma porta de QA, e toda referência indexada de propriedade da Especificação. Um Override de Arquivamento de QA registra a exceção explícita sem afirmar verificação. Após qualquer disposição, um ls <spec-root>/ separa o trabalho ativo do histórico, e o arquivamento permanece pesquisável como o registro do que foi construído e por quê.

O gatilho é a conclusão da especificação, não a publicação: execute isso automaticamente ao final de uma Roundfix Spec Run assim que a porta de QA for aprovada, ou sempre que o usuário pedir. Mesclagem e lançamento são etapas separadas, orientadas pelo usuário — o commit de arquivamento simplesmente viaja com o branch e é enviado dentro do PR da própria funcionalidade.

Relink de Arquivamento

Antes de escrever o Registro de Arquivamento, o arquivamento realiza um Relink de Arquivamento. Ele promove automaticamente cada arquivo não principal citado que um Documento Vivo referencia da Especificação proprietária para docs/references/<basename>, então reescreve as citações de cada Documento Vivo para a cópia promovida; citações da pasta da Especificação ou de um artefato principal apontam para o Registro de Arquivamento. O registro lista arquivos reescritos sob relinked quando existem. A fonte mantém um proprietário, então uma Especificação secundária não precisa de cópia (ADR-0260, ADR-0083).

A pasta da Especificação se aposenta por exclusão. No resultado copiado e em cada cópia promovida, um destino dentro da pasta removida nomeia uma cópia promovida ou se torna um Localizador Git, `<path>@<commit>`; ele nunca aponta para o próprio registro. O commit contém o caminho e é acessível a partir do branch padrão ou de uma tag. Quando nenhum commit existe, o localizador nomeia o caminho e o pull request do registro. Outros destinos retêm seu alvo de repositório (ADR-0278).

O arquivamento se recusa a escrever quando um destino de promoção já existe, quando duas promoções compartilham um basename, ou quando um Documento Vivo a ser reescrito tem alterações não commitadas em HEAD. Citações em arquivos que não são Documentos Vivos, ou citações que permanecem após a reescrita, são avisos nomeando o arquivo, linha e alvo; o arquivamento deixa esses arquivos inalterados.

Mesclagens squash

Uma mesclagem squash mantém source_revision apenas na ref head do pull request; o registro nomeia esse pull request em pull_request.

Declaração de recusa de QA

Um Grafo de Tarefas que declara qa: declined com um qa_reason não vazio arquiva uma vez que toda Tarefa está concluída, sem um Relatório de QA e sem um override, e seu Registro de Arquivamento tem a disposição no-qa. --qa-override é recusado para tal Especificação. Toda outra pré-condição de arquivamento ainda se aplica.

Liquidação de QA

O mesmo resultado liquida a tarefa qa autorada e determina o que o arquivamento deixa:

ResultadoLiquidaArquiva
passLiquida a Tarefa de QA como completed e torna a Especificação elegível para arquivamento quando o relatório não tem linhas bloqueadas proibidas.O Registro de Arquivamento, que nomeia o Relatório de QA e veredito; a Especificação, seu relatório de QA e evidências permanecem no Git na source_revision do registro.
partial declarado qualificadoLiquida a Tarefa de QA como completed quando nenhuma linha falhou, foi pulada ou está bloqueada por descoberta, toda linha bloqueada declarada é coberta por uma declaração ## Unreachable Acceptance correspondente, e toda linha bloqueada por ambiente é a linha de Pull Request pré-PR, registrada como blocked (environment: no open Pull Request) com a linha de Pull Request nomeada em sua proveniência, ou uma linha de evidência externa que o sandbox da Run não pôde alcançar, registrada como blocked (environment: network denied: <host>) com a linha de evidência externa nomeada em sua proveniência. Nenhuma linha precisa de uma declaração Unreachable Acceptance, e um partial cujas únicas linhas não atendidas são tais linhas se qualifica.O Registro de Arquivamento, que nomeia o Relatório de QA e veredito e carrega o registro satisfied-by das declarações como unproven; a Especificação, seu relatório de QA e evidências permanecem no Git na source_revision do registro.
environment-blockedDeixa a linha bloqueada; o relatório ainda pode liquidar como pass quando evidência equivalente satisfaz a política de ambiente.Nada por si só; um relatório qualificado pode arquivar a Especificação.
failedDeixa a Tarefa de QA não resolvida e recusa o arquivamento a menos que um override autorizado se aplique.Nada.
missingDeixa a Tarefa de QA não resolvida e recusa o arquivamento a menos que um override autorizado se aplique.Nada.
overrideNão altera o status da Tarefa de QA ou veredito do relatório; liquida o arquivamento como explicitamente autorizado apesar de QA falho ou ausente.O Registro de Arquivamento com qa_override, qa_override_approval, qa_override_reason, qa_override_qa_outcome, qa_override_qa_task_status quando a Tarefa de QA está incompleta, e qa_override_revision; a Tarefa de QA e Relatórios permanecem inalterados no Git na source_revision do registro.

Linhas que a autorização da Especificação mantém offline

O partial declarado qualificado acima também aceita uma linha de evidência externa que a porta não consultou porque a autorização da própria Especificação proíbe essa consulta, registrada como blocked (environment: <subject> prohibited by Spec authorization) com a linha de evidência externa nomeada em sua proveniência. O subject nomeia o que a autorização proíbe, em suas palavras: network para uma consulta de rede, ou another repository; tem 1 a 80 caracteres e não contém parênteses. Como a linha negada pela rede, ela nunca decide um partial qualificado e não precisa de declaração Unreachable Acceptance, uma linha conta para no máximo um tipo isento, e a liquidação, roundfix qa-report accept e roundfix archive a leem através da mesma política (ADR-0276, ADR-0335).

Cancelando uma Especificação

Uma Especificação que não será entregue é cancelada com roundfix cancel <slug> --reason <text>, nunca excluída manualmente. O comando escreve um Registro de Arquivamento com disposição cancelled, retorna cada Entrada de Backlog adotada para docs/backlog/ com status: open e cada Descoberta adotada para docs/findings/ com status: pending, então remove a pasta da Especificação enquanto seus bytes permanecem no Git em source_revision. Um registro cancelado nunca atende a um pré-requisito, nunca substitui outra Especificação e é recusado pela Tentativa de Entrega.

Arquivos ignorados e uma remoção falha

O Comando de Arquivamento e o Comando de Cancelamento recusam enquanto o Git ignorar qualquer arquivo sob a pasta da Especificação. Cada comando lista cada arquivo ignorado e não escreve nada. O operador deve remover cada arquivo ou commitá-lo com git add -f, então tentar novamente.

Se a remoção final da pasta da Especificação falhar, ambos os comandos mantêm cada escrita, saem com 1 e imprimem o comando que conclui a remoção: chmod -R u+w '<pasta>' && rm -rf '<pasta>'.

Pré-condições — verifique, não confie

Verifique todas as três com evidências de comando frescas antes de tocar em qualquer coisa:

  1. Tarefas obrigatórias concluídas. Para um arquivamento normal, leia cada task_NN.md listado em _tasks.md; todo status deve ser completed. Para um Override de Arquivamento de QA, toda Tarefa não-QA deve estar completed; a Tarefa de QA pode permanecer pending ou failed. Se a Tarefa de QA também estiver completed, o relatório mais recente deve permanecer inelegível ou o override é desnecessário e recusado.

    Comando: execute grep -n '^status:' <cada-arquivo-de-tarefa-listado-em-_tasks.md> e retenha sua saída. Qualquer valor diferente de status: completed bloqueia um arquivamento normal. Durante um override, apenas uma Tarefa não-QA com outro status bloqueia o arquivamento; nomeie esse arquivo de Tarefa.

  2. QA aprovado. O relatório mais recente em qa/ deve passar pelo verificador de QA do repositório. Não substitua um grep de linha por validação estruturada. No Roundfix, use o mesmo contrato internal/spec.QAVerdict que o Comando de Arquivamento: selecione o relatório mais recente pelo contrato de nome de arquivo qa-report-YYYY-MM-DD[-NN].md, analise seu frontmatter YAML, exija um verdict suportado, exija que ambos os campos de linha bloqueada sejam inteiros não negativos quando presentes, e rejeite verdict: pass quando rows_blocked_finding for diferente de zero. Retenha o caminho do relatório do verificador e o resultado como evidência. Um diretório qa/ ausente, relatório mais recente malformado ou veredito não aprovado bloqueia o arquivamento normal. Proceda apenas sob um Override de Arquivamento de QA explícito realizado através de roundfix archive <slug> --qa-override --approval <source> --reason <text>. Nunca registre o override editando o Registro de Arquivamento. Um relatório mais recente qualificado não torna uma Tarefa de QA falha ou pendente concluída; o override é recusado apenas quando o relatório se qualifica e toda Tarefa está concluída.

  3. A Especificação é autocontida. Aplique esta pré-condição quando docs/specs/<slug>/references/_index.md existir ou for um link simbólico; um link simbólico, incluindo um quebrado, é estado de índice inválido em vez de uma Especificação legada. Apenas uma Especificação onde esse caminho não existe nem é um link simbólico é anterior a este contrato e passa sem adaptar artefatos históricos. Para uma Especificação indexada, todo path indexado deve existir relativo a _index.md, todo caminho source nunca atualizado deve estar ausente, e nenhum destino de link Markdown dentro da Especificação pode apontar para docs/_inbox/ ou docs/findings/.

    Comandos: primeiro execute esta verificação de destino de link; sua sintaxe deliberadamente corresponde a links Markdown inline ou de estilo de referência, não prosa que meramente nomeia qualquer árvore:

    spec_dir=docs/specs/<slug>
    link_hits=$(grep --include='*.md' -RInE '(\]\([^)]*(docs/)?(_inbox|findings)/[^)]*\)|^[[:space:]]*\[[^]]+\]:[[:space:]]*<?[^[:space:]>]*(docs/)?(_inbox|findings)/)' "$spec_dir")
    link_status=$?
    if test "$link_status" -eq 0; then
      printf '%s\n' "$link_hits"
      echo "self-containment failed: rewrite each listed link at adoption step 8"
      exit 1
    fi
    test "$link_status" -eq 1 || exit "$link_status"
    

    Em seguida, analise e valide cada linha de dados. O índice pertence à Especificação atual: owner deve igualar seu prefixo de quatro dígitos, type deve ser inbox, finding ou backlog, e cada source e path deve aparecer apenas uma vez. Um path deve ser um basename relativo a _index.md; rejeite caminhos absolutos, ., .., separadores de caminho e links simbólicos em vez de permitir travessia ou um link fora de references/. Execute o seguinte da raiz do repositório e retenha as linhas normalizadas mais qualquer diagnóstico como evidência:

    slug=<slug>
    index="docs/specs/$slug/references/_index.md"
    expected_owner=${slug%%-*}
    parsed_index=$(mktemp) || exit 1
    trap 'rm -f "$parsed_index"' EXIT HUP INT TERM
    
    if test -L "$(dirname "$index")"; then
      printf 'self-containment failed: references/ must not be a symbolic link\n' >&2
      exit 1
    fi
    
    if test -L "$index" || test ! -f "$index"; then
      printf 'self-containment failed: references/_index.md must be a regular, non-symbolic-link file\n' >&2
      exit 1
    fi
    
    awk -F '|' -v expected_owner="$expected_owner" '
    function trim(value) {
      gsub(/^[[:space:]]+|[[:space:]]+$/, "", value)
      return value
    }
    function reject(message) {
      print "self-containment failed: " message > "/dev/stderr"
      invalid = 1
    }
    function separator(value) {
      value = trim(value)
      return value ~ /^:?-{3,}:?$/
    }
    /^[[:space:]]*$/ || /^[[:space:]]*#/ { next }
    !header {
      if (NF != 7 || trim($2) != "source" || trim($3) != "type" ||
          trim($4) != "owner" || trim($5) != "adopted date" ||
          trim($6) != "path") {
        reject("_index.md must use the fixed source | type | owner | adopted date | path header")
      } else {
        header = 1
      }
      next
    }
    !divider {
      if (NF != 7 || !separator($2) || !separator($3) || !separator($4) ||
          !separator($5) || !separator($6)) {
        reject("_index.md has an invalid table separator")
      } else {
        divider = 1
      }
      next
    }
    {
      source = trim($2)
      type = trim($3)
      owner = trim($4)
      adopted = trim($5)
      path = trim($6)
      if (NF != 7 || source == "" || type == "" || owner == "" ||
          adopted == "" || path == "") {
        reject("invalid index row at line " NR ": " $0)
        next
      }
      if (type != "inbox" && type != "finding" && type != "backlog") {
        reject("type must be `inbox`, `finding`, or `backlog` at line " NR ": " type)
      }
      if (owner != expected_owner) {
        reject("owner must be " expected_owner " at line " NR ": " owner)
      }
      if (seen_source[source]++) {
        reject("duplicate source at line " NR ": " source)
      }
      if (seen_path[path]++) {
        reject("duplicate path at line " NR ": " path)
      }
      if (adopted !~ /^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$/) {
        reject("adopted date must be YYYY-MM-DD at line " NR ": " adopted)
      }
      if ((type == "inbox" && source !~ /^docs\/_inbox\/[^\/]+\.md$/) ||
          (type == "finding" && source !~ /^docs\/findings\/[^\/]+\.md$/) ||
          (type == "backlog" && source !~ /^docs\/backlog\/[^\/]+\.md$/)) {
        reject("source does not match type at line " NR ": " source)
      }
      print source "|" type "|" owner "|" adopted "|" path
    }
    END {
      if (!header || !divider) {
        reject("_index.md is missing its fixed table header")
      }
      if (invalid) {
        exit 1
      }
    }
    ' "$index" > "$parsed_index" || exit $?
    
    while IFS='|' read -r source type owner adopted path; do
      case "$path" in
        ""|.|..|/*|*/*|*\\*)
          printf 'self-containment failed: path must be one basename relative to `_index.md`: %s\n' "$path" >&2
          exit 1
          ;;
      esac
      source_basename=${source##*/}
      if test "$path" != "$source_basename"
    

    …[truncado para tradução]

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

marcioaltoe/roundfix

Use Roundfix to plan releases with the read-only Release Plan Command, clean CodeRabbit pull request feedback, diagnose runtime readiness with the Doctor Command, execute a Spec's Task Graph with the Implement Command, monitor Runs through the Supervisor Run Event Stream, reclaim Run storage with the GC Command, archive completed Specs, run its `--follow-up`, `--status` and `--unattended` Skill Modes, and, inside daemon-assigned Batch runs, follow the bounded Review Issue or Task resolution contract.

marcioaltoe/write-prd

Write a PRD as a durable local artifact at docs/specs/<slug>/_prd.md — research first, clarify with one multiple-choice question at a time, record decisions as ADRs, then write directly without draft-approval rounds.

marcioaltoe/write-tasks

Decompose a spec's PRD/TechSpec into a dependency-ordered task graph — vertical-slice task files plus a machine-parseable _tasks.md DAG manifest under docs/specs/<slug>/, including the authored QA gate decision, decided autonomously from the Spec and escalated only when authority, architecture, or blast radius is at stake.

marcioaltoe/write-techspec

Write the technical spec at docs/specs/<slug>/_techspec.md — explore the architecture, settle technical decisions one question at a time, record them as ADRs, and produce a build order that write-tasks can decompose. Entry point for feature work with an approved PRD, and also for refactors and bug fixes, where it mints the spec folder with a minimal _prd.md instead of requiring a product interview.

Habilidades Relacionadas