Faden 5: Box-Selbstwissen mechanisch in jeden Kanban-Worker (pre_llm_call-Hook)

Fallstrick #1 behoben: Ops-/Mess-/Verify-Aufgaben landen oft auf `default`
(= Lucys Persona, "nicht technisch, keine Pfade/Versionen") und flailen, weil
sie llama-swap :8080 & Co. nicht kennen. Nur `werkstatt` hatte Box-Wissen.

deploy/agent-hooks/box-steckbrief-inject.sh (neu): pre_llm_call-Hook, haengt
eine kompakte Box-Orientierung ephemer an die User-Message JEDES Kanban-Workers
(egal welches Profil) — aber NUR wenn eine task_id gesetzt ist. Lucys
interaktiver/Voice-Chat hat keine task_id -> sofortiger No-op (7 ms gemessen),
kein Persona- oder Latenz-Eingriff. Inhalt: Identitaet + Modell-Endpunkte
(llama-swap :8080, MC2 :9001/v1, gateway :8642, mem0 :8765) + Tabu-Live-Checkout
+ Zeiger auf den vollen Selbst-Steckbrief und docs/wissen. = der "via Hook/
Wrapper/Guard"-Weg aus der Fallstrick-Karte (Dispatcher-Spawn ist Hermes-intern).

deploy/agent-hooks/pre-verify-gates.sh: der bestehende py_compile/dist-Gate-Hook,
bisher nur manuell auf der Box -> jetzt verbatim im Repo getrackt (ueberlebt
Box-Neuaufbau, schliesst eine Autonomie-Luecke).

deploy.sh synct beide nach ~/.hermes/agent-hooks/ (+chmod). Die Registrierung
in ~/.hermes/config.yaml (hooks: pre_llm_call) bleibt einmalig von Hand
(config.yaml ist Zwei-Schreiber-sensibel).

Verifiziert: Hook-Logik auf der Box gegen synthetische Payloads (Worker ->
987-Zeichen-Kontext injiziert, Lucy/leer -> {}, JSON valide), bash -n + LF sauber.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-07-13 21:10:34 +02:00
parent e5f546a72f
commit c81523c0f4
3 changed files with 91 additions and 0 deletions
+52
View File
@@ -0,0 +1,52 @@
#!/usr/bin/env bash
# pre_verify-Gate (P1-5, 09.07.2026): erinnert den Agenten VOR dem Fertigmelden an
# die zwei MC2-Pflichten aus AGENTS.md — py_compile-Gate und die dist-Falle.
# Antwort {"action":"continue","message":...} = Agent arbeitet weiter; {} = durchlassen.
set -u
payload="$(cat -)"
attempt=$(printf %s "$payload" | jq -r '.extra.attempt // 0' 2>/dev/null || echo 0)
# Ein-Schuss: nach dem ersten Nudge nicht erneut nerven (Docs-Empfehlung).
if [ "$attempt" != "0" ]; then printf '{}'; exit 0; fi
mapfile -t paths < <(printf %s "$payload" | jq -r '.extra.changed_paths[]? // empty' 2>/dev/null)
[ ${#paths[@]} -eq 0 ] && { printf '{}'; exit 0; }
msgs=()
# Gate 1: py_compile fuer alle geaenderten .py, die existieren
pyfail=""
for p in "${paths[@]}"; do
case "$p" in
*.py)
if [ -f "$p" ] && ! err=$(python3 -m py_compile "$p" 2>&1); then
pyfail="${pyfail}${p}: ${err}"$'\n'
fi
;;
esac
done
if [ -n "$pyfail" ]; then
msgs+=("py_compile-Gate ROT:"$'\n'"${pyfail}Erst fixen, dann fertigmelden.")
fi
# Gate 2: dist-Falle — frontend/src geaendert, aber kein frontend/dist angefasst.
# Feuert NUR in Repos mit der MC2-Konvention (frontend/dist ist git-getrackt) —
# sonst nudgt es in beliebigen Spielordnern ohne Build (False-Positive, 09.07. beobachtet).
srcfile=""; dist=0
for p in "${paths[@]}"; do
case "$p" in
*/frontend/src/*|frontend/src/*) srcfile="$p" ;;
*/frontend/dist/*|frontend/dist/*) dist=1 ;;
esac
done
if [ -n "$srcfile" ] && [ $dist -eq 0 ]; then
# Repo-Wurzel vom geaenderten File aus hochlaufen (max 8 Ebenen).
root=$(dirname "$srcfile"); n=0
while [ $n -lt 8 ] && [ -n "$root" ] && [ "$root" != "/" ] && [ ! -e "$root/.git" ]; do
root=$(dirname "$root"); n=$((n+1))
done
if [ -e "$root/.git" ] && git -C "$root" ls-files frontend/dist 2>/dev/null | head -1 | grep -q .; then
msgs+=("AGENTS.md-Gate: Du hast frontend/src geaendert, aber frontend/dist nicht. Die Box baut NICHT selbst: cd frontend && npm run build, dann das neue dist im selben Branch mit-committen — sonst zeigt die Box nach Merge+Deploy den alten Stand.")
fi
fi
if [ ${#msgs[@]} -eq 0 ]; then printf '{}'; exit 0; fi
joined=$(printf '%s\n\n' "${msgs[@]}")
jq --null-input --arg m "$joined" '{action:"continue", message:$m}'