CommunityProgramación y desarrollogithub.com

chrislacey89/pre-merge

Revisión principal del pipeline previa a la fusión. Usar para crear un PR con trazabilidad y realizar una revisión arquitectónica antes de fusionar. No es para entrada de QA, planificación, ni implementación.

¿Qué es pre-merge?

Esta habilidad de agente de IA para pre-fusión (pre-merge) automatiza la creación de Pull Requests (PRs) en GitHub y la revisión arquitectónica. Es un paso del pipeline diseñado para ejecutarse en el punto de control final antes de fusionar una rama a main, asegurando que el código se alinee con los principios arquitectónicos del proyecto. Soporta tres modos: modo Autor (crea el PR y proporciona hallazgos de revisión), modo Revisor (genera borradores de comentarios para PRs de otros), y modo Bucle (registra los hallazgos de forma duradera para sesiones de revisión asíncronas o sin conexión). La habilidad se integra de forma nativa con los issues de GitHub y un backend 'sidecar' para gestionar la trazabilidad entre PRDs (documentos de requisitos del producto), slices (porciones de trabajo) y las propias revisiones. Enfatiza la revisión del 'delta' (cambios desde la última revisión) en lugar de volver a revisar todo el código, y no realiza correcciones automáticas, sino que produce hallazgos como asesoramiento para que el operador humano decida. Funciona en plataformas como Claude Code, Cursor y Codex, y se invoca mediante comandos como `/pre-merge`. El flujo de ejecución incluye la recolección de contexto (PRDs, ramas base), la determinación del alcance de la revisión (todo el slice o el delta posterior a la marca) y la generación de resultados estructurados (hallazgos de revisión, comentarios).

Compatible con✓Claude Code✓Codex CLI~Cursor✓Gemini CLI
npx skills add https://github.com/chrislacey89/skills/tree/HEAD/pre-merge

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

Pre-Fusión

Crea un PR de GitHub que enlace con el PRD y los issues de slice, luego revisa el diff completo contra los principios arquitectónicos del proyecto. Produce hallazgos como asesoramiento — no bloquea la fusión, no corrige código automáticamente ni crea issues.

Posición de Invocación

Esta es una habilidad primaria del pipeline que se utiliza después de que la implementación ha sido verificada y antes de fusionar a main, o al retomar el PR de otra persona para revisión.

Use /pre-merge cuando la rama esté lista para la creación del PR, la revisión arquitectónica y la conciliación final entre plan y código. Use /pre-merge --pr <número> cuando esté revisando un PR que usted no creó.

No lo use como sustituto de la verificación de implementación, la entrada de QA o la planificación de refactorización. Asume que el trabajo ya está construido y listo para revisar.

Modos

/pre-merge se ejecuta en uno de tres modos. Los tres reutilizan las dimensiones de revisión arquitectónica definidas en review-checklist.md; se diferencian en lo que consumen y lo que producen.

  • Modo Autor (predeterminado) — se invoca en su propia rama sin el argumento --pr. La habilidad crea el PR (Fase 2) e imprime los hallazgos en la terminal como asesoramiento (Fase 4), y luego devuelve el control — no realiza commits de corrección propios ni abre una segunda pasada. Este es el modo invocado automáticamente por /execute Paso 6 en la ruta HITL. Lo que lee lo decide el estado de la rama, no una bandera: una primera revisión lee el slice completo, que es toda la rama a menos que el elemento de trabajo del slice registre dónde comenzó; una re-ejecución contra un PR que ya tiene una marca de moneda de revisión, cuya cabeza se ha movido desde entonces, toma el delta posterior a la marca — los commits después del SHA marcado — como el sujeto de la revisión, y no vuelve a leer lo que cubrió la revisión anterior. El Paso 1, paso 4, toma esa decisión y la imprime. El delta es el sujeto, no el límite de lo que un revisor puede leer: review-checklist.md establece lo que un revisor lee, e incluye el árbol alrededor del delta.
  • Modo Revisor — se invoca como /pre-merge --pr <número> contra un PR que usted no creó. La habilidad omite la creación del PR (el PR ya existe) y produce texto de comentario borrador (Fase 4) para que usted lo revise y publique, estructurado según references/comment-craft.md (compuerta 5P, Triple-R, Señales de Comentario, Intercambio MMG).
  • Modo Bucle — se invoca como /pre-merge --loop, o se ingresa automáticamente cuando /execute transfiere el control en una ejecución AFK. Ejecuta las Fases 1–4 como lo hace el modo Autor, excepto la decisión de alcance del Paso 1, paso 4: el modo bucle siempre lee toda la rama y nunca toma el delta posterior a la marca, luego continúa a la Fase 5: registra cada hallazgo en un registro duradero — en el cuerpo del PR, o en el elemento de trabajo, donde references/state-backend.md § Dónde viven los registros de la revisión dice — adjunta la evidencia que apoya o refuta cada uno, y devuelve el control al operador. Los hallazgos dejan de ser salida de terminal en este modo; se convierten en filas duraderas con propietarios. El modo bucle no arregla nada y no hace commits — el operador decide qué sucede con cada hallazgo (ver Fase 5 § Por qué el bucle no arregla).

La condición de salida del modo bucle es que cada hallazgo tenga un propietario, nunca que la revisión haya salido limpia. "Cero hallazgos" es una señal de terminación prohibida, coherente con la protección de hallazgos mínimos existente de la Fase 4, que se escribió porque una revisión casi vacía en un diff no trivial significa que la revisión se detuvo temprano, no que el código sea impecable. Un bucle que termina en revisiones limpias producirá de manera confiable revisiones limpias y nada más (Meadows, Buscando el Objetivo Erróneo; Leveson: nunca recompense recuentos bajos de incidentes — recompense la notificación en sí).

Si se está ejecutando en una rama que no es la rama de trabajo del usuario y no se proporcionó --pr, pregunte una vez si el usuario quiere decir modo revisor contra un número de PR específico en lugar de adivinar — la detección automática ahorra una pulsación de tecla, pero clasificar mal el modo produce comentarios borrador que habrían sido avisos locales o viceversa.

Cuándo Usar

  • Modo Autor: después de que QA pase y antes de fusionar una rama de característica a main; después de que Ralph termine la ejecución AFK y usted haya verificado el comportamiento; o para cualquier rama que desee revisar antes de fusionar, incluso sin una ejecución completa del pipeline.
  • Modo Revisor: cuando un compañero de equipo o colaborador externo abre un PR y usted desea aplicar la revisión arquitectónica completa en review-checklist.md a su diff y producir texto de comentario constructivo.
  • Modo Bucle: cuando los hallazgos deben sobrevivir a la sesión que los produjo — la transferencia AFK de /execute, o cualquier rama que revisará en varias sesiones y no desea volver a derivar cada vez. Úselo cuando el costo que está pagando es perder el rastro de los hallazgos, no hacer las correcciones.

Flujo de Ejecución

Fase 1: Recopilar Contexto

Modo Autor:

  1. Pregunte por el número de issue del PRD. Acepte "ninguno" si este cambio no pasó por el pipeline completo. En el modo bucle ingresado desde una transferencia AFK de /execute, no pregunte — tome el número de issue de la transferencia (/execute Paso 6 lo pasa) y trate su ausencia como "ninguno". No hay nadie para responder, por lo que una pregunta incondicional colgaría la ejecución en su primer paso. En el backend sidecar, la respuesta es un id de elemento de trabajo W-<n> (paso 2). "Ninguno" allí deja a la Fase 2 sin nada donde registrar el PR, y a las Notas de Revisión y al registro del modo bucle sin hogar: references/state-backend.md § Dónde viven los registros de la revisión dice lo que les sucede.

  2. Si se proporcionó un PRD:

    gh issue view <número>
    gh issue list --search "in:body #<prd-number>" --state all --json number,title,state,body --limit 100
    

    Analice los mapas de límites (secciones Produce/Consume) del cuerpo de cada issue de slice.

    En el backend sidecar (bash "$SC" backend slices responde sidecar, según references/state-backend.md; el bloque a continuación lo pregunta, y se detiene ante una negativa en lugar de recurrir a gh issue), el PRD y sus slices son elementos de trabajo, y el número solicitado en el paso 1 es un id W-<n>: el slice que implementa esta rama, que /execute pasa, o su PRD. No se ejecuta ningún comando gh issue; el linaje y los mapas de límites provienen de los elementos de trabajo:

    SC="<directorio de esta habilidad>/references/sidecar.sh"
    W="W-<n>"
    case "$(bash "$SC" backend slices)" in
      sidecar) ;;
      github) echo "el backend es github: lea el linaje con el bloque de issue anterior"; exit 0 ;;
      *) echo "linaje abortado: sidecar.sh backend slices falló; no adivino la ruta de github" >&2; exit 1 ;;
    esac
    J="$(bash "$SC" work view "$W" --json)" || { echo "linaje abortado: no se puede leer $W" >&2; exit 1; }
    case "$(jq -r '.kind // empty' <<<"$J")" in
      slice) PRD="$(jq -r '.parent // empty' <<<"$J")" ;;
      prd)   PRD="$W" ;;
      *) echo "linaje abortado: $W no tiene kind" >&2; exit 1 ;;
    esac
    SLICES="$W"
    if [ -n "$PRD" ]; then
      bash "$SC" work view "$PRD" --json | jq -r '"# \(.id) (prd, \(.state))\n\(.body)"'
      SLICES="$(bash "$SC" work list --kind slice --parent "$PRD" --state all)" \
        || { echo "linaje abortado: no se pueden listar los slices de $PRD" >&2; exit 1; }
    fi
    while IFS= read -r S; do
      [ -n "$S" ] || continue
      bash "$SC" work view "$S" --json | jq -r '"# \(.id) (slice, \(.state))\n\(.body)"'
    done <<<"$SLICES"
    

    Analice los mapas de límites de esos cuerpos exactamente como de los cuerpos de issue. Mantenga $W: la Fase 2 registra el PR en él.

  3. Detecte la rama base y evalúe el diff:

    SC="<directorio de esta habilidad>/references/sidecar.sh"
    # $BASE_REF es el extremo del rango; $BASE_BRANCH es el nombre que toma `--base`.
    BASE_REF="$(bash "$SC" base-ref)" || { echo "base-ref falló: no adivino una base" >&2; exit 1; }
    BASE_BRANCH="$(bash "$SC" base-ref --name)" || { echo "base-ref --name falló: no adivino una base" >&2; exit 1; }
    git diff "$BASE_REF...HEAD" --stat
    git log --oneline "$BASE_REF..HEAD"
    

    base-ref imprime el base_ref declarado del sidecar cuando lo hay, y de lo contrario el valor predeterminado origin/HEAD. En una salida distinta de cero, no imprime ningún ref: deténgase y transmita su stderr en lugar de adivinar una base. Para un slice de PR apilado, ninguna variable establecida aquí llega a un bloque posterior: coloque el nombre de la rama del slice hermano (el upstream al que se dirigirá el PR) en el marcador de posición BASE_BRANCH= de cada bloque que lo consume (el bloque de la Fase 2 para su backend y el bloque de sello de la Fase 4). Si no hay diff desde la base, dígale al usuario que no hay nada que revisar y deténgase.

    Residual: $BASE_REF solo está tan actualizado como el último git fetch. Cuando origin/<base> no se resuelve, base-ref mide contra la rama local y lo dice en stderr; si los recuentos parecen incorrectos, haga git fetch y vuelva a ejecutar.

  4. Decida el alcance — todo el slice, o el delta posterior a la marca. Esta decisión es solo para el modo Autor. El modo Bucle la omite y establece SCOPE_FROM="$BASE_REF" incondicionalmente, leyendo toda la rama en cada invocación, según la viñeta del modo Bucle de la Fase 3. Una primera revisión lee todo el slice: sidecar.sh range da su extremo izquierdo, que es el inicio registrado del slice cuando el elemento de trabajo del paso 2 nombrado tiene uno todavía en esta rama, y $BASE_REF en caso contrario, por lo que en el backend github un slice es toda la rama. Una re-ejecución contra un PR que esta habilidad ya selló, cuya cabeza se ha movido desde entonces — una ronda de /fix-findings, o una corrección manual después de una eliminación deliberada de bloqueo — toma el delta posterior a la marca como su sujeto. El sello vive donde backend stamp dice, según references/state-backend.md: el cuerpo del PR, o el sidecar. Lea el cuerpo del PR con la misma expresión que usa el Paso 2 de /closeout; scripts/test-review-currency-marker.sh fija los dos byte-idénticos, y scripts/test-delta-review-scope.sh ejecuta este bloque contra un fixture para cada estado de rama que nombra, en ambos backends:

    SC="<directorio de esta habilidad>/references/sidecar.sh"
    case "$(bash "$SC" backend stamp)" in
      sidecar)
        REVIEWED_SHA=$(bash "$SC" stamp read "$(git branch --show-current)") ;;
      github)
        REVIEWED_SHA=$(gh pr list --head "$(git branch --show-current)" --json body -q '.[0].body // ""' \
          | sed -n 's/.*<!-- reviewed-at: \([0-9a-f]\{40\}\) -->.*/\1/p' | tail -1) ;;
      *) echo "alcance abortado: sidecar.sh backend stamp falló; no adivino la ruta de github" >&2; exit 1 ;;
    esac
    W="<el W-<n> nombrado en el paso 2, o vacío en el backend github>"
    BASE_REF="$(bash "$SC" base-ref)" || { echo "alcance abortado: sidecar.sh base-ref falló" >&2; exit 1; }
    RANGE="$(bash "$SC" range ${W:+"$W"})" || { echo "alcance abortado: sidecar.sh range falló" >&2; exit 1; }
    SLICE_FROM="${RANGE%%..*}"
    SCOPE_FROM="$SLICE_FROM"
    if [ -n "$REVIEWED_SHA" ] \
      && git merge-base --is-ancestor "$REVIEWED_SHA" HEAD 2>/dev/null \
      && [ "$REVIEWED_SHA" != "$(git rev-parse HEAD)" ] \
      && [ -z "$(git log --merges --format=%H "$REVIEWED_SHA..HEAD")" ]; then
      SCOPE_FROM="$REVIEWED_SHA"
    elif [ -n "$REVIEWED_SHA" ] \
      && ! git merge-base --is-ancestor "$REVIEWED_SHA" HEAD 2>/dev/null \
      && [ "$(git rev-parse -q --verify "$REVIEWED_SHA^{tree}")" = "$(git rev-parse 'HEAD^{tree}')" ]; then
      SCOPE_FROM="HEAD"
    fi
    if [ "$SCOPE_FROM" = HEAD ]; then
      echo "alcance de revisión: ninguno, reescritura solo de historial — HEAD lleva el árbol revisado en $REVIEWED_SHA"
    elif [ "$SCOPE_FROM" = "$BASE_REF" ]; then
      echo "alcance de revisión: rama completa, desde $BASE_REF"
    elif [ "$SCOPE_FROM" = "$SLICE_FROM" ]; then
      echo "alcance de revisión: slice completo, desde $SLICE_FROM (inicio registrado de $W)"
    else
      echo "alcance de revisión: delta posterior a la marca, desde $SCOPE_FROM"
    fi
    git diff "$SCOPE_FROM...HEAD" --stat
    git log --oneline "$SCOPE_FROM..HEAD"
    

    Cuatro estados recurren al slice completo, cada uno a propósito: sin sello (una primera revisión, o un PR creado manualmente); un sello que no es un ancestro de HEAD y cuyo árbol HEAD ya no lleva (la rama fue reescrita y el contenido cambió con ella, o el commit revisado se ha ido — /closeout llama a esto la señal de divergencia más fuerte, y no es una revisión más pequeña); un sello igual a HEAD (nada nuevo a qué alcance); y un commit de fusión después del sello (el diff posterior a la marca llevaría los cambios de la propia rama base, que nadie en esta rama escribió). El slice completo es toda la rama a menos que range haya encontrado un inicio registrado, y cuando encuentra uno que un pliegue o rebase reescribió, lo dice en stderr y responde $BASE_REF, nunca re-anclando el inicio. La decisión se imprime para que la lectura de la terminal y el PR digan lo mismo sobre lo que se leyó.

    Una reescritura que mantuvo el árbol revisado no es una divergencia. Cuando el commit sellado no es un ancestro de HEAD pero aún existe localmente y lleva el mismo árbol que HEAD, el historial cambió y el contenido no: el pliegue que ofrece la transferencia de la Fase 4 (git rebase -i --autosquash) produce exactamente esto. El bloque imprime alcance de revisión: ninguno y establece SCOPE_FROM="HEAD". Omita la Fase 3 y todo en la Fase 4 excepto el sello, que re-sella en HEAD, y el menú de transferencia. El sello certifica el contenido revisado, y un hash de árbol es ese contenido exactamente. Si el commit sellado no está disponible localmente, el árbol no se puede comparar y la reescritura toma la alternativa de rama completa anterior.

    En una re-ejecución delta, el delta es el sujeto y el árbol aún es legible. Informe a cada revisor de la Fase 3 con los hallazgos que los commits posteriores a la marca afirman cerrar — la lectura anterior en esta sesión, el registro si el modo bucle escribió uno (donde references/state-backend.md § Dónde viven los registros de la revisión dice), o los propios mensajes de commit — con los veredictos del interruptor /fix-findings cuando los haya, y con la salida de bash "$SC" profile, textualmente, que el contrato de la Fase 3 entrega a cada revisor. La primera pregunta por commit es si la corrección cierra su hallazgo en cada sitio que el hallazgo nombró, que es la dimensión de Integridad de la Corrección; la segunda es...

[truncado para traducción]

Individual skills in this repo

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

chrislacey89/closeout

Primary pipeline tail step after /pre-merge, when a reviewed PR is ready to land and you want the workspace back to a clean base. Use to merge, switch off the worktree before removing it, prune the merged branch, pull base, and verify a clean end state. Triggers on 'close out', 'merge and clean up', 'get back to a clean main/base', 'tear down the worktree'. Not for capturing lessons (that's /compound), or closing the PRD and any other open slices and research-artifact hygiene (that's the cleanup prose in SYSTEM-OVERVIEW Step 9).

chrislacey89/compound

Primary pipeline knowledge-capture step that closes the compounding loop. Capture a durable lesson in docs/solutions/ onto the open PR before /closeout merges (the default), or post-merge when the lesson only surfaces during/after merge. Use so future /research and /write-a-prd runs improve. Not for trivial edits with no reusable project-level learning, and not for the merge/teardown itself (that's /closeout).

chrislacey89/excavate

User-invoked side-route for onboarding to a legacy repo with no docs/solutions/, research archive, or written decisions. Mines the last 12 months of git history and, when gh is available, PR bodies and review threads, into ranked hotspots, cited recovered decisions, and a who-to-ask map, then offers a PR of docs/solutions/ entries. Not for repos that already compound, not for judging people, not model-invoked.

chrislacey89/execute

Primary pipeline execution step after /prd-to-issues or for clearly scoped implementation work. Use to build, verify, and commit a concrete slice, delegating to /tdd for backend work and behavior-heavy frontend logic when red-green-refactor will reduce risk. Not for shaping or pre-merge review.

Skills relacionados