Agentic QA · Tooling
Cómo una skill de flujo llega a Jira, a Xray, al navegador o a la web sin conocer la sintaxis de ninguna herramienta: escribe una etiqueta, el repo la resuelve y la skill dueña de la herramienta pone el cómo.
Mapa · 2 de 19
Skill de flujo
Escribe pseudocódigo
[ISSUE_TRACKER_TOOL]
[TMS_TOOL] · [AUTOMATION_TOOL]
agent-tool-resolution.md §6
Resuelve la etiqueta
primario CLI · MCP de respaldo
según modalidad y capacidad
agent-tool-resolution.md §6.5
Carga la skill dueña
antes de invocar el binario
gate duro, no sugerencia
Herramienta
Ejecuta
acli · bun xray · playwright-cli
un MCP resuelto por sufijo
Las tres familias que cubre este deck
Utilidad · slides 4 a 12
Skills del repo
metadata.kind: utility
lista: .agents/skills/REGISTRY.md
Comunidad · slides 13 a 15
Instaladas a nivel proyecto
cli/install.ts
PROJECT_LEVEL_SKILLS
MCP · slides 16 a 18
Capacidades
mcp-capabilities.md
sufijo del nombre de la tool
agent-tool-resolution.md §6 · 3 de 19
| Etiqueta | Primario | Si no está |
|---|---|---|
| [ISSUE_TRACKER_TOOL] | /acli: Story, Bug, Epic, transiciones, comentarios, links | MCP de Atlassian, solo si se activó (opt-in) |
| [TMS_TOOL] · jira-xray | /xray-cli: Test, Test Plan, Test Execution, Test Set, Precondition | no hay MCP de respaldo: credenciales Xray rotas = parar |
| [TMS_TOOL] · jira-native | /acli: los artefactos de test son issues nativas de Jira | MCP de Atlassian, opt-in |
| [AUTOMATION_TOOL] | /playwright-cli, el único camino (no hay MCP de navegador) | ninguno: parar en el punto de uso |
| [DOCS_TOOL] · [WEB_SEARCH_TOOL] | capacidades library-docs y web-search, por sufijo | WebSearch / WebFetch solo si el usuario lo elige |
| [ORCHESTRATION_TOOL] | /orca-orchestration: workers, worktrees, runs, automatizaciones (si el binario orca está y el runtime responde) | subagentes de un solo disparo; las líneas de lanzamiento se pegan a mano en terminales |
| [DB_TOOL] · [API_TOOL] | capacidades db y api-schema (el esquema); la ejecución de API es curl | según §6 (.agents/instructions/agent-tool-resolution.md) |
La modalidad del TMS la resuelve una vez /test-documentation (Fase 0) y el resto del flujo la hereda; nunca se redecide a mitad de camino. Tabla completa y vigente: §6, en .agents/instructions/agent-tool-resolution.md.
agent-tool-resolution.md §6.5 · 4 de 19
El gate
Antes de cualquier llamada a Bash que nombre uno de estos binarios, la IA verifica que la skill que le corresponde esté cargada. Si no lo está, la carga primero. Sin ella va a ciegas en sintaxis, flags, auth y errores.
El reparto
La skill sabe cuándo y qué; el binario ejecuta el cómo. Por eso una skill de flujo nunca escribe acli … ni bun xray … literal: escribe la etiqueta y carga la skill dueña.
Ejemplos del mapeo
| Binario | Skill que se carga antes |
|---|---|
| acli | /acli |
| jq | /acli (su consumidor principal) |
| bun xray | /xray-cli |
| playwright-cli | /playwright-cli + /playwright-best-practices |
| resend | /resend-cli |
Mapeo completo, con gh, bunx allure, orca y el resto: §6.5, en .agents/instructions/agent-tool-resolution.md.
Utilidad · 5 de 19
Qué resuelve
[ISSUE_TRACKER_TOOL] siempre, y [TMS_TOOL] solo en modalidad jira-native. Cubre Jira Cloud, Confluence y admin de la organización.
El patrón selector
Los comandos que mutan aceptan --key, --jql, --filter o --from-file. En un batch, --yes evita que se cuelgue esperando stdin.
Texto enriquecido
Markdown → ADF con acli/scripts/md-to-adf.ts, que valida antes de publicar. Antes de escribir se mide el ADF serializado contra un presupuesto de 30000 caracteres (Jira cuenta el JSON, no el Markdown); después se relee el campo.
Trampas que la skill conoce
| Paginación opt-in. Sin --paginate o --limit, una búsqueda trae la primera página y no avisa. |
| Exit 0 no prueba nada. Un subcomando inexistente cae en la ayuda del padre con código 0. |
| workitem edit rechaza campos custom y no tiene flag de components: se setean al crear o por REST PUT. |
| --out / --in invertidos respecto de Jira: después de cada link se lista y se verifica la dirección. |
| Auth por producto. jira, confluence y admin son sesiones separadas: verificar antes de un batch. |
Utilidad · 6 de 19
| Operación | Herramienta | Por qué |
|---|---|---|
| Lectura detallada (campos custom, ACs, ATP, ATR, comentarios) | bun run jira:sync-issues get <KEY> --include-comments | acli view devuelve null en customfield_*; el sync resuelve slugs, pasa ADF a Markdown y escribe un .md por campo |
| Lectura en lote | bun run jira:sync-issues jql "<query>" | la misma materialización para cada resultado |
| Escritura (crear, transicionar, comentar, linkear, asignar) | /acli (o /xray-cli en jira-xray) | el script de sync solo lee; toda mutación queda en la herramienta |
| Consulta trivial (resumen, estado, lista de keys) | acli workitem view / search | no necesita materializar nada |
| Trazabilidad (grafo de links, estado de runs) | /acli · /xray-cli | el sync no refleja el estado de cobertura ni de runs de Xray |
Lo sincronizado vive en .context/PBI/: caché de Jira, sin commit y sin edición a mano. bun run context:hydrate reconstruye el árbol.
Los catálogos de campos, workflows y tipos de vínculo (.agents/jira-*.json) se refrescan con bun run jira:sync-fields, jira:sync-workflows y jira:sync-link-types. La lista vigente de scripts jira:* es package.json.
Utilidad · 7 de 19
El host no es una variable de entorno
Vive en .agents/project.yaml → issue_tracker.atlassian_url y en ningún otro lado local. Desde el shell se lee con el accesor:
bun run --silent jira:url
bun run --silent jira:url --slug
--slug da el host pelado que pide acli --site.
| Herramienta | Credenciales | Login |
|---|---|---|
| acli | ATLASSIAN_EMAIL ATLASSIAN_API_TOKEN | token por stdin a acli jira auth login --site … con el --slug; el CLI guarda la sesión |
| bun xray | XRAY_CLIENT_ID XRAY_CLIENT_SECRET + el par ATLASSIAN_* | bun xray auth login sin argumentos lee todo de .env |
Regla #10
Credencial faltante o rota: parar. Nombrar la variable, apuntar a .env / .env.example y reiniciar la sesión.
Utilidad · 8 de 19
Chequeo de modalidad
Solo en jira-xray (Jira Cloud con el plugin de Xray). En jira-native esta skill no se usa: los artefactos de test van por /acli.
La membresía del ATS lleva las dos
set add-tests en Xray y un link create <TC> <ATS> --type test por cada miembro. Solo la de Xray es invisible para IQL y para el sync.
Capturar la key
Cada create termina con una línea pelada KEY <PROJ-123> y acepta --json. Nunca se raspa la línea decorada de éxito.
Utilidad · 9 de 19
0 · Tests
Crear y sumar pasos
test create --type Manual
un test add-step por paso
1 · ATS
Set con los TCs
set create --tests …
link create TC ATS
2 · Cobertura
ATS → Story
link create ATS STORY
trace STORY
3 · ATP
Plan derivado
plan create
plan add-set PLAN --set ATS
4 · ATR
Execution derivada
exec create --environment
exec add-set EXEC --set ATS
5 · Resultados
Sobre la Execution
import xray (por ATC)
run status
Una lista, no tres
El ATS es la única fuente de qué tests cubren la Story. Plan y Execution derivan su lista con plan add-set y exec add-set; listar ids a mano es justo la deriva que la doctrina prohíbe.
Pasos manuales
Xray Cloud descarta en silencio los pasos pasados al crear un test. Se crea primero, se suma un paso por llamada y se verifica con test get.
Entorno obligatorio
Cada ATR va fijada a un Test Environment, con el valor de active_env, para que los resultados se puedan comparar. Si se escapó una sin entorno: exec set-environment.
Nombres: ATS: {US_ID}: {título} para el Set por Story; los Sets de feature llevan TS:. Opcional: plan add-executions asocia la Execution al Plan.
Utilidad · 10 de 19
La única frase medida
En una Story, el borde que cuenta para la cobertura es la entrada de issuelinks que lleva el artefacto bajo inwardIssue. bun xray link create <ARTEFACTO> <STORY> produce exactamente esa forma. La forma opuesta existe, se ve como un link y cubre cero.
Reparar un link invertido
Jira deduplica por par y tipo sin mirar la dirección: crear el correcto encima es un no-op silencioso. Se lee el id del link con trace --json, se mira con link delete --id … --dry-run, se borra con --yes y se recrea.
bun xray trace: el chequeo de tres bordes
| Borde | Qué tiene que cumplirse |
|---|---|
| Story↔ATS | link test con el Set bajo inwardIssue; el único que cuenta el panel |
| ATP↔Story | misma forma, desde el Plan; administrativo |
| ATR↔Story | misma forma, desde la Execution; administrativo |
| paridad | membresía del ATS = lista del ATP = lista del ATR |
Un borde que falla imprime el comando que lo repara. Con varias keys o --jql barre el proyecto y devuelve una lista de trabajo: un link invertido es invisible en una Story y solo se ve en el agregado.
Utilidad · 11 de 19
Import
JUnit, Cucumber o Xray JSON se importan con --execution <KEY>. Con --project, la API de import no puede setear un padre y acuña una Execution nueva sin padre en cada corrida, fuera de la épica de artefactos QA.
--plan sin --execution
También crea una Execution nueva y la asocia al plan. Es el camino de respaldo de la RTR; /regression-testing crea la RTR primero y pasa su key.
Estados de run
TODO, EXECUTING, PASSED y FAILED son el piso seguro. ABORTED y BLOCKED son defaults de Xray que un proyecto puede no tener: la mutación se rechaza. Un caso bloqueado va a un estado que exista, con la explicación en el comentario; nunca queda en TODO.
Evidencia y defectos
run evidence adjunta archivos o una carpeta, run step-evidence va a un paso, run defect linkea bugs.
ROI manda
Nunca resultados para TCs que el ROI marcó como Manual terminal.
Utilidad · 12 de 19
Sync & repair
Si un camino de respaldo creó el contenedor sin Xray autenticado, la capa Jira lo acepta pero Xray nunca registra los tests: los runs vuelven vacíos.
exec sync · plan sync · set sync
repair --project
Dry-run por defecto, --apply para reenganchar.
Sin MCP de respaldo
El MCP de Atlassian es opt-in y no expone entidades de Xray. Sin credenciales Xray: Regla #10, parar. Las operaciones solo de capa Jira (links, transiciones, comentarios) pueden ir por /acli o Jira REST, y después, con Xray de vuelta, se corre el sync.
test enrich
El sync del PBI va por REST y no ve lo que es interno de Xray. bun xray test enrich lo trae por GraphQL y escribe solo archivos locales: preconditions inline en cada TEST-*.md y un índice por Set en .context/PBI/test-sets/. Se corre después de cada sync que toque tests.
Backup, restore y migración de sitio
Entre sitios se restaura con --sync, porque Xray reasigna los ids numéricos y las keys se conservan, y se cierra con /jira-administration modo instance-migration. Runbook: xray-cli/references/migration-runbook.md.
Comunidad · 13 de 19
Nivel proyecto, sin commit
Son skills de tier T3: el instalador las agrega a .agents/skills/ junto a las del repo, pero no se commitean. La lista vive en PROJECT_LEVEL_SKILLS de cli/install.ts; bun setup vuelve a correr la instalación.
Por qué a nivel proyecto
Un flujo depende de ellas y no puede quedar atado a la lista global de plugins de cada persona. Una instalación a nivel usuario también las satisface.
Ejemplos y para qué sirven
| playwright-cli | el [AUTOMATION_TOOL]: capturas, traces, video, sesiones, mocks de requests (slide 14) |
| playwright-best-practices | referencia de tests flaky, POM, accesibilidad con axe-core, auth, fixtures, tags; se carga junto a /test-automation |
| resend-cli | testing de emails; va de la mano del binario resend, que tiene su propio resend login |
| skill-creator | el constructor de toda skill que el repo crea: /framework-development y project-context modo context-skill |
| diagram-design | los diagramas de los mapas de contexto; es la capacidad diagrams, con su propio STOP (slide 17) |
Comunidad · 14 de 19
| Caso | Cuándo | Navegador | Cómo termina |
|---|---|---|---|
| (a) anónimo | página pública, localhost, la página de anotación de bugs | Chromium en memoria | close |
| (b) usuario de test | la app bajo prueba, logueada con un rol (credenciales en .env) | Chromium en memoria + state-load del rol | close |
| (c) perfil del dueño | una cuenta que un script no puede loguear (SSO, MFA, Google) | Chrome real con --profile absoluto, fuera del repo | close (guarda las cookies) |
| (d) Agentic Pair Testing | la persona y la IA prueban juntas en el Chrome de la persona | el Chrome humano, con attach | detach, nunca close |
Reglas para todos los casos
Siempre una sesión con nombre (-s=<KEY>), nunca --persistent. Una cuenta, un navegador vivo. close siempre, y la prueba es playwright-cli list vacío.
testing.browser.pair_mode
En null, la primera sesión agéntica pregunta una vez (dedicada o pair) y guarda true / false. Lo desatendido nunca entra al caso (d).
Comunidad · 15 de 19
Estado por rol
Cada rol de la app tiene un archivo de estado por entorno: .auth/<env>-<rol>.json, con sus credenciales en <ENV>_<ROL>_EMAIL / _PASSWORD. Lo produce el setup de la suite cuando existe; si no, un login agéntico por rol y entorno.
Si falta una mitad del par: parar y nombrar las dos variables. Nunca el usuario de otro rol: sería un PASS falso.
La sesión es un secreto
Un archivo de estado, un perfil o una cookie son credenciales con otra forma. Nunca se imprimen. Una contraseña se tipea con --raw fill <ref> "$VAR": el comando lleva solo el nombre de la variable y --raw suprime el eco. Los archivos van a .auth/ con chmod 600.
Flotas y worktrees
El espacio de nombres de sesiones es el .playwright/ más cercano: cada worktree es el suyo, y el mismo -s en dos worktrees son dos navegadores. En una flota el conductor genera los .auth/ antes de lanzar; un worker solo hace state-load, nunca loguea ni escribe ahí.
Dos roles en un ticket = dos sesiones (-s=<KEY>-admin, -s=<KEY>-member), cada una con su archivo. Login después de goto = estado vencido: se regenera desde su productor.
MCP · 16 de 19
Prefijo = servidor, sufijo = capacidad
La misma tool llega como mcp__tavily__tavily_search, como mcp__claude_ai_<conector>__tavily_search o con el prefijo de un servidor de usuario. Un worker concluyó una vez "no hay Tavily" por mirar el prefijo. Por eso la IA busca cualquier tool cuyo nombre termine en el sufijo.
Declaración en la skill
En el frontmatter, dentro de metadata.requires_capabilities. Se declara lo que la skill instruye usar, ni más ni menos; bun run skills:check lo verifica.
El vocabulario
| Capacidad | Dónde vive el proveedor |
|---|---|
| web-search | a nivel harness, nunca en el repo: Exa primero, Tavily segundo |
| library-docs | servidor local comprometido en el repo (resolve-library-id → query-docs) |
| db | servidor local del repo, con variables de proyecto |
| api-schema | servidor local del repo; solo lectura del esquema, la ejecución es curl |
| diagrams | no es un MCP: la skill diagram-design |
Dueño del vocabulario y de los sufijos exactos: agentic-qa-core/references/mcp-capabilities.md, espejado en KNOWN_CAPABILITIES de scripts/lint-skills.ts.
MCP · 17 de 19
Regla #10 · credenciales
Servidor activo pero 401/403 o una falla misteriosa: es el caso de credencial. Con una variable sin setear, el loader de .env arranca el servidor igual en los tres hosts y falla en silencio en la primera llamada; ninguno falla fuerte al arrancar. Nombrar la variable, apuntar a .env y pedir reinicio: los valores se leen al arrancar el MCP.
Sin degradar por cuenta propia
WebSearch / WebFetch integrados no son respaldo silencioso de web-search ni de library-docs, y leer archivos de rutas no reemplaza a api-schema.
MCP · 18 de 19
Servidores locales: un set, tres formatos
Solo los servidores locales (stdio) se comprometen en el repo. El set canónico es el que declara .mcp.json, y cada uno tiene que existir también en opencode.jsonc y .codex/config.toml con las mismas dependencias de .env. bun run agents:compat:check compara los tres normalizados.
Remotos: a nivel harness
Un servidor remoto cuyo único contenido de proyecto era una API key (búsqueda web, Postman) se conecta una vez por máquina: un conector de claude.ai, un servidor de usuario, la config de usuario de OpenCode o Codex. La lista: cli/lib/harness-level-mcps.ts.
| Host | Activar o revisar |
|---|---|
| Claude Code | /mcp dentro de la sesión (habilitar, autenticar, reconectar). Los servidores del proyecto leen .env a través del loader, se lance como se lance la sesión. |
| OpenCode | enabled: true en opencode.jsonc; los secretos se leen de .env a través del loader. Reiniciar. |
| Codex CLI / Desktop | carga la config del proyecto solo en un repo confiable. Reiniciar. |
bun run setup:doctor informa qué servidores de nivel harness declaran las configs de usuario de la máquina; un conector en la nube no deja archivo y figura como no detectable, no como faltante.
Cierre · 19 de 19
Cómo se invoca
Claude Code: /acli, /xray-cli, /playwright-cli.
OpenCode y Codex: cargá la skill acli (o xray-cli, playwright-cli).
Ninguna tiene modos: la operación sale del pedido. Casi nunca se invocan a mano: las carga una skill de flujo al resolver su etiqueta, o el gate de §6.5 al ver el binario.
Quién las carga
/sprint-testing: Jira, Xray y navegador.
/test-documentation: resuelve la modalidad.
/test-automation: navegador y buenas prácticas.
/regression-testing: la RTR y sus resultados.
/git-flow-master: /acli desde un commit o PR.
Dónde leer más
.agents/skills/acli/ y agentic-qa-core/references/acli-integration.md
.agents/skills/xray-cli/ y traceability-linking.md
agentic-qa-core/references/browser-sessions.md
agentic-qa-core/references/mcp-capabilities.md
La idea que ordena todo
Las skills de flujo deciden qué hacer y escriben una etiqueta. §6 (.agents/instructions/agent-tool-resolution.md) decide quién lo hace. La skill de la herramienta sabe cómo, con sus trampas. Y cuando falta una herramienta, la IA para y te pregunta en lugar de improvisar.
Inventario de skills con su tier y su tipo: .agents/skills/REGISTRY.md (bun run skills:registry).