Agentic QA · Skill de soporte
El operador de Git del repo: ramas, commits, push, pull requests, conflictos y worktrees, adaptados a la estrategia de branching que el proyecto declaró en .agents/project.yaml.
Mapa · 2 de 19
Paso 1
Leer el estado del repo
status · branch -a · diff
log · fetch · remote -v
Paso 1b
Política vs host
git:policy verify
una vez por sesión
Paso 2
Resolver la estrategia
git_strategy:
heurísticas · preguntar
Las seis operaciones (paso 3)
Branch
Proponer nombre
prefijo + clave + slug
Commit
Agrupar por responsabilidad
conventional + trailers
Push
Política de protegidas
Regla #5 · nunca --force
PR
Base según estrategia
gh pr create · sin merge
Conflict
Diagnosticar primero
opciones por seguridad
Strategy Setup
Establecer el flujo
Q1-Q4 · materializar
Caminos adyacentes
Escala
PRs encadenados
más de 400 líneas · trunk sdet
Paridad
Rulesets del host
verify · apply · divergencias aceptadas
Aislamiento
Worktrees
provision · audit --rescue
Paso 2 · 3 de 19
Una sola fuente
El bloque git_strategy: de .agents/project.yaml. Nunca un archivo aparte ni prosa de política en AGENTS.md, que solo apunta al bloque.
sdet es opt-in
Nunca se infiere del layout: lo confirma un trunk test/<module>-suite vivo con PRs que le apuntan.
Paso 2 · 4 de 19
| Estrategia | Ramas largas | Base del PR | Protegidas |
|---|---|---|---|
| solo-main | solo main | main | main |
| github-flow | main siempre desplegable | main | main |
| trunk-based | trunk + ramas de menos de un día | main | main |
| main-integration | main + staging / dev | integración | ambas |
| gitlab-flow | + ramas de entorno | integración | producción + integración + pre-production |
| enterprise | + feature/* release/* hotfix/* | integración · hotfix/* a main | + release/* |
| gitflow | main + develop | feature/* a develop | main + develop |
| sdet | main + trunk efímero por suite | el trunk · al final, main | main |
Catálogo completo con señales de detección y trade-offs: git-flow-master/references/branching-strategies.md. Prefijos de rama: feat/ fix/ test/ docs/ refactor/ chore/, con precedencia y formato en git_strategy.branch_prefixes.
Strategy Setup · 5 de 19
La trampa del template
El boilerplate trae el bloque lleno. Un proyecto nuevo lo hereda y el updater congela project.yaml, así que un valor presente no prueba que alguien lo haya decidido. Eso lo dice meta.strategy_source: inherited o chosen.
La oferta
Con la estrategia heredada, la skill ofrece Strategy Setup una vez por sesión y cuenta lo que cuesta el default (sin rama de integración, sin camino de promoción, sin gate de review). Un "no" sigue bajo la heredada. Solo Strategy Setup estampa chosen.
El cuestionario (cada pregunta, solo si aplica)
| Q1 | promoción integración → producción: fast-forward only / merge commit / squash |
| Q2 | merge de la rama de trabajo: merge commit (--no-ff) / squash / rebase + merge |
| Q3 | hotfix: rama desde producción, PR a producción y back-merge el mismo día |
| Q4 | todas las estrategias: direct_push_to_protected · admin_bypass · require_pr_reviews |
Después materializa: crea ramas solo si faltan y sincroniza solo por fast-forward real, nunca --force. El push de ese sync a una rama protegida siempre pregunta.
Al cierre ofrece llevar la política al host: primero bun run git:policy verify (solo lectura), y si hay deriva muestra el dry run de apply y escribe únicamente con tu sí.
Push · 6 de 19
git_strategy.policy.direct_push_to_protected en .agents/project.yaml. AGENTS.md no fija la respuesta: la variable es la decisión.
forbidden
Rechaza el push directo y redirige al flujo de PR: propone una rama de trabajo y gh pr create.
confirm
Pregunta antes de cada push y espera un sí explícito. Es también lo que pasa si el bloque falta o está en null.
allowed
Autorización permanente: pushea sin preguntar. Preguntar igual convertiría allowed en confirm.
Bypass de admin
Solo con admin_bypass: true la skill puede ofrecer saltear el PR en una urgencia, y aun así reconfirma que el operador tiene permisos de admin y la acción misma. Con false, nunca.
Push según upstream
Sin upstream: git push -u origin {branch}. Atrasado: git push. Divergido: parar y pasar a resolución de conflictos, nunca forzar.
Salvaguardas · 7 de 19
Regla #6 · historia
--force, --force-with-lease y --no-verify solo con autorización explícita y rama no compartida.
Regla #15 · sin descartes globales
Prohibidos git restore ., git checkout -- ., git reset --hard, git stash sin path y git clean -f. Otra sesión puede compartir el árbol: se descartan solo los paths propios.
Staging explícito
Nunca git add -A ni git add .: paths explícitos, para que no viaje un secreto ni el trabajo de otro.
Hook rechazó el commit
Arreglar la causa y hacer un commit nuevo. --amend operaría sobre el commit anterior.
Commit · 8 de 19
Con clave: {type}({ISSUE-KEY}): {description}. Sin clave: {type}: {description}. Cambio que rompe: ! tras el tipo y footer BREAKING CHANGE:.
Un Docs-Checked: <label> <motivo> puede ir encima del par forense, solo con motivo y nunca por reflejo: sin él, o sin editar las páginas que el contrato nombra, el pre-push y la CI bloquean.
Prefijos semánticos
feat fix docs style refactor perf test chore build ci revert. Detalle: references/conventional-commits.md.
Agrupar por responsabilidad
Test code, schemas de API, test data, skills / docs, config. Los datos y fixtures de un test viajan en el mismo commit que el test.
Sin atribución a la IA
Nada de "Generated with…", ni Co-Authored-By de una IA, ni Claude-Session: u otro trailer con marca de harness. El commit se ve escrito por una persona.
Commit · 9 de 19
Se copian del contexto
El label llega hasta el token literal harness= (puede tener espacios y paréntesis). primary fuera de un worktree; unknown si no resuelve. Nada debajo. Al commitear, .husky/commit-msg solo avisa (no bloquea) si falta alguno o si aparece un Claude-Session:.
Procedencia
Responden qué checkout y qué sesión produjeron la línea, para un bisect o un post-mortem de sesiones paralelas. No nombran herramienta, vendor ni modelo: por eso no cuentan como atribución (Regla #3).
Un emisor, tres hosts
Claude Code y Codex lo corren como command hook; OpenCode importa la constante desde un plugin. Mismo texto, sin copias por harness.
Paso 1b · 10 de 19
verify: una vez por sesión, en la primera intención de push, PR o merge, y en el hook pre-push y bun run repo:check. Host inalcanzable = aviso y exit 0.
Un 404 no es "sin protección"
Con rulesets, branches/{b}/protection responde 404 mientras rules/branches/{b} exige PR. El tool consulta los dos.
Un push que pasó puede ser un bypass
Changes must be made through a pull request en la salida: la regla sigue viva para el resto y el push se reporta como bypass.
Code owners sin CODEOWNERS
Requisito imposible de cumplir: todo merge termina en bypass. verify lo marca como drift.
Paridad · 11 de 19
El yaml estaba mal
Se corrige .agents/project.yaml para que diga lo que el host aplica.
El host estaba mal
git:policy apply: leer el dry run antes de --yes.
Los dos tienen razón
Se registra en policy.accepted_divergences con su motivo.
verify lo lista bajo ACCEPTED y sale con 0; avisa si la entrada ya no matchea ningún drift.
verify --stamp registra policy_source: accepted, distinto de verified (host idéntico al yaml).
apply conserva el lado del host del campo aceptado: no le abre main a nadie.
Con la divergencia declarada, la línea Bypassed rule violations del remoto es lo esperado: no se trata como anomalía ni se abre un PR para "cumplir" la regla.
PR · 12 de 19
| Rama | Plantilla del cuerpo |
|---|---|
| test/* | references/pr-test-automation.md: Summary, Changes, Test Plan, Traceability (issue, ATP, ATR, TCs), evidencia, riesgo, checklist |
| el resto | references/pr-templating.md |
Título y placeholders
Menos de 70 caracteres. Un placeholder que la skill no pudo llenar queda visible para el autor; ninguna sección se borra en silencio. Labels: verificar con gh label list.
Se detiene en la creación
El merge es el paso del usuario. Excepción: un worker supervisado cuyo brief nombra el merge ejecuta la instrucción del owner y lo dice en su reporte.
Gate adversarial opcional
Diff de más de 400 líneas o que toca scaffolding compartido: la skill ofrece /judgment-day antes de abrir. Nunca lo invoca sola.
Escala · 13 de 19
El plan es un contrato. Si el diff real supera la estimación, se vuelve a correr la decisión en vez de estirar el presupuesto en silencio. Se devuelve con su traza, nunca como etiqueta suelta: Chain strategy:, cada pregunta respondida con el motivo de este cambio y Decided by:. Una traza que solo repite la conclusión cuenta como no decidida. El umbral sale de la investigación sobre review de código: por encima, la detección de defectos cae.
Con sdet activo, el trunk de integración ya es el modo encadenado de toda suite de tests y este árbol no se recorre para test automation. Sigue valiendo para cambios no-test del mismo repo.
Escala · 14 de 19
Por ticket
Rama cortada del trunk, nunca del ticket anterior. Gate local en local y staging, push, Sanity CI, PR al trunk, merge --no-ff.
Plus Branches
Trabajo adyacente (docs/* chore/* fix/*) entre tickets, con PR al trunk como cualquier ticket.
Cierre
Sync gate para que el diff final muestre solo la suite, un PR revisado trunk → main, y el trunk se borra. Solo main está protegida.
Aislamiento · 15 de 19
| Manual | Claude Code | Orquestado | |
|---|---|---|---|
| Cómo | git worktree add ../dir -b feat/x main | EnterWorktree / ExitWorktree | la capa de orquestación, uno por worker (/orca-orchestration) |
| Dónde | donde elijas | .claude/worktrees/ | fuera del repo, visible para el owner |
| Para quién | cualquier agente o persona | solo Claude Code | una flota que el owner quiere ver y dirigir |
Lo que no viaja
Un worktree nuevo trae solo lo trackeado. Lo untracked se mueve a mano; lo gitignored (.env, node_modules/, el alias de skills, la caché PBI) falta, y falla con mensajes que apuntan a otro lado.
Compartido entre árboles
Objetos, refs, config, hooks y la lista de stash. Para pasar trabajo entre sesiones se commitea, nunca se stashea.
Cuándo no hace falta
Una tarea lineal sobre un árbol limpio, o sesiones que solo leen código y escriben al tracker: ahí alcanza un branch o el mismo checkout.
Aislamiento · 16 de 19
Tres caminos al mismo provisioning
orca.yaml corre worktree:provision en cada worktree de Orca. Los worktrees de harness (Claude Code, la app de Codex) copian la lista de .worktreeinclude, la misma que copia el script; la app de Codex además corre el script desde .codex/environments/environment.toml.
<<PRIMARY_ROOT>>
El checkout principal, el mismo valor desde cualquier worktree. Ahí van .session/**, evidencia y reportes: lo ignorado que se escribe dentro de un worktree muere con él.
La auditoría clasifica
STATE va al principal (--rescue copia sin pisar) · CACHE vuelve con el comando que nombra · DISPOSABLE se pierde sin culpa · UNKNOWN se decide a mano. Exit 1 mientras quede STATE o UNKNOWN solo en el worktree.
El updater se niega
bun sync guarda backups, marcadores y prompts dentro del checkout: en un worktree aborta y pide correrlo en el principal.
Conflict · 17 de 19
1
Explicar la causa
status · diff --check
MERGE_HEAD · REBASE_HEAD
2
Opciones por seguridad
nunca una destructiva
en silencio
3
Guiar paso a paso
en el idioma del usuario
4
Verificar
status · log --oneline -3
5
Prevenir
una nota corta
Tipos con playbook propio
Ante la duda, abortar: git merge --abort, git rebase --abort, git cherry-pick --abort.
Salvaguardas · 18 de 19
| # | Regla |
|---|---|
| G1 | Force-push a main o a cualquier rama compartida. |
| G2 | Amend o rebase de un commit ya pusheado. |
| G3 | Commitear secretos, credenciales, contenido de .env o tokens: la historia de git es para siempre. |
| G4 | Atribución a la IA en commits o cuerpos de PR (Regla #3). |
| G5 | Pushear a una protegida salteando la política de la Regla #5. |
| G6 | --no-verify para "ir más rápido": el hook atrapa el bug que no viste. |
| G7 | Mezclar responsabilidades en un commit (feat + refactor + lint). |
| G8 | Apilar PRs sin nombrar la cadena de dependencias en el cuerpo. |
| G9 | Descartes globales del working tree (Regla #15). |
Cierre · 19 de 19
Cómo se invoca
Claude Code: /git-flow-master.
OpenCode y Codex: cargá la skill git-flow-master.
En los tres hosts se carga sola ante intenciones como "commit and push", "abrí un PR", "tengo conflictos" o "configura el flujo de git". No tiene modos: la operación sale del pedido.
Quién la llama
/test-automation termina en un review local limpio y le pasa el envío.
/framework-development despacha el código verificado.
/orca-orchestration la cita como canon de los trailers y del worktree plano.
/agentic-qa-onboard la usa para el Strategy Setup.
A quién llama
/judgment-day: gate opcional antes del PR.
/regression-testing: Sanity CI del trunk sdet.
/acli: operaciones Jira que dispara un commit o PR.
Testing de tickets: vuelve a /sprint-testing y compañía.
Lo que deja la skill
Ramas con prefijo y clave · commits atómicos con trailers forenses · un PR por gh que espera tu merge · el bloque git_strategy: actualizado · meta.policy_* estampado por git:policy verify --stamp.
Referencias: .agents/skills/git-flow-master/references/