Agentic QA · Skill de evidencia
Cuando una captura cruda necesitaría un párrafo para explicar el bug, esta skill la marca como lo haría una persona de QA: un óvalo sobre la zona rota, una flecha, un texto que explica y una etiqueta BUG en la esquina. Quien abre el ticket entiende el defecto de un vistazo.
Cuándo usarla · 2 de 13
| Lo que tenés | Con qué |
|---|---|
| Un bug visual o de posición: elementos superpuestos, algo desalineado, una fecha corrida en el eje de un gráfico, un elemento en el lugar equivocado | /bug-screenshot-annotation, antes de reportar |
| Un hallazgo textual: un mensaje de error, un número equivocado en un campo | nada: la captura cruda ya se lee sola |
| Capturas de antes y después que se entienden sin marcas | nada: van como están |
| Reportar el bug en sí (título, pasos, severidad, campos) | /sprint-testing, Stages 2 y 3, con sus plantillas de reporte |
| Una foto de un objeto físico o de un documento | fuera de alcance: se habla primero con el humano sobre cómo anonimizarla |
Parte de una captura que ya existe
La skill superpone formas sobre una imagen que está en disco. Nunca genera ni edita una imagen a partir de una descripción en texto.
Cómo se dispara
"annotate bug screenshot", "mark up evidence", "anota este bug", "marca la captura", "resalta el bug en la imagen".
Un ejemplo real · 3 de 13
Captura cruda (recortada)
Qué está mal? Hay que mirar con atención para notar que dos cuadros están vacíos.
Evidencia anotada
Óvalo, flecha, recuadro explicativo y etiqueta BUG: el defecto se ve sin leer el ticket.
Hecho con el proceso de este deck sobre una página pública de práctica (the-internet.herokuapp.com/broken_images, de Elemental Selenium): sin datos de producto. DEMO-1 y DEMO-2 son claves de ejemplo. El texto va en inglés porque la imagen termina en el bug de Jira, y los artefactos externos se escriben en inglés.
La regla de seguridad · 4 de 13
Primer intento: un MCP de imágenes
Un diseño anterior mandaba las capturas a servicios externos de edición generativa. El primero tenía cuota agotada en todos sus planes. Simplemente no andaba.
Segundo intento: bloqueado, tarde
El clasificador de exfiltración del propio runtime del agente lo bloqueó: las capturas traían datos reales de producto, clientes y competencia, y el destino no era confiable. La autorización explícita del usuario en el chat no levantó el bloqueo. Antes de que lo frenaran, una captura ya había quedado en un bucket público del servicio.
La lección que quedó como regla
La evidencia de QA con datos reales de producto o de clientes nunca pasa por un servicio externo de imágenes, generativo o no. Ni con permiso en el chat.
Cómo lo evita la skill
HTML y CSS renderizados por un servidor HTTP atado a 127.0.0.1, capturados por un navegador local. Nada sale de la máquina.
Si aparece un caso que no cubre
Por ejemplo, una foto de cartelería física: la skill vuelve al humano y conversan cómo anonimizar. Nunca la manda en silencio a un servicio externo.
Mapa · 5 de 13
Pasos 1 a 3 · 6 de 13
Paso 1 · Ubicar la zona
Sobre la captura cruda (o su snapshot de accesibilidad) se calcula la caja de recorte en píxeles y dónde cae cada forma respecto de ella.
Paso 2 · Recortar con Python y PIL
Paso 3 · El HTML de anotación
La crop entra como <img> de fondo y cada anotación es un <div> con posición absoluta encima. No se diseña desde cero: se copian y ajustan los bloques comentados de references/shapes.html.
Dos cosas que no se pierden al copiar
La escala de z-index (si se cae, la etiqueta queda escondida detrás de un recuadro) y <meta charset="utf-8"> (sin ella, los acentos se capturan como basura).
Todo en el scratchpad
La crop y el HTML son intermedios: nunca se escriben en evidence/ ni se citan desde un ticket.
La biblioteca de formas · 7 de 13
| Bloque de shapes.html | Para qué |
|---|---|
| circle-callout | óvalo alrededor de la zona rota, con margen para no cortar la UI |
| arrow-to-region | línea con punta; se ubica en la cola y se rota |
| callout-box | recuadro blanco que explica el defecto, con ancho máximo y texto que salta de línea |
| badge-corner | la etiqueta roja BUG con la clave, en la esquina lejos del bug |
| axis-tick + axis-tag | para fechas corridas en un eje: marca y valor correcto, con la etiqueta equivocada del gráfico a la vista |
| before-after | dos recortes lado a lado con su leyenda |
La escala de z-index
Pasos 4 y 5 · 8 de 13
Paso 4 · Un servidor solo de loopback
Por qué no file://?
La CLI del navegador rechaza file:// antes de renderizar. El servidor en loopback es el único camino, y además es lo que mantiene todo en la máquina.
Paso 5 · Capturar con /playwright-cli
Una sesión con nombre propio, anónima: -s=<KEY>-annotate. Se ajusta el viewport a las medidas reales del HTML (igual o más grande: uno más chico corta los recuadros) y se captura con la ruta de destino explícita en evidence/.
El nombre del archivo
{KEY}-BUG-{BUG-KEY}-annotated.png: la clave del ticket que se testea y la del bug reportado. Ejemplo: UPEX-411-BUG-UPEX-512-annotated.png. Las dos claves lo mantienen trazable aunque termine en un hilo de Slack.
Dónde está evidence/
En la carpeta del ticket bajo .context/PBI/ del checkout principal: la copia de un worktree muere con el worktree.
Pasos 6 a 8 · 9 de 13
Paso 6
Revisar y ajustar
leer el PNG; al menos una pasada más
Paso 7
Limpiar
kill <pid> del http.server
Paso 8
Informar la ruta
en el mismo turno, sin que la pidan
Lo típico de la segunda pasada
Mover o agrandar un círculo, acortar o partir el texto de un recuadro, correr la etiqueta o la flecha para que no choquen. El ejemplo del slide 3 necesitó tres.
Nada queda corriendo
El servidor se mata antes de que termine la sesión, y la sesión del navegador se cierra cuando el PNG ya está en disco.
La ruta, a mano
Tu próximo paso casi siempre es adjuntarla al bug. Por eso la ruta relativa al repo aparece apenas el PNG existe y vuelve a encabezar el grupo Bug annotations en la lista de capturas del cierre.
Paso 9 · opcional · 10 de 13
El helper de la skill /acli
Sube el archivo como adjunto, resuelve el id de media de Atlassian y publica un comentario con la imagen inline.
Vos confirmás primero
La skill ofrece publicar; no publica sola. Y nunca dice que adjuntó algo si el helper no terminó bien de forma verificable.
La foto principal
Publicada, encabeza la sección Evidence del bug, delante de la captura cruda. Si el bug tiene página de evidencia, va primera en su pack: encabeza la página y es la miniatura del bug en el tracker. El Evidence Handoff del Stage 3 enlaza esa página.
Si el helper no llega
Queda el camino de siempre: la ruta está en el chat y la adjuntás vos.
En el pipeline · 11 de 13
/sprint-testing · Stage 2
Exploración
aparece un hallazgo y se captura crudo en evidence/
Visual o de posición?
Anotar antes de reportar
/bug-screenshot-annotation
/sprint-testing · Stage 3
Reporte del bug
el PNG anotado va primero como evidencia
Se carga adentro
Corre dentro del subagente que ya está ejecutando el stage, como /playwright-cli. No lanza agentes propios ni tiene estrategia de despacho.
Sin cierre propio
El footer de cierre lo imprime la skill dueña del stage. Esta solo garantiza que su ruta aparezca, y primera.
Las herramientas que usa
/playwright-cli para capturar, Python con PIL para recortar, http.server en loopback, y /acli solo si publicás en Jira.
Salvaguardas · 12 de 13
| Regla | Por qué |
|---|---|
| Mandar una captura de QA a un servicio externo de imágenes, ni con permiso en el chat | las capturas traen datos reales; ya hubo una fuga a un bucket público |
| Generar o editar una imagen desde una descripción en texto | la evidencia sale de una captura real que está en disco |
| Guardar la crop o el HTML en evidence/, o citarlos en un ticket | son intermedios; la evidencia es un solo PNG |
| Abrir el HTML por file:// | la CLI lo rechaza; el camino es loopback |
| Capturar con un viewport más chico que el lienzo | corta los recuadros en el borde |
| Dar por buena la primera captura | siempre hay algo que mover o reescribir |
| Dejar el servidor corriendo después de la sesión | el paso 7 lo cierra siempre: no queda nada escuchando |
| Publicar en Jira sin tu confirmación | lo que se publica en el bug lo decidís vos |
Cierre · 13 de 13
Cómo se invoca
Claude Code: /bug-screenshot-annotation más la captura y la clave del bug.
OpenCode y Codex: cargá la skill bug-screenshot-annotation y nombrá la captura y el bug.
No tiene modos. Lo normal es que la cargue /sprint-testing sola, en el Stage 2.
Qué lee
La captura cruda en evidence/ · references/shapes.html · la clave del ticket y la del bug.
Qué deja
{KEY}-BUG-{BUG-KEY}-annotated.png en evidence/, su ruta en el chat y, si confirmaste, un comentario con la imagen en el bug.
Canon
.agents/skills/bug-screenshot-annotation/SKILL.md (regla de seguridad, proceso, gotchas) y references/shapes.html (formas y escala de capas). Buckets y nombres: agentic-qa-core/references/evidence-conventions.md.
Relacionadas: /sprint-testing la carga en el Stage 2 y reporta el bug en el Stage 3 · tooling cubre /playwright-cli y /acli.