O que Correção de Dependabot faz?
Corrija sistematicamente uma PR falha do Dependabot. O usuário fornece um número de PR (ex.: /dependabot-fix 42).
Esta habilidade abrange seis fases (A–F). Não comece a editar código até que a Fase D esteja concluída. Não mergulhe nos logs até que a Fase B esteja concluída.
Configure o espaço de rascunho uma vez no início:
mkdir -p ./tmp && touch ./tmp/null
PR_NUM=<do prompt do usuário>
REPO=EthicalML/ethical
Fase A — Contexto
Passo 1 · Contexto da PR
Busque metadados e produza um resumo escrito de um parágrafo da PR (ecossistema, agrupamento, tamanho, se é uma atualização de segurança, quais arquivos ela toca). Não abra arquivos de origem ainda.
gh pr view $PR_NUM --repo $REPO --json title,body,headRefName,labels,files,mergeable,createdAt
gh pr diff $PR_NUM --repo $REPO | head -200
Identifique:
- Ecossistema:
npm|github-actions— esses são os únicos dois que este repositório tem - Agrupamento: agrupado (
all,all-security) vs um único npm major (majors são excluídos do grupoallpor design, então cada um chega sozinho) - Tamanho: número de arquivos e LOC aproximado alterado; para npm, se
package.jsonfoi movido ou apenaspackage-lock.json - Se alguma dependência alterada pode afetar a saída renderizada — isso decide a Fase E (veja Passo 8.5)
Passo 2 · Levantamento de erro de alto nível
Liste as verificações com falha e capture a primeira e a última linha de erro de cada log de job com falha. Não investigue o significado ainda — apenas enumere sintomas.
CI (.github/workflows/ci.yml) tem exatamente três jobs obrigatórios: lint (ESLint + Prettier), typecheck (npm run check:ratchet) e build (a construção Astro de produção em modo demo, sem FORM_ENDPOINT). Qualquer outra coisa vermelha não é uma verificação obrigatória.
gh pr checks $PR_NUM --repo $REPO
# Para cada verificação com falha, pegue o ID do job da URL e busque logs
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
A saída deve ser uma lista com marcadores como:
lint:Prettier check failed: package.jsontypecheck:astro check reported 3 errors, baseline is 0build:[vite] Rollup failed to resolve import "..."
Observe o que a CI não pode ver. Lint, a catraca (ratchet) do astro-check e uma construção bem-sucedida não dizem nada sobre a aparência da página. Essa lacuna é o trabalho da Fase E, e é a parte de maior valor desta habilidade neste repositório.
Fase B — Ingestão de contexto via subagentes
Inicie dois ou três subagentes explore paralelos com escopo no que a PR toca. Não leia nada disso você mesmo antes — delegue.
Passo 3 · Subagente de convenções
.github/copilot-instructions.md é o ponto de entrada canônico do agente neste repositório (o AGENTS.md e o CLAUDE.md raiz são symlinks para ele). Peça ao subagente para lê-lo e retornar: o fluxo de trabalho de mudança, suas verificações locais, as convenções de commit/PR e qualquer pegadinha relevante para os caminhos tocados. Aponte para STYLES.md também quando a PR puder tocar estilo ou a catraca de token, e para REUSABLE.md quando uma API de componente estiver implicada.
Passo 4 · Subagente de harness
Peça a ele que leia scripts/verify/README.md e retorne um briefing (~40 linhas) sobre o harness de verificação local: o que verify:dom, verify:shots, verify:parity, verify:typewriter e check:ratchet cada um afirma, como os sinalizadores de tema e viewport funcionam, onde a saída é gerada e qual é o mecanismo de lista de permissões de paridade e o que não é. Este briefing é o que a Fase E executa.
Passo 5 · Subagente de base de código
Peça a ele que produza um mapa direcionado para a área tocada:
- Qual(is) pacote(s) no diff são realmente importados por
src/**ouscripts/**, e onde (um bump para algo que nada importa é uma classe de risco diferente de um bump paraastro) - Comandos de construção e verificação (
npm run build,npm run lint,npm run format:check,npm run check:ratchet) - Se o bump toca o pipeline de construção (
astro,vite,@astrojs/*,pagefind,mdx/rehype/remarkplugins) ou apenas ferramentas (eslint,prettier,typescript) - Para uma PR
github-actions: quais workflows mudam e se alguma alteração afeta o caminho de deploy (.github/workflows/deploy.yml) em vez de apenas CI
Os briefings dos subagentes juntos formam o contexto de trabalho para a Fase C.
Fase C — Diagnóstico profundo de causa raiz
Passo 6 · Diagnosticar
Agora — e só agora — mergulhe nos logs dos jobs com falha com contexto completo da Fase B. Para cada verificação com falha, rastreie o primeiro erro significativo de volta para:
- Uma regressão direta da dependência bumpada (export removido, mudança de assinatura, validação mais rigorosa, padrão alterado)
- Um problema de toolchain transitivo (uma dep exigindo um Node mais recente do que
.tool-versionsfixa; um postinstall precisando de um runtime mais novo; uma ligação nativa opcional não sendo resolvida) - Fragilidade pré-existente exposta por um bump inócuo (a linha de base do astro-check, a catraca de token
-a###ou o hash deSTYLES.mdtropeçando em mudanças de formatação) - Instabilidade de infraestrutura (limitação de taxa de registro, job cancelado, falha de rede do
npm ci)
Para uma PR agrupada, diagnostique cada verificação com falha separadamente — as falhas podem ter causas independentes, e em um lote geralmente rastreiam para pacotes diferentes. Grave as descobertas em ./tmp/pr-${PR_NUM}-diagnosis.md.
Fase D — Design da correção
Passo 6.5 · Triagem de escopo — isso é uma correção ou um problema de configuração do Dependabot?
Antes de planejar uma correção, verifique se a PR está dentro do escopo para ser corrigida. .github/dependabot.yml agrupa atualizações npm de minor/patch de rotina em um único grupo all por ecossistema mais um grupo all-security, e exclui deliberadamente npm majors do grupo all para que cada major chegue sozinho. Essa forma significa duas situações distintas de falha:
Uma PR agrupada falhando em um pacote. Este é o caso comum e está dentro do escopo. Não abandone o lote. Encontre o único pacote ofensor e corrija o código para ele, ou fixe esse único pacote (uma entrada em package.json estreitando o intervalo, ou uma entrada de ignore do Dependabot para aquele pacote e versão) para que o resto do lote possa ser mesclado. Abandonar um lote verde-exceto-um joga fora uma dúzia de boas atualizações por uma ruim.
Gatilhos de rejeição de escopo (qualquer um é suficiente — a PR é um problema de configuração, não uma correção):
- Uma PR de grupo único contém ≥ 2 major bumps — o que deveria ser impossível sob a configuração atual do grupo npm, então se acontecer, a configuração em si se desviou e é o bug real
- Um major solitário em um pacote de nível de framework (
astro,vite,@astrojs/*,typescript,eslint,prettier,preact,pagefind) que é uma migração genuína — não uma correção, um projeto - O lote é principalmente rotineiro, mas sua falha precisa de uma migração em um pacote que não pode ser contornado com fixação
Quando acionado, não tente uma correção e não feche a PR você mesmo — deixe-a aberta para o proprietário. Em vez disso:
- Se a causa for um desvio de configuração, prepare a correção de
.github/dependabot.ymlcomo uma PR pequena separada (deixe para o proprietário revisar e mesclar). Caso contrário, nenhuma mudança de configuração é necessária e a recomendação é simplesmente que a migração seja agendada como seu próprio trabalho. - Verbalize a decisão de rejeição de escopo como um comentário na PR do Dependabot: explique por que não pode ser corrigida em uma única passada, vincule qualquer PR de configuração e diga o que uma migração envolveria. Deixe a PR aberta — não pause para uma decisão, não a feche.
- Pule o fluxo de commit da Fase F — não há correção. O conteúdo do relatório se dobra nesse comentário.
Grupos de atualização de segurança (all-security) são deixados agrupados: bumps de segurança são sensíveis ao tempo e raros o suficiente para que dividi-los custe mais do que economiza. Só divida um se um bloqueador concreto forçar.
Passo 7 · Plano abrangente
Escreva um plano cobrindo o seguinte; dimensione a profundidade pelo risco:
| Seção | Sempre | Se risco ≥ médio |
|---|---|---|
| Causa raiz | ✅ | ✅ |
| Arquivos que devem mudar | ✅ | ✅ |
| Abordagem de correção (e alternativas consideradas) | ✅ | ✅ |
| Classificação de risco (baixo/médio/alto) | ✅ | ✅ |
| Passos de reprodução | ✅ | ✅ (deve ser executável) |
| Estratégia de teste manual | ✅ | ✅ expandido |
| Plano de reversão | ✅ | |
| Raio de explosão (saída renderizada / deploy / URLs) | ✅ |
Risco ≥ médio se qualquer um dos seguintes:
- o bump toca o pipeline de construção (
astro,vite,@astrojs/*, plugins MDX/rehype/remark,pagefind) - a correção edita qualquer coisa sob
src/em vez de config ou lockfile - o bump pode alterar HTML emitido, ordenação de CSS, carregamento de fontes ou comportamento de hidratação
- uma mudança
github-actionstocadeploy.yml(um deploy quebrado é uma interrupção de site ao vivo, não uma verificação vermelha)
Qualquer npm major é pelo menos médio por padrão. Um major chega sozinho precisamente porque merece leitura e teste por si só; trate-o com mais escrutínio do que um lote do mesmo tamanho.
Passo 8 · Estratégia de teste manual (em camadas)
Classifique o esforço pela classificação de risco do Passo 7:
- Baixo (apenas ferramentas) — aplique a correção, execute a verificação mais estreita relevante (
npm run lint,npm run format:checkounpm run check:ratchet). Nenhum passo de reprodução necessário. - Médio (pipeline de construção ou edição em
src/) — primeiro reproduza a falha localmente no branch da PR para provar que a regressão é real (não um artefato de CI). Em seguida, aplique a correção, reexecute as verificações locais completas:npm run lint && npm run format:check && npm run check:ratchet && npm run build. Em seguida, Fase E. - Alto (majors, qualquer coisa que possa mudar a saída renderizada, mudanças de deploy) — tudo no médio, mais a varredura de paridade da Fase E é obrigatória, mais
npm run verify:dom:allcontra o cabeçalho da PR construído, maisnpm run verify:typewriterse o herói ou tokens de movimento estiverem implicados.
Mantenha toda a saída de rascunho sob ./tmp/ (gitignorado). Use ./tmp/null como o sumidouro ao suprimir saída:
npm run build 2>./tmp/null
Fase E — Paridade visual contra a base de merge
A CI prova que o site ainda constrói. Ela não prova que o site ainda parece o mesmo. Um bump de dependência deve ser pixel-neutro por definição — se não for, algo foi renderizado de forma diferente e ninguém teria visto. Esta fase é a razão pela qual esta habilidade existe neste repositório.
Nenhuma linha de base de pixel está commitada (scripts/verify/out/ e tmp/ são gitignorados), então a comparação precisa ser gerada em execução: capture a base de merge, capture o cabeçalho da PR, compare.
Passo 8.5 · Decida se deve executar
A varredura custa aproximadamente 4–5 minutos por PR (duas construções mais duas varreduras de screenshot em 37 rotas × 2 viewports). Pule apenas quando a mudança não pode afetar a renderização. É pulável quando todas as seguintes condições são verdadeiras:
- A PR é
github-actionsapenas, ou toca apenas.github/** - Nenhum arquivo sob
src/,public/,astro.config.mjsoupackage.jsondependenciesmudou - O diff está confinado a devDependencies cuja saída nunca chega a
dist/(eslint*,prettier,@types/*,typescriptquando a catraca está inalterada)
Qualquer outra coisa — qualquer bump de astro, vite, @astrojs/*, preact, pagefind, MDX/rehype/remark, font ou ferramentas de CSS, e todo npm major — executa a varredura. Quando em dúvida, execute; cinco minutos são mais baratos do que uma regressão visual silenciosa em um site ao vivo.
Diga explicitamente no relatório qual ramo desta decisão foi tomado e por quê.
Passo 9 · Capture e compare
Playwright não é uma dependência do repositório; o harness o dirige de um caminho de cache npx já configurado nos scripts. Sirva cada construção com um servidor estático simples.
BASE_SHA=$(git merge-base origin/master HEAD)
mkdir -p ./tmp/parity
# --- base de merge ---
git checkout $BASE_SHA
npm ci
npm run build
cp dist/index.html ./tmp/parity/base-index.html # impressão digital do que está sendo servido
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
# --- cabeçalho da 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
# --- compare, 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
A armadilha do dist obsoleto. Reutilizar a porta 4126 entre duas construções é a maneira mais provável de produzir um verde confiante e sem sentido: se o servidor antigo não morreu de fato, ou dist não foi reconstruído, a segunda varredura fotografa a primeira construção e a paridade passa porque você comparou uma construção a si mesma. Proteja contra isso em cada execução:
- Confirme que o servidor anterior desapareceu antes de iniciar o próximo (
lsof -i :4126não retorna nada). - Diferencie as duas impressões digitais —
cmp ./tmp/parity/base-index.html ./tmp/parity/head-index.htmlretornando "idêntico" para uma PR que mudousrc/ou uma dep do pipeline de construção é um sinal para desconfiar da execução, não um resultado. - Se o próprio JSON da varredura relatar
compared: 0ou toda rota faltando, o servidor não estava funcionando; a execução é nula, não aprovada.
verify:shots escreve a saída do tema escuro para out/<width>/. Se um bump plausivelmente afeta o tema claro de forma diferente (ferramentas de CSS, manipulação de cores, emissão de token), repita a varredura com --theme light, que escreve para out/light/<width>/ e não pode sobrescrever a árvore escura.
Passo 10 · Interprete o resultado
verify-parity relata dois números por rota, e ambos importam.