Agentic QA · Skill de soporte

/git-flow-master

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.

Se carga sola ante cualquier intención git / PR Fuente de verdad: git_strategy: Transporte de PRs: gh
Deck de la skill git-flow-master: el único punto de entrada para todo lo que pasa en la capa de control de versiones. No asume un modelo de branching: lo lee del proyecto y adapta cada comando. Pulsá → para avanzar, S para modo presentador, O para overview, F para pantalla completa.

Mapa · 2 de 19

Seis operaciones sobre una estrategia resuelta

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

Todo arranca igual: leer el estado del repo, reconciliar la política declarada con el host la primera vez que hay intención de push o PR, y resolver la estrategia. Recién ahí corre la operación pedida. Cada nodo del mapa es una sección del deck.

Paso 2 · 3 de 19

Qué decide por vos: la estrategia

1 · PROJECT.YAML git_strategy.strategy set meta.strategy_source vale chosen? sí Confirmada se usa tal cual, sin preguntar no Heredada del template inherited, o project_name en null: ofrece Strategy Setup, no lo corre null 2-5 · HEURÍSTICAS DE LAYOUT solo main en el remoto solo-main main + staging / dev / develop main-integration + feature/* o release/* activas enterprise .gitlab-ci.yml · release/* + hotfix/* gitlab-flow · gitflow sin respuesta 6 · Preguntar nunca elige en silencio · en un repo de test automation recomienda sdet Persistir en el bloque git_strategy: del mismo project.yaml

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.

La resolución es pegajosa: la próxima invocación relee el bloque en vez de volver a preguntar, y editarlo a mano es válido. El orden importa: primero el bloque declarado, después las señales del layout de ramas, y como último recurso la pregunta. La rama "heredada" existe porque el boilerplate se distribuye con el bloque lleno (solo-main) y un proyecto nuevo lo recibe tal cual.

Paso 2 · 4 de 19

La estrategia elige la base y las protegidas

EstrategiaRamas largasBase del PRProtegidas
solo-mainsolo mainmainmain
github-flowmain siempre desplegablemainmain
trunk-basedtrunk + ramas de menos de un díamainmain
main-integrationmain + staging / devintegraciónambas
gitlab-flow+ ramas de entornointegraciónproducción + integración + pre-production
enterprise+ feature/* release/* hotfix/*integración · hotfix/* a main+ release/*
gitflowmain + developfeature/* a developmain + develop
sdetmain + trunk efímero por suiteel trunk · al final, mainmain

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.

La tabla resume el catálogo; el detalle vive en la referencia de la skill. En un repo QA la mayoría del trabajo cae en ramas test/, fix/ o chore/. Un feat/ acá suele ser un cambio al framework de tests.

Strategy Setup · 5 de 19

solo-main viene por defecto: falta elegirla

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)

Q1promoción integración → producción: fast-forward only / merge commit / squash
Q2merge de la rama de trabajo: merge commit (--no-ff) / squash / rebase + merge
Q3hotfix: rama desde producción, PR a producción y back-merge el mismo día
Q4todas 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í.

Disparadores: "set up our git strategy", "configura el flujo de git", "bootstrap branching". Las estrategias de una sola rama no responden Q1 a Q3; Q4 aplica siempre, porque un main solitario también está protegido. Una pregunta ya respondida en decisions.* no se repite, y la creación de ramas siempre se propone antes. Mecánica completa: references/strategy-setup.md.

Push · 6 de 19

Push a una protegida: la Regla #5 lee una variable

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.

El valor allowed lo estampa Strategy Setup con el usuario, por eso vale como autorización. La lista de protegidas sale de la estrategia (slide 4) unida a git_strategy.protected.

Salvaguardas · 7 de 19

Lo que ninguna estrategia relaja

Regla #6 · historia

  • Nunca reescribir historia pusheada (rebase o amend sobre commits ya publicados).
  • Nunca force-push a una rama que otros pueden compartir.
  • Nunca borrar ramas remotas sin confirmación.
  • Siempre hacia adelante: commits nuevos, merges preservados.

--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.

Estas son invariantes, no opciones de estrategia: ningún valor de git_strategy las afloja. En repos con caché PBI, la skill además revisa que nada de .context/ fuera del tier COMMIT quede en staging.

Commit · 8 de 19

Un commit, una responsabilidad

test(UPEX-123): cover bulk-assign empty states Adds the empty-list and single-item cases the ATP marked as risk beyond the criterion. Worktree: bulk-assign Session: bulk-assign-w2 (c0ffee12)

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.

La skill propone todos los commits como un bloque y espera OK, cambios o rechazo antes de ejecutarlos uno por uno. Lo mismo vale para nombres de rama y cuerpos de PR.

Commit · 9 de 19

Trailers forenses: Worktree: y Session:

CADA PROMPT Hook UserPromptSubmit .agents/hooks/ personality-reinject.mjs CONTEXTO DE LA SESIÓN AGENT IDENTITY: worktree=<name|primary> session=<label> harness=<host> ÚLTIMAS DOS LÍNEAS Worktree: <name|primary> Session: <label>

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.

Son obligatorios en todo commit y en toda estrategia. Un trailer faltante es menos recuperable que un unknown honesto. El hook es el mismo que reinyecta el contrato de personalidad.

Paso 1b · 10 de 19

Lo declarado contra lo que el host aplica

$ bun run git:policy plan # el mapeo, sin red $ bun run git:policy verify # lee el host · exit 1 si hay drift $ bun run git:policy verify --stamp # además registra meta.policy_* $ bun run git:policy apply # dry run $ bun run git:policy apply --yes # escribe el ruleset [--allow-loosening] # solo si afloja un guard

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.

Por qué un script y no un checklist: la reconciliación existía como prosa y no ocurría. Un script hace todas las consultas en cada corrida. Mapeo estrategia → ruleset: references/ruleset-parity.md.

Paridad · 11 de 19

Drift con tres salidas, y una se declara

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.

git_strategy: policy: direct_push_to_protected: allowed accepted_divergences: - field: main.direct_push_to_protected enforced: blocked (pull_request rule) accepted: <YYYY-MM-DD> reason: > Why both sides differ on purpose.

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.

Caso típico: el yaml declara allowed porque la credencial de push está en la lista de bypass, y el host mantiene la regla de PR para el resto de los contribuidores. La aceptación es por campo y exige un motivo. Nunca se corre apply para arreglar un verify que no se leyó.

PR · 12 de 19

El PR: base por estrategia, sin merge

$ gh pr create \ --title "{type}({ISSUE-KEY}): {description}" \ --body-file "$(mktemp)" \ --base {base} \ [--reviewer {users}] [--label {labels}] [--draft]
RamaPlantilla del cuerpo
test/*references/pr-test-automation.md: Summary, Changes, Test Plan, Traceability (issue, ATP, ATR, TCs), evidencia, riesgo, checklist
el restoreferences/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.

El cuerpo se escribe a un tempfile y se pasa con --body-file para evitar problemas de escape. Sin gh o sin auth, la skill reporta el bloqueo; nunca da a entender que el PR existe.

Escala · 13 de 19

Más de 400 líneas: decidir antes de codear

Q1 Mayormente mecánico? rename · formatter · generado sí size-exception override explícito + línea "Why size-exception:" no Q2 2 a 4 rebanadas lineales? cada una menor a 400 líneas sí stacked-to-main cada PR desde la base default; la base funciona entre merges no Q3 Scaffolding compartido? tipos · bases · schemas nuevos sí feature-branch-chain una rama de integración, PRs hijos y un PR final a la base no Re- descomponer

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.

Un cambio monolítico no mecánico y sin scaffolding compartido es un olor de planificación: vuelve al breakdown de la historia. El árbol completo está en references/branching-strategies.md.

Escala · 14 de 19

sdet: un trunk efímero por suite

main PR final a main, el único que enfrenta los rulesets trunk test/<module>-suite test/{KEY}-a docs/* (Plus) test/{KEY}-b sync gate merge origin/main

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.

El trunk es un sustituto de main para la suite: "nunca volver a main" significa volver al trunk hasta el final. El nombre sale del alcance: test/<module>-suite o test/<STORY-KEY>-<slug>-suite. Runbook completo: references/sdet-integration-trunk.md.

Aislamiento · 15 de 19

Worktrees: una sesión, un árbol, una rama

ManualClaude CodeOrquestado
Cómogit worktree add ../dir -b feat/x mainEnterWorktree / ExitWorktreela capa de orquestación, uno por worker (/orca-orchestration)
Dóndedonde elijas.claude/worktrees/fuera del repo, visible para el owner
Para quiéncualquier agente o personasolo Claude Codeuna 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.

Git bloquea la misma rama en dos worktrees, y eso es lo que los vuelve seguros para sesiones paralelas. Referencia completa con la guía de decisión: git-flow-master/references/worktrees.md.

Aislamiento · 16 de 19

Del alta a la baja sin perder estado

1 · CREAR verificar HEAD contra origin/<base> creado justo antes de lanzar la sesión 2 · PROVISIONAR bun run worktree:provision .env y overrides, .auth/, deps, alias de skills, skills T3 Orca: setup de orca.yaml 3 · TRABAJAR estado durable por ruta absoluta en <<PRIMARY_ROOT>> commit + push + PR 4 · AUDITAR Y REMOVER bun run worktree:audit --rescue Orca: archive de orca.yaml exit 0 → remove + prune

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.

Un worktree removido con git worktree remove borra lo ignorado sin avisar, y la CLI de Orca saltea los archive hooks salvo con --run-hooks. Por eso la auditoría va antes de cualquier baja. Doctrina de provisioning: orca-orchestration/references/provisioning.md.

Conflict · 17 de 19

Conflictos: diagnosticar antes de resolver

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

merge de contenido rename / delete rebase push rechazado (divergido) detached HEAD stash apply historias no relacionadas hook rechazó el commit

Ante la duda, abortar: git merge --abort, git rebase --abort, git cherry-pick --abort.

Un arreglo equivocado acá cuesta horas, y el usuario rara vez está tan apurado. Playbooks completos: references/conflict-resolution.md.

Salvaguardas · 18 de 19

Anti-patrones: nunca hacer

#Regla
G1Force-push a main o a cualquier rama compartida.
G2Amend o rebase de un commit ya pusheado.
G3Commitear secretos, credenciales, contenido de .env o tokens: la historia de git es para siempre.
G4Atribución a la IA en commits o cuerpos de PR (Regla #3).
G5Pushear 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.
G7Mezclar responsabilidades en un commit (feat + refactor + lint).
G8Apilar PRs sin nombrar la cadena de dependencias en el cuerpo.
G9Descartes globales del working tree (Regla #15).
Los anti-patrones del SKILL.md. G1, G2 y G9 protegen el trabajo de otros; G3 y G4 protegen la historia; G5 a G8 protegen el review.

Cierre · 19 de 19

Invocación y handoffs

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/

Fin del recorrido. El mapa del slide 2 resume todo: leer el estado, reconciliar política, resolver la estrategia y recién ahí operar.
← → navegar · O resumen · S presentador · N notas · F pantalla