#!/usr/bin/env bash # Doku-Drift-Gate: prueft Manifest-Referenzen + STATE-Aktualitaet + Doc-Budget. set -uo pipefail fail=0; man="manifests/requirements.md" # Dormant solange das Template nicht initialisiert ist (scripts/init.sh). if grep -q '' STATE.md 2>/dev/null; then echo "[drift] Template noch nicht initialisiert (scripts/init.sh) — uebersprungen." echo "GATE: PASS"; exit 0 fi echo "[drift] pruefe im Manifest referenzierte Pfade (nur done/in_progress/drift)..." # Nur Pfade aus ERLEDIGTEN Zeilen muessen existieren — 'todo'-Zeilen sind Plan, # ihre Dateien gibt es absichtlich noch nicht. Treffer in eine Datei sammeln, # damit fail=1 nicht in einer Pipe-Subshell verloren geht. miss=$(mktemp) if [ -f "$man" ]; then while IFS= read -r line; do case "$line" in \|*) : ;; *) continue ;; esac # nur Tabellenzeilen status=$(printf '%s' "$line" | sed 's/^|//; s/|[[:space:]]*$//' \ | awk -F'|' '{print $NF}' | tr -d ' ' | tr 'A-Z' 'a-z') case "$status" in done|in_progress|drift) : ;; *) continue ;; esac while IFS= read -r tok; do case "$tok" in *" "*|*…*|_*|*path/to*) continue ;; esac case "$tok" in */*|*.py|*.md|*.sh|*.js|*.ts|*.yml|*.yaml|*.json|*.conf|*.ini|*.txt) [ -e "$tok" ] || echo "$status $tok" >> "$miss" ;; esac done < <(printf '%s\n' "$line" | grep -oE '`[^`]+`' | tr -d '`') done < "$man" fi if [ -s "$miss" ]; then while IFS=" " read -r st p; do echo " - fehlende Referenz (Status $st): $p"; done < "$miss" fail=1 fi rm -f "$miss" echo "[drift] STATE.md Stale-Check (Commits seit letzter Aenderung)..." last_state=$(git log -1 --format=%H -- STATE.md 2>/dev/null || true) if [ -n "$last_state" ]; then since=$(git rev-list --count "${last_state}..HEAD" 2>/dev/null || echo 0) [ "${since:-0}" -le 3 ] || { echo " - STATE.md seit $since Commits unveraendert"; fail=1; } fi echo "[drift] Doc-Groessenbudget (Faustregel < 200 Zeilen)..." while read -r f; do case "$f" in examples/*) continue ;; esac # Beispiele duerfen laenger sein n=$(wc -l < "$f" 2>/dev/null || echo 0) [ "$n" -le 200 ] || echo " - Hinweis: $f hat $n Zeilen (> 200, Drift-Risiko)." done < <(git ls-files 2>/dev/null | grep '\.md$' || true) echo "[drift] Code ohne Doc-Aenderung im letzten Commit?" files=$(git show --name-only --pretty= HEAD 2>/dev/null || true) if echo "$files" | grep -qE '\.(py|sh|js|ts)$' && ! echo "$files" | grep -qE '\.md$'; then echo " - Hinweis: Code geaendert, keine Doku angepasst (Drift-Verdacht)." fi [ "$fail" -eq 0 ] && echo "GATE: PASS" || { echo "GATE: FAIL"; exit 1; }