#!/usr/bin/env python3 """pruefe_upstream_drift.py — Byte-Vergleich gegen die gepinnte Baseline. Schützt die übernommenen Framework-Dateien vor stillem Umschreiben (Entscheidung 8 im Design 2026-08-11, Frage von sorb: „wird die AGENTS.md ggf. durch Agenten umgeschrieben?"). Die Baseline liegt unter docs/sources/upstream/neckbeard-v0.1.1/ (siehe HERKUNFT.md dort); ein Framework-Upgrade aktualisiert Baseline und Arbeitskopie im selben, bewussten Commit. Prüfungen (Fehler, Exit 1): * byte-identische Paare laut PAARE * AGENTS.md beginnt byte-identisch mit der Baseline-AGENTS.md und trägt direkt danach die Marke des Projektabschnitts Fehlt eine Baseline-Datei, ist das ein Fehler, kein Skip (Stillstandsprüfungs-Regel: eine Prüfung ohne Gegenseite ist ungeprüft). Usage: python scripts/pruefe_upstream_drift.py [repo-root] """ from __future__ import annotations import sys from pathlib import Path BASELINE = "docs/sources/upstream/neckbeard-v0.1.1" MARKE = "" # (Arbeitskopie, Baseline-Datei) — byte-identisch PAARE = [ ("CLAUDE.md", "CLAUDE.md"), ("WORKFLOW.md", "WORKFLOW.md"), ("docs/adr/template.md", "templates/adr-template.md"), ("docs/design/template.md", "templates/design-template.md"), ("docs/aar/template.md", "templates/aar-template.md"), ("docs/issues/template.md", "templates/issue-template.md"), ] def main() -> int: root = Path(sys.argv[1]) if len(sys.argv) > 1 else Path.cwd() base = root / BASELINE fehler: list[str] = [] for arbeit, original in PAARE: a, b = root / arbeit, base / original if not b.is_file(): fehler.append(f"Baseline fehlt: {BASELINE}/{original}") continue if not a.is_file(): fehler.append(f"Arbeitskopie fehlt: {arbeit}") continue if a.read_bytes() != b.read_bytes(): fehler.append(f"DRIFT: {arbeit} weicht von {BASELINE}/{original} ab") agents, agents_base = root / "AGENTS.md", base / "AGENTS.md" if not agents_base.is_file(): fehler.append(f"Baseline fehlt: {BASELINE}/AGENTS.md") elif not agents.is_file(): fehler.append("Arbeitskopie fehlt: AGENTS.md") else: upstream = agents_base.read_bytes() arbeit = agents.read_bytes() if not arbeit.startswith(upstream): fehler.append("DRIFT: AGENTS.md — Upstream-Teil (§1–5) ist " "nicht mehr byte-identisch mit der Baseline") else: rest = arbeit[len(upstream):].decode("utf-8", "replace") if MARKE not in rest.splitlines()[0:3]: fehler.append(f"AGENTS.md: Marke '{MARKE}' fehlt direkt " "nach dem Upstream-Teil") for f in fehler: print(f"FEHLER {f}") print(f"pruefe_upstream_drift: {len(fehler)} Fehler") return 1 if fehler else 0 if __name__ == "__main__": sys.exit(main())