CommunityProgramación y desarrollogithub.com

marcioaltoe/archive-spec

Archivar una especificación completada — verificar que cada tarea esté completada, que el QA haya pasado y que las referencias indexadas sean autocontenidas, luego escribir <slug>.md bajo la raíz de archivo resuelta (<spec-root>/_archived/, o docs/history/specs/ para la raíz integrada docs/specs) y eliminar la carpeta Spec, que permanece en Git en la revisión fuente del registro. Se ejecuta automáticamente al final de una Ejecución de Especificación Roundfix después de una pasada de QA, o cuando el usuario solicite archivar una especificación.

¿Qué es archive-spec?

Esta habilidad para agentes de IA, como Claude Code o Codex, automatiza el archivado de especificaciones completadas (Specs) en un repositorio. Su función principal es verificar que cada tarea esté completada, que el QA haya pasado, y que las referencias indexadas sean autocontenidas; luego escribe un registro de archivo (<slug>.md) en una ubicación predefinida y elimina la carpeta de la especificación original, manteniendo el historial en Git. Soporta plataformas como Roundfix y es útil para desarrolladores que gestionan proyectos con un ciclo de vida claro de especificaciones, desde su creación hasta su archivado. La habilidad incluye precondiciones estrictas (tareas completadas, QA aprobado y autocontención) y maneja casos como cancelaciones, anulaciones de QA, fusiones squash, y relink de referencias. También gestiona conflictos de archivos ignorados y fallos en la eliminación, proporcionando comandos de diagnóstico y acciones correctivas. El resultado es un flujo de trabajo limpio donde el código archivado es trazable y verificable.

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

Installed? Explore more Programación y desarrollo skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Archivar Especificación

Archivar una especificación completada escribiendo <slug>.md bajo la raíz de archivo resuelta y eliminando <raíz-especificación-resuelta>/<slug>/, que permanece en Git en la source_revision del registro. La fuente es la Raíz de Especificación configurada; el destino es su raíz de archivo resuelta — docs/history/specs/ para la raíz integrada docs/specs, o <spec-root>/_archived/ para una raíz externa o no predeterminada, coincidiendo con el destino de roundfix archive. Un archivo normal significa implementado, verificado y autocontenido — cada tarea realizada, QA pasado cuando el Grafo de Tareas define una puerta de QA, y cada referencia indexada propiedad de la Especificación. Una Anulación de Archivo de QA registra la excepción explícita sin reclamar verificación. Después de cualquier disposición, un ls <spec-root>/ separa el trabajo vivo del historial, y el archivo permanece buscable como el registro de lo que se construyó y por qué.

El desencadenante es la finalización de la especificación, no la publicación: ejecutar esto automáticamente al final de una Ejecución de Especificación Roundfix una vez que la puerta de QA pase, o cuando el usuario lo solicite. La fusión y el lanzamiento son pasos separados, impulsados por el usuario; el commit de archivo simplemente viaja con la rama y se envía dentro del PR de la propia característica.

Reenlace de Archivo

Antes de escribir el Registro de Archivo, el archivo realiza un Reenlace de Archivo. Promueve automáticamente cada archivo no central citado al que un Documento Vivo hace referencia desde la Especificación propietaria a docs/references/<basename>, luego reescribe las citas de cada Documento Vivo a la copia promovida; las citas de la carpeta Especificación o un artefacto central apuntan al Registro de Archivo. El registro enumera los archivos reescritos bajo relinked cuando existen. La fuente mantiene un propietario, por lo que una Especificación secundaria no necesita copia (ADR-0260, ADR-0083).

La carpeta Especificación se retira mediante eliminación. En el resultado copiado y cada copia promovida, un destino dentro de la carpeta eliminada nombra una copia promovida o se convierte en un Localizador Git, `<path>@<commit>`; nunca apunta al registro en sí. El commit contiene la ruta y es accesible desde la rama predeterminada o una etiqueta. Cuando no existe tal commit, el localizador nombra la ruta y la solicitud de extracción del registro. Otros destinos conservan su objetivo de repositorio (ADR-0278).

El archivo se niega a escribir cuando un destino de promoción ya existe, cuando dos promociones comparten un nombre base, o cuando un Documento Vivo que se va a reescribir tiene cambios no confirmados en HEAD. Las citas en archivos que no son Documentos Vivos, o las citas que permanecen después de la reescritura, son advertencias que nombran el archivo, la línea y el objetivo; el archivo deja esos archivos sin cambios.

Fusiones squash

Una fusión squash mantiene source_revision solo en la ref head de la solicitud de extracción; el registro nombra esa solicitud de extracción en pull_request.

Declinación de QA declarada

Un Grafo de Tareas que declara qa: declined con un qa_reason no vacío archiva una vez que cada Tarea está completada, sin un Informe de QA y sin una anulación, y su Registro de Archivo tiene la disposición no-qa. --qa-override es rechazado para tal Especificación. Cada otra condición previa de archivo aún se aplica.

Liquidación de QA

El mismo resultado liquida la tarea qa creada y determina lo que el archivo deja:

ResultadoLiquidaArchiva
passLiquida la Tarea de QA como completed y hace que la Especificación sea elegible para archivo cuando el informe no tiene filas bloqueadas no permitidas.El Registro de Archivo, que nombra el Informe de QA y el veredicto; la Especificación, su informe de QA y la evidencia permanecen en Git en la source_revision del registro.
partial declarado calificadoLiquida la Tarea de QA como completed cuando ninguna fila falló, se omitió o está bloqueada por hallazgo, cada fila bloqueada declarada está cubierta por una declaración ## Aceptación Inalcanzable coincidente, y cada fila bloqueada por entorno es la fila de Solicitud de Extracción previa al PR, registrada como blocked (environment: no open Pull Request) con la fila de Solicitud de Extracción nombrada en su procedencia, o una fila de evidencia externa que el sandbox de la Ejecución no pudo alcanzar, registrada como blocked (environment: network denied: <host>) con la fila de evidencia externa nombrada en su procedencia. Ninguna fila necesita una declaración de Aceptación Inalcanzable, y un partial cuyas únicas filas no cumplidas son tales filas califica.El Registro de Archivo, que nombra el Informe de QA y el veredicto y lleva el registro satisfied-by de las declaraciones como unproven; la Especificación, su informe de QA y la evidencia permanecen en Git en la source_revision del registro.
environment-blockedDeja la fila bloqueada; el informe aún puede liquidarse como pass cuando la evidencia equivalente satisface la política de entorno.Nada por sí mismo; un informe calificado puede archivar la Especificación.
failedDeja la Tarea de QA sin resolver y rechaza el archivo a menos que se aplique una anulación autorizada.Nada.
missingDeja la Tarea de QA sin resolver y rechaza el archivo a menos que se aplique una anulación autorizada.Nada.
overrideNo cambia el estado de la Tarea de QA ni el veredicto del informe; liquida el archivo como explícitamente autorizado a pesar de QA fallido o faltante.El Registro de Archivo con qa_override, qa_override_approval, qa_override_reason, qa_override_qa_outcome, qa_override_qa_task_status cuando la Tarea de QA está incompleta, y qa_override_revision; la Tarea de QA y los Informes permanecen sin cambios en Git en la source_revision del registro.

Filas que la autorización de la Especificación mantiene fuera de línea

El partial declarado calificado anterior también acepta una fila de evidencia externa que la puerta no buscó porque la autorización de la propia Especificación prohíbe esa búsqueda, registrada como blocked (environment: <subject> prohibited by Spec authorization) con la fila de evidencia externa nombrada en su procedencia. El sujeto nombra lo que la autorización prohíbe, en sus palabras: network para una búsqueda de red, o another repository; tiene de 1 a 80 caracteres y no contiene paréntesis. Al igual que la fila denegada por red, nunca decide un partial calificado y no necesita una declaración de Aceptación Inalcanzable, una fila cuenta como máximo para un tipo exento, y la liquidación, roundfix qa-report accept y roundfix archive lo leen a través de la misma política (ADR-0276, ADR-0335).

Cancelar una Especificación

Una Especificación que no será entregada se cancela con roundfix cancel <slug> --reason <text>, nunca se elimina a mano. El comando escribe un Registro de Archivo con disposición cancelled, devuelve cada Elemento del Backlog adoptado a docs/backlog/ con status: open y cada Hallazgo adoptado a docs/findings/ con status: pending, luego elimina la carpeta Especificación mientras sus bytes permanecen en Git en source_revision. Un registro cancelado nunca cumple un requisito previo, nunca reemplaza a otra Especificación y es rechazado por Reintento de Entrega.

Archivos ignorados y una eliminación fallida

El Comando de Archivo y el Comando de Cancelación se niegan mientras Git ignore cualquier archivo dentro de la carpeta Especificación. Cada comando enumera cada archivo ignorado y no escribe nada. El operador debe eliminar cada archivo o confirmarlo con git add -f, luego reintentar.

Si la eliminación final de la carpeta Especificación falla, ambos comandos mantienen cada escritura, salen con 1, e imprimen el comando que finaliza la eliminación: chmod -R u+w '<folder>' && rm -rf '<folder>'.

Condiciones previas — verificar, no confiar

Verificar las tres con evidencia de comando fresca antes de tocar algo:

  1. Tareas requeridas completadas. Para un archivo normal, leer cada task_NN.md listado en _tasks.md; cada status debe ser completed. Para una Anulación de Archivo de QA, cada Tarea no-QA debe estar completed; la Tarea de QA puede permanecer pending o failed. Si la Tarea de QA también está completed, el informe más reciente debe permanecer no elegible o la anulación es innecesaria y rechazada.

    Comando: ejecutar grep -n '^status:' <cada-archivo-de-tarea-listado-en-_tasks.md> y conservar su salida. Cualquier valor que no sea status: completed bloquea un archivo normal. Durante una anulación, solo una Tarea no-QA con otro estado bloquea el archivo; nombrar ese archivo de Tarea.

  2. QA aprobado. El informe más reciente en qa/ debe pasar el verificador de QA del repositorio. No sustituir un grep de línea por una validación estructurada. En Roundfix, usar el mismo contrato internal/spec.QAVerdict que el Comando de Archivo: seleccionar el informe más reciente por el contrato de nombre de archivo qa-report-YYYY-MM-DD[-NN].md, analizar su preámbulo YAML, requerir un verdict compatible, requerir que ambos campos de fila bloqueada sean enteros no negativos cuando estén presentes, y rechazar verdict: pass cuando rows_blocked_finding sea distinto de cero. Conservar la ruta del informe del verificador y el resultado como evidencia. Un directorio qa/ faltante, informe más reciente mal formado o veredicto que no sea pass bloquea el archivo normal. Proceder solo bajo una Anulación de Archivo de QA explícita realizada a través de roundfix archive <slug> --qa-override --approval <source> --reason <text>. Nunca registrar la anulación editando el Registro de Archivo. Un informe más reciente calificado no completa una Tarea de QA fallida o pendiente; la anulación se rechaza solo cuando el informe califica y cada Tarea está completada.

  3. La Especificación es autocontenida. Aplicar esta condición previa cuando docs/specs/<slug>/references/_index.md existe o es un enlace simbólico; un enlace simbólico, incluido uno roto, es un estado de índice inválido en lugar de una Especificación heredada. Solo una Especificación donde esa ruta no existe ni es un enlace simbólico es anterior a este contrato y pasa sin adaptar artefactos históricos. Para una Especificación indexada, cada path indexado debe existir relativo a _index.md, cada ruta source nunca actualizada debe estar ausente, y ningún destino de enlace Markdown dentro de la Especificación puede apuntar a docs/_inbox/ o docs/findings/.

    Comandos: primero ejecutar esta verificación de destino de enlace; su sintaxis coincide deliberadamente con enlaces Markdown en línea o de estilo de referencia, no prosa que simplemente nombre cualquiera de los árboles:

    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"
    

    Luego analizar y validar cada fila de datos. El índice pertenece a la Especificación actual: owner debe ser igual a su prefijo de cuatro dígitos, type debe ser inbox, finding o backlog, y cada source y path deben aparecer solo una vez. Un path debe ser un nombre base relativo a _index.md; rechazar rutas absolutas, ., .., separadores de ruta y enlaces simbólicos en lugar de permitir el cruce o un enlace fuera de references/. Ejecutar lo siguiente desde la raíz del repositorio y conservar las filas normalizadas más cualquier diagnóstico como evidencia:

    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\/[^\/]+$/) ||
          (type == "finding" && source !~ /^docs\/findings\/[^\/]+$/) ||
          (type == "backlog" && source !~ /^docs\/backlog\/[^\/]+$/)) {
        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 traducción]

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.

Skills relacionados