Skill: Crear Pull Request (PR / MR)
Crear un PR o MR desde la rama actual hacia una rama destino preguntada al usuario, sobre cualquier repo git con remoto configurado.
Origen = rama actual, sin excepción. Hay dos modos válidos, que el skill deduce del par origen→destino (ver Modos: implementación y promoción):
- PR de implementación — de una rama de trabajo (
feature/,fix/,chore/,refactor/,test/,hotfix/…) a su rama de integración o despliegue. Es el caso por defecto.- PR de promoción — de una rama de integración a una de despliegue (
develop → master,develop → release/x,release/x → main). No trae código nuevo: consolida trabajos que ya pasaron sus puertas al integrarse.El modo lo decide una sola tabla de decisión, evaluada en el Paso 3 con el destino ya conocido; ver Modos: implementación y promoción. Ahí se define también cuándo se para y cuándo se pregunta.
Working tree sucio no detiene el flujo: si hay cambios sin commitear, el skill invoca automáticamente el flujo del skill
git-commit(sin preguntar al usuario si desea commitear — la decisión de invocarlo es automática) y, una vez el working tree queda limpio, continúa con el resto del pre-flight. Nota:git-commitno tiene modo silencioso — un commit único lo ejecuta sin confirmar, pero puede pausar para confirmar su propuesta de división cuando el diff se reparte en varios commits (concommitConfirmation = always) y puede detenerse del todo ante secretos, rama protegida o hook fallido; ese comportamiento no se suprime al invocarlo desde aquí.Plataforma se auto-detecta del remoto
origin. No preguntar.Puertas de calidad obligatorias y bloqueantes: en un PR de implementación se ejecutan siempre
quality-check,code-reviewytrace-validate; en uno de promoción, soloquality-check. En ambos modos, si existe la Definition of Done (docs/policies/definition-of-done.md), se verifica. Todas las que apliquen deben quedar en aprobado; si alguna no lo está, no se crea el PR. No hay flujo "crear como draft" ni "ignorar y continuar", ni forma de saltarse una puerta que aplica.No incluye: modificar código por iniciativa propia, merges, rebases, resolver conflictos, asignar reviewers/labels/milestones, editar PRs existentes. (Las correcciones solo se aplican si el usuario las autoriza explícitamente — ver Manejo de fallos en las puertas.)
Modos: implementación y promoción
El ciclo normal tiene dos saltos, no uno: el trabajo se implementa en una rama, se integra en una rama de integración (develop), y desde ahí varios trabajos se promueven juntos a una rama de despliegue (master, main, release/*). Este skill cubre los dos.
| PR de implementación | PR de promoción | |
|---|---|---|
| Origen | Rama de trabajo: prefijo feature/, fix/, chore/, refactor/, test/, hotfix/, o el equivalente del repo |
Rama de integración o de despliegue: develop, release/*, main, master, trunk |
| Destino | Su rama de integración | Otra rama de integración/despliegue, aguas abajo |
| Qué aporta | Código nuevo, aún sin revisar | Nada nuevo: consolida trabajos ya integrados |
| Puertas | quality-check + code-review + trace-validate (+ DoD) |
quality-check (+ DoD). Ver Puertas en un PR de promoción |
| Descripción | Commits del rango + ticket | Trabajos que se promueven (US-XXX/WI-XXX) + delta de commits |
Tabla de decisión. Es la única regla de clasificación del skill; se evalúa en el Paso 3, con el destino ya conocido. El Paso 1 no clasifica ni para: solo detecta si el origen tiene prefijo de implementación.
| # | Origen | Destino | Resultado |
|---|---|---|---|
| 1 | Prefijo de implementación (feature/, fix/, chore/, refactor/, test/, hotfix/, o el equivalente del repo) |
Rama de integración/despliegue | PR de implementación. Camino por defecto, sin confirmación. |
| 2 | Rama de integración/despliegue | Otra, aguas abajo | PR de promoción, previa confirmación (ver abajo). |
| 3 | Rama de integración/despliegue | Aguas arriba, o la misma | Parar. No es una promoción. |
| 4 | Cualquiera | Rama de implementación | Parar. Este skill no abre PRs hacia una rama de trabajo. |
| 5 | Sin prefijo reconocible y que no es rama de integración | Cualquiera | Preguntar a qué categoría pertenece la rama (hotfix-cache, PROJ-1234…). Si el usuario la sitúa, aplicar la fila que corresponda; si no, parar. No clasificarla como promoción por descarte. |
La confirmación de la fila 2 no se omite nunca. Estar parado en develop también es lo que ocurre cuando alguien olvidó cambiar de rama —lo típico justo después de work-integrate, que deja HEAD en la base—, y ahí el PR correcto es otro. Es la única defensa contra ese error.
Qué cuenta como rama de integración o despliegue. Por defecto
main,master,develop,trunkyrelease/*. Si el repo usa otros nombres (staging,uat,qa,produccion) y el usuario indica uno como destino, tratarlo como tal: el destino manda. No inventar una jerarquía propia ni exigir que el repo siga git-flow.
Qué es «aguas abajo». El orden canónico del ciclo es:
rama de implementación → develop → release/* → main | master
El destino está aguas abajo si aparece a la derecha del origen en ese orden. develop → master lo está; master → develop no, y por eso la fila 3 lo corta. No usar «la rama de la que nace» como criterio: en git-flow develop nace de master, así que esa lectura clasificaría la promoción canónica como marcha atrás y desactivaría el modo entero. Si el repo usa otros nombres, el orden lo fija el usuario al indicar el destino; ante duda sobre la dirección, preguntar en vez de asumir.
Sincronizar una rama hacia atrás (traer master a develop tras un hotfix) es un merge o un rebase, no un PR de este skill.
Detección de plataforma
Heurística por host de git remote get-url origin:
| Host | Plataforma | CLI |
|---|---|---|
github.com o GitHub Enterprise |
GitHub | gh |
gitlab.com o host GitLab self-managed |
GitLab | glab |
bitbucket.org |
Bitbucket Cloud | REST + curl (o CLI instalado) |
Host con segmento /scm/ o Bitbucket Server |
Bitbucket Server | REST + curl |
dev.azure.com o *.visualstudio.com |
Azure Repos | az repos |
| Marcadores de Gitea/Forgejo | Gitea | tea |
| Cualquier otro | — | Probar CLI conocido instalado; si nada encaja, parar y avisar |
Verificar que el CLI elegido está instalado (<cli> --version); si falta, parar y avisar. Las credenciales son responsabilidad del entorno del usuario (variables de entorno, ~/.netrc, config previa del CLI).
Rutas de las referencias compartidas
${PLUGIN_ROOT} es la raíz del plugin instalado (la carpeta que contiene skills/, agents/ y reference/), y toda referencia compartida de este skill se escribe como ${PLUGIN_ROOT}/reference/<archivo>.md. Resolverla así, en este orden: (1) en Claude Code, ${PLUGIN_ROOT} es ${CLAUDE_PLUGIN_ROOT} — comprobar con echo "$CLAUDE_PLUGIN_ROOT" y usar ese valor; (2) en cualquier otro cliente, o si la variable está vacía, la carpeta desde la que se cargó este archivo, dos niveles arriba. El destino de cada enlace markdown (../../reference/…) existe solo para navegar el repositorio en GitHub o en un editor: no resolverlo desde el directorio de trabajo. Nunca buscar reference/ en el proyecto: un <proyecto>/reference/language.md que no existe no es un archivo que falte, es una ruta mal resuelta — corregir la raíz y volver a leer, sin preguntar al usuario ni saltarse la lectura.
Resolución de idioma
Antes de ejecutar este skill, DEBES leer ${PLUGIN_ROOT}/reference/language.md.
Las reglas de language.md son obligatorias y tienen prioridad para determinar el idioma de todos los artefactos y mensajes generados por este skill.
No continúes hasta haber leído y aplicado language.md.
Excepción deliberada: un título o descripción explícitos del usuario se respetan literalmente, en el idioma en que los escribió. Cuando el idioma resuelto obliga a traducir el título, el prefijo de ticket ([US-042], [TK-007]) se mantiene intacto; los subjects de commits citados en la descripción no se traducen: van literales para preservar la trazabilidad. Si language.md llega a su paso de preguntar, ofrecer como opción por defecto el idioma predominante de los commits del rango origin/<destino>..HEAD — pero preguntar igual, no decidirlo por cuenta propia.
Flujo
Paso 1 — Pre-flight (obligatorio antes de cualquier acción)
git rev-parse --is-inside-work-tree— confirmar repo git.git rev-parse --abbrev-ref HEAD— obtener rama actual.- Caracterizar la rama actual — sin clasificar el modo ni parar: eso es del Paso 3, que ya conoce el destino. Anotar simplemente en cuál de las tres categorías cae:
- de implementación (prefijo
feature/,fix/,chore/,refactor/,test/,hotfix/, o el equivalente del repo), - de integración o despliegue (
develop,release/*,main,master,trunk, o la que el repo use), - ninguna de las dos (rama suelta como
hotfix-cacheoPROJ-1234) → se resolverá preguntando al usuario en el Paso 3, no parando aquí.
- de implementación (prefijo
git status --porcelain— si no está vacío, invocar automáticamente el flujo del skillgit-commitsobre los cambios pendientes (sin preguntar al usuario si desea commitear) y esperar a que termine. La invocación delega engit-committodo su criterio operativo (agrupación por cambio lógico, inferencia de tipo/scope/mensaje, staging, detección de secretos, confirmación de la propuesta de división) —pr-createno decide un mensaje de commit ni qué stagear por su cuenta; solo dispara el flujo y espera su resultado.git-commitno tiene modo silencioso: un commit único lo ejecuta sin confirmar, pero puede pausar para confirmar su propuesta de división cuando el diff se reparte en varios commits (concommitConfirmation = always), y puede detenerse ante secretos, rama protegida o hook fallido. «Sin preguntar al usuario» se refiere solo a quepr-createno pide permiso para invocargit-commit, no a que esas pausas y paradas propias degit-commitdesaparezcan.- Si
git-commitno está disponible (skill no instalado o no localizable en el entorno): parar y avisar, mostrando los archivos pendientes y sugiriendo al usuario commitear manualmente antes de reintentar — no ejecutargit add/git commitdirectos como sustituto. - Si
git-commitdeja el working tree completamente limpio, continuar con el resto del pre-flight. - Si
git-committermina dejando el working tree parcialmente limpio por una decisión de alcance suya (p. ej. agrupó y commiteó unos archivos pero dejó otros fuera deliberadamente, o el usuario excluyó algunos de un commit propuesto): no es un error depr-create. Volver a comprobargit status --porcelain; si sigue habiendo cambios, invocargit-commitde nuevo sobre el remanente (mismo criterio, sin preguntar) hasta que quede limpio ogit-commitse detenga por un motivo real (secretos, o una decisión que no puede resolver solo). - Si se detiene sin commitear (p. ej. por detección de secretos, o porque requiere una decisión del usuario que el propio
git-commitno puede resolver solo), parar y avisar con el motivo que reportógit-commit.
- Si
Paso 2 — Detectar plataforma y CLI
Aplicar la tabla de detección. (La comprobación de «PR ya existente» necesita el destino, así que se hace al final del Paso 3, no aquí.)
Paso 3 — Preguntar destino y cerrar el modo
- Rama destino (pregunta única): validar que existe en
origin(git ls-remote --heads origin <destino>) y que no coincide con la rama actual. - Verificar que hay algo que integrar:
git rev-list --count origin/<destino>..HEAD. Si es0, parar y avisar — el PR saldría vacío. Aplica a los dos modos. - Extraer los trabajos del rango (ver Paso 7 para el orden de degradación). Hace falta aquí, no solo en el Paso 7: el mensaje de confirmación del punto 5 los enumera.
- Clasificar el modo aplicando la tabla de decisión de Modos: implementación y promoción sobre el par origen→destino. Si la rama actual no encajaba en ninguna categoría (fila 5), preguntar ahora al usuario a cuál pertenece.
- Si el resultado es promoción, confirmar la intención antes de continuar: «Vas a crear un PR de promoción de
<origen>a<destino>: N commits, trabajos X, Y, Z. ¿Es lo que quieres, o te olvidaste de cambiar a tu rama de trabajo?». Sin confirmación no se sigue. - PR ya existente: con origen y destino resueltos, comprobar si hay un PR abierto para
<rama-actual> → <destino>; si lo hay, capturar su URL y devolvérsela al usuario sin crear uno nuevo.
Las puertas que aplican al modo no se preguntan: son obligatorias (ver Paso 4) y no hay opción de saltarlas. Que en una promoción no corran code-review ni trace-validate no es una excepción concedida al usuario: es que su unidad de análisis no existe en ese modo.
Paso 4 — Puertas de calidad (obligatorias, bloqueantes)
Antes de cualquier push o creación de PR se ejecutan las puertas que aplican al modo, en este orden. Una puerta que aplica y no queda en aprobado detiene el flujo: no se hace push ni se crea el PR. Ver Manejo de fallos en las puertas para qué hacer ante un fallo.
| Puerta | PR de implementación | PR de promoción |
|---|---|---|
4.1 quality-check |
Obligatoria | Obligatoria |
4.2 code-review |
Obligatoria | No aplica |
4.3 trace-validate |
Obligatoria | No aplica |
| 4.4 Definition of Done | Si existe el archivo | Si existe el archivo |
4.1 — quality-check (siempre). Invocar el flujo de quality-check (verificaciones automatizadas: tipado, linter, validaciones de arquitectura, unit, coverage, build, e2e, sonar, más las suites que declare el estándar de testing) sobre la rama.
- Aprobado =
verdict=APPROVEDen la marca de pie → continuar (aunque haya warnings o resultados informativos). - Rechazado =
verdict=REJECTEDoverdict=INCOMPLETE→ detener.
Cómo se lee un veredicto. Los informes de las puertas se redactan en el idioma resuelto del repo, así que ni la palabra ni el símbolo del encabezado son comparables. Lo que se lee es la marca oculta del pie del informe:
<!-- <skill>:verdict=<VALOR> … -->.APPROVEDdeja pasar;REJECTEDeINCOMPLETEbloquean;APPROVED_WITH_NOTES(solotrace-validate) no bloquea: se muestran las observaciones y se continúa. Contrato completo en${PLUGIN_ROOT}/reference/verdicts.md.
Este es el punto de cierre donde
quality-checkejecuta la batería completa y persistetest-run.json. El orden importa:4.1antes de4.3permite quetrace-validatereutilice esa corrida sin re-ejecutar las pruebas. La misma caché deja fresca la entradaarchitecture, quearch-auditreutiliza si se audita después sin tocar el código.
4.2 — code-review (solo en PR de implementación). Invocar el flujo de code-review (revisión cualitativa: intención, arquitectura y diseño) con base origin/<destino>, su alcance por defecto (todo lo que la rama difiere de esa base, incluidas las correcciones que 4.1 haya podido dejar sin commitear). Emite un veredicto propio e independiente del de 4.1; ninguno sustituye al otro. Si el docs/audits/code-review.md existente ya estaba fresco y aprobado (mismo fingerprint, misma base y mismo modo, y 4.1 no aplicó correcciones), lo devuelve sin volver a revisar — no forzar revalidate desde aquí. Un informe previo en ❌/⚠️ nunca se sirve desde caché: code-review lo revisa de nuevo por su cuenta.
- Aprobado =
verdict=APPROVEDen la marca de pie → continuar. - Rechazado =
verdict=REJECTEDoverdict=INCOMPLETE→ detener.
4.3 — trace-validate (solo en PR de implementación). Resolver el trabajo a validar (US-XXX o WI-XXX) del patrón de la rama, del prefijo de los commits, o de la ruta de trabajo. trace-validate traza los criterios de aceptación AC-XXX del trabajo (mismo formato en US y WI). Si no se puede determinar el trabajo, preguntar al usuario cuál validar; si no lo provee, la puerta no puede quedar aprobada → detener. Invocar trace-validate sobre ese trabajo. Reutiliza el test-run.json producido por 4.1 (misma rama, sin cambios) y, si el coverage.md ya estaba fresco, lo devuelve sin regenerarlo.
- Aprobado =
verdict=APPROVEDen la marca de pie → continuar. El⚠️de esta puerta esAPPROVED_WITH_NOTESy también se considera aprobado, pero se muestran las observaciones al usuario antes de seguir. - Rechazado =
verdict=REJECTED→ detener.
4.4 — Definition of Done (solo si existe el archivo). Comprobar si existe docs/policies/definition-of-done.md en la raíz del repo (test -f docs/policies/definition-of-done.md).
Ningún skill del plugin genera ese archivo: lo escribe y lo mantiene el equipo. Es deliberado —una Definition of Done es un acuerdo del equipo, no un artefacto derivable— y por eso la puerta es condicional: en un repo que no lo tenga, simplemente no aplica. Si el usuario pregunta cómo tenerla, indicarle que basta con crear ese archivo con una checklist de condiciones de cierre verificables; no ofrecer generarla por él.
- Si no existe → omitir esta puerta (no afecta el resultado).
- Si existe → leerla y verificar el código/cambio contra cada política/ítem de esa Definition of Done, sobre el rango
origin/<destino>contra el estado actual del árbol, de modo que incluya las correcciones que las puertas anteriores hayan podido dejar sin commitear (el mismo alcance que4.2en un PR de implementación; en una promoción, donde4.2no corre, el rango sigue siendo ese). Formato esperado dedocs/policies/definition-of-done.md: un documento de política con ítems/checklist verificables (cada ítem una condición concreta de cierre). El skill solo evalúa automáticamente los ítems comprobables desde el repo o el diff; para el resto, pregunta.- Ítems comprobables desde el repo/diff → evaluarlos directamente: cumplido / incumplido.
- Ítems no comprobables automáticamente → presentarlos al usuario y preguntarle si se cumplen (no inventar su cumplimiento). Si el usuario confirma que se cumplen → cuentan como cumplidos. Si no los confirma o los marca incumplidos → cuentan como incumplidos.
- Aprobado = todos los ítems aplicables se cumplen (los comprobables verificados + los no comprobables confirmados por el usuario) → continuar.
- Rechazado = al menos un ítem incumplido, o algún ítem no comprobable que el usuario no confirma → la puerta no queda aprobada → detener, listando qué ítem(s) de la DoD no se cumplen o quedan sin confirmar.
Solo si todas las puertas aplicables quedan en aprobado se avanza al Paso 5 (archivado, solo implementación) y de ahí al push.
Puertas en un PR de promoción
Una promoción no introduce código nuevo: cada trabajo que viaja en ella ya pasó las tres puertas cuando se integró en la rama de integración. Repetirlas aquí no descubre nada y sale caro. Lo que sí queda por demostrar —y nadie verificó feature por feature— es que la rama consolidada está verde: eso es exactamente quality-check.
| Puerta | Por qué no aplica |
|---|---|
code-review |
Su unidad es un diff sin revisar. En una promoción, todo el diff origin/<destino>..HEAD ya fue revisado y aprobado PR a PR; volver a pasarlo sería revisar diez diffs ya cerrados y produciría hallazgos sobre código que ya se justificó en su momento. |
trace-validate |
Valida un artefacto contra sus criterios de aceptación. Una promoción abarca varios trabajos, así que no hay un artefacto que validar; y cada uno ya trae su coverage.md aprobado. |
Reglas al reportar:
- En el resumen al usuario y en la descripción del PR, esas dos puertas se listan como
N/A(—) con el motivo «PR de promoción». No se omiten en silencio ni se marcan como aprobadas: quien lea el PR debe ver que no corrieron y por qué. - La Definition of Done sí aplica, si el archivo existe: sus ítems suelen ser condiciones de despliegue (changelog, versión, migraciones revisadas) que es justo aquí donde toca comprobar. Su alcance es el mismo rango
origin/<destino>..HEAD. - Si el usuario pide expresamente una revisión adicional, se puede invocar
code-reviewotrace-validatea mano; no es parte del flujo ni condiciona la creación del PR.
Paso 5 — Archivar el artefacto de trabajo (solo PR de implementación)
Con todas las puertas del Paso 4 en aprobado, el trabajo está listo para integrarse: mover su carpeta de especificación a docs/archive/ en la rama actual, antes del push, para que el archivado viaje dentro del PR y se integre en el mismo merge que el código. Si el archivado no aplica (promoción, rama test/, carpeta ya archivada), no se resuelve archiveMode ni se pregunta nada — se salta el paso.
Si aplica, resolver implementation.archiveMode (ver ../work-integrate/references/archive.md): con ask (por defecto), ofrecer al usuario el movimiento y preguntar primero, mover después — sin un sí explícito no se mueve nada; con always, mover directo sin preguntar; con never, no archivar ni preguntar. En los tres casos, no archivar no impide crear el PR: se anota como omitido en el Paso 9 (con el motivo: declinado, never, o sin canal para preguntar) y el flujo sigue.
Localizar la carpeta y verificar el progress.md. Buscar primero en la ruta activa (docs/specs/<user-stories|work-items>/<ID>-<slug>/) y, si no está ahí, en docs/archive/: si aparece en el archivo, el trabajo ya estaba archivado — informarlo en el reporte y saltar el resto del paso, no es un error.
En la ruta activa, leer su progress.md y comprobar que todas las unidades del trabajo están en Done — a diferencia de work-integrate, este skill no lo valida en su pre-flight, así que se hace aquí. Si alguna no lo está, o si el progress.md no existe, no se archiva: el PR sí se crea (las puertas pasaron; no es este el momento de bloquearlo) y se avisa en el reporte del Paso 9 — «No se archivó US-XXX: TK-002 en In Progress».
| Aplica a | US-XXX y WI-XXX en un PR de implementación |
| No aplica a | PR de promoción (cada trabajo ya se archivó al integrarse); cualquier rama test/, sea sobre FT-XXX, US-XXX o WI-XXX (cierra unos TC-XXX, no el artefacto); trabajos cuyo progress.md no esté completo en Done (se avisa, no se bloquea); y trabajos cuya carpeta ya esté bajo docs/archive/ (ya archivados: se informa y se sigue) |
| Destino | docs/archive/user-stories/US-XXX-{slug}/ · docs/archive/work-items/WI-XXX-{kebab-case}/ · investigaciones RS-XXX sueltas que quedan huérfanas: docs/archive/research/RS-XXX-{slug}/ |
| Confirmación | Según implementation.archiveMode. Con ask (por defecto), obligatoria: se muestra qué se movería (carpeta + investigaciones huérfanas) y se pide confirmación con la herramienta de preguntas estructuradas — sin un sí explícito no se mueve nada. Con always, se mueve directo. Con never, no se mueve nada. En ningún caso archivar (o no hacerlo) impide crear el PR. Sin canal de respuesta con ask: no se archiva. Se reporta el desenlace en el Paso 9. |
El trabajo a archivar es el mismo que resolvió 4.3 (trace-validate); no volver a deducirlo por otra vía. Si 4.3 no corrió porque el modo es promoción, este paso entero se omite. Que 4.3 resuelva un US-XXX desde una rama test/US-XXX no habilita el archivado: ese PR cierra la automatización de unos TC-XXX, no la historia.
El orden importa: 4.3 escribe el coverage.md dentro de la carpeta del trabajo, así que archivar antes lo dejaría escribiendo en una ruta que ya no existe. Y archivar después del push dejaría el movimiento fuera del PR.
El git mv queda stageado sin commitear: lo recoge la re-comprobación del working tree del Paso 6. No commitear aquí.
Procedimiento completo —guards de destino, investigaciones RS-XXX sueltas que quedan huérfanas, reparación de enlaces relativos, formato del reporte, anti-patrones— en work-integrate/references/archive.md. Es el mismo procedimiento en los dos skills: no reimplementarlo aquí ni divergir de él.
Si el git mv falla (destino ya ocupado, origen inexistente con destino presente), aplicar lo que dice esa referencia: parar e informar en el primer caso, informar y continuar en el segundo. No se crea el PR con un archivado a medias.
Paso 6 — Push de la rama actual
Antes del push, re-comprobar el working tree. Las puertas del Paso 4 pueden haber dejado cambios sin commitear (correcciones aplicadas por quality-check o delegadas en work-implement), y el Paso 5 deja stageado el renombrado del archivado, si el usuario lo confirmó. Ejecutar git status --porcelain y, si hay salida, invocar de nuevo git-commit con el mismo criterio del pre-flight: el código que se sube debe ser exactamente el que las puertas verificaron. El archivado del Paso 5 es la única salvedad, y es deliberada: mueve documentación bajo docs/specs/, no toca código ni fuentes de prueba, así que no invalida los veredictos de quality-check ni de code-review. Sí desplaza el SPEC_FINGERPRINT de trace-validate, cuyo coverage.md se regenerará una vez en la siguiente validación. En modo promoción, borrar antes docs/audits/quality-check.md del árbol y, si develop lo traía trackeado, retirarlo del índice — ver la nota siguiente. Solo entonces re-comprobar el estado e invocar git-commit.
.sdd-devkit/test-run.jsonnunca se commitea, en ninguno de los dos modos: está en el.gitignoreporque es una caché local y desechable, y un resultado de pruebas producido en otra máquina no es evidencia aquí. Nada de lo que sigue desplaza el fingerprint de frescura:.sdd-devkit/cae bajo la exclusión de carpetas ocultas ydocs/bajo la suya.En un PR de implementación, los informes viajan en el PR. Las puertas escriben
docs/audits/quality-check.md,docs/audits/code-review.mdy elcoverage.mddel trabajo; ese commit los incluye a propósito, para que el revisor vea los tres veredictos junto al cambio. Pero los dos dedocs/audits/son fotos de esta rama y no deben quedarse en la de destino: su encabezado lleva la rama y el commit sobre los que se corrieron las puertas, endevelopafirmarían un veredicto que nadie ejecutó allí, y como viven en una ruta fija, cada rama que se integre los pisaría.work-integratelos retira dentro del propio merge, pero aquí el merge lo hace la plataforma y este skill no lo controla. De ahí dos cosas:
- Decirlo en el cuerpo del PR. La descripción que compone el Paso 7 cierra con esta línea: «
docs/audits/quality-check.mdydocs/audits/code-review.mdson artefactos de esta rama — eliminarlos al integrar.»- Al reportar al usuario, recordar que tras el merge en la plataforma conviene borrarlos en la rama de destino (
git rm docs/audits/quality-check.md docs/audits/code-review.md), o integrar conwork-integrate, que ya lo hace solo. Solo esos dos: losarch-audit-*.md, las copias desave-reporty elcoverage.mddel trabajo sí pertenecen a la rama base.En un PR de promoción, el informe no llega a disco. Aquí la rama de origen ya es una rama de integración: commitear
docs/audits/quality-check.mdlo dejaría plantado endevelopy de ahí viajaría amastercon la promoción — el problema anterior, pero sin nadie que pueda limpiarlo después. El manejo, en el orden exacto en que ocurre:
- Tras leer el veredicto de
4.1, borrar el informe del árbol de trabajo conrm -f docs/audits/quality-check.md(rm, nogit rm: en la mayoría de repos ni siquiera está trackeado).- Si
developya lo traía trackeado —lo habitual si antes se integraron PRs de implementación que sí lo commiteaban—, retirarlo también del índice:git rm -q -f --ignore-unmatch ':(top,glob)**/docs/audits/quality-check.md' ':(top,glob)**/docs/audits/code-review.md'. Las rutas van ancladas a la raíz (:(top)) y con**/: en un monorepoquality-checkaudita el módulo elegido y escribe enpackages/<mod>/docs/audits/, que un pathspec literal no alcanzaría. Ese borrado sí se commitea: limpia la rama de integración de informes que nunca debieron llegar ahí.- El veredicto y el resumen van en la descripción del PR, que es donde el revisor de una promoción los necesita y que muere con el PR.
Por qué borrar y no «dejarlo sin commitear». Este skill no puede excluir un archivo del commit: delega en
git-commit, al que no se le puede imponer un alcance desde fuera (el suyo lo decide él), y el propio flujo manda reinvocarlo hasta que el árbol quede limpio — el remanente sería justo ese informe, así que o entra en bucle o se commitea lo que se quería evitar. Borrarlo deja el árbol limpio, que es la precondición que asumen tanto el push de este flujo como cualquier cambio de rama posterior — un archivo modificado sin commitear haría fallar ungit checkout.Si el usuario quiere constancia en disco de esa corrida,
save-reportdeja una copia con marca de tiempo que él puede commitear a mano.
Si la rama no existe en origin o tiene commits no publicados (git rev-list origin/<rama>..HEAD no vacío): ejecutar git push -u origin <rama-actual>. Nunca --force ni --force-with-lease. Si el push falla por divergencia: parar y avisar — el usuario decide cómo resolver.
En modo promoción, el push es a una rama protegida: confirmarlo. La rama actual es
develop, que tras uno o varioswork-integrateacumula merges locales que nadie ha publicado — ywork-integratedeja ese push explícitamente como decisión del usuario, fuera de su alcance. Antes de empujar, listar los commits que se van a publicar y pedir confirmación. Es la única operación de todo el flujo que escribe en una rama protegida del remoto; en modo implementación no aplica, porque ahí se empuja la rama de trabajo.
Paso 7 — Generar título y descripción
Sin pedir confirmación (salvo override explícito del usuario):
En un PR de implementación:
- Título: un único commit en el rango → su subject (
git log -1 --pretty=%s). Varios commits → subject del más antiguo. Si la rama sigue patrón<prefix>/<TICKET>-<desc>oUS-XXX-..., anteponer[<TICKET>]. Traducir al idioma resuelto manteniendo el prefijo de ticket intacto. - Descripción: lista de commits (
git log origin/<destino>..HEAD --pretty="- %s"), resumen de cambios (git diff --stat origin/<destino>..HEAD) y referencia a issue/ticket si el nombre de la rama lo contiene (patrónUS-XXX,TK-XXX,JIRA-XXX,#NNN).
En un PR de promoción, el rango son commits de merge de varios trabajos y una lista plana de subjects no dice nada útil:
Cómo se extraen los trabajos (también lo usa la confirmación del Paso 3). Probar en este orden y quedarse con el primero que dé resultado:
- Commits de merge:
git log origin/<destino>..HEAD --merges --pretty="- %s", buscandoUS-XXX/WI-XXX. - Identificadores en los subjects de todos los commits del rango — necesario cuando la plataforma integró con squash merge, que no deja commits de merge.
- Nombres de rama presentes en el rango.
Si ninguno da nada, no inventar: el título va sin lista y la confirmación del Paso 3 se formula por delta («N commits») en lugar de enumerar trabajos.
- Commits de merge:
Título:
Promoción <origen> → <destino>, más los identificadores si se obtuvieron (p. ej.Promoción develop → master (US-042, US-047, WI-007)) o(N commits)si no. Sin prefijo de ticket: no hay uno solo.Descripción: los trabajos que se promueven, el delta (
git rev-list --count origin/<destino>..HEADcommits) y el resumen de cambios (git diff --stat origin/<destino>..HEAD). Si algún commit del rango no mapea a ningún trabajo, listarlo aparte como «commits sueltos»: es información que el revisor de una promoción quiere ver.Veredictos de las puertas: el de
quality-checkcon su resumen —aquí va el contenido, no un enlace: el informe no se commitea en este modo— y las otras dos comoN/A(—) con el motivo «PR de promoción», con el motivo en una línea.
Solo en implementación, si el commit de las puertas incluyó informes en docs/audits/, añadir como última línea: «docs/audits/quality-check.md y docs/audits/code-review.md son artefactos de esta rama — eliminarlos al integrar.» Ver la nota del Paso 6.
Paso 8 — Crear PR/MR
| Plataforma | Comando |
|---|---|
| GitHub | gh pr create --base <destino> --head <rama> --title "<título>" --body "<desc>" |
| GitLab | glab mr create --target-branch <destino> --source-branch <rama> --title "<título>" --description "<desc>" --yes |
| Bitbucket Cloud | POST https://api.bitbucket.org/2.0/repositories/<workspace>/<repo>/pullrequests con payload JSON |
| Bitbucket Server | POST /rest/api/1.0/projects/<key>/repos/<slug>/pull-requests con payload equivalente |
| Azure Repos | az repos pr create --source-branch <rama> --target-branch <destino> --title "<título>" --description "<desc>" |
| Gitea/Forgejo | tea pr create --base <destino> --head <rama> --title "<título>" --description "<desc>" |
Si el CLI indica que ya existe un PR: capturar y devolver la URL existente.
Paso 9 — Reportar
✓ PR creado en <plataforma> Origen: <rama-actual> Destino: <rama-destino> Título: <título-generado> URL: <url>
En un PR de implementación, añadir debajo el desenlace del archivado del Paso 5:
- Si se archivó — el bloque con origen → destino de la carpeta y qué pasó con las investigaciones sueltas, con el formato de
work-integrate/references/archive.md. - Si no se archivó — una línea con el motivo: el usuario lo declinó, no había canal para confirmarlo, el
progress.mdno estaba completo enDone, o el trabajo ya estaba archivado. Nunca omitirlo en silencio.
En una promoción no aparece ninguna de las dos: el archivado no aplica a ese modo.
Bloqueo por una puerta de calidad:
✗ PR NO creado: la puerta <quality-check | code-review | trace-validate | definition-of-done> no quedó enAPPROVED. (En un PR de promoción solo pueden aparecer aquí quality-check y definition-of-done.) Veredicto: <REJECTED(quality-check) |INCOMPLETE(quality-check) |REJECTED(code-review) |INCOMPLETE(code-review) |REJECTED` (trace-validate) | DoD incumplida>
<reporte literal del skill, o lista de ítems de la DoD incumplidos>
Acciones para reintentar: ` Si la corrección está al alcance de este skill, ofrecer aplicarla antes de pedir acción manual (ver Manejo de fallos en las puertas).
Manejo de fallos en las puertas de calidad
Cuando una de las puertas del Paso 4 no queda en aprobado, detener el flujo (sin push ni PR) y, en este orden:
- Informar al usuario qué puerta falló, con su veredicto/motivo y el reporte literal del skill (o la lista de ítems de DoD incumplidos).
- Indicar las acciones concretas que debe tomar para dejar la puerta en aprobado y poder reintentar la creación del PR (p. ej. «corregir los tests fallidos de
X», «cubrir el criterioAC-003con un test», «cumplir el ítem "changelog actualizado" de la DoD»). - Si la corrección está al alcance de este skill, no aplicarla en automático: preguntar al usuario si desea que se aplique. Solo con su autorización explícita, aplicar la corrección mínima y reintentar la puerta que falló; si esa puerta vuelve a quedar aprobada, continuar con el resto del flujo (re-ejecutando las puertas posteriores que correspondan). Si el usuario no autoriza, terminar dejando las acciones indicadas.
Notas:
- Las correcciones dentro de
quality-check,code-reviewytrace-validatese gobiernan por el flujo propio de cada skill (que también exige autorización del usuario). No re-implementar esa lógica aquí. - Tras cualquier corrección autorizada, re-ejecutar la puerta afectada antes de avanzar; no asumir que quedó aprobada.
Ejemplos
Ejemplo 1 — Camino feliz (GitLab self-managed)
Usuario: «Crea el PR de esta rama.»
Skill: pre-flight OK (rama feature/US-042-auth-refresh-token). Detecta GitLab (ns.bayteq.com:3311). Pregunta destino → develop. Puertas: quality-check → APPROVED; code-review con base origin/develop → APPROVED; resuelve US-042, trace-validate → APPROVED; existe docs/policies/definition-of-done.md → todos los ítems cumplidos. Pregunta si archivar, mostrando docs/specs/user-stories/US-042-auth-refresh-token/ → docs/archive/user-stories/ más RS-003 (suelto, sin artefactos activos que lo referencien) → docs/archive/research/; el usuario confirma y git-commit recoge el renombrado. Push. Auto-genera título [US-042] feat(auth): refresh token con expiración 15min. Ejecuta glab mr create. Devuelve URL.
Ejemplo 2 — quality-check bloquea
quality-check devuelve REJECTED (tests fallidos + eslint errors). El skill no crea el PR, no hace push, muestra el reporte, lista las acciones para reintentar y —al estar a su alcance— pregunta si aplica la corrección. Si el usuario no autoriza, termina.
Ejemplo 3 — trace-validate bloquea
quality-check y code-review → APPROVED, pero trace-validate de US-042 devuelve REJECTED (criterio AC-003 sin test). El skill no crea el PR; informa que falta cubrir AC-003 y pregunta si desea que se intente la corrección (delegando al flujo correspondiente). Sin autorización, termina con las acciones indicadas.
Ejemplo 4 — Definition of Done incumplida
Las tres primeras puertas en aprobado, pero docs/policies/definition-of-done.md exige «CHANGELOG.md actualizado» y el diff no lo toca. El skill detiene la creación, lista ese ítem como incumplido e indica la acción; si el usuario autoriza y la corrección está a su alcance, la aplica y reintenta la puerta.
Ejemplo 5 — Sin Definition of Done
No existe docs/policies/definition-of-done.md. Esa puerta se omite; el PR se crea si las puertas del modo quedaron en aprobado — las tres en implementación, solo quality-check en promoción.
Ejemplo 6 — Azure Repos
origin apunta a https://dev.azure.com/<org>/<proyecto>/_git/<repo>. Detecta Azure Repos, verifica az repos, pregunta destino, ejecuta las puertas, push, crea PR con az repos pr create.
Ejemplo 7 — PR de promoción
Usuario en develop: «crea un PR a master.» El Paso 1 no bloquea: develop es rama de integración, así que el modo queda abierto. El Paso 3 ve que el destino es una rama de despliegue y confirma: «Vas a crear un PR de promoción de develop a master: 23 commits, trabajos US-042, US-047 y WI-007. ¿Es lo que quieres, o te olvidaste de cambiar a tu rama de trabajo?». Confirmado, corre quality-check (+ D
…(truncated)