Corrección de Dependabot
Corrige sistemáticamente una PR fallida de Dependabot. El usuario proporciona un número de PR (p.ej., /dependabot-fix 42).
Esta habilidad abarca seis fases (A–F). No comiences a editar código hasta que la Fase D esté completa. No te sumerjas en los registros hasta que la Fase B esté completa.
Configura el espacio de trabajo temporal una vez al inicio:
mkdir -p ./tmp && touch ./tmp/null
PR_NUM=<del prompt del usuario>
REPO=EthicalML/ethical
Fase A — Contexto
Paso 1 · Contexto de la PR
Obtén metadatos y produce un resumen escrito de un párrafo de la PR (ecosistema, agrupación, tamaño, si es una actualización de seguridad, qué archivos toca). No abras archivos fuente todavía.
gh pr view $PR_NUM --repo $REPO --json title,body,headRefName,labels,files,mergeable,createdAt
gh pr diff $PR_NUM --repo $REPO | head -200
Identifica:
- Ecosistema:
npm|github-actions— estos son los únicos dos que tiene este repositorio - Agrupación: agrupado (
all,all-security) vs. un npm major solitario (los majors están excluidos del grupoallpor diseño, por lo que cada uno llega por separado) - Tamaño: número de archivos y LOC aproximados cambiados; para npm, si
package.jsonse movió o solopackage-lock.json - Si algún cambio de dependencia puede afectar la salida renderizada — esto decide la Fase E (ver Paso 8.5)
Paso 2 · Inspección de errores de alto nivel
Enumera las verificaciones que fallan y captura la primera y última línea de error de los registros de cada trabajo que falla. No investigues su significado todavía — solo enumera los síntomas.
CI (.github/workflows/ci.yml) tiene exactamente tres trabajos requeridos: lint (ESLint + Prettier), typecheck (npm run check:ratchet) y build (la compilación de producción de Astro en modo demo, sin FORM_ENDPOINT). Cualquier otra cosa en rojo no es una verificación requerida.
gh pr checks $PR_NUM --repo $REPO
# Para cada verificación que falla, obtén el ID del trabajo desde la URL y extrae los registros
gh run view --job <JOB_ID> --repo $REPO --log 2>./tmp/null \
| grep -iE "error|exit code|##[error]|FAILED|assert|timed ?out" \
| head -20 > ./tmp/pr-${PR_NUM}-symptoms.txt
La salida debe ser una lista con viñetas como:
lint:La verificación de Prettier falló: package.jsontypecheck:astro check reportó 3 errores, la línea base es 0build:[vite] Rollup falló al resolver la importación "..."
Nota lo que el CI no puede ver. Lint, el pestillo astro-check y una compilación exitosa no dicen nada sobre cómo se ve la página. Ese vacío es el trabajo de la Fase E, y es la parte de mayor valor de esta habilidad en este repositorio.
Fase B — Ingestión de contexto mediante subagentes
Genera dos o tres subagentes explore en paralelo con alcance a lo que toca la PR. No leas nada de esto tú mismo de antemano — delega.
Paso 3 · Subagente de convenciones
.github/copilot-instructions.md es el único punto de entrada canónico del agente en este repositorio (los archivos raíz AGENTS.md y CLAUDE.md son enlaces simbólicos a él). Pídele al subagente que lo lea y devuelva: el flujo de trabajo de cambios, sus verificaciones locales, las convenciones de commits/PR y cualquier detalle relevante para las rutas tocadas. Señálale también STYLES.md cuando la PR pueda tocar el estilo o el pestillo de tokens, y REUSABLE.md cuando una API de componente esté implicada.
Paso 4 · Subagente de herramientas
Pídele que lea scripts/verify/README.md y devuelva un informe breve (~40 líneas) sobre el conjunto de herramientas de verificación local: qué verifican verify:dom, verify:shots, verify:parity, verify:typewriter y check:ratchet, cómo funcionan los indicadores de tema y viewport, dónde aterriza la salida y cuál es el mecanismo de lista blanca de paridad y cuál no. Este informe es contra lo que ejecutará la Fase E.
Paso 5 · Subagente de código base
Pídele que produzca un mapa dirigido para el área tocada:
- Qué paquete(s) en el diff son realmente importados por
src/**oscripts/**, y dónde (un aumento de algo que nada importa es una clase de riesgo diferente de un aumento deastro) - Comandos de compilación y verificación (
npm run build,npm run lint,npm run format:check,npm run check:ratchet) - Si el aumento toca el pipeline de compilación (
astro,vite,@astrojs/*,pagefind, complementosmdx/rehype/remark) o solo herramientas (eslint,prettier,typescript) - Para una PR de
github-actions: qué flujos de trabajo cambian y si algún cambio afecta la ruta de despliegue (.github/workflows/deploy.yml) en lugar de solo CI
Los informes de los subagentes juntos forman el contexto de trabajo para la Fase C.
Fase C — Diagnóstico profundo de causa raíz
Paso 6 · Diagnosticar
Ahora —y solo ahora— sumérgete en los registros de los trabajos que fallan con el contexto completo de la Fase B. Para cada verificación que falla, rastrea el primer error significativo hasta:
- Una regresión directa de la dependencia aumentada (exportación eliminada, cambio de firma, validación más estricta, valor predeterminado cambiado)
- Un problema transitorio de la cadena de herramientas (una dependencia que requiere una versión de Node más reciente de la que fija
.tool-versions; un postinstall que necesita un tiempo de ejecución más reciente; un enlace nativo opcional que no se resuelve) - Fragilidad preexistente expuesta por un aumento inofensivo (la línea base de astro-check, el pestillo de token
-a###o el hash deSTYLES.mdque se activa por cambios de formato) - Inestabilidad de infraestructura (límite de tasa del registro, trabajo cancelado, fallo de red de
npm ci)
Para una PR agrupada, diagnostica cada verificación que falla por separado: las fallas pueden tener causas independientes, y en un lote generalmente se rastrean a diferentes paquetes. Registra los hallazgos en ./tmp/pr-${PR_NUM}-diagnosis.md.
Fase D — Diseño de la corrección
Paso 6.5 · Triage de alcance — ¿Es esto una corrección o un problema de configuración de Dependabot?
Antes de planificar una corrección, verifica si la PR está dentro del alcance para ser corregida. .github/dependabot.yml agrupa las actualizaciones menores/de parche de npm de rutina en un solo grupo all por ecosistema más un grupo all-security, y excluye deliberadamente los majors de npm del grupo all para que cada major llegue por sí solo. Esta forma significa dos situaciones distintas de falla:
Una PR agrupada que falla en un solo paquete. Este es el caso común y está dentro del alcance. No abandones el lote. Encuentra el paquete ofensor único y corrige el código para él, o fija ese paquete (una entrada en package.json que estreche el rango, o una entrada de ignore de Dependabot para ese paquete y versión) para que el resto del lote pueda aterrizar. Abandonar un lote verde excepto uno desecha una docena de buenas actualizaciones por una mala.
Disparadores de rechazo de alcance (cualquiera es suficiente — la PR es un problema de configuración, no una corrección):
- Una PR de grupo único contiene ≥ 2 aumentos mayores — lo que debería ser imposible bajo la configuración de grupo npm actual, por lo que si sucede, la configuración misma se ha desviado y es el error real
- Un major solitario en un paquete de nivel de framework (
astro,vite,@astrojs/*,typescript,eslint,prettier,preact,pagefind) que es una migración genuina — no una corrección, un proyecto - El lote es mayormente rutinario pero su falla necesita una migración en un paquete que no se puede evitar con un pin
Cuando se active, no intentes una corrección y no cierres la PR tú mismo — déjala abierta para el propietario. En su lugar:
- Si la causa es una desviación de configuración, prepara la corrección de
.github/dependabot.ymlcomo una PR pequeña separada (déjala para que el propietario la revise y fusione). De lo contrario, no se necesita ningún cambio de configuración y la recomendación es simplemente que la migración se programe como su propio trabajo. - Expresa la decisión de rechazo de alcance como un comentario en la PR de Dependabot: explica por qué no se puede corregir en una sola pasada, enlaza cualquier PR de configuración y di qué implicaría una migración. Deja la PR abierta — no pauses para una decisión, no la cierres.
- Omite el flujo de commit de la Fase F — no hay corrección. El contenido del informe se pliega en ese comentario.
Los grupos de actualización de seguridad (all-security) se dejan agrupados: los aumentos de seguridad son urgentes y lo suficientemente raros como para que dividirlos cueste más de lo que ahorra. Solo divide uno si un bloqueador concreto lo fuerza.
Paso 7 · Plan integral
Escribe un plan que cubra lo siguiente; escala la profundidad según el riesgo:
| Sección | Siempre | Si el riesgo ≥ medio |
|---|---|---|
| Causa raíz | ✅ | ✅ |
| Archivos que se espera cambiar | ✅ | ✅ |
| Enfoque de corrección (y alternativas consideradas) | ✅ | ✅ |
| Clasificación de riesgo (bajo/medio/alto) | ✅ | ✅ |
| Pasos de reproducción | ✅ | ✅ (deben ser ejecutables) |
| Estrategia de pruebas manuales | ✅ | ✅ ampliada |
| Plan de reversión | ✅ | |
| Radio de explosión (salida renderizada/despliegue/URLs) | ✅ |
Riesgo ≥ medio si cualquiera de:
- el aumento toca el pipeline de compilación (
astro,vite,@astrojs/*, complementos MDX/rehype/remark,pagefind) - la corrección edita algo bajo
src/en lugar de configuración o archivo de bloqueo - el aumento puede cambiar el HTML emitido, el orden de CSS, la carga de fuentes o el comportamiento de hidratación
- un cambio de
github-actionstocadeploy.yml(un despliegue roto es una interrupción del sitio en vivo, no una verificación roja)
Cualquier npm major es al menos medio por defecto. Un major llega solo precisamente porque merece ser leído y probado por sí mismo; trátalo con más escrutinio que un lote del mismo tamaño.
Paso 8 · Estrategia de pruebas manuales (por niveles)
Nivela el esfuerzo según la clasificación de riesgo del Paso 7:
- Bajo (solo herramientas) — aplica la corrección, ejecuta la puerta más estrecha relevante (
npm run lint,npm run format:checkonpm run check:ratchet). No se necesita paso de reproducción. - Medio (pipeline de compilación o edición de
src/) — primero reproduce la falla localmente en la rama de la PR para probar que la regresión es real (no un artefacto de CI). Luego aplica la corrección, vuelve a ejecutar las verificaciones locales completas:npm run lint && npm run format:check && npm run check:ratchet && npm run build. Luego Fase E. - Alto (majors, cualquier cosa que pueda cambiar la salida renderizada, cambios de despliegue) — todo lo del nivel medio, más el barrido de paridad de la Fase E es obligatorio, más
npm run verify:dom:allcontra la cabeza de la PR compilada, másnpm run verify:typewritersi el héroe o los tokens de movimiento están implicados.
Mantén toda la salida de trabajo bajo ./tmp/ (gitignorada). Usa ./tmp/null como sumidero al suprimir salida:
npm run build 2>./tmp/null
Fase E — Paridad visual contra la base de fusión
El CI prueba que el sitio aún se compila. No prueba que el sitio se vea igual. Un aumento de dependencia debería ser píxel-neutral por definición — si no lo es, algo se renderizó de manera diferente y nadie lo habría visto. Esta fase es la razón por la que esta habilidad existe en este repositorio.
No hay líneas base de píxeles confirmadas (scripts/verify/out/ y tmp/ están gitignoradas), por lo que la comparación debe generarse en tiempo de ejecución: captura la base de fusión, captura la cabeza de la PR, compara.
Paso 8.5 · Decidir si ejecutarlo
El barrido cuesta aproximadamente 4–5 minutos por PR (dos compilaciones más dos barridos de capturas de pantalla en 37 rutas × 2 viewports). Omítelo solo cuando el cambio no pueda afectar el renderizado. Es omisible cuando todas estas condiciones se cumplen:
- La PR es solo de
github-actions, o toca solo.github/** - Ningún archivo bajo
src/,public/,astro.config.mjsopackage.jsondependenciescambió - El diff se limita a devDependencies cuya salida nunca llega a
dist/(eslint*,prettier,@types/*,typescriptcuando el pestillo no cambia)
Cualquier otra cosa — cualquier aumento de astro, vite, @astrojs/*, preact, pagefind, MDX/rehype/remark, fuente o herramientas de CSS, y cada npm major — ejecuta el barrido. Ante la duda, ejecútalo; cinco minutos son más baratos que una regresión visual silenciosa en un sitio en vivo.
Di explícitamente en el informe qué rama de esta decisión se tomó y por qué.
Paso 9 · Capturar y comparar
Playwright no es una dependencia del repositorio; el conjunto de herramientas lo ejecuta desde una ruta de caché npx ya cableada en los scripts. Sirve cada compilación con un servidor estático simple.
BASE_SHA=$(git merge-base origin/master HEAD)
mkdir -p ./tmp/parity
# --- base de fusión ---
git checkout $BASE_SHA
npm ci
npm run build
cp dist/index.html ./tmp/parity/base-index.html # huella de lo que estamos sirviendo
nohup npx --yes http-server dist -p 4126 --silent < ./tmp/null > ./tmp/parity/base-server.log 2>&1 &
BASE_SERVER=$!
npm run verify:shots:all
kill $BASE_SERVER
cp -R scripts/verify/out ./tmp/parity/base
# --- cabeza de la PR ---
gh pr checkout $PR_NUM --repo $REPO
npm ci
npm run build
cp dist/index.html ./tmp/parity/head-index.html
nohup npx --yes http-server dist -p 4126 --silent < ./tmp/null > ./tmp/parity/head-server.log 2>&1 &
HEAD_SERVER=$!
npm run verify:shots:all
kill $HEAD_SERVER
cp -R scripts/verify/out ./tmp/parity/head
# --- comparar, por viewport ---
npm run verify:parity -- ./tmp/parity/base/1440 ./tmp/parity/head/1440 > ./tmp/parity/1440.json
npm run verify:parity -- ./tmp/parity/base/420 ./tmp/parity/head/420 > ./tmp/parity/420.json
La trampa del dist obsoleto. Reutilizar el puerto 4126 en dos compilaciones es la forma más probable de producir un verde confiado pero sin sentido: si el servidor anterior no murió realmente, o dist no se reconstruyó, el segundo barrido fotografía la primera compilación y la paridad pasa porque comparaste una compilación consigo misma. Protégelo en cada ejecución:
- Confirma que el servidor anterior se ha ido antes de iniciar el siguiente (
lsof -i :4126no devuelve nada). - Compara las dos huellas —
cmp ./tmp/parity/base-index.html ./tmp/parity/head-index.htmldevolviendo "idéntico" para una PR que cambiósrc/o una dependencia del pipeline de compilación es una señal para desconfiar de la ejecución, no un resultado. - Si el propio JSON del barrido informa
compared: 0o cada ruta falta, el servidor no estaba activo; la ejecución es nula, no exitosa.
verify:shots escribe la salida del tema oscuro en out/<width>/. Si un aumento plausiblemente afecta el tema claro de manera diferente (herramientas de CSS, manejo de color, emisión de tokens), repite el barrido con --theme light, que escribe en out/light/<width>/ y no puede sobrescribir el árbol oscuro.
Paso 10 · Interpretar el resultado
verify-parity informa dos números por ruta, y ambos importan
… [truncado para traducción]