Informe de evidencia
Momento de carga: cuando necesitas mostrar resultados a otros pero las palabras no son suficientes, y la evidencia es la pantalla real. Si has implementado o modificado una función grande visible en pantalla, comienza aquí el informe de finalización incluso sin que te lo pidan. Los mapas de flujo de navegación entre documentos y pantallas no son objetivo de este skill.
Propósito
Crear un documento que responda a una sola pregunta utilizando capturas de pantalla reales. El receptor no lee código ni registros de commits. Lo único que conoce son las pantallas, por lo que el peso del documento recae enteramente en que esas pantallas son el resultado real de la ejecución. Diez viñetas con hallazgos no se comprenden ni se rebaten tan rápido como dos fotos del mismo registro colocadas una al lado de la otra. Si terminas una función grande y la das por finalizada sin este informe, el costo de que el receptor abra la aplicación y verifique personalmente se traslada a él.
El resultado es una sola página HTML. El receptor puede abrirla en el móvil o imprimirla como PDF desde el navegador, por lo que la plantilla está preparada tanto para pantallas estrechas como para impresión A4. No se genera un PDF ni Markdown aparte.
Este skill no tiene una tabla de contenidos fija. Primero se define la pregunta que responde este documento, y a partir de ella surgen los ejes de comparación y la estructura de secciones.
| Pregunta | Eje de comparación | Qué hace el documento |
|---|---|---|
| ¿Qué cambió? | Código anterior <-> Código actual | Coloca dos pantallas una al lado de la otra para demostrar la mejora |
| ¿Se hizo según lo planeado? ¿Qué falta? | Especificación, requisitos <-> Pantalla actual | Asigna un veredicto a cada cláusula y deja solo las que no cumplen |
| ¿Cumplimos nuestros principios? | Principios, checklist <-> Producto actual | Agrupa los hallazgos de la revisión por causa y captura los que se puedan mostrar en pantalla |
| ¿Qué cambia si cambian las condiciones? | Estado A <-> Estado B | Cambia realmente flags, fechas y permisos y captura los resultados |
| ¿Cuál es el estado actual? | Sin eje | Recorre toda la aplicación solo con la pantalla actual |
| ¿Qué hay que decidir? | Opción <-> Opción | Empareja cada elemento con su pantalla actual, las opciones y la entrada necesaria |
Es habitual que se mezclen dos o más ejes. Al contrastar con la especificación puede aparecer "algo que no estaba en el plan pero ya existe", y eso es un elemento de otro eje que requiere una sección aparte. Si la pregunta es difusa, el documento también lo será. Si no se puede escribir en una frase, divide el documento en dos.
Principios fundamentales
- La pantalla es resultado real, no una recreación. Hacer "cómo creo que era" de memoria casi siempre falla. La pantalla anterior podía tener elementos ahora eliminados, o el problema era menor o mayor de lo que recuerdas. "Con esta condición se verá así" también falla. Al activar un flag real aparece una pantalla diferente a la esperada. Por eso, se crea el estado que se quiere mostrar y luego se captura. Así se puede escribir en el documento "esto es el resultado real, no una recreación", y esa frase determina la credibilidad de todo el documento. -> Paso 3
- Coloca los valores junto a las fotos. La foto solo dice "se ve así". Al escribir los valores almacenados y los valores en pantalla (atributos
data-*, texto de accesibilidad) se dice también "por qué se ve así". -> Paso 3 - Las marcas se dibujan dentro de la pantalla. Introducir coordenadas a ojo casi siempre desplaza una columna o una fila. Si es una pantalla de navegador, busca el elemento por texto o selector, dibuja el borde y el número en su lugar y captura. -> Paso 4
- Lo que se añade para explicar no debe tapar lo que explica. Poner etiquetas de resaltado directamente sobre la pantalla casi siempre tapa algo: títulos, etiquetas de campos de entrada, valores de columnas adyacentes. En la imagen solo se pone el número y la explicación va en el pie de foto. Las insignias numeradas son pequeñas y causan poca pérdida en cualquier lugar donde se pongan. -> Paso 4
- Lo que se ha creado debe verse con los ojos. Que la herramienta devuelva éxito solo significa que el archivo se ha escrito. Si el borde está en un elemento equivocado, la insignia tapa contenido, la cabecera se repite en las uniones o la imagen de un enlace está rota, solo se descubre al abrirlo. -> Pasos 5 y 6
- Separa lo que se capturó de lo que no. Lo que se verificó con código pero no se pudo mostrar en pantalla por falta de datos se marca como "(fundamento de código)" aparte. Mezclarlos hace que se ponga en duda incluso lo que sí se capturó. -> Pasos 1 y 3
Políticas
| Política | Cuándo se aplica | Contenido |
|---|---|---|
| Los datos y la configuración son solo lectura; si hay que cambiarlos, se pregunta | Paso 3 | Las consultas para buscar casos son libres. Cambiar la base de datos de desarrollo para crear un caso solo después de confirmación del usuario, y se registra el cambio para revertirlo. La base de datos de producción nunca es objetivo |
| Los cambios realizados durante la captura se registran en el documento y el informe | Pasos 3 y 6 | Huellas como creación de sesión de inicio de sesión, consentimiento de inicio de sesión externo, cambios en la base de datos de desarrollo |
| Se entrega en un formato que el receptor pueda abrir | Paso 6 | Las rutas locales no se abren en el dispositivo del receptor. Se envía el archivo report.html o se crea un enlace, y si es un enlace, se verifica que se abre realmente antes de entregarlo |
| Lo que se envía al exterior se confirma | Paso 6 | Para Slack, correo o entrega al cliente, primero se pregunta si se deja como borrador o se envía directamente |
Requisitos previos
| Requisito | Verificación | Si no se cumple |
|---|---|---|
| El trabajo se refleja en la pantalla | ¿El cambio aparece en la pantalla que ve el usuario? | Los trabajos que solo modifican backend o scripts no son objetivo. Se informa por escrito |
| El producto a capturar está funcionando | ¿El servidor de desarrollo local o la URL de staging responde? | La forma de ponerlo en marcha sigue la documentación del repositorio. Para código anterior, ver axes §eje temporal |
| Hay herramienta de navegador | ¿node scripts/shot.mjs funciona con Playwright? Otra herramienta que pueda ejecutar JS en la página también vale | La instalación de Playwright y la forma de capturar con otras herramientas está en capture §manipulación del navegador |
| Se puede iniciar sesión | ¿Es una pantalla que requiere inicio de sesión? ¿Hay una cuenta? | capture §crear estado de inicio de sesión |
| Python Pillow | python3 -c "import PIL" | No se podrán unir ni recortar imágenes |
Procedimiento
0. Pregunta y eje LEER <- variants/axes - Cada eje requiere preparaciones diferentes (revertir código, cambiar datos, leer documentos, buscar casos). Solo las secciones del eje elegido
1. Elementos y veredicto (Si es eje de revisión, axes §eje de revisión pasos 1-2 crean los elementos)
2. Estructura LEER <- steps/20-document - Criterios para agrupar elementos en secciones, vocabulario de veredicto, resumen, lugar de figuras y tablas
3. Captura LEER <- steps/30-capture - Problemas de inicio de sesión, eventos sintéticos, pantallas largas, lectura de valores en pantalla
4. Marcas LEER <- steps/30-capture §marcas dibujadas dentro de la pantalla - Introducir coordenadas desplaza una columna
5. Verificación de imágenes (Sin documento aparte. La lista de verificación está dentro del Paso 5)
6. Salida LEER <- steps/60-output - Si se rompe la plantilla, la pantalla estrecha y la impresión fallan; si se incumplen las reglas del bloque de decisión, los grupos copiados se cortan
Paso 0. Pregunta y eje
Escríbela en una frase. Debe incluir al receptor y el propósito, como "explicar al cliente lo que se ha corregido esta semana" o "decidir con el planificador qué falta respecto a la especificación". Si el propósito es diferente, aunque sea la misma pantalla, cambiará lo que se destaca. Luego elige el eje en la tabla de la sección de propósito y lee esa sección de axes.
Al finalizar, se tiene la pregunta en una frase, el eje y el receptor.
Paso 1. Elementos y veredicto
No empieces por la captura. Escribe como elementos lo que se tratará en este documento, y asigna a cada uno un código de referencia y un veredicto. Esta lista es el esqueleto del documento, y también determina qué pantallas capturar y en qué puntos poner marcas.
Los códigos de referencia se dividen por prefijos según su naturaleza, porque el interés del receptor es diferente.
- Trabajo solicitado:
R-1,R-2... (interesa si está hecho) - Descubrimientos corregidos durante el trabajo:
A-1,A-2... (interesa por qué se tocó) - Discrepancias con la especificación:
G-1,G-2... (interesa qué se hará al respecto) - Hallazgos de la revisión: siguen el número del grupo
1-1,1-2... (interesa agrupar por causa)
El vocabulario de veredicto debe ser uniforme en todo el documento (ejemplos en document §vocabulario de veredicto). Los veredictos se cuentan y se colocan en la primera página. Una línea como "35 implementados, 3 requieren decisión, 1 defecto" resume todo el documento. Al contar también se revelan los huecos en la lista.
Es fácil olvidar correcciones realizadas durante el trabajo, así que revisa git log; si es contraste con especificación, repasa el texto original línea por línea para llenar la lista. También marca en este punto si cada elemento se puede mostrar en pantalla (si hay un caso en los datos). -> Principio fundamental 6
Al finalizar, cada elemento tiene código, veredicto y pantalla a capturar o "(fundamento de código)".
Paso 2. Estructura
Las secciones no se eligen de un índice, surgen al agrupar los elementos. El criterio de agrupación es uno de estos cuatro:
- Por pantalla - cuando varios elementos se concentran en una misma pantalla. Es la base de los informes de mejora
- Por veredicto - cuando los veredictos son divergentes. Es la base de los informes de contraste, y el receptor ve primero solo "lo que hay que decidir"
- Por causa - cuando hay muchos hallazgos dispersos en varias pantallas. Es la base de los informes de revisión
- Por elemento - cuando cada elemento es una decisión independiente. Es la base de los documentos de decisión
En cualquier caso, al principio se coloca un resumen que abarque todo el documento en una página, y cuanto más atrás, más detalle. Se asume que el receptor lee de arriba abajo y puede detenerse en cualquier momento. El número de secciones se determina según lo que se vaya a mostrar. No se rellena forzadamente ni se crean secciones vacías. Los métodos concretos para estructurar y ejemplos reales están en document.
Paso 3. Captura
La preparación varía según el eje (axes). Aquí solo se menciona lo común.
- Las parejas que se van a superponer se capturan con el mismo viewport, la misma posición de scroll y el mismo rango. Así las dos imágenes coinciden píxel a píxel y se pueden ver con deslizador y diferencia (60-output §superposición)
- Las pantallas que se comparan deben tener los mismos datos. Si los datos son diferentes, la comparación no es válida. Para mostrar cómo un mismo hecho se ve diferente en distintas pantallas, se capturan todas con el mismo registro
- Antes de capturar, verifica con una consulta que los datos necesarios para la función a mostrar existen realmente. Si capturas una pantalla vacía y lo descubres después, tendrás que volver a montar la pila
- Verifica el estado de inicio de sesión antes de capturar. Es un error real capturar elementos que requieren inicio de sesión en estado de desconexión y escribir "no existe". Antes de decidir que algo no está, distingue si realmente no existe o simplemente no se ve en la sesión actual
- Opera en el mismo orden. Si la lista de capturas se guarda en un solo archivo, al volver a capturar solo hay que ejecutar ese archivo
- Ajusta el viewport generosamente. Si la parte inferior de la pantalla se corta, hay que volver a capturar
- Lee tanto los valores almacenados como los valores en pantalla. -> Principio fundamental 2
- Anota también cómo se llegó a esa pantalla. Para reconstruir la ruta y los pasos más tarde, hay que volver a entrar. Anotarlo durante la captura no cuesta nada (document §ubicación y profundidad de la pantalla)
Para los puntos que suelen atascarse durante la manipulación, consulta capture.
Paso 4. Marcas
Si es una pantalla de navegador, al capturar con scripts/shot.mjs se dibujan en ese momento los bordes y números dentro de la pantalla (-> capture §marcas dibujadas dentro de la pantalla). Las pantallas largas se capturan en partes y se unen con scripts/stitch.py; las partes fuera del foco (como barras laterales) se recortan con el mismo script. Solo para pantallas que no son de navegador se leen las coordenadas con grid_overlay.py y se dibujan con annotate.py.
- Los bordes solo envuelven el elemento a destacar. Si se toman demasiado amplios, no queda claro qué se debe mirar
- Los colores se estandarizan según el veredicto. Al pasar el documento, solo el color comunica la naturaleza. El rojo es para antes de la mejora y puntos problemáticos, el verde para después de la mejora; en informes de contraste, rojo para lo que falta, verde para lo que está, naranja para lo que requiere decisión
- Las marcas de las dos pantallas que se comparan se buscan por separado. La longitud del texto puede hacer que el diseño se mueva ligeramente
- Todas las capturas y marcas se recogen en un solo archivo. Cada vez que se corrijan las marcas, se regenera todo; y si más tarde hay que volver a capturar la pantalla, solo se ejecuta ese archivo
Paso 5. Verificación de imágenes
Ábrelas todas con una herramienta de lectura. Verifica lo siguiente:
- ¿La línea de resultado de la marca no contiene
NOT FOUND? - ¿El borde envuelve exactamente el elemento destacado? ¿No ha tomado otra posición del mismo texto (por ejemplo, el mismo nombre de columna en otra tabla)?
- ¿La insignia numerada no tapa texto o celdas de barras?
- ¿En las uniones no se repiten cabeceras o tablas de contenido?
- ¿El título no queda medio cortado en la parte superior del recorte? ¿La proporción de las dos imágenes que se colocan una al lado de la otra no es excesivamente diferente?
- ¿Lo que se ha escrito como "no existe" realmente no está en la pantalla? Si no se ve por el estado de inicio de sesión o por una condición, el veredicto debe invertirse
- ¿El pie de foto dice lo mismo que muestra la imagen? ¿No se ha escrito "repetido tres veces" para una columna oculta en ese ancho?
Corrige lo que esté mal y vuelve a verificar. Rara vez sale bien a la primera.
Paso 6. HTML y entrega
- Copia
assets/web-report.htmlcomoindex.htmlen la carpeta del informe y complétalo. La estructura y la forma de las tarjetas están en 60-output estructura. - Si el receptor tiene que decidir algo, coloca un bloque de decisión justo debajo de la tarjeta de evidencia correspondiente. Al pulsar
Copiaren la barra, lo decidido se agrupa en Markdown y se puede pegar en una conversación (60-output recibir decisión). - Abre las tres vistas: pantalla ancha, 390px de ancho, y todas las páginas de impresión extraídas por
scripts/check_print.sh(60-output pantalla e impresión). - Combina todo en un solo archivo
report.htmlconinline-images.py. Envía el archivo directamente o expórtalo como enlace, y ábrelo de la misma manera que lo hará el receptor para verificarlo (60-output entrega).
No modifiques el <style> de la plantilla para cada informe. Si fijas el ancho en px o colocas tablas fuera de .tw, la pantalla estrecha se rompe. -> Principio fundamental 5
Al finalizar, report.html no se rompe en ninguna de las tres vistas, se abre en la forma en que lo abrirá el receptor, y el envío queda a la espera de confirmación del usuario.
Puntos problemáticos frecuentes
| Síntoma | Causa y solución |
|---|---|
| El servidor de desarrollo muere inmediatamente | next dev lee stdin. Si se le pasa < /dev/null, recibe EOF y termina normalmente. Mantén stdin abierto con `tail -f /dev/null |
| Los popovers o desplegables no se abren | Radix y otros no responden a eventos sintéticos. Usa el click real de la herramienta de automatización, no dispatchEvent |
| La captura de página completa repite la misma pantalla o superpone cabeceras fijas | La captura de página completa de la herramienta no puede desplazar ventanas o contenedores internos. Usa el modo full de shot.mjs para capturar en partes y unir |
| En la imagen unida se repite la tabla de contenidos | Quedan elementos fijos. Captura o recorta solo la sección relevante |
| En el móvil, tablas o imágenes se salen de la pantalla | La tabla no está envuelta en .tw o se ha puesto un ancho en px en el style en línea. Usa solo las clases de la plantilla |
| La marca apunta a la tabla equivocada | Hay varias apariciones del mismo texto en la pantalla. Cambia el nth o usa exact o un selector más específico |
| Se captura la pestaña equivocada | Otra sesión comparte el demonio del navegador. Aísla la sesión |
| Se escribe que una función no existe cuando sí existe | Se capturó en estado de desconexión o con condiciones incorrectas. Antes del veredicto, verifica el inicio de sesión y las condiciones |
| Al abrir con un enlace faltan varias imágenes | El servidor simple pierde solicitudes concurrentes. Combínalo en un solo archivo con inline-images.py |
| La imagen aparece pequeña dentro del marco | Está reducida por un límite de altura. Las imágenes verticales largas se agrandan si se colocan en dos columnas horizontales |
| El cambio es demasiado sutil | Se eligió mal el objetivo de comparación. Mostrar la pantalla de edición real del valor es mejor que mostrar un cambio en el nombre de una columna en una lista |
| La tabla es demasiado densa y difícil de leer | Conviértela en una lista de elementos con etiquetas a la izquierda y contenido a la derecha. Si hay grupos, coloca la etiqueta del grupo solo una vez a la izquierda de la fila |
| El documento solo se alarga cada vez que se corrige | Si se ha creado una nueva sección, elimina la descripción anterior que contenía ese contenido |
Mecanismos comunes
| Script | Qué hace | Qué produce |
|---|---|---|
scripts/shot.mjs | Abre la pantalla con Playwright según la lista de capturas, dibuja las marcas y captura. Las pantallas largas se capturan en partes | PNG en la carpeta de salida, una línea por resultado de marca |
scripts/mark.js | Busca el elemento dentro de la página por texto o selector y dibuja borde y número. Lo usa shot.mjs; en otras herramientas de navegador se inyecta con eval | Una línea por resultado de marca |
scripts/stitch.py | Une las partes capturadas y recorta por coordenadas según nombre | PNG en la carpeta de salida, una línea con el tamaño |
scripts/inline-images.py | Incrusta imágenes de ruta relativa y scripts en el HTML para crear un solo archivo | report.html, número y tamaño de archivos incluidos |
assets/decisions.js | Almacena los bloques de decisión y, con el botón Copiar de la barra inferior, agrupa lo decidido en Markdown para copiarlo | Barra fija, localStorage |
assets/compare.js | Añade a .pair[data-compare] los modos lado a lado, deslizador y barra de diferencia. El modo es un estado global de la página y por defecto es deslizador. Si las dos imágenes tienen diferente tamaño en píxeles, desactiva la superposición | Barra de comparación, porcentaje de diferencia |
assets/report-nav.js | Construye el índice izquierdo con h2 y h3, mostrando el volumen (secciones, fotos, decisiones, tiempo de lectura), secciones leídas, decisiones restantes y posición actual. Al reabrir, continúa desde donde se dejó | Índice izquierdo (cajón en pantalla estrecha), localStorage |
scripts/serve-tailscale.sh | En entornos con Tailscale, exporta la carpeta como una URL HTTPS dentro de la tailnet y verifica la respuesta (opcional) | URL, PID, comando para bajar |
scripts/check_print.sh | Genera un PDF A4 de prueba en una carpeta temporal siguiendo la misma ruta que la impresión del navegador | Ruta del PDF, número de páginas, PNG por página |
scripts/grid_overlay.py · scripts/annotate.py | Superpone una cuadrícula de coordenadas en imágenes fuera del navegador y dibuja cajas y leyendas | Imagen anotada |
El uso y las advertencias están en los comentarios del encabezado de cada script.
Salida
Una carpeta de informe (<fecha>-<tema>/): index.html para editar, imágenes en images/ (originales en images/raw/), archivos de lista de capturas y coordenadas de recorte, y report.html para entregar (un solo archivo con imágenes incrustadas). Al entregar, se comunica junto con el enlace, lo que se cambió durante la captura y los elementos que no se pudieron mostrar en pantalla.
Posición en el ecosistema del skill
- Herramienta de navegador - Este skill trata de qué y cómo capturar con la herramienta elegida y plasmar en el documento. Si hay reglas para elegir la herramienta y aislar la sesión en el entorno, se siguen esas
- Skill de documento - Los informes, propuestas y diapositivas sin pantalla no son de este skill, sino del skill de documento general
- Pulido de texto - Si hay criterios en el entorno para pulir las frases del informe y la composición de la pantalla, se usan. En el eje de revisión también puede ser la fuente de los principios