Skill: Integración de trabajo
Guía para cerrar e integrar el trabajo ya implementado —una historia de usuario US-XXX o una tarea de mantenimiento WI-XXX— verificando que su progress.md tenga todas las unidades del trabajo en Done, que pasen las puertas de calidad de cierre (quality-check, code-review y trace-validate, en ese orden), y luego hacer merge de la rama actual hacia la rama desde la que se creó.
Alcance del submit: El skill cierra localmente lo ya implementado. Verifica condiciones, ofrece archivar el artefacto (mover su carpeta a docs/archive/, solo si el usuario lo confirma) y ejecuta git merge --no-ff. No hace push, no borra ramas, no crea MRs/PRs, no modifica el contenido de progress.md, y no resuelve conflictos —con la única salida declarada del modify/delete sobre los dos informes de docs/audits/, que se resuelve por el lado del borrado (ver references/flows.md). Lo que no esté en Done bloquea el merge — el usuario decide cómo proceder, nunca se fuerza.
Encaja al final de los ciclos work-define → work-plan → work-implement (historias y tareas de mantenimiento). Ver Handoffs del ciclo en references/examples.md.
Cómo preguntar al usuario
Mecanismo, ritmo y fallback compartidos: ${PLUGIN_ROOT}/reference/asking.md.
Cada vez que este skill o sus referencias digan preguntar, pedir, confirmar, validar o sugerir algo al usuario, asume ese mecanismo; no se repite allí.
La tanda inicial va antes de cualquier operación git y cubre: trabajo asociado a la rama, carpeta ambigua y rama base. No empezar a mover, mergear ni archivar con lagunas abiertas.
Excepción al ritmo: la confirmación del archivado (paso 11) va por fuerza después del merge — hasta entonces no se sabe si el trabajo llega a integrarse, y el cierre (Done + archivado) solo tiene sentido con el código ya en la rama base.
Rama base ambigua: listar los candidatos detectados como opciones tappables (p. ej. develop, main, release/2026.q2); no proponer un default implícito.
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.
Resolución de las puertas de cierre
Antes de ejecutar este skill, DEBES leer ${PLUGIN_ROOT}/reference/verification.md.
Las reglas de verification.md son obligatorias y determinan, vía verification.qualityCheck.enabled / verification.codeReview.enabled / verification.requirementCoverage.enabled, si corre cada puerta antes del merge (true la ejecuta, false la omite).
No continúes hasta haber leído y aplicado verification.md.
Excepción deliberada: esto decide si la puerta corre, nunca si aprueba. Una puerta que se ejecuta manda con su veredicto igual que siempre; una omitida no bloquea, pero tampoco cuenta como aprobada y se reporta como tal, con su motivo.
Límite de intentos y escalamiento
Antes de ejecutar este skill, DEBES leer ${PLUGIN_ROOT}/reference/escalation.md.
Las reglas de escalation.md son obligatorias y determinan, vía escalation.maxAttempts y escalation.onLimit, cuántos intentos consecutivos se hacen sobre el mismo problema que no se resuelve —una puerta de cierre que sigue en rojo tras corregir, o una validación previa que no se logra dejar en verde— y qué se hace al agotarlos: detener el trabajo sobre ese problema, presentar el parte de bloqueo y preguntar al usuario cómo seguir (ask), o marcarlo como BLOCKED en el informe y continuar con el alcance que no dependa de él (report).
El contador es por problema, no global, y el límite es un techo, no una cuota: si no hay una hipótesis nueva que justifique el siguiente intento, se escala ya. Nunca se «resuelve» un bloqueo desactivando o saltando una prueba, relajando una aserción ni bajando un umbral.
No continúes hasta haber leído y aplicado escalation.md.
Tipos de trabajo
El tipo se determina por el identificador presente en el nombre de rama. Cada tipo fija de dónde se deriva la carpeta, dónde vive el progress.md y qué se considera una unidad a cerrar.
| Tipo |
Identificador en la rama |
progress.md |
Unidad a verificar en Done |
| Historia de usuario |
US-XXX |
docs/specs/user-stories/US-XXX-[nombre-corto]/progress.md (por carpeta de la US) |
todas las TK-XXX de la US |
| Tarea de mantenimiento |
WI-XXX |
docs/specs/work-items/WI-XXX-[kebab-case]/progress.md (por carpeta del WI) |
todas las unidades del WI-XXX en su propio progress.md |
| Automatización de pruebas |
rama con prefijo test/ + FT-XXX, US-XXX o WI-XXX |
En la carpeta del artefacto padre: docs/specs/features/FT-XXX-[slug]/progress.md, o la de la US/WI correspondiente |
todas las unidades de esa ejecución (el FT-XXX completo, o cada TC-XXX del alcance) |
Una rama = un trabajo. El skill cierra el trabajo asociado a la rama actual. Cada tipo tiene su progress.md dentro de la carpeta del trabajo (la US, el WI o el feature) y contiene únicamente ese trabajo; se verifican todas sus unidades.
Ramas test/: el entregable son pruebas automatizadas de los TC-XXX documentados por test-define (ver work-implement, references/test-cases.md). El progress.md de la US o el WI puede contener unidades de otras ramas (TK-XXX, el propio WI-XXX): en ese caso se verifican en Done solo las unidades TC-XXX/FT-XXX de esta ejecución, no las del trabajo funcional.
Ubicación de archivos
Layout completo del harness e identificadores: ${PLUGIN_ROOT}/reference/artifacts.md. Este skill es el que ejecuta el archivado; su contrato para el resto del catálogo está en references/archive.md.
Lo que este skill lee y mueve:
| Artefacto |
Ruta |
| Carpeta / documento del trabajo |
US: docs/specs/user-stories/US-XXX-[nombre-corto]/ · WI: docs/specs/work-items/WI-XXX-[kebab-case]/ · FT: docs/specs/features/FT-XXX-[slug]/ |
| Progreso del trabajo |
progress.md dentro de esa carpeta |
| Unidades referenciadas |
US: …/TK-XXX-[kebab-case].md · WI: el propio …/README.md · pruebas: …/test-cases/TC-XXX-[slug].md |
| Destino del archivado (paso 11) |
US: docs/archive/user-stories/US-XXX-[nombre-corto]/ · WI: docs/archive/work-items/WI-XXX-[kebab-case]/ · investigaciones sueltas huérfanas: docs/archive/research/RS-XXX-[slug]/ |
Convenciones de rama
- Historia de usuario:
feature/US-XXX-[nombre-corto] con prefijo feature/ obligatorio.
- Work item:
feature/WI-XXX-[kebab-case] por defecto; se aceptan además los prefijos por tipo que usa work-implement: fix/WI-XXX-..., chore/WI-XXX-..., refactor/WI-XXX-....
- Automatización de pruebas: prefijo
test/ + el identificador del artefacto padre: test/FT-XXX-[slug], test/US-XXX-[nombre-corto], test/WI-XXX-[kebab-case].
XXX: tres dígitos con cero a la izquierda (sin ADO); coincide con el identificador del trabajo.
- La carpeta/documento del trabajo se deriva descontando el prefijo de rama y leyendo el identificador:
feature/US-042-exportacion-csv → docs/specs/user-stories/US-042-exportacion-csv/; fix/WI-007-cache-ttl → docs/specs/work-items/WI-007-cache-ttl/; test/FT-003-carga-masiva → docs/specs/features/FT-003-carga-masiva/ (cada uno con su propio progress.md).
- Una rama sin un prefijo válido para su tipo o sin un identificador
US-XXX / WI-XXX / FT-XXX reconocible no es submiteable por este skill.
- Ejemplos:
feature/US-042-exportacion-csv, fix/WI-013-fuga-memoria, test/FT-003-carga-masiva.
Información requerida antes de mergear
Antes de tocar git, el agente debe tener clara la siguiente información. No asumir nada — si algún dato no se resuelve, preguntar al usuario.
| Dato |
Cómo obtenerlo |
Si no está disponible |
| Rama actual y tipo |
git branch --show-current; el tipo se infiere del identificador (US-/WI-/FT-) y del prefijo (test/ ⇒ automatización de pruebas) |
Si no encaja con un patrón válido: preguntar a qué trabajo corresponde antes de continuar |
| Carpeta/documento del trabajo |
Derivar del nombre de rama según el tipo (ver Tipos de trabajo); si no está en la ruta activa, buscarla bajo docs/archive/ (el trabajo pudo archivarse en una corrida anterior) |
Si no existe en ninguna de las dos: parar e informar; si hay varias coincidentes: preguntar cuál |
Estado de progress.md |
Leer el archivo en la ubicación correspondiente al tipo; si el trabajo ya está archivado, en su ruta bajo docs/archive/ |
Si no existe en ninguna de las dos: parar e informar; el merge requiere progress.md poblado |
| Working tree |
git status --porcelain |
Si hay salida: invocar automáticamente el flujo del skill git-commit sobre los cambios pendientes (sin preguntar al usuario si conviene invocarlo — la decisión de invocar es automática; git-commit sí puede pausar para confirmar una propuesta de división en varios commits, o detenerse ante secretos, rama protegida o hook fallido, y eso no lo decide work-integrate) y continuar una vez quede limpio; si git-commit no logra dejarlo limpio, parar e informar el motivo. Detalle operativo (fallback sin git-commit, working tree parcialmente limpio): ver Validación antes de mergear |
| Rama base |
(1) git reflog show <branch> → línea Created from; (2) git config --get branch.<branch>.merge; (3) preguntar al usuario |
No asumir main, master ni develop por defecto |
Leer el progress.md completo antes de iniciar cualquier operación git. Las tres condiciones (rama, working tree, estados) se evalúan antes de cambiar de rama o invocar git merge.
Validación antes de mergear
Antes de cambiar de rama o ejecutar el merge, verificar las siguientes condiciones. Si alguna falla, no mergear — informar al usuario y resolver primero.
¿Qué verificar?
- Rama actual con formato válido para su tipo:
feature/US-XXX-...; feature/|fix/|chore/|refactor/ + WI-XXX-...; o test/ + FT-XXX-...|US-XXX-...|WI-XXX-.... Sin un identificador reconocible no se puede derivar la carpeta/documento del trabajo.
- Working tree limpio:
git status --porcelain sin salida. Si hay cambios sin commitear, invocar automáticamente el flujo del skill git-commit sobre ellos (sin preguntar al usuario si conviene invocarlo — la decisión de invocar es automática, no requiere permiso previo) y continuar una vez el working tree quede limpio. La invocación delega en git-commit todo 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) — work-integrate no decide un mensaje de commit ni qué stagear por su cuenta. git-commit no 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 (con commitConfirmation = always) y puede detenerse del todo ante secretos, rama protegida o hook fallido; ese comportamiento no se suprime ni se evita al invocarlo desde aquí — «sin preguntar al usuario» se refiere solo a que work-integrate no pide permiso para invocar git-commit, no a que esas pausas y paradas propias de git-commit desaparezcan.
- Si
git-commit no 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 ejecutar git add/git commit directos como sustituto.
- Si
git-commit deja el working tree parcialmente limpio por una decisión de alcance suya (p. ej. commiteó unos archivos pero dejó otros fuera deliberadamente): no es un error — volver a comprobar git status --porcelain e invocar git-commit de nuevo sobre el remanente (mismo criterio, sin preguntar) hasta que quede limpio o se detenga por un motivo real.
- Si
git-commit se detiene sin dejarlo limpio (p. ej. por secretos detectados, o por una decisión que el propio git-commit no puede resolver solo), eso sí bloquea el merge — informar el motivo reportado.
- Carpeta/documento del trabajo existe: la ubicación correspondiente al tipo, con su
progress.md.
- Unidades del trabajo en
Done: parsear progress.md y confirmar que cada unidad del trabajo de la rama tiene estado Done. El estado se lee de la marca oculta de la unidad (<!-- unit:id=… · status=… -->), no de la etiqueta visible, que va en el idioma resuelto; comparar el valor case-insensitive y sin espacios extra. El progress.md vive en la carpeta del trabajo (la US o el WI) y contiene solo ese trabajo: para US son sus TK, para WI las unidades de su propio progress.md. Estados como Pending, In Progress o vacío bloquean el merge.
- Rama base resoluble (antes de las puertas): identificada por reflog, por config, o confirmada explícitamente por el usuario. Si hay varios candidatos plausibles y ninguno definitivo, preguntar. Se resuelve antes de invocar las puertas porque
code-review la necesita para acotar su diff.
- Verificaciones automatizadas — solo si
verification.qualityCheck.enabled la activa: ejecutar quality-check (modificador default) antes del merge — es la compuerta de cierre que corre la batería completa de pruebas sobre la rama consolidada y persiste .sdd-devkit/test-run.json. Cuando corre, solo un veredicto APPROVED permite continuar: REJECTED e INCOMPLETE bloquean el merge hasta que el usuario corrija los problemas y la corrida se repita con veredicto APPROVED. Si la política la omite, el merge continúa sin esa evidencia y así se reporta.
- Code review — solo si
verification.codeReview.enabled la activa: ejecutar code-review después de quality-check, pasándole la rama base ya resuelta (base <rama>) — es la revisión cualitativa (intención, arquitectura y diseño) sobre el diff de la rama contra esa base, incluidos los cambios sin commitear que quality-check haya podido dejar al corregir. Emite su propio veredicto, independiente del anterior: solo APPROVED permite continuar; REJECTED e INCOMPLETE bloquean el merge hasta que los hallazgos se corrijan o se justifiquen y la revisión se repita con veredicto APPROVED. Si la política la omite, el merge continúa sin revisión cualitativa y así se reporta.
- Trazabilidad — solo si
verification.requirementCoverage.enabled la activa: ejecutar trace-validate sobre el trabajo de la rama (US-XXX/WI-XXX), después de quality-check para que reutilice su test-run.json sin re-ejecutar pruebas. Cuando corre, solo APPROVED (o APPROVED_WITH_NOTES, mostrando las observaciones) permite continuar; REJECTED (algún criterio de aceptación sin cubrir o con prueba fallida) bloquea el merge. Si la política la omite, el merge continúa sin evidencia de cobertura y así se reporta.
Una puerta omitida no es una puerta aprobada. Registrar cada omisión con su motivo (policy, enabled: false) y arrastrarla hasta el reporte del cierre y el mensaje al usuario. Nunca listarla como aprobada ni callarla. Si las tres quedan omitidas, decirlo de forma destacada: el merge se hace sin ninguna verificación de cierre.
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> … -->. APPROVED deja pasar; REJECTED e INCOMPLETE bloquean; APPROVED_WITH_NOTES (solo trace-validate) no bloquea: se muestran las observaciones y se continúa. Contrato completo en ${PLUGIN_ROOT}/reference/verdicts.md.
- Archivado (no es una condición, es una oferta): superadas las tres puertas se resuelve el archivado de la carpeta del trabajo en
docs/archive/ según implementation.archiveMode antes del merge. Ni preguntarlo, ni archivarlo directo, ni saltarlo por política bloquea nada; lo único que bloquea es que el git mv falle una vez decidido archivar (destino ya ocupado) — ver references/archive.md.
- Working tree limpio otra vez, ya pasadas las puertas: las puertas pueden dejar cambios sin commitear (correcciones aplicadas por
quality-check, o por work-implement en su modo corrección) y sus propios artefactos versionados: docs/audits/quality-check.md, docs/audits/code-review.md y el coverage.md del trabajo, que se escriben siempre; más el renombrado del archivado, si el usuario lo confirmó. (.sdd-devkit/test-run.json no aparece: está en el .gitignore por ser una caché local.) Antes del merge, re-comprobar git status --porcelain e invocar de nuevo git-commit si hay salida — el código que se integra debe ser exactamente el que verificaron las puertas, con sus artefactos. El renombrado del archivado es la única salvedad: 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 (se calcula sobre la carpeta del artefacto, cuyas rutas cambian): su coverage.md se regenerará una vez en la siguiente validación, sin más consecuencia.
Si hay conflicto:
`
⚠️ No es posible mergear todavía:
- <razón concreta>
- [<TK-XXX | WI-XXX>: estado-actual] —
`
Ejemplos de razón concreta: Rama actual no cumple un patrón válido: rama es 'hotfix-cache', Working tree sucio: 3 archivos modificados, progress.md: TK-002 en In Progress, TK-005 en Pending, progress.md: WI-007 en In Progress, Rama base ambigua: candidatos main, develop, release/2026.q2.
Flujo: Submit estándar
Camino feliz cuando todas las verificaciones pasan.
Detectar rama actual con git branch --show-current, identificar el tipo por el identificador (US-/WI-) y validar el patrón de rama de ese tipo. Si no encaja, parar y preguntar.
Verificar working tree limpio con git status --porcelain. Si hay salida, invocar automáticamente el flujo del skill git-commit sobre los cambios pendientes (sin preguntar al usuario si conviene invocarlo) y esperar a que termine; con el working tree limpio, continuar al siguiente paso. Si git-commit no logra dejarlo limpio (incluido el caso de quedar parcialmente limpio, o de no estar disponible), aplicar el criterio de Validación antes de mergear — reintentar sobre el remanente o parar e informar el motivo, según corresponda.
Localizar la carpeta/documento del trabajo según el tipo (ver Tipos de trabajo). Si no está en la ruta activa, buscarla bajo docs/archive/ antes de rendirse: si aparece ahí, el trabajo ya estaba archivado — continuar el flujo leyendo su progress.md desde esa ruta y saltar luego el archivado del paso 11 (el Done del trabajo sí se marca, sobre la carpeta archivada). Si no está en ninguna de las dos, o hay varias coincidentes, parar.
Leer progress.md (en la carpeta del trabajo) y validar que todas las unidades del trabajo de la rama tienen estado Done. Si alguna no lo está, parar mostrando la lista completa de unidades no Done con su estado actual.
Resolver la rama base — antes de las puertas, porque code-review la necesita para acotar su diff. Resolverla primero contra integrationBranches de ${PLUGIN_ROOT}/reference/git.md: si la lista está declarada, la base es una de esas ramas y no se adivina. Comprobar su commitPolicy antes de seguir:
merge → continuar con el flujo normal.
pull_request → parar aquí. Esa rama no admite merge local: informarlo y ofrecer dos salidas — crear el PR con pr-create, o terminar. No mergear «avisando».
- No declarada → resolverla desde el historial de la rama:
git reflog show <branch> → buscar la entrada inicial con Created from <ref> o branch: Created from <ref>.
- Fallback:
git config --get branch.<branch>.merge y derivar la rama base local correspondiente.
- Si ninguno concluye o hay ambigüedad: preguntar al usuario sin proponer un default.
Resolver y ejecutar las puertas. Antes de la primera, aplicar ${PLUGIN_ROOT}/reference/verification.md: las puertas con enabled: false no se ejecutan ni se ofrecen. Anotar cada omisión con su motivo para el paso 12. Luego, en este orden y solo las activas:
6.1 quality-check (modificador default) sobre la rama actual. Si el veredicto es REJECTED o INCOMPLETE, parar y reportar el informe al usuario — no continuar con el merge hasta obtener veredicto APPROVED en una nueva ejecución.
6.2 code-review con base <rama-base> (la del paso 5). Su alcance incluye los cambios sin commitear, así que también revisa las correcciones que quality-check haya podido aplicar. Si su informe existente ya estaba fresco y aprobado (mismo fingerprint, misma base y mismo modo, sin correcciones en el 6.1), lo devuelve sin volver a revisar; no forzar revalidate desde aquí. Un ❌/⚠️ previo lo revisa de nuevo por su cuenta. Si el veredicto es REJECTED o INCOMPLETE, parar y reportar los hallazgos — no continuar hasta obtener APPROVED con los hallazgos bloqueantes corregidos o justificados.
6.3 trace-validate sobre el trabajo de la rama (después de quality-check, para reutilizar su test-run.json; si quality-check quedó omitida, trace-validate invocará él mismo el modo tests-only al no encontrar corrida fresca). Si el veredicto es REJECTED, parar y reportar los criterios faltantes/fallidos — no mergear hasta obtener APPROVED (o APPROVED_WITH_NOTES, mostrando las observaciones al usuario).
Con todas las puertas activas en veredicto que deja pasar, resolver verification.handoff: con ask (comportamiento por defecto), preguntar al usuario si se continúa con el merge y el cierre (pasos 7 en adelante); con always, continuar directo sin preguntar.
Calcular delta con git rev-list --count <base>..HEAD. Es una puerta, no solo un dato para el reporte: si el resultado es 0, la rama ya está integrada (típicamente porque el PR se mergeó en la plataforma) — parar y avisar, sin tocar nada. Seguir adelante produciría un commit que no es un merge y que solo borra archivos, con un mensaje que miente. Va antes de cualquier commit a propósito: seguir adelante dejaría un commit nuevo en una rama que solo había que dejar en paz.
Re-comprobar el working tree tras las puertas. Las puertas dejan cambios sin commitear de dos clases: correcciones (aplicadas por quality-check o por work-implement en su modo corrección) y sus propios artefactos —docs/audits/quality-check.md, docs/audits/code-review.md y el coverage.md del trabajo, que se escriben siempre—. Todo se commitea: la rama debe conservar su evidencia (el paso 10 es quien decide qué no pasa a la base). Volver a ejecutar git status --porcelain y, si hay salida, invocar de nuevo git-commit con el mismo criterio del paso 2. El merge solo procede con el árbol limpio: el código que se integra es exactamente el que verificaron las puertas. Aquí no se archiva ni se marca nada como Done: eso va después del merge (paso 11), porque hasta que el código no está integrado y el usuario puede probarlo en la rama base, el trabajo no está cerrado.
Cambiar a la rama base con git checkout <base>. Si falla, parar y reportar.
Ejecutar el merge en tres tiempos, para que los informes de las puertas no lleguen a la rama base (ver Los informes de las puertas no se integran):
git merge --no-ff --no-commit <feature-branch>
test -f "$(git rev-parse --git-dir)/MERGE_HEAD" || { echo "no hay merge en curso"; exit 1; }
git rm -q -f --ignore-unmatch ':(top,glob)**/docs/audits/quality-check.md' ':(top,glob)**/docs/audits/code-review.md'
test -z "$(git ls-files --cached -- ':(top,glob)**/docs/audits/quality-check.md' ':(top,glob)**/docs/audits/code-review.md')" \
|| { echo "los informes siguen en el índice"; exit 1; }
git commit -m "Merge <ID>: <nombre-corto>"
<ID> es el identificador del trabajo (US-XXX o WI-XXX) y <nombre-corto> su nombre/slug sin el prefijo de rama.
Las dos comprobaciones no son adorno:
MERGE_HEAD confirma que el merge quedó realmente en curso. Si git respondió Already up to date, no hay merge, y ejecutar el git rm + git commit de todos modos crearía un commit normal que borra dos archivos de la base. Parar ahí.
:(top,glob)**/… en las rutas hace dos cosas, y las dos hacen falta. :(top) las ancla a la raíz del repositorio: git rm interpreta las rutas relativas al cwd, así que sin ese ancla, lanzado desde packages/api/, no casarían, --ignore-unmatch devolvería 0 sin borrar nada, y los informes se integrarían en la base en silencio mientras el paso 12 reporta lo contrario. Y el glob con **/ inicial las hace casar a cualquier profundidad, que es lo que exige el monorepo por el otro lado: quality-check audita el módulo elegido, no el repo entero, y escribe su informe en el docs/audits/ de ese módulo (packages/api/docs/audits/quality-check.md). Con :(top)docs/audits/… a secas —anclado pero literal— solo casaría el docs/ de la raíz, y el informe del módulo se colaría en la base con el mismo silencio. Es la misma razón por la que el FINGERPRINT de quality-check excluye **/docs/** y no docs/. **/ casa también cero directorios, así que el caso de repo simple sigue cubierto. El git ls-files --cached posterior es el cinturón: verifica el resultado en vez de confiar en el código de salida. Tiene que ser ls-files, no git diff --cached: el diff lista también los borrados stageados, así que cuando la base ya trackeaba el informe —y el git rm funcionó— la ruta aparecería igual y el guard cortaría un merge correcto. ls-files --cached responde la pregunta que importa: ¿queda algo de esos dos archivos en el índice?
--ignore-unmatch está para el caso legítimo de que un informe no se haya commiteado en la rama, no para tapar rutas mal resueltas. Borrar exactamente esos dos archivos, ni uno más: las copias de save-report y los arch-audit-*.md se quedan. Si surge conflicto, ir al flujo de conflictos.
Cerrar el trabajo en la rama base — después del merge, nunca antes. Con el merge hecho, el código ya está integrado y el usuario puede probarlo donde de verdad importa; solo entonces el trabajo pasa a estar cerrado, y las dos operaciones de cierre se hacen sobre la rama base, en un único commit propio, separado del merge:
11.1 Marcar el trabajo como Done. En el progress.md del trabajo, poner el estado del trabajo (el encabezado **Estado:** y su marca <!-- work:id=… · status=Done -->) en Done y actualizar Ultima actualizacion. Es el estado del trabajo, no de sus unidades: las unidades ya estaban Done desde la implementación (paso 4 lo exige); el trabajo entero solo lo está cuando su código vive en la rama base. Solo aplica a US-XXX y WI-XXX en su rama funcional; una rama test/ no cierra el trabajo (su paso 4 solo verificó las unidades TC-XXX de esa ejecución).
11.2 Resolver el archivado del artefacto. Mismas condiciones de aplicabilidad que el Done: US-XXX/WI-XXX en rama funcional, y carpeta todavía en la ruta activa (si el paso 3 la encontró ya bajo docs/archive/, informarlo y saltar). Si no aplica, no se resuelve archiveMode ni se pregunta nada. Si aplica, resolver implementation.archiveMode (ver references/archive.md): con ask (por defecto), mostrar la carpeta origen → destino y las investigaciones sueltas que se irían con ella, y pedir confirmación con la herramienta de preguntas estructuradas — respuesta binaria, preguntar primero, mover después; con always, git mv directo, mostrando igual el bloque origen → destino en el reporte; con never, no archivar ni preguntar. Si no se archiva —negativa del usuario, sesión desatendida, o never— se anota el motivo para el paso 12 y se sigue: el merge ya está hecho y no depende de esto. Procedimiento completo (destinos, investigaciones RS-XXX huérfanas, reparación de enlaces, guards) en references/archive.md.
11.3 Commitear el cierre en la rama base. Un solo commit con el progress.md en Done y, si lo hubo, el git mv del archivado: chore(<ID>): cerrar trabajo (+ « y archivar» si se movió). Invocar git-commit sobre esos cambios; la rama base es commitPolicy: merge (paso 5), así que no hay confirmación extra de rama protegida. Si la base fuera pull_request, el flujo ni siquiera habría llegado aquí. Nunca meter este cierre dentro del commit de merge del paso 10: el merge integra exactamente el código verificado, y el cierre es un cambio de estado posterior que debe poder leerse —y revertirse— por separado.
Por qué después del merge. Archivar y marcar Done en la rama del trabajo, antes de integrar, obligaba a decidir el cierre a ciegas: si el merge fallaba, o el usuario detectaba un problema al probar la integración, el artefacto ya estaba archivado y el trabajo «cerrado» sin estarlo. Con el cierre en la base y después del merge, el orden refleja la realidad: se integra, se prueba, se cierra. pr-create mantiene su comportamiento: ahí el archivado va en la rama antes del PR, porque el merge lo hace la plataforma y el skill no vuelve a tener el control después.
Reportar resultado al usuario: rama origen (con su prefijo), rama destino, número de commits integrados, hash del commit de merge, hash del commit de cierre (paso 11) con el progress.md en Done, estado del HEAD, el estado de cada una de las tres puertas —veredicto si corrió, u «omitida» con su motivo si no— y nota explícita de que no se hizo push ni se borró la rama del trabajo. Si el paso 11 movió algo, incluir su bloque de archivado (origen → destino y qué pasó con las investigaciones sueltas; formato en references/archive.md). Si no archivó —el usuario lo declinó, no había con quién confirmar, rama test/, o el trabajo ya estaba archivado—, decirlo en una línea con el motivo, en vez de omitirlo en silencio. Mencionar también que los informes de las puertas quedaron en la rama del trabajo y no se integraron.
Los informes de las puertas no se integran
docs/audits/quality-check.md y docs/audits/code-review.md son fotos de una rama concreta: su encabezado lleva la rama y el commit sobre los que se corrieron las puertas. Se versionan en la rama del trabajo —ahí valen: quedan junto a los commits que verifican, y el revisor los ve en el PR— pero no deben llegar a la rama base, por dos razones:
- En
develop serían mentira. Nadie corrió las puertas sobre develop; ese archivo diría «APPROVED» sobre una rama que ni siquiera es la suya. Y con cada integración lo pisaría la última feature en entrar.
- Viven en una ruta fija, así que toda rama escribe el mismo archivo: dejarlos integrarse convierte cada merge en un conflicto seguro sobre un artefacto generado.
Por eso el paso 10 parte el merge: --no-commit deja el resultado en el índice, se retiran los dos informes y el commit de merge se cierra ya sin ellos. La rama del trabajo conserva los suyos intactos — no se reescribe su historia, solo se decide qué entra en la base.
Qué NO se toca:
| Artefacto |
Por qué se queda |
docs/audits/arch-audit-*.md |
Auditorías de arquitectura del repositorio, no de una rama. Su sitio es la rama base. |
docs/audits/quality-check-<timestamp>.md · code-review-<timestamp>.md |
Copias de save-report: el usuario las pidió para conservar histórico. Llevan marca de tiempo, así que no colisionan ni pisan nada. |
coverage.md del trabajo |
Vive junto a su artefacto en docs/specs/, es del trabajo y no de la rama, y se integra con él. |
La carpeta del trabajo movida a docs/archive/ y el progress.md en Done |
No viajan en el merge: se hacen en la rama base, después del merge (paso 11), en un commit de cierre propio. El coverage.md que la carpeta lleva dentro se mueve con ella. |
.sdd-devkit/test-run.json |
Ni aparece: está en el .gitignore. |
Esta limpieza solo cubre los merges que hace este skill. Un merge desde la UI de GitHub/GitLab —el camino de pr-create— sí propaga los informes: ahí la limpieza hay que hacerla en la rama base después de integrar. Ver pr-create.
Conflictos y rama base ambigua: si el git merge produce conflictos, seguir el Flujo de manejo de conflictos, que clasifica antes de abortar: un modify/delete sobre los dos informes de docs/audits/ se resuelve por el lado del borrado y el merge continúa; cualquier otro conflicto se aborta con git merge --abort, se reporta y se para. Si la rama base no se resuelve por reflog ni config, seguir el Flujo de rama base ambigua (listar candidatos, preguntar, no asumir default). Ambos flujos íntegros y el checklist detallado están en references/flows.md.
Mapa de referencias
Cargar bajo demanda; el contenido íntegro vive en estos archivos:
| Necesitas… |
Archivo |
| Flujo de manejo de conflictos, flujo de rama base ambigua, checklist detallado antes de mergear |
references/flows.md |
Archivado del artefacto (paso 11, tras el merge): cuándo aplica y cuándo no, destinos, git mv y guards, investigaciones RS-XXX sueltas huérfanas, reparación de enlaces, formato del reporte, anti-patrones |
references/archive.md |
Ejemplos por tipo (US/WI: camino feliz, unidad pendiente, base ambigua, working tree sucio, conflicto, prefijo inválido), anti-patrones, y notas (handoffs del ciclo, progress.md, estados, detección de rama base, sin push intencional, mensaje al usuario) |
references/examples.md |
Referencias compartidas del plugin
Reglas transversales del catálogo; viven en la raíz del plugin, no en este skill.
1---2name: work-integrate3description: Cerrar e integrar el trabajo de una historia de usuario (US-XXX), una tarea de mantenimiento (WI-XXX) o una automatización de pruebas (rama test/ sobre un US-XXX, WI-XXX o FT-XXX) haciendo merge de la rama hacia la rama desde la que se creó, previa verificación de que progress.md tenga todas las unidades del trabajo en Done y de que pasen las puertas de calidad de cierre (quality-check, code-review y trace-validate). Cuando el trabajo es un US o WI en su rama funcional, pasadas las puertas resuelve el archivado según implementation.archiveMode (pregunta, archiva directo, o nunca) moviendo su carpeta bajo docs/archive/ antes del merge; si no se archiva, el merge sigue igual. En ramas test/ no archiva. Activar cuando el usuario pida cerrar, entregar, mergear, integrar, finalizar o hacer submit del trabajo de una historia, un WI, un feature o de la rama actual.4license: MIT5---67# Skill: Integración de trabajo89Guía para **cerrar e integrar** el trabajo ya implementado —una historia de usuario `US-XXX` o una tarea de mantenimiento `WI-XXX`— verificando que su `progress.md` tenga todas las unidades del trabajo en `Done`, que pasen las **puertas de calidad de cierre** (`quality-check`, `code-review` y `trace-validate`, en ese orden), y luego hacer **merge** de la rama actual hacia la rama desde la que se creó.1011> **Alcance del submit:** El skill **cierra** localmente lo ya implementado. Verifica condiciones, **ofrece archivar el artefacto** (mover su carpeta a `docs/archive/`, solo si el usuario lo confirma) y ejecuta `git merge --no-ff`. No hace push, no borra ramas, no crea MRs/PRs, no modifica el **contenido** de `progress.md`, y no resuelve conflictos —con la única salida declarada del `modify/delete` sobre los dos informes de `docs/audits/`, que se resuelve por el lado del borrado (ver [references/flows.md](references/flows.md)). Lo que no esté en `Done` bloquea el merge — el usuario decide cómo proceder, nunca se fuerza.1213Encaja al final de los ciclos **work-define** → **work-plan** → **work-implement** (historias y tareas de mantenimiento). Ver Handoffs del ciclo en [references/examples.md](references/examples.md).1415---1617## Cómo preguntar al usuario1819Mecanismo, ritmo y fallback compartidos: [`${PLUGIN_ROOT}/reference/asking.md`](../../reference/asking.md).2021Cada vez que este skill o sus referencias digan *preguntar*, *pedir*, *confirmar*, *validar* o *sugerir* algo al usuario, asume ese mecanismo; no se repite allí.2223**La tanda inicial va antes de cualquier operación git** y cubre: trabajo asociado a la rama, carpeta ambigua y rama base. No empezar a mover, mergear ni archivar con lagunas abiertas.2425**Excepción al ritmo:** la confirmación del archivado (paso 11) va por fuerza **después del merge** — hasta entonces no se sabe si el trabajo llega a integrarse, y el cierre (`Done` + archivado) solo tiene sentido con el código ya en la rama base.2627**Rama base ambigua:** listar los candidatos detectados como opciones tappables (p. ej. `develop`, `main`, `release/2026.q2`); no proponer un default implícito.2829---3031## Rutas de las referencias compartidas3233`${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.3435## Resolución de idioma3637Antes de ejecutar este skill, DEBES leer [`${PLUGIN_ROOT}/reference/language.md`](../../reference/language.md).3839Las reglas de `language.md` son obligatorias y tienen prioridad para determinar el idioma de todos los artefactos y mensajes generados por este skill.4041No continúes hasta haber leído y aplicado `language.md`.4243---4445## Resolución de las puertas de cierre4647Antes de ejecutar este skill, DEBES leer [`${PLUGIN_ROOT}/reference/verification.md`](../../reference/verification.md).4849Las reglas de `verification.md` son obligatorias y determinan, vía `verification.qualityCheck.enabled` / `verification.codeReview.enabled` / `verification.requirementCoverage.enabled`, **si corre cada puerta** antes del merge (`true` la ejecuta, `false` la omite).5051No continúes hasta haber leído y aplicado `verification.md`.5253**Excepción deliberada:** esto decide si la puerta **corre**, nunca si **aprueba**. Una puerta que se ejecuta manda con su veredicto igual que siempre; una omitida no bloquea, pero **tampoco cuenta como aprobada** y se reporta como tal, con su motivo.5455---5657## Límite de intentos y escalamiento5859Antes de ejecutar este skill, DEBES leer [`${PLUGIN_ROOT}/reference/escalation.md`](../../reference/escalation.md).6061Las reglas de `escalation.md` son obligatorias y determinan, vía `escalation.maxAttempts` y `escalation.onLimit`, cuántos intentos consecutivos se hacen sobre **el mismo** problema que no se resuelve —una puerta de cierre que sigue en rojo tras corregir, o una validación previa que no se logra dejar en verde— y qué se hace al agotarlos: detener el trabajo sobre ese problema, presentar el **parte de bloqueo** y preguntar al usuario cómo seguir (`ask`), o marcarlo como `BLOCKED` en el informe y continuar con el alcance que no dependa de él (`report`).6263El contador es **por problema**, no global, y **el límite es un techo, no una cuota**: si no hay una hipótesis nueva que justifique el siguiente intento, se escala ya. Nunca se «resuelve» un bloqueo desactivando o saltando una prueba, relajando una aserción ni bajando un umbral.6465No continúes hasta haber leído y aplicado `escalation.md`.6667---6869## Tipos de trabajo7071El tipo se determina por el **identificador presente en el nombre de rama**. Cada tipo fija de dónde se deriva la carpeta, dónde vive el `progress.md` y qué se considera una **unidad** a cerrar.7273| Tipo | Identificador en la rama | `progress.md` | Unidad a verificar en `Done` |74|------|--------------------------|---------------|------------------------------|75| **Historia de usuario** | `US-XXX` | `docs/specs/user-stories/US-XXX-[nombre-corto]/progress.md` (por carpeta de la US) | **todas** las `TK-XXX` de la US |76| **Tarea de mantenimiento** | `WI-XXX` | `docs/specs/work-items/WI-XXX-[kebab-case]/progress.md` (por carpeta del WI) | **todas** las unidades del `WI-XXX` en su propio `progress.md` |77| **Automatización de pruebas** | rama con prefijo `test/` + `FT-XXX`, `US-XXX` o `WI-XXX` | En la carpeta del artefacto padre: `docs/specs/features/FT-XXX-[slug]/progress.md`, o la de la US/WI correspondiente | **todas** las unidades de esa ejecución (el `FT-XXX` completo, o cada `TC-XXX` del alcance) |7879> **Una rama = un trabajo.** El skill cierra el trabajo asociado a la rama actual. Cada tipo tiene su `progress.md` **dentro de la carpeta del trabajo** (la US, el WI o el feature) y contiene únicamente ese trabajo; se verifican **todas** sus unidades.80>81> **Ramas `test/`:** el entregable son pruebas automatizadas de los `TC-XXX` documentados por `test-define` (ver `work-implement`, `references/test-cases.md`). El `progress.md` de la US o el WI puede contener unidades de otras ramas (`TK-XXX`, el propio `WI-XXX`): en ese caso se verifican en `Done` **solo las unidades `TC-XXX`/`FT-XXX` de esta ejecución**, no las del trabajo funcional.8283---8485## Ubicación de archivos8687Layout completo del harness e identificadores: [`${PLUGIN_ROOT}/reference/artifacts.md`](../../reference/artifacts.md). Este skill es el que **ejecuta** el archivado; su contrato para el resto del catálogo está en [`references/archive.md`](references/archive.md).8889Lo que este skill lee y mueve:9091| Artefacto | Ruta |92|-----------|------|93| Carpeta / documento del trabajo | US: `docs/specs/user-stories/US-XXX-[nombre-corto]/` · WI: `docs/specs/work-items/WI-XXX-[kebab-case]/` · FT: `docs/specs/features/FT-XXX-[slug]/` |94| Progreso del trabajo | `progress.md` dentro de esa carpeta |95| Unidades referenciadas | US: `…/TK-XXX-[kebab-case].md` · WI: el propio `…/README.md` · pruebas: `…/test-cases/TC-XXX-[slug].md` |96| Destino del archivado (paso 11) | US: `docs/archive/user-stories/US-XXX-[nombre-corto]/` · WI: `docs/archive/work-items/WI-XXX-[kebab-case]/` · investigaciones sueltas huérfanas: `docs/archive/research/RS-XXX-[slug]/` |9798---99100## Convenciones de rama101102- **Historia de usuario:** `feature/US-XXX-[nombre-corto]` con prefijo **`feature/` obligatorio**.103- **Work item:** `feature/WI-XXX-[kebab-case]` por defecto; se aceptan además los prefijos por tipo que usa `work-implement`: `fix/WI-XXX-...`, `chore/WI-XXX-...`, `refactor/WI-XXX-...`.104- **Automatización de pruebas:** prefijo **`test/`** + el identificador del artefacto padre: `test/FT-XXX-[slug]`, `test/US-XXX-[nombre-corto]`, `test/WI-XXX-[kebab-case]`.105- `XXX`: tres dígitos con cero a la izquierda (sin ADO); coincide con el identificador del trabajo.106- La carpeta/documento del trabajo se deriva descontando el prefijo de rama y leyendo el identificador: `feature/US-042-exportacion-csv` → `docs/specs/user-stories/US-042-exportacion-csv/`; `fix/WI-007-cache-ttl` → `docs/specs/work-items/WI-007-cache-ttl/`; `test/FT-003-carga-masiva` → `docs/specs/features/FT-003-carga-masiva/` (cada uno con su propio `progress.md`).107- Una rama sin un prefijo válido para su tipo o sin un identificador `US-XXX` / `WI-XXX` / `FT-XXX` reconocible **no** es submiteable por este skill.108- Ejemplos: `feature/US-042-exportacion-csv`, `fix/WI-013-fuga-memoria`, `test/FT-003-carga-masiva`.109110---111112## Información requerida antes de mergear113114Antes de tocar git, el agente debe tener clara la siguiente información. **No asumir nada** — si algún dato no se resuelve, preguntar al usuario.115116| Dato | Cómo obtenerlo | Si no está disponible |117|------|----------------|-----------------------|118| **Rama actual y tipo** | `git branch --show-current`; el tipo se infiere del identificador (`US-`/`WI-`/`FT-`) y del prefijo (`test/` ⇒ automatización de pruebas) | Si no encaja con un patrón válido: preguntar a qué trabajo corresponde antes de continuar |119| **Carpeta/documento del trabajo** | Derivar del nombre de rama según el tipo (ver [Tipos de trabajo](#tipos-de-trabajo)); si no está en la ruta activa, buscarla bajo `docs/archive/` (el trabajo pudo archivarse en una corrida anterior) | Si no existe en ninguna de las dos: parar e informar; si hay varias coincidentes: preguntar cuál |120| **Estado de `progress.md`** | Leer el archivo en la ubicación correspondiente al tipo; si el trabajo ya está archivado, en su ruta bajo `docs/archive/` | Si no existe en ninguna de las dos: parar e informar; el merge requiere `progress.md` poblado |121| **Working tree** | `git status --porcelain` | Si hay salida: invocar automáticamente el flujo del skill **`git-commit`** sobre los cambios pendientes (sin preguntar al usuario si conviene invocarlo — la decisión de invocar es automática; `git-commit` sí puede pausar para confirmar una propuesta de división en varios commits, o detenerse ante secretos, rama protegida o hook fallido, y eso no lo decide `work-integrate`) y continuar una vez quede limpio; si `git-commit` no logra dejarlo limpio, parar e informar el motivo. Detalle operativo (fallback sin `git-commit`, working tree parcialmente limpio): ver [Validación antes de mergear](#validación-antes-de-mergear) |122| **Rama base** | (1) `git reflog show <branch>` → línea `Created from`; (2) `git config --get branch.<branch>.merge`; (3) preguntar al usuario | No asumir `main`, `master` ni `develop` por defecto |123124> Leer el `progress.md` **completo** antes de iniciar cualquier operación git. Las tres condiciones (rama, working tree, estados) se evalúan antes de cambiar de rama o invocar `git merge`.125126---127128## Validación antes de mergear129130Antes de cambiar de rama o ejecutar el merge, verificar las siguientes condiciones. Si alguna falla, **no mergear** — informar al usuario y resolver primero.131132**¿Qué verificar?**133- **Rama actual con formato válido para su tipo:** `feature/US-XXX-...`; `feature/`|`fix/`|`chore/`|`refactor/` + `WI-XXX-...`; o `test/` + `FT-XXX-...`|`US-XXX-...`|`WI-XXX-...`. Sin un identificador reconocible no se puede derivar la carpeta/documento del trabajo.134- **Working tree limpio:** `git status --porcelain` sin salida. Si hay cambios sin commitear, **invocar automáticamente el flujo del skill `git-commit`** sobre ellos (sin preguntar al usuario si conviene invocarlo — la decisión de invocar es automática, no requiere permiso previo) y continuar una vez el working tree quede limpio. La invocación delega en `git-commit` todo 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) — `work-integrate` no decide un mensaje de commit ni qué stagear por su cuenta. **`git-commit` no 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 (con `commitConfirmation = always`) y puede detenerse del todo ante secretos, rama protegida o hook fallido; ese comportamiento no se suprime ni se evita al invocarlo desde aquí — «sin preguntar al usuario» se refiere solo a que `work-integrate` no pide permiso para *invocar* `git-commit`, no a que esas pausas y paradas propias de `git-commit` desaparezcan.135 - **Si `git-commit` no 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 ejecutar `git add`/`git commit` directos como sustituto.136 - **Si `git-commit` deja el working tree parcialmente limpio por una decisión de alcance suya** (p. ej. commiteó unos archivos pero dejó otros fuera deliberadamente): no es un error — volver a comprobar `git status --porcelain` e invocar `git-commit` de nuevo sobre el remanente (mismo criterio, sin preguntar) hasta que quede limpio o se detenga por un motivo real.137 - Si `git-commit` se detiene sin dejarlo limpio (p. ej. por secretos detectados, o por una decisión que el propio `git-commit` no puede resolver solo), eso sí bloquea el merge — informar el motivo reportado.138- **Carpeta/documento del trabajo existe:** la ubicación correspondiente al tipo, con su `progress.md`.139- **Unidades del trabajo en `Done`:** parsear `progress.md` y confirmar que **cada unidad del trabajo de la rama** tiene estado `Done`. El estado se lee de la marca oculta de la unidad (`<!-- unit:id=… · status=… -->`), no de la etiqueta visible, que va en el idioma resuelto; comparar el valor case-insensitive y sin espacios extra. El `progress.md` vive en la carpeta del trabajo (la US o el WI) y contiene solo ese trabajo: para US son sus `TK`, para WI las unidades de su propio `progress.md`. Estados como `Pending`, `In Progress` o vacío bloquean el merge.140- **Rama base resoluble (antes de las puertas):** identificada por reflog, por config, o confirmada explícitamente por el usuario. Si hay varios candidatos plausibles y ninguno definitivo, preguntar. Se resuelve **antes** de invocar las puertas porque `code-review` la necesita para acotar su diff.141- **Verificaciones automatizadas — solo si `verification.qualityCheck.enabled` la activa:** ejecutar **`quality-check`** (modificador `default`) antes del merge — es la **compuerta de cierre** que corre la batería completa de pruebas sobre la rama consolidada y persiste `.sdd-devkit/test-run.json`. Cuando corre, solo un veredicto `APPROVED` permite continuar: `REJECTED` e `INCOMPLETE` bloquean el merge hasta que el usuario corrija los problemas y la corrida se repita con veredicto `APPROVED`. Si la política la omite, el merge continúa **sin esa evidencia** y así se reporta.142- **Code review — solo si `verification.codeReview.enabled` la activa:** ejecutar **`code-review`** después de `quality-check`, pasándole la **rama base ya resuelta** (`base <rama>`) — es la revisión cualitativa (intención, arquitectura y diseño) sobre el diff de la rama contra esa base, **incluidos los cambios sin commitear** que `quality-check` haya podido dejar al corregir. Emite su **propio** veredicto, independiente del anterior: solo `APPROVED` permite continuar; `REJECTED` e `INCOMPLETE` bloquean el merge hasta que los hallazgos se corrijan o se justifiquen y la revisión se repita con veredicto `APPROVED`. Si la política la omite, el merge continúa **sin revisión cualitativa** y así se reporta.143- **Trazabilidad — solo si `verification.requirementCoverage.enabled` la activa:** ejecutar **`trace-validate`** sobre el trabajo de la rama (`US-XXX`/`WI-XXX`), **después** de `quality-check` para que reutilice su `test-run.json` sin re-ejecutar pruebas. Cuando corre, solo `APPROVED` (o `APPROVED_WITH_NOTES`, mostrando las observaciones) permite continuar; `REJECTED` (algún criterio de aceptación sin cubrir o con prueba fallida) bloquea el merge. Si la política la omite, el merge continúa **sin evidencia de cobertura** y así se reporta.144145> **Una puerta omitida no es una puerta aprobada.** Registrar cada omisión con su motivo (`policy`, `enabled: false`) y arrastrarla hasta el reporte del cierre y el mensaje al usuario. Nunca listarla como aprobada ni callarla. Si las tres quedan omitidas, decirlo de forma destacada: el merge se hace sin ninguna verificación de cierre.146> **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> … -->`. `APPROVED` deja pasar; `REJECTED` e `INCOMPLETE` bloquean; `APPROVED_WITH_NOTES` (solo `trace-validate`) **no** bloquea: se muestran las observaciones y se continúa. Contrato completo en [`${PLUGIN_ROOT}/reference/verdicts.md`](../../reference/verdicts.md).147148- **Archivado (no es una condición, es una oferta):** superadas las tres puertas se resuelve el archivado de la carpeta del trabajo en `docs/archive/` según `implementation.archiveMode` antes del merge. Ni preguntarlo, ni archivarlo directo, ni saltarlo por política bloquea nada; lo único que bloquea es que el `git mv` falle una vez decidido archivar (destino ya ocupado) — ver [references/archive.md](references/archive.md).149- **Working tree limpio otra vez, ya pasadas las puertas:** las puertas pueden dejar cambios sin commitear (correcciones aplicadas por `quality-check`, o por `work-implement` en su modo corrección) **y sus propios artefactos versionados**: `docs/audits/quality-check.md`, `docs/audits/code-review.md` y el `coverage.md` del trabajo, que se escriben siempre; más el **renombrado del archivado**, si el usuario lo confirmó. (`.sdd-devkit/test-run.json` no aparece: está en el `.gitignore` por ser una caché local.) Antes del merge, re-comprobar `git status --porcelain` e invocar de nuevo `git-commit` si hay salida — el **código** que se integra debe ser exactamente el que verificaron las puertas, con sus artefactos. El renombrado del archivado es la única salvedad: 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` (se calcula sobre la carpeta del artefacto, cuyas rutas cambian): su `coverage.md` se regenerará una vez en la siguiente validación, sin más consecuencia.150151**Si hay conflicto:**152`153⚠️ No es posible mergear todavía:154- <razón concreta>155- [<TK-XXX | WI-XXX>: estado-actual] — <detalle si aplica>156`157158Ejemplos de razón concreta: `Rama actual no cumple un patrón válido: rama es 'hotfix-cache'`, `Working tree sucio: 3 archivos modificados`, `progress.md: TK-002 en In Progress, TK-005 en Pending`, `progress.md: WI-007 en In Progress`, `Rama base ambigua: candidatos main, develop, release/2026.q2`.159160---161162## Flujo: Submit estándar163164Camino feliz cuando todas las verificaciones pasan.1651661. **Detectar rama actual** con `git branch --show-current`, identificar el **tipo** por el identificador (`US-`/`WI-`) y validar el patrón de rama de ese tipo. Si no encaja, parar y preguntar.1672. **Verificar working tree limpio** con `git status --porcelain`. Si hay salida, **invocar automáticamente el flujo del skill `git-commit`** sobre los cambios pendientes (sin preguntar al usuario si conviene invocarlo) y esperar a que termine; con el working tree limpio, continuar al siguiente paso. Si `git-commit` no logra dejarlo limpio (incluido el caso de quedar parcialmente limpio, o de no estar disponible), aplicar el criterio de [Validación antes de mergear](#validación-antes-de-mergear) — reintentar sobre el remanente o parar e informar el motivo, según corresponda.1683. **Localizar la carpeta/documento del trabajo** según el tipo (ver [Tipos de trabajo](#tipos-de-trabajo)). Si no está en la ruta activa, buscarla bajo `docs/archive/` antes de rendirse: si aparece ahí, el trabajo **ya estaba archivado** — continuar el flujo leyendo su `progress.md` desde esa ruta y saltar luego el archivado del paso 11 (el `Done` del trabajo sí se marca, sobre la carpeta archivada). Si no está en ninguna de las dos, o hay varias coincidentes, parar.1694. **Leer `progress.md`** (en la carpeta del trabajo) y validar que **todas las unidades del trabajo de la rama** tienen estado `Done`. Si alguna no lo está, parar mostrando la lista completa de unidades no `Done` con su estado actual.1705. **Resolver la rama base** — antes de las puertas, porque `code-review` la necesita para acotar su diff. Resolverla primero contra `integrationBranches` de [`${PLUGIN_ROOT}/reference/git.md`](../../reference/git.md): si la lista está declarada, la base es una de esas ramas y **no se adivina**. Comprobar su `commitPolicy` antes de seguir:171172 - **`merge`** → continuar con el flujo normal.173 - **`pull_request`** → **parar aquí**. Esa rama no admite merge local: informarlo y ofrecer dos salidas — crear el PR con **`pr-create`**, o terminar. No mergear «avisando».174 - **No declarada** → resolverla desde el historial de la rama:175 - `git reflog show <branch>` → buscar la entrada inicial con `Created from <ref>` o `branch: Created from <ref>`.176 - Fallback: `git config --get branch.<branch>.merge` y derivar la rama base local correspondiente.177 - Si ninguno concluye o hay ambigüedad: preguntar al usuario sin proponer un default.1786. **Resolver y ejecutar las puertas.** Antes de la primera, aplicar [`${PLUGIN_ROOT}/reference/verification.md`](../../reference/verification.md): las puertas con `enabled: false` no se ejecutan ni se ofrecen. Anotar cada omisión con su motivo para el paso 12. Luego, **en este orden y solo las activas**:179180 **6.1 `quality-check`** (modificador `default`) sobre la rama actual. Si el veredicto es `REJECTED` o `INCOMPLETE`, parar y reportar el informe al usuario — no continuar con el merge hasta obtener veredicto `APPROVED` en una nueva ejecución.181182 **6.2 `code-review`** con `base <rama-base>` (la del paso 5). Su alcance incluye los cambios sin commitear, así que también revisa las correcciones que `quality-check` haya podido aplicar. Si su informe existente ya estaba fresco **y aprobado** (mismo fingerprint, misma base y mismo modo, sin correcciones en el 6.1), lo devuelve sin volver a revisar; no forzar `revalidate` desde aquí. Un `❌`/`⚠️` previo lo revisa de nuevo por su cuenta. Si el veredicto es `REJECTED` o `INCOMPLETE`, parar y reportar los hallazgos — no continuar hasta obtener `APPROVED` con los hallazgos bloqueantes corregidos o justificados.183184 **6.3 `trace-validate`** sobre el trabajo de la rama (después de `quality-check`, para reutilizar su `test-run.json`; si `quality-check` quedó omitida, `trace-validate` invocará él mismo el modo `tests-only` al no encontrar corrida fresca). Si el veredicto es `REJECTED`, parar y reportar los criterios faltantes/fallidos — no mergear hasta obtener `APPROVED` (o `APPROVED_WITH_NOTES`, mostrando las observaciones al usuario).185186 Con todas las puertas activas en veredicto que deja pasar, resolver `verification.handoff`: con `ask` (comportamiento por defecto), preguntar al usuario si se continúa con el merge y el cierre (pasos 7 en adelante); con `always`, continuar directo sin preguntar.1877. **Calcular delta** con `git rev-list --count <base>..HEAD`. Es una **puerta, no solo un dato para el reporte**: si el resultado es `0`, la rama ya está integrada (típicamente porque el PR se mergeó en la plataforma) — parar y avisar, **sin tocar nada**. Seguir adelante produciría un commit que no es un merge y que solo borra archivos, con un mensaje que miente. **Va antes de cualquier commit a propósito:** seguir adelante dejaría un commit nuevo en una rama que solo había que dejar en paz.1888. **Re-comprobar el working tree tras las puertas.** Las puertas dejan cambios sin commitear de dos clases: **correcciones** (aplicadas por `quality-check` o por `work-implement` en su modo corrección) y **sus propios artefactos** —`docs/audits/quality-check.md`, `docs/audits/code-review.md` y el `coverage.md` del trabajo, que se escriben siempre—. Todo se commitea: la rama debe conservar su evidencia (el paso 10 es quien decide qué **no** pasa a la base). Volver a ejecutar `git status --porcelain` y, si hay salida, **invocar de nuevo `git-commit`** con el mismo criterio del paso 2. **El merge solo procede con el árbol limpio:** el **código** que se integra es exactamente el que verificaron las puertas. **Aquí no se archiva ni se marca nada como `Done`**: eso va después del merge (paso 11), porque hasta que el código no está integrado y el usuario puede probarlo en la rama base, el trabajo no está cerrado.1899. **Cambiar a la rama base** con `git checkout <base>`. Si falla, parar y reportar.19010. **Ejecutar el merge en tres tiempos**, para que los informes de las puertas no lleguen a la rama base (ver [Los informes de las puertas no se integran](#los-informes-de-las-puertas-no-se-integran)):191192 ```bash193 git merge --no-ff --no-commit <feature-branch>194 test -f "$(git rev-parse --git-dir)/MERGE_HEAD" || { echo "no hay merge en curso"; exit 1; }195 git rm -q -f --ignore-unmatch ':(top,glob)**/docs/audits/quality-check.md' ':(top,glob)**/docs/audits/code-review.md'196 test -z "$(git ls-files --cached -- ':(top,glob)**/docs/audits/quality-check.md' ':(top,glob)**/docs/audits/code-review.md')" \197 || { echo "los informes siguen en el índice"; exit 1; }198 git commit -m "Merge <ID>: <nombre-corto>"199 ```200201 `<ID>` es el identificador del trabajo (`US-XXX` o `WI-XXX`) y `<nombre-corto>` su nombre/slug sin el prefijo de rama.202203 Las dos comprobaciones no son adorno:204205 - **`MERGE_HEAD`** confirma que el merge quedó realmente en curso. Si git respondió *Already up to date*, no hay merge, y ejecutar el `git rm` + `git commit` de todos modos crearía un commit normal que borra dos archivos de la base. Parar ahí.206 - **`:(top,glob)**/…` en las rutas** hace dos cosas, y las dos hacen falta. `:(top)` las ancla a la raíz del repositorio: `git rm` interpreta las rutas **relativas al cwd**, así que sin ese ancla, lanzado desde `packages/api/`, no casarían, `--ignore-unmatch` devolvería `0` sin borrar nada, y los informes se integrarían en la base **en silencio** mientras el paso 12 reporta lo contrario. Y el **`glob` con `**/` inicial** las hace casar a cualquier profundidad, que es lo que exige el monorepo por el otro lado: `quality-check` audita **el módulo elegido**, no el repo entero, y escribe su informe en el `docs/audits/` de ese módulo (`packages/api/docs/audits/quality-check.md`). Con `:(top)docs/audits/…` a secas —anclado pero literal— solo casaría el `docs/` de la raíz, y el informe del módulo se colaría en la base con el mismo silencio. Es la misma razón por la que el `FINGERPRINT` de `quality-check` excluye `**/docs/**` y no `docs/`. `**/` casa también cero directorios, así que el caso de repo simple sigue cubierto. El `git ls-files --cached` posterior es el cinturón: verifica el resultado en vez de confiar en el código de salida. **Tiene que ser `ls-files`, no `git diff --cached`:** el diff lista también los **borrados** stageados, así que cuando la base ya trackeaba el informe —y el `git rm` funcionó— la ruta aparecería igual y el guard cortaría un merge correcto. `ls-files --cached` responde la pregunta que importa: ¿queda algo de esos dos archivos en el índice?207208 `--ignore-unmatch` está para el caso legítimo de que un informe no se haya commiteado en la rama, no para tapar rutas mal resueltas. **Borrar exactamente esos dos archivos, ni uno más:** las copias de `save-report` y los `arch-audit-*.md` se quedan. Si surge conflicto, ir al flujo de conflictos.20911. **Cerrar el trabajo en la rama base — después del merge, nunca antes.** Con el merge hecho, el código ya está integrado y el usuario puede probarlo donde de verdad importa; solo entonces el trabajo pasa a estar cerrado, y las dos operaciones de cierre se hacen **sobre la rama base**, en un único commit propio, separado del merge:210211 **11.1 Marcar el trabajo como `Done`.** En el `progress.md` del trabajo, poner el **estado del trabajo** (el encabezado `**Estado:**` y su marca `<!-- work:id=… · status=Done -->`) en `Done` y actualizar `Ultima actualizacion`. Es el estado del **trabajo**, no de sus unidades: las unidades ya estaban `Done` desde la implementación (paso 4 lo exige); el trabajo entero solo lo está cuando su código vive en la rama base. Solo aplica a `US-XXX` y `WI-XXX` en su rama funcional; una rama `test/` no cierra el trabajo (su paso 4 solo verificó las unidades `TC-XXX` de esa ejecución).212213 **11.2 Resolver el archivado del artefacto.** Mismas condiciones de aplicabilidad que el `Done`: `US-XXX`/`WI-XXX` en rama funcional, y carpeta todavía en la ruta activa (si el paso 3 la encontró ya bajo `docs/archive/`, informarlo y saltar). Si no aplica, **no se resuelve `archiveMode` ni se pregunta nada**. Si aplica, resolver `implementation.archiveMode` (ver [references/archive.md](references/archive.md#política-implementationarchivemode)): con `ask` (por defecto), mostrar la carpeta origen → destino y las investigaciones sueltas que se irían con ella, y pedir confirmación con la herramienta de preguntas estructuradas — respuesta binaria, **preguntar primero, mover después**; con `always`, `git mv` directo, mostrando igual el bloque origen → destino en el reporte; con `never`, no archivar ni preguntar. Si no se archiva —negativa del usuario, sesión desatendida, o `never`— se anota el motivo para el paso 12 y se sigue: **el merge ya está hecho y no depende de esto.** Procedimiento completo (destinos, investigaciones `RS-XXX` huérfanas, reparación de enlaces, guards) en [references/archive.md](references/archive.md).214215 **11.3 Commitear el cierre en la rama base.** Un solo commit con el `progress.md` en `Done` y, si lo hubo, el `git mv` del archivado: `chore(<ID>): cerrar trabajo` (+ « y archivar» si se movió). Invocar `git-commit` sobre esos cambios; la rama base es `commitPolicy: merge` (paso 5), así que no hay confirmación extra de rama protegida. **Si la base fuera `pull_request`, el flujo ni siquiera habría llegado aquí.** Nunca meter este cierre dentro del commit de merge del paso 10: el merge integra exactamente el código verificado, y el cierre es un cambio de estado posterior que debe poder leerse —y revertirse— por separado.216217 > **Por qué después del merge.** Archivar y marcar `Done` en la rama del trabajo, antes de integrar, obligaba a decidir el cierre a ciegas: si el merge fallaba, o el usuario detectaba un problema al probar la integración, el artefacto ya estaba archivado y el trabajo «cerrado» sin estarlo. Con el cierre en la base y después del merge, el orden refleja la realidad: se integra, se prueba, se cierra. **`pr-create` mantiene su comportamiento:** ahí el archivado va en la rama antes del PR, porque el merge lo hace la plataforma y el skill no vuelve a tener el control después.21812. **Reportar resultado** al usuario: rama origen (con su prefijo), rama destino, número de commits integrados, hash del commit de merge, **hash del commit de cierre** (paso 11) con el `progress.md` en `Done`, estado del HEAD, **el estado de cada una de las tres puertas** —veredicto si corrió, u «omitida» con su motivo si no— y nota explícita de que **no** se hizo push ni se borró la rama del trabajo. Si el paso 11 movió algo, incluir su **bloque de archivado** (origen → destino y qué pasó con las investigaciones sueltas; formato en [references/archive.md](references/archive.md)). Si no archivó —el usuario lo declinó, no había con quién confirmar, rama `test/`, o el trabajo ya estaba archivado—, decirlo en una línea **con el motivo**, en vez de omitirlo en silencio. Mencionar también que los informes de las puertas quedaron en la rama del trabajo y no se integraron.219220---221222### Los informes de las puertas no se integran223224`docs/audits/quality-check.md` y `docs/audits/code-review.md` son **fotos de una rama concreta**: su encabezado lleva la rama y el commit sobre los que se corrieron las puertas. Se **versionan en la rama del trabajo** —ahí valen: quedan junto a los commits que verifican, y el revisor los ve en el PR— pero **no deben llegar a la rama base**, por dos razones:225226- **En `develop` serían mentira.** Nadie corrió las puertas sobre `develop`; ese archivo diría «`APPROVED`» sobre una rama que ni siquiera es la suya. Y con cada integración lo pisaría la última feature en entrar.227- **Viven en una ruta fija**, así que toda rama escribe el mismo archivo: dejarlos integrarse convierte cada merge en un conflicto seguro sobre un artefacto generado.228229Por eso el paso 10 parte el merge: `--no-commit` deja el resultado en el índice, se retiran los dos informes y el commit de merge se cierra ya sin ellos. La rama del trabajo **conserva los suyos intactos** — no se reescribe su historia, solo se decide qué entra en la base.230231**Qué NO se toca:**232233| Artefacto | Por qué se queda |234|-----------|------------------|235| `docs/audits/arch-audit-*.md` | Auditorías de arquitectura del **repositorio**, no de una rama. Su sitio es la rama base. |236| `docs/audits/quality-check-<timestamp>.md` · `code-review-<timestamp>.md` | Copias de `save-report`: el usuario las pidió **para conservar histórico**. Llevan marca de tiempo, así que no colisionan ni pisan nada. |237| `coverage.md` del trabajo | Vive junto a su artefacto en `docs/specs/`, es del **trabajo** y no de la rama, y se integra con él. |238| La carpeta del trabajo movida a `docs/archive/` y el `progress.md` en `Done` | No viajan en el merge: se hacen **en la rama base, después del merge** (paso 11), en un commit de cierre propio. El `coverage.md` que la carpeta lleva dentro se mueve con ella. |239| `.sdd-devkit/test-run.json` | Ni aparece: está en el `.gitignore`. |240241> **Esta limpieza solo cubre los merges que hace este skill.** Un merge desde la UI de GitHub/GitLab —el camino de `pr-create`— sí propaga los informes: ahí la limpieza hay que hacerla en la rama base después de integrar. Ver [`pr-create`](../pr-create/SKILL.md).242243---244245> **Conflictos y rama base ambigua:** si el `git merge` produce conflictos, seguir el **Flujo de manejo de conflictos**, que **clasifica antes de abortar**: un `modify/delete` sobre los dos informes de `docs/audits/` se resuelve por el lado del borrado y el merge continúa; cualquier otro conflicto se aborta con `git merge --abort`, se reporta y se para. Si la rama base no se resuelve por reflog ni config, seguir el **Flujo de rama base ambigua** (listar candidatos, preguntar, no asumir default). Ambos flujos íntegros y el **checklist detallado** están en [references/flows.md](references/flows.md).246247---248249## Mapa de referencias250251Cargar bajo demanda; el contenido íntegro vive en estos archivos:252253| Necesitas… | Archivo |254|------------|---------|255| Flujo de manejo de conflictos, flujo de rama base ambigua, checklist detallado antes de mergear | [references/flows.md](references/flows.md) |256| Archivado del artefacto (paso 11, tras el merge): cuándo aplica y cuándo no, destinos, `git mv` y guards, investigaciones `RS-XXX` sueltas huérfanas, reparación de enlaces, formato del reporte, anti-patrones | [references/archive.md](references/archive.md) |257| Ejemplos por tipo (US/WI: camino feliz, unidad pendiente, base ambigua, working tree sucio, conflicto, prefijo inválido), anti-patrones, y notas (handoffs del ciclo, `progress.md`, estados, detección de rama base, sin push intencional, mensaje al usuario) | [references/examples.md](references/examples.md) |258259### Referencias compartidas del plugin260261Reglas transversales del catálogo; viven en la raíz del plugin, no en este skill.262263- [`${PLUGIN_ROOT}/reference/language.md`](../../reference/language.md): **Idioma** — resolución obligatoria del idioma de artefactos y mensajes. *Lectura obligatoria antes de ejecutar el skill.*264- [`${PLUGIN_ROOT}/reference/asking.md`](../../reference/asking.md): **Preguntas** — mecanismo estructurado, ritmo, fallback. *Antes de la primera pregunta.*265- [`${PLUGIN_ROOT}/reference/artifacts.md`](../../reference/artifacts.md): **Artefactos** — rutas del harness, identificadores, archivado. *Al resolver una ruta o calcular un ID.*266- [`${PLUGIN_ROOT}/reference/verification.md`](../../reference/verification.md): **Política de verificación** — qué puertas corren antes del merge (`enabled`) y si el cierre continúa con archivado y merge sin preguntar (`handoff`). *Lectura obligatoria antes de ejecutar el skill.*267- [`${PLUGIN_ROOT}/reference/implementation.md`](../../reference/implementation.md): **Política de implementación** — de aquí sale `archiveMode`. *Antes de resolver el archivado (paso 11).*268- [`${PLUGIN_ROOT}/reference/git.md`](../../reference/git.md): **Política de commit y push** — de aquí sale `integrationBranches` y su `commitPolicy`. *Al resolver la rama base.*269- [`${PLUGIN_ROOT}/reference/escalation.md`](../../reference/escalation.md): **Límite de intentos** — cuántos intentos consecutivos se hacen sobre un mismo problema que no se resuelve antes de escalar al usuario, y qué hacer al agotarlos. *Lectura obligatoria antes de ejecutar el skill.*270