audit – der vierteljährliche Crawl
analysis sieht das Repository; audit sieht, was ein Besucher und ein Crawler sehen: das Live-HTML, die echten Statuscodes, die Weiterleitungen, die Sitemap wie ausgeliefert. Alles, was es findet, wird entweder zu einem Backlog-Eintrag, den der fix-Skill mechanisch ausführen kann, oder zu einer Zeile in der Besitzerliste für Dinge, die kein Skill anfassen sollte (Navigation, Layouts, Preis- und rechtliche Seiten, Hosting). Es bearbeitet nie einen Artikel und eröffnet nie einen PR.
Skripte: ${CLAUDE_PLUGIN_ROOT}/scripts/{crawl,inventory,sitecheck}.js. Set P=${CLAUDE_PLUGIN_ROOT}.
Argumente: --origin <url> (Standard: https://<domain> aus seo/brand.json, sonst der Host der Preview-Zeile), --max <n> Seiten (500), --external <n> externe Links zum Prüfen (200), --cwv (PageSpeed Insights für die Startseite und Cluster-Hubs abfragen; benötigt Netzwerk zu googleapis.com, PAGESPEED_API_KEY optional), --no-items (nur Bericht, nichts in das Backlog schreiben), --dry-run (crawlen und berichten, nichts committen).
0. Voraussetzungen
Product-Repo-Root; git status --porcelain leer; auf dem Standard-Branch; seo/strategy.md und der Block ## SEO agent existieren. Zuerst node $P/scripts/inventory.js --root ., damit der Crawl Pfade zu Dateien und Arten zuordnen kann. Kein gh erforderlich.
1. Crawl
PREV=$(ls seo/data/crawl/*.json 2>/dev/null | sort | tail -1)
node $P/scripts/crawl.js --root . --origin <origin> --max <n> --external <n> [--cwv] --save seo/data/crawl ${PREV:+--diff $PREV} --quiet
Das JSON lesen: summary (Seiten, Funde nach Code, truncated), findings[] (code, severity fix|report, path, file, msg, to), sitemap (count, error, missing), external[], cwv[], diff (new, resolved seit dem vorherigen Audit). Ein error-Schlüssel auf oberster Ebene oder sitemap.error → dies sagen und anhalten; eine Website, die down ist, ist das Problem des Besitzers, kein Backlog-Eintrag. truncated: true → sagen, dass der Crawl --max erreicht hat und welche Pfade noch in der Warteschlange waren.
Dann auch node $P/scripts/sitecheck.js --root .: Es sieht die Quelle (Blade-Argumente, Routen, Frames), die das Live-HTML verbirgt, und die beiden zusammen ergeben das vollständige Bild.
2. Triage
Drei Buckets (Eimer), in dieser Reihenfolge:
fix-Einträge — Funde mitseverity: fix(Codestitle,description,canonical,alt,link,sitemap) auf einer Seite, deren Inventareintrag einefileder Art guide, article oder tool hat. Ein Eintrag pro Seite, genau wie inanalysis§1c beschrieben, mit zwei Unterschieden:- evidence: audit <date>: <n> findingsund jedefixes:-Zeile endet mit(audit <date>), damitfixweiß, dass es gegen die Live-Site bestätigen soll, nicht gegen sitecheck:
Eine Seite, die bereits einen offenen/beanspruchten/in-Review### [B-nnn] fix: <path> - type: fix - target: <path> - score: <n> (potential <p> × ease 10 × fit <f>) ← potential 3, oder der gsc_potential der Seite aus dem letzten seo/data/gsc-Snapshot; fit aus der Cluster-Priorität - evidence: audit <date>: <n> findings - status: open - fixes: link: internal link /old-path redirects to /new-path: link the final URL (audit <date>) description: no meta description (audit <date>)fix-Eintrag hat → die neuenfixes:-Zeilen anhängen (Zeilen überspringen, die bereits nach Code +tovorhanden sind). Eine Seite, die von einem offenenrefresh-Eintrag besessen wird →owned by B-nnn, kein Fix-Eintrag. Ein Fund, den auch sitecheck meldet (gleiche Seite, gleicher Code), wird einmal aufgeführt, aus dem Audit, mit dem Tag(audit <date>).link-Einträge —orphan-Funde auf Artikelseiten: einlink-Eintrag pro Cluster ($P/skills/analysis/SKILL.md§1c-Format,- links:-Zeilen/hub → /orphan (orphan, audit <date>)); ein Cluster mit einem offenenlink-Eintrag erhält die Paare angehängt. Orphans ohne Cluster (kein Hub passt) gehen in die Besitzerliste.- Besitzerliste — alles andere:
broken-external,redirect-chain,duplicate-title/duplicate-description,noindex-in-sitemap,sitemap-404,thin,h1,mixed-content,slow,server-error, jeder Fund auf einer Nicht-Artikel-Seite (Startseite, Preise, Rechtliches, Layouts),sitemap.missingund die CWV-Zeilen. Nach Code gruppieren, die schlimmsten zuerst, ≤ 3 Beispielpfade pro Code; die Datei nennen, wenn das Inventar sie kennt.thinauf einem Artikel ist ein Refresh-Signal, kein Fix: dies sagen und esanalysisüberlassen.
--no-items → nur Bucket 3, mit einer Zählung der sonstigen Einträge.
3. Commit
Außer bei --dry-run: git add seo/data/crawl/<date>.json seo/backlog.md und seo: audit <date> — <pages> pages, <findings> findings, <k> fix items, <m> link items auf dem Standard-Branch committen (Planungsdateien direkt committen); pushen, wenn der Branch einen Upstream hat. Kein PR.
4. Bericht (≤ 15 Zeilen)
audit <date>: <pages> pages crawled (<html> html, <truncated?>), <findings> findings (<fixable> fixable); Sitemap<count>URLs,<missing>fehlend oder fehlerhaft- Funde nach Code, eine Zeile, Anzahl
- Diff vs.
<previous>:<new>neu,<resolved>gelöst (die neuen benennen, wenn ≤ 5) - Einträge:
fix-IDs mit Pfaden;link-IDs mit Clustern;owned by/already open-Notizen - Besitzerliste: ≤ 8 Zeilen, die schlimmsten zuerst (ein 5xx oder eine Redirect-Kette in der Navigation vor einer langen Beschreibung)
- CWV-Tabelle bei
--cwv: Pfad, LCP, CLS, INP, perf, Quelle - Als nächstes:
fixführt die Einträge am Freitag aus (oder/seo-agent:fixjetzt); das nächste Audit ist in 3 Monaten fällig
Harte Regeln
- Schreibgeschützt auf der Website: GET/HEAD mit dem User-Agent
seo-agent-audit, eine Herkunft,--maxSeiten,--delayzwischen Anfragen; niemals Formulare absenden, niemals einloggen, niemals einen anderen Host crawlen - Niemals Artikel, Layouts oder die Sitemap bearbeiten; niemals einen PR eröffnen; schreibt nur in
seo/data/crawl/undseo/backlog.md - Backlog-Einträge nur für Artikelseiten, die der
fix-Skill bearbeiten darf; alles andere ist Sache des Besitzers - Deterministisch: Die Funde stammen von
crawl.js; kein Fund wird durch manuelles Lesen von HTML hinzugefügt thinist niemals ein Fix-Eintrag