EthicalML/ethical

Systematische Fehlerdiagnose und Behebung eines fehlschlagenden Dependabot-PRs auf dieser Astro-Website. Verwenden Sie dieses Skill, wenn /dependabot-fix <PR-Nummer> aufgerufen wird.

Was ist ethical?

Dieser Skill diagnostiziert und behebt systematisch einen fehlschlagenden Dependabot-PR auf einer Astro-Website. Er ist für die Verwendung mit KI-Agenten wie Claude Code, Cursor oder Codex konzipiert, die über Kommandozeilenzugriff, Befehlsausführung und Integration mit GitHub-CLI verfügen. Der Skill führt sechs Phasen durch: Kontexterhebung (PR-Metadaten, fehlgeschlagene CI-Checks), parallele Kontexterfassung durch Subagenten (Konventionen, Testumgebung, Codebasis), tiefgehende Ursachenanalyse, abgestufte Fix-Planung mit manueller Teststrategie, einen Merge-Base-Pixel-Paritäts-Sweep zum Aufdecken visueller Regressionen, die CI nicht erkennen kann, und direkten Commit des Fixes auf den Dependabot-PR-Branch. Der Skill läuft auf jedem System mit Node.js, npm, GitHub-CLI und Playwright, die in der Repository-Umgebung verfügbar sind. Der hochgelobte Pixel-Paritäts-Sweep ist der kritischste Teil, da er sicherstellt, dass Abhängigkeitsaktualisierungen pixelneutral sind und keine unbeabsichtigten visuellen Änderungen auf der Live-Website verursachen.

Funktioniert mit✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/EthicalML/ethical/tree/HEAD/.claude/skills/dependabot-fix

Installed? Explore more Produktivität & Zusammenarbeit skills: steipete/gemini, steipete/gh-issues, steipete/skill-creator · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Dependabot-Fix

Beheben Sie systematisch einen fehlschlagenden Dependabot-PR. Der Benutzer gibt eine PR-Nummer an (z. B. /dependabot-fix 42).

Dieser Skill umfasst sechs Phasen (A–F). Beginnen Sie nicht mit dem Bearbeiten von Code, bis Phase D abgeschlossen ist. Tauchen Sie nicht in Logs ein, bis Phase B abgeschlossen ist.

Richten Sie einmalig zu Beginn einen Scratch-Bereich ein:

mkdir -p ./tmp && touch ./tmp/null
PR_NUM=<aus Benutzer-Prompt>
REPO=EthicalML/ethical

Phase A — Kontext

Schritt 1 · PR-Kontext

Rufen Sie Metadaten ab und erstellen Sie eine einseitige Zusammenfassung des PRs (Ökosystem, Gruppierung, Größe, ob es sich um ein Sicherheitsupdate handelt, welche Dateien betroffen sind). Öffnen Sie nicht noch keine Quelldateien.

gh pr view $PR_NUM --repo $REPO --json title,body,headRefName,labels,files,mergeable,createdAt
gh pr diff $PR_NUM --repo $REPO | head -200

Identifizieren Sie:

  • Ökosystem: npm | github-actions — dies sind die einzigen beiden in diesem Repository
  • Gruppierung: gruppiert (all, all-security) vs. einzelne npm Major (Majors werden bewusst aus der all-Gruppe ausgeschlossen, sodass jede einzeln eintrifft)
  • Größe: Anzahl der Dateien und ungefähre geänderte Codezeilen; für npm, ob package.json verschoben wurde oder nur package-lock.json
  • Ob eine geänderte Abhängigkeit überhaupt die gerenderte Ausgabe beeinflussen kann — dies entscheidet über Phase E (siehe Schritt 8.5)

Schritt 2 · Hochrangige Fehlererhebung

Listen Sie fehlgeschlagene Checks auf und erfassen Sie die erste und letzte Fehlerzeile aus den Logs jedes fehlgeschlagenen Jobs. Untersuchen Sie deren Bedeutung noch nicht — erfassen Sie nur Symptome.

CI (.github/workflows/ci.yml) hat genau drei erforderliche Jobs: lint (ESLint + Prettier), typecheck (npm run check:ratchet) und build (der Produktions-Astro-Build im Demo-Modus, kein FORM_ENDPOINT). Alles andere Rote ist kein erforderlicher Check.

gh pr checks $PR_NUM --repo $REPO

# Für jeden fehlgeschlagenen Check die Job-ID aus der URL holen und Logs abrufen
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

Die Ausgabe sollte eine Aufzählungsliste sein, z. B.:

  • lint: Prettier-Check fehlgeschlagen: package.json
  • typecheck: astro check meldet 3 Fehler, Basislinie ist 0
  • build: [vite] Rollup konnte Import "..." nicht auflösen

Beachten Sie, was CI nicht sehen kann. Lint, die astro-check-Ratchet und ein erfolgreicher Build sagen nichts darüber aus, wie die Seite aussieht. Diese Lücke ist Aufgabe von Phase E, und es ist der wertvollste Teil dieses Skills in diesem Repository.


Phase B — Kontexterfassung durch Subagenten

Starten Sie zwei oder drei parallele explore-Subagenten, die auf die vom PR berührten Bereiche abgestimmt sind. Lesen Sie selbst vorher nichts davon — delegieren Sie.

Schritt 3 · Konventionen-Subagent

.github/copilot-instructions.md ist der einzige kanonische Agenteneinstiegspunkt in diesem Repository (root AGENTS.md und CLAUDE.md sind Symlinks darauf). Bitten Sie den Subagenten, es zu lesen und zurückzugeben: den Änderungsworkflow, die lokalen Checks, die Commit/PR-Konventionen und alle Stolpersteine, die für die betroffenen Pfade relevant sind. Verweisen Sie es auch auf STYLES.md, wenn der PR Styling oder die Token-Ratchet betreffen könnte, und auf REUSABLE.md, wenn eine Komponenten-API betroffen ist.

Schritt 4 · Testumgebungs-Subagent

Bitten Sie es, scripts/verify/README.md zu lesen und ein Briefing (~40 Zeilen) über die lokale Verifikationsumgebung zurückzugeben: was verify:dom, verify:shots, verify:parity, verify:typewriter und check:ratchet jeweils prüfen, wie die Theme- und Viewport-Flags funktionieren, wo die Ausgabe landet und was der Parity-Allowlist-Mechanismus ist und nicht ist. Dieses Briefing ist das, was Phase E ausführt.

Schritt 5 · Codebasis-Subagent

Bitten Sie es, eine zielgerichtete Karte für den betroffenen Bereich zu erstellen:

  • Welche(s) Paket(e) im Diff werden tatsächlich von src/** oder scripts/** importiert und wo (ein Bump für etwas, das nichts importiert, ist eine andere Risikoklasse als ein Bump für astro)
  • Build- und Check-Befehle (npm run build, npm run lint, npm run format:check, npm run check:ratchet)
  • Ob der Bump die Build-Pipeline betrifft (astro, vite, @astrojs/*, pagefind, mdx/rehype/remark-Plugins) oder nur Tooling (eslint, prettier, typescript)
  • Für einen github-actions-PR: welche Workflows sich ändern und ob eine Änderung den Deploy-Pfad betrifft (.github/workflows/deploy.yml) und nicht nur CI

Die Subagenten-Briefings bilden zusammen den Arbeitskontext für Phase C.


Phase C — Tiefgehende Ursachenanalyse

Schritt 6 · Diagnose

Tauchen Sie jetzt — und erst jetzt — mit vollständigem Kontext aus Phase B in die Logs der fehlgeschlagenen Jobs ein. Verfolgen Sie für jeden fehlgeschlagenen Check den ersten bedeutungsvollen Fehler zurück auf:

  1. Eine direkte Regression durch die hochgestufte Abhängigkeit (entferntes Export, geänderte Signatur, strengere Validierung, geänderter Standardwert)
  2. Ein Problem der transitiven Toolchain (eine Abhängigkeit, die ein neueres Node erfordert als .tool-versions vorgibt; ein Postinstall, das eine neuere Laufzeit benötigt; eine optionale native Bindung, die nicht aufgelöst wird)
  3. Vorbestehende Fragilität, die durch einen harmlosen Bump aufgedeckt wird (die astro-check-Basislinie, die -a###-Token-Ratchet oder der STYLES.md-Hash, der durch Formatierungsänderungen ausgelöst wird)
  4. Infrastruktur-Flake (Registry-Ratenbegrenzung, abgebrochener Job, npm ci-Netzwerkfehler)

Diagnostizieren Sie für einen gruppierten PR jeden fehlgeschlagenen Check separat — Fehler können unabhängige Ursachen haben, und in einem Batch sind sie normalerweise auf verschiedene Pakete zurückzuführen. Speichern Sie die Ergebnisse in ./tmp/pr-${PR_NUM}-diagnosis.md.


Phase D — Fix-Planung

Schritt 6.5 · Bereichstriage — ist dies ein Fix oder ein Dependabot-Konfigurationsproblem?

Bevor Sie einen Fix planen, prüfen Sie, ob der PR überhaupt im Bereich der Behebung liegt. .github/dependabot.yml bündelt routinemäßige npm Minor/Patch-Updates in einer einzelnen all-Gruppe pro Ökosystem plus einer all-security-Gruppe und schließt npm Majors bewusst aus der all-Gruppe aus, sodass jeder Major einzeln eintrifft. Diese Form bedeutet zwei unterschiedliche Fehlersituationen:

Ein gruppierter PR, der bei einem Paket fehlschlägt. Dies ist der häufige Fall und ist im Bereich. Geben Sie den Batch nicht auf. Finden Sie das einzelne störende Paket und beheben Sie entweder den Code dafür oder pinnen Sie dieses eine Paket (ein Eintrag in package.json, der den Bereich eingrenzt, oder ein Dependabot ignore-Eintrag für dieses Paket und diese Version), damit der Rest des Batches landen kann. Das Aufgeben eines grün-bis-auf-einen-Batches wirft ein Dutzend guter Updates für ein schlechtes weg.

Bereichsablehnungs-Trigger (jeder einzelne ist ausreichend — der PR ist ein Konfigurationsproblem, kein Fix):

  • Eine einzelne Gruppen-PR enthält ≥ 2 Major-Bumps — was unter der aktuellen npm-Gruppenkonfiguration unmöglich sein sollte, also wenn es passiert, ist die Konfiguration selbst abgedriftet und der eigentliche Fehler
  • Ein einzelner Major auf einem Framework-Ebene-Paket (astro, vite, @astrojs/*, typescript, eslint, prettier, preact, pagefind), das eine echte Migration ist — kein Fix, ein Projekt
  • Der Batch ist meist routinemäßig, aber sein Fehler erfordert eine Migration bei einem Paket, das nicht umgangen werden kann

Wenn ausgelöst, versuchen Sie keinen Fix und schließen Sie den PR nicht selbst — lassen Sie ihn für den Eigentümer offen. Stattdessen:

  1. Wenn die Ursache eine Konfigurationsabweichung ist, bereiten Sie die Korrektur von .github/dependabot.yml als separaten kleinen PR vor (lassen Sie ihn vom Eigentümer überprüfen und zusammenführen). Andernfalls ist keine Konfigurationsänderung erforderlich, und die Empfehlung ist lediglich, dass die Migration als eigene Arbeit geplant wird.
  2. Verbalisieren Sie die Bereichsablehnungsentscheidung als Kommentar auf dem Dependabot-PR: Erklären Sie, warum er nicht in einem Durchgang behoben werden kann, verlinken Sie ggf. den Konfigurations-PR und sagen Sie, was eine Migration beinhalten würde. Lassen Sie den PR offen — warten Sie nicht auf eine Entscheidung, schließen Sie ihn nicht.
  3. Überspringen Sie den Commit-Fluss von Phase F — es gibt keinen Fix. Der Berichtsinhalt fließt in diesen Kommentar ein.

Sicherheitsupdate-Gruppen (all-security) bleiben gebündelt: Sicherheits-Bumps sind zeitkritisch und selten genug, dass das Aufteilen mehr kostet als es spart. Teilen Sie nur eine auf, wenn ein konkreter Blocker es erzwingt.

Schritt 7 · Umfassender Plan

Schreiben Sie einen Plan, der Folgendes abdeckt; skalieren Sie die Tiefe nach Risiko:

AbschnittImmerWenn Risiko ≥ mittel
Ursache✅✅
Erwartete Änderungsdateien✅✅
Lösungsansatz (und erwogene Alternativen)✅✅
Risikobewertung (niedrig/mittel/hoch)✅✅
Reproduktionsschritte✅✅ (muss ausführbar sein)
Manuelle Teststrategie✅✅ erweitert
Rollback-Plan✅
Auswirkungsbereich (gerenderte Ausgabe / Deploy / URLs)✅

Risiko ≥ mittel, wenn irgendeines zutrifft:

  • der Bump die Build-Pipeline betrifft (astro, vite, @astrojs/*, MDX/rehype/remark-Plugins, pagefind)
  • der Fix etwas unter src/ bearbeitet, anstatt Konfiguration oder Lockfile
  • der Bump gerendertes HTML, CSS-Reihenfolge, Schriftarten-Laden oder Hydratationsverhalten ändern kann
  • eine github-actions-Änderung deploy.yml betrifft (ein defekter Deploy ist ein Live-Site-Ausfall, kein roter Check)

Jedes npm Major ist standardmäßig mindestens mittel. Ein Major trifft genau deshalb allein ein, weil er Lesen und Testen für sich verdient; behandeln Sie es mit mehr Sorgfalt als einen Batch derselben Größe.

Schritt 8 · Manuelle Teststrategie (abgestuft)

Stufen Sie den Aufwand nach der Risikobewertung von Schritt 7:

  • Niedrig (nur Tooling) — Fix anwenden, engstes relevantes Gate ausführen (npm run lint, npm run format:check oder npm run check:ratchet). Kein Reproduktionsschritt erforderlich.
  • Mittel (Build-Pipeline oder src/-Bearbeitung) — Zuerst den Fehler lokal auf dem PR-Branch reproduzieren, um zu beweisen, dass die Regression real ist (kein CI-Artefakt). Dann Fix anwenden, alle lokalen Checks erneut ausführen: npm run lint && npm run format:check && npm run check:ratchet && npm run build. Dann Phase E.
  • Hoch (Majors, alles, was gerenderte Ausgabe ändern kann, Deploy-Änderungen) — alles in mittel, plus Phasen E's Parity-Sweep ist obligatorisch, plus npm run verify:dom:all gegen den gebauten PR-Head, plus npm run verify:typewriter, wenn die Hero- oder Motion-Token betroffen sind.

Halten Sie alle Scratch-Ausgaben unter ./tmp/ (gitignoriert). Verwenden Sie ./tmp/null als Senke beim Unterdrücken von Ausgaben:

npm run build 2>./tmp/null

Phase E — Visuelle Parität gegen den Merge-Base

CI beweist, dass die Site noch baut. Es beweist nicht, dass die Site noch gleich aussieht. Ein Abhängigkeits-Bump sollte per Definition pixelneutral sein — wenn nicht, wird etwas anders gerendert und niemand hätte es gesehen. Diese Phase ist der Grund, warum dieser Skill in diesem Repository existiert.

Keine Pixel-Baselines sind committet (scripts/verify/out/ und tmp/ sind gitignoriert), daher muss der Vergleich während der Laufzeit generiert werden: Merge-Base erfassen, PR-Head erfassen, vergleichen.

Schritt 8.5 · Entscheiden, ob es ausgeführt werden soll

Der Sweep kostet etwa 4–5 Minuten pro PR (zwei Builds plus zwei Screenshot-Durchläufe über 37 Routen × 2 Viewports). Überspringen Sie ihn nur, wenn die Änderung das Rendering nicht beeinflussen kann. Er ist überspringbar, wenn alle dieser Bedingungen zutreffen:

  • Der PR ist nur github-actions oder betrifft nur .github/**
  • Keine Datei unter src/, public/, astro.config.mjs oder package.json dependencies hat sich geändert
  • Der Diff beschränkt sich auf devDependencies, deren Ausgabe nie dist/ erreicht (eslint*, prettier, @types/*, typescript, wenn die Ratchet unverändert ist)

Alles andere — jeder astro, vite, @astrojs/*, preact, pagefind, MDX/rehype/remark, Schriftart- oder CSS-Tooling-Bump, und jeder npm Major — führt den Sweep aus. Im Zweifel ausführen; fünf Minuten sind billiger als eine stille visuelle Regression auf einer Live-Site.

Geben Sie explizit im Bericht an, welcher Zweig dieser Entscheidung getroffen wurde und warum.

Schritt 9 · Erfassen und vergleichen

Playwright ist keine Repository-Abhängigkeit; die Testumgebung treibt es von einem npx-Cache-Pfad an, der bereits in die Skripte eingebunden ist. Servieren Sie jeden Build mit einem einfachen statischen Server.

BASE_SHA=$(git merge-base origin/master HEAD)
mkdir -p ./tmp/parity

# --- Merge-Base ---
git checkout $BASE_SHA
npm ci
npm run build
cp dist/index.html ./tmp/parity/base-index.html    # Fingerabdruck dessen, was wir servieren
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

# --- PR-Head ---
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

# --- vergleichen, pro 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

Die stale-dist-Falle. Die Wiederverwendung von Port 4126 über zwei Builds hinweg ist der mit Abstand häufigste Weg, ein selbstbewusstes, bedeutungsloses Grün zu produzieren: Wenn der alte Server nicht wirklich gestorben ist oder dist nicht neu gebaut wurde, fotografiert der zweite Durchlauf den ersten Build und die Parität besteht, weil Sie einen Build mit sich selbst verglichen haben. Schützen Sie sich bei jedem Lauf:

  • Bestätigen Sie, dass der vorherige Server weg ist, bevor Sie den nächsten starten (lsof -i :4126 gibt nichts zurück).
  • Vergleichen Sie die beiden Fingerabdrücke — cmp ./tmp/parity/base-index.html ./tmp/parity/head-index.html, das für einen PR, der src/ oder eine Build-Pipeline-Abhängigkeit geändert hat, "identisch" zurückgibt, ist ein Signal, dem Lauf zu misstrauen, kein Ergebnis.
  • Wenn der Sweep-eigene JSON compared: 0 oder jede Route fehlt meldet, war der Server nicht aktiv; der Lauf ist ungültig, nicht bestanden.

verify:shots schreibt Dark-Theme-Ausgabe in out/<width>/. Wenn ein Bump plausibel das Light Theme anders beeinflusst (CSS-Tooling, Farbbehandlung, Token-Emission), wiederholen Sie den Sweep mit --theme light, das in out/light/<width>/ schreibt und den Dark-Tree nicht überschreiben kann.

Schritt 10 · Ergebnis interpretieren

verify-parity meldet zwei Zahlen pro Route, und beide sind wichtig

…

[gekürzt für die Übersetzung]

Verwandte Skills