Umbau Stufe 1-5: Governor v2 + OpenCode-Plugin + Subagenten-Mannschaft

Die Intelligenz sitzt nicht mehr NEBEN dem Coden, sondern DRIN. Alles auf der
Box gemessen, nicht angenommen.

Stufe 1 — Speicher-Haushalt (llama-swap-Config, nicht im Repo):
  Coder dauerwarm statt ttl 600 (Kaltstart 23 s -> 491 ms), Devstral als
  'kritiker' verdrahtet, Swap 11 GB -> 0. Zwei Befunde: Kontext 131k->65k spart
  bei Qwen3-Next 0 GB (Hybrid-Attention), und llama-swap haelt nur EINE Gruppe
  resident -> alles Ko-Residente in dieselbe Gruppe. `persistent: true` verhindert
  dabei das Freiraeumen vor grossen Modellen -> ausgeloester Kernel-OOM, behoben
  durch persistent:false + TTLs (Vision laedt jetzt in 10 s statt 117 s + Absturz).

Stufe 2 — Governor v2 (deploy/governor/):
  Steht jetzt IM Pfad (:8100 -> MC2 :9001) statt daneben. Zaehlt den GANZEN
  Anfragekoerper inkl. tools/tool_calls und kalibriert sich aus den echten
  usage.prompt_tokens jeder Antwort nach: Schaetzfehler 200 % -> 0,3 %.
  Soft-Einschub nur noch, wenn die Nachrichtenkette es erlaubt (kein Dazwischen-
  funken in offene tool_calls). Neuer Status-Endpunkt + systemd-Unit.
  Lucys Alltagsmodelle sind vom Schnitt ausgenommen.

Stufe 3 — OpenCode-Plugin (deploy/opencode/plugin/mc2-governor.ts):
  Werkzeug-Zaun (git push, rm -rf, sudo, curl|sh — bewiesen), Pruef-Tor auf
  session.idle mit Selbstreparatur, Savepoint statt Kompression, Meldungen an
  Lucys Briefkasten mit eigenem Absender 'loop'.

Stufe 4 — Mannschaft (opencode.json):
  plan+build -> coder (51,5 t/s) · explore -> hermes (69,6 t/s, warm, gratis) ·
  review -> Devstral (15,0 t/s, FREMDE Modellfamilie gegen blinde Flecken).
  Der 63-GB-Planer faellt aus der Tagesrolle raus.

Stufe 5 — ein Regelwerk, zwei Ausloeser:
  deploy/opencode-lauf.sh faehrt dieselbe Bau-Pruef-Schleife unbeaufsichtigt
  (die Schleife liegt hier UND im Plugin: bei `opencode run` endet der Prozess,
  bevor session.idle fertig ist — gemessen). Bricht ab, wenn der Governor fehlt.
  gitea-repo-create.sh saet jetzt VERIFY neben der CI-Ampel: jedes neue Repo
  wird mit Innen- UND Aussen-Pruefung geboren.

Oberflaeche:
  Token-Waechter-Kachel im Cockpit (Fuellstand, Marken, Ehrlichkeits-Nachweis),
  /api/governor als gleichursprüngliches Fenster, Devstral im Modellkatalog,
  Rollen-Texte auf die neue Mannschaft aktualisiert.

.gitattributes: deploy/**/*.py auf LF (deploy/*.py greift nur eine Ebene tief).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-07-25 21:39:32 +02:00
parent 775e862652
commit 7fac17ed9a
43 changed files with 1542 additions and 610 deletions
+23 -12
View File
@@ -79,26 +79,37 @@ case "$CODE" in
# Vorlage oder scheitert der Seed, wird die Anlage NICHT abgebrochen, nur gewarnt.
# WICHTIG: Contents-API braucht write:repository → PUSH-Token nutzen (das
# dedizierte Anlage-Token hat u.U. nur write:user).
AMPEL="$REALHOME/mission-control-v2/deploy/ampel-ci.yml"
PUSHTOKEN="$(printf '%s' "$LINE" | sed -nE 's#https://[^:]+:([^@]+)@.*#\1#p')"; PUSHTOKEN="${PUSHTOKEN:-$TOKEN}"
if [ -r "$AMPEL" ]; then
SEED_CODE="$(curl -s -o /dev/null -w '%{http_code}' -X POST "$BASE/api/v1/repos/$FULL/contents/.gitea/workflows/ci.yml" \
# saat <lokale-vorlage> <pfad-im-repo> <commit-nachricht> <klartext-name>
saat () {
local QUELLE="$1" ZIEL="$2" MSG="$3" NAME="$4" CODE
if [ ! -r "$QUELLE" ]; then
echo "WARNUNG: Vorlage fehlt ($QUELLE) — Repo ohne $NAME angelegt." >&2
return
fi
CODE="$(curl -s -o /dev/null -w '%{http_code}' -X POST "$BASE/api/v1/repos/$FULL/contents/$ZIEL" \
-H "Authorization: token $PUSHTOKEN" -H "Content-Type: application/json" \
--data "$(python3 - "$AMPEL" <<'PY'
--data "$(python3 - "$QUELLE" "$MSG" <<'PY'
import base64, json, sys
inhalt = open(sys.argv[1], "rb").read()
print(json.dumps({"content": base64.b64encode(inhalt).decode(),
"message": "CI-Ampel (automatisch bei Repo-Anlage eingepflanzt)"}))
print(json.dumps({"content": base64.b64encode(inhalt).decode(), "message": sys.argv[2]}))
PY
)")"
if [ "$SEED_CODE" = "201" ]; then
echo "CI-Ampel eingepflanzt (.gitea/workflows/ci.yml)."
if [ "$CODE" = "201" ]; then
echo "$NAME eingepflanzt ($ZIEL)."
else
echo "WARNUNG: CI-Ampel-Seed antwortete HTTP $SEED_CODE (Repo ist trotzdem da)." >&2
echo "WARNUNG: $NAME-Seed antwortete HTTP $CODE (Repo ist trotzdem da)." >&2
fi
else
echo "WARNUNG: Ampel-Vorlage fehlt ($AMPEL) — Repo ohne CI-Ampel angelegt." >&2
fi
}
# JEDES neue Repo wird mit beiden Wächtern geboren:
# ci.yml = die AUSSEN-Prüfung (Gitea Actions nach dem Push, Wasserdicht-Runde 22.07.)
# VERIFY = die INNEN-Prüfung (das OpenCode-Plugin führt sie nach jeder Etappe aus und
# gibt rote Tests dem Agenten sofort zurück, statt sie erst der CI zu zeigen)
# Defensiv: scheitert ein Seed, wird die Anlage NICHT abgebrochen, nur gewarnt.
saat "$REALHOME/mission-control-v2/deploy/ampel-ci.yml" ".gitea/workflows/ci.yml" \
"CI-Ampel (automatisch bei Repo-Anlage eingepflanzt)" "CI-Ampel"
saat "$REALHOME/mission-control-v2/deploy/opencode/VERIFY.template" "VERIFY" \
"Pruef-Tor (automatisch bei Repo-Anlage eingepflanzt)" "Pruef-Tor"
echo "Repo '$FULL' angelegt (privat, main initialisiert)."
echo "CLONE ${CLONE}"
exit 0 ;;