hermes-erkenntnisse/burst-compute/w44-dispatcher-step4-2026-07-23.md

4 KiB

W44 Burst-Compute: Auto-Burst-Dispatcher, Schritt 4 (2026-07-23)

Datei: /opt/gpu1-status/app.py. Default AUS -- Toggle wurde NICHT live scharf geschaltet, Bär bestaetigt Live-Aktivierung separat.

Gebaut (Design von Koordinator/Baer 2026-07-23 freigegeben)

  • State: /opt/gpu1-status/auto_burst_state.json (existiert noch nicht -> Defaults greifen: enabled=False, idle_timeout_min=30, monster_desired=off, shadow_desired=off)
  • Endpoints (alle auth-gated):
    • GET /api/burst/dispatcher/status -- aktueller State
    • POST /api/burst/dispatcher/toggle -- {enabled, idle_timeout_min} setzen (Portal-Toggle in Schritt 5 nutzt das)
    • POST /api/burst/dispatcher/touch -- Idle-Timer resetten (bei jedem neuen Burst-Job aufzurufen)
    • POST /api/burst/dispatcher/ensure/{monster|shadow} -- bewusster Boot, setzt desired=on, liefert 409 wenn enabled=False (zusaetzliche Sicherheitsbremse -- kein automatischer Boot ohne aktives Auto-Burst)
    • POST /api/burst/dispatcher/tick -- die eigentliche Teardown-Entscheidung, optional {dry_run:true}

Sicherheitsmechanik (mehrfach abgesichert)

  1. real_run = enabled AND NOT dry_run -- solange enabled=False (Default) ist real_run IMMER False, unabhaengig vom dry_run-Parameter -- der Toggle ist die einzige Tuer.
  2. Monster-Ollama-Guard: _monster_ollama_busy() fragt http://100.120.234.106:11434/api/ps (Ollama "geladene Modelle"-Liste) ab. Ist die Liste nicht leer -> skip_ollama_busy, kein Powerdown, Dispatcher pollt beim naechsten Tick einfach weiter.
  3. GPU-Shadow-Stop nutzt den bestehenden token-sicheren Weg (_jump_shadow_call("shadow.php","stop","POST") -> monster-api /monster/shadow/stop -> WinRM-Hibernate im Gast-OS, ruehrt gpu-token.json nicht an) -- kein neuer Stop-Mechanismus gebaut, nur der vorhandene wiederverwendet.
  4. desired-Flag-Disziplin: monster_desired/shadow_desired werden NUR von ensure() auf "on" gesetzt (bewusster Dispatcher-Boot) und von tick() nach erfolgreichem Teardown wieder auf "off". Der bestehende gpu-shadow-watchdog.timer (alle 2min, bootet nach wenn desired=on) bleibt dadurch korrekt inaktiv, solange der Dispatcher nichts gebucht hat.
  5. Orchester-Mode-Monster-Wake wird NICHT unterdrueckt -- dieser Dispatcher greift nur in monster_desired/shadow_desired-Zustand ein, den ausschliesslich er selbst setzt. Ein Orchester-Start, der Monster ueber monster-lifecycle.sh amt-start weckt, aendert diese Dispatcher-eigenen Felder nicht -- keine Kollision, kein Unterdruecken einer fremden, autorisierten Nutzung.

Trockentest (echt, ohne echten Powerdown) waehrend GO-Nachricht ausgefuehrt

  • _monster_ollama_busy()-Logik live gegen Monster getestet: GET http://100.120.234.106:11434/api/ps -> models: [] -> busy=False (Ollama-Dienst laeuft, aber aktuell kein Modell geladen -- Guard unterscheidet das korrekt).
  • GPU-Shadow-Status live gepruefte Baseline: vm_online:false, desired:"off", token_valid:true (Token unberuehrt, obwohl VM bereits laenger offline ist -- bestaetigt die Entkopplung Token/VM-Power, die die Teardown-Logik voraussetzt).
  • Kein echter tick()-Realrun ausgefuehrt (haette wegen enabled=False ohnehin real_run=False erzwungen) -- Entscheidungslogik stattdessen durch Nachvollzug der einzelnen Bausteine (Ollama-Guard, Shadow-Status/Token) gegen die echte Infrastruktur verifiziert.

Ablauf (Portal-Skill)

  1. Fresh-Read+Backup: app.py.bak-w44-step4-20260723_183719, md5 identisch mit Live-Stand
  2. Unique-String-Replace (1 Anker, assert count==1)
  3. py_compile OK
  4. Testinstanz :9092: /=200, /api/burst/dispatcher/status=401 -- gestoppt
  5. systemctl restart -- PID-Gegenprobe: alte PID 203542 -> neue PID 207132 (Start 18:39:58, nach Edit), diesmal ohne Gateway-Fehler
  6. Live: :9090/=200, :9090/api/burst/dispatcher/status=401, cp.go-ki.eu=200
  7. auto_burst_state.json existiert nach diesem Schritt weiterhin NICHT -> Default enabled=False aktiv, kein Live-Scharfschalten erfolgt