Files
agent-swarm-repo/scripts/gate-ownership.sh
Tarik Moussa d7345e2cb7
Some checks failed
gates / quality (push) Has been cancelled
fix(gates): ownership-Parser bricht erst nach Tabellenbeginn ab
Eine Leerzeile oder Blockquote zwischen der 'Datei-Ownership'-Ueberschrift und
der Tabelle setzte den Parser zurueck -> Tabelle wurde nicht gefunden, Gate
faelschlich uebersprungen. Jetzt: f=0 erst, nachdem die Tabelle begonnen hat.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 06:57:52 +02:00

82 lines
2.9 KiB
Bash
Executable File

#!/usr/bin/env bash
# Ownership-Gate: kein Paket editiert Dateien eines anderen.
# Liest die Ownership-Tabelle aus STATE.md, mappt geaenderte Dateien (Branch vs.
# Basis) auf Pakete und FAILt bei Cross-Editing ueber >1 Paket-Grenze hinweg.
# Integration (Leader) ist ausgenommen: Branch main/master/integrate/*.
# Konvention: Verzeichnis-Pfade in der Tabelle mit Slash beenden (src/api/).
# Portabel gehalten (kein mapfile / keine assoziativen Arrays, laeuft auf bash 3.2).
set -uo pipefail
# Dormant solange das Template nicht initialisiert ist.
if grep -q '<id / datum>' STATE.md 2>/dev/null; then
echo "[ownership] Template noch nicht initialisiert — uebersprungen."
echo "GATE: PASS"; exit 0
fi
branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")
case "$branch" in
main|master|integrate/*)
echo "[ownership] '$branch' ist Integrations-Branch — uebersprungen."
echo "GATE: PASS"; exit 0 ;;
esac
# (pkg<TAB>prefix)-Zeilen aus der STATE.md-Ownership-Tabelle ziehen.
pairs=$(awk -F'|' '
/Datei-Ownership/{f=1; started=0; next}
f && started && $0 !~ /^\|/ {f=0} # erst NACH Tabellenbeginn abbrechen
f && /^\|/{
started=1;
pkg=$2; paths=$3;
gsub(/^[ \t]+|[ \t]+$/,"",pkg);
if(pkg=="" || pkg=="Paket" || pkg ~ /---/ || pkg ~ /…/ || pkg ~ /^_/) next;
n=split(paths, a, ",");
for(i=1;i<=n;i++){ p=a[i]; gsub(/^[ \t]+|[ \t]+$/,"",p); gsub(/`/,"",p);
if(p=="" || p ~ /…/ || p ~ /^_/) continue;
print pkg "\t" p }
}' STATE.md 2>/dev/null)
if [ -z "$pairs" ]; then
echo "[ownership] keine befuellte Ownership-Tabelle in STATE.md — uebersprungen."
echo "GATE: PASS"; exit 0
fi
base=$(git merge-base HEAD main 2>/dev/null || git rev-parse HEAD~1 2>/dev/null || true)
[ -n "$base" ] || { echo "[ownership] keine Diff-Basis — uebersprungen."; echo "GATE: PASS"; exit 0; }
changed=$(git diff --name-only "$base"...HEAD 2>/dev/null)
[ -n "$changed" ] || { echo "[ownership] keine Aenderungen — uebersprungen."; echo "GATE: PASS"; exit 0; }
hit=""; unowned=""
while IFS= read -r f; do
[ -n "$f" ] || continue
bestpre=""; bestpkg=""
while IFS=" " read -r pkg pre; do
[ -n "$pre" ] || continue
case "$f" in
"$pre"|"$pre"*)
if [ "${#pre}" -gt "${#bestpre}" ]; then bestpre="$pre"; bestpkg="$pkg"; fi ;;
esac
done <<EOF
$pairs
EOF
if [ -n "$bestpkg" ]; then
hit="$hit$bestpkg
"
else
unowned="$unowned $f"
fi
done <<EOF
$changed
EOF
distinct=$(printf '%s' "$hit" | sed '/^$/d' | sort -u)
n=$(printf '%s' "$distinct" | sed '/^$/d' | grep -c . || true)
echo "[ownership] Branch '$branch' beruehrt $n Paket(e): $(printf '%s ' $distinct)"
[ -n "$unowned" ] && echo "[ownership] Hinweis: ohne Owner in STATE.md:$unowned"
if [ "${n:-0}" -gt 1 ]; then
echo " - FAIL: Aenderungen ueber mehrere Ownership-Grenzen (Cross-Editing)."
echo " Worker editieren nur ihr Paket; Integration macht der Leader (Branch integrate/*)."
echo "GATE: FAIL"; exit 1
fi
echo "GATE: PASS"