# Automatik der Box: Hermes-Jobs und Timer _Stand 24.09.2026 (erster Stand: KISS-Umbau 21.08.2026)._ Bis zum 20.08. liefen 4 Hermes-Crons und 6 systemd-Timer nebeneinander; dass ein Wächter fehlte, fiel tagelang niemandem auf, weil niemand an zwei Orten nachsah. Seitdem gibt es wenige, klar getrennte Jobs, und die Startseite des Box-Warts zeigt Hermes-Jobs und Timer zusammen im **Flugplan**. ## Was läuft | Job | Wann | Mechanismus | Skript | Meldet | |---|---|---|---|---| | **Daily News Report** | täglich 07:00 | Hermes-Cron, Agent mit Websuche | `news-melden.sh` | Text und Sprachnachricht | | **KI und Stack Radar** | samstags 08:00 | Hermes-Cron, `--no-agent` | `stack-radar.sh` → `stack-ist.sh`, `stack-upstream.py` | immer, Betreff `[Stack-Radar]` | | **Updates am Sonntag** | sonntags 04:30 (+≤10 min) | systemd-Timer `mc2-autoupdate.timer` | `sonntags-update.sh` → `deploy/autoupdate.sh` | `[Box-Update]` | | Modell-Radar | täglich 00:30, Test bis 02:30 | systemd-Timer `mc2-radar.timer` | `backend/radar_lauf.py` | nur „bestanden" (`[Modell-Radar]`) | | Sicherung | täglich 03:30 (+≤5 min) | systemd-Timer `mc2-backup.timer` | `deploy/backup.sh` | nein; einen Fehlschlag meldet der Wächter | | Morgenmeldung | täglich 07:00 | systemd-Timer `mc2-morgenmeldung.timer` | `deploy/morgenmeldung.sh` | die Sammelmeldung der Nacht | | projekte-sync | stündlich | systemd-Timer `projekte-sync.timer` | `deploy/projekte-sync.sh` | nein | | NerdQuiz-Nachtlauf | ~03:00 | extern: NerdQuiz auf Arcane fragt das Hirn direkt über llama-swap (`:8080`) | – | – | - **Updates laufen seit 24.09. wieder per Timer.** Der Hermes-Cron „Updates am Sonntag" ist pausiert: Als Kind des Hermes-Gateways hing der Updater am eigenen Neustart, wenn er Hermes aktualisierte (20.09.: 180 s, Fehlschlag). - **Das Modell-Radar endet um 02:30,** weil der NerdQuiz-Nachtlauf um 03:00 das Hirn braucht. Den Nachtlauf erkennt der Flugplan an den nächtlichen Anfragen (Modell-Nutzung aus dem Journal von llama-swap). - Übersicht auf der Box: `bash -lc 'hermes cron list'` (Hermes-Jobs), `systemctl --user list-timers` (Timer). ## Der Entwurfsgrundsatz > **Fakten sammelt ein Skript, Prosa schreibt das Modell.** Der alte Selbsttest war am 20.08. grün, während vier Dinge kaputt waren: Das Kritiker-Gate zeigte seit einem Tag auf ein umbenanntes Modell (404), Lucys `SOUL.md` war blockiert, das Dashboard stand ohne Passwort offen, die CI war rot. Er hatte geprüft, ob Dienste **antworten**, nicht, ob sie **stimmen**. `stack-ist.sh` prüft deshalb Ergebnisse: Lösen die Rollen-Aliase noch auf? Ist der letzte Timer-Lauf gutgegangen? Ist eine Sicherung jünger als zwei Tage? `stack-upstream.py` vergleicht Neuigkeiten draußen (Releases, gemergte PRs, neue Entwurfsmodelle) mit dem letzten Lauf. ## Kugelsicher heißt konkret - **Das Modell steht nicht im kritischen Pfad.** Antwortet es nicht, gehen die Rohbefunde trotzdem raus; nur die Prosa fällt weg, nie die Meldung. - **Es meldet immer.** „Alles grün" ist ein Ergebnis, kein Grund zu schweigen. - **Kein `set -e`.** Ein einzelner fehlschlagender Test darf den Bericht nicht abschneiden. - **Ein Meldeweg:** `deploy/notify.sh` erreicht Telegram **und** Lucys Briefkasten in einem Aufruf; scheitert `hermes send`, geht es direkt an die Telegram-Bot-API. Nachts (00:00–06:59) sammelt es bis zur Morgenmeldung um 07:00, Dringendes geht sofort. Die Hermes-Jobs laufen mit `--deliver local`, damit Hermes nicht ein zweites Mal sendet. - **Kein Füllmaterial.** Die Prompts verbieten ausgedachte Vorschläge: Ein Bericht mit Füllmaterial wird nicht gelesen, und dann auch der echte Befund nicht. - **Werkzeuge der Cron-Jobs:** `platform_toolsets.cron` = `[web, terminal]`; mehr braucht der Nachrichtenbericht nicht. ## Ausbringen Die Skripte müssen unter `~/.hermes/scripts/` liegen (Vorgabe von `hermes cron --script`). Das macht seit 24.09. `deploy/deploy.sh` (Stufe 2): Es installiert `deploy/jobs/*.sh` und `deploy/jobs/*.py` aus dem Box-Checkout nach `~/.hermes/scripts/`, ausführbar und mit LF-Zeilenenden. Kopieren per `scp` von Hand entfällt. Alte Skripte in `~/.hermes/scripts/` räumt der Deploy nicht weg. ## Daily News: Text und Stimme - **Persona statt Stilvorgaben:** Der Job-Prompt bleibt kurz. Emojis, Ton und die Anrede „Commander" kommen aus `~/.hermes/SOUL.md`. Wer im Prompt Stil verbietet, überstimmt die Persona (21.08. so passiert). - **Ablauf:** Der Agent schreibt zwei Dateien, `/tmp/news-text.md` (mit Emojis, Links, Formatierung) und `/tmp/news-sprich.txt` (3–4 Sätze zum Vorlesen), und ruft einmal `news-melden.sh` auf. Das Skript schickt den Text über `notify.sh`, räumt den Bericht weg und startet die Stimme abgekoppelt: `lucy-stimme` (`:8021`, pocket-tts `german_24l`) → WAV → OGG/Opus mit ffmpeg → `hermes send --to telegram "MEDIA:…"` (eine echte Sprachnachricht). - **Sofort zurück:** Hermes' `terminal`-Werkzeug bricht nach 30 s ab. Das Skript kehrt deshalb sofort zurück und sperrt denselben Bericht 2 Stunden gegen Doppelversand (22.08.: der Text kam einmal doppelt). - **Aufräumen:** Hermes' `write_file` überschreibt keine vorhandene Datei. Bliebe der Bericht vom Vortag liegen, scheiterte der nächste Lauf (23.09.). - **Nicht `voice-service` (`:8650`) nehmen:** Dort sind nur Cloud-Stimmen geladen, nicht Lucy. - Fällt die Stimme aus, geht der Text trotzdem raus. ## Kugelsicher-Regeln für Hermes-Crons - `hermes cron edit "text"` speichert nichts; der Prompt muss über `--prompt` kommen. Nach jeder Änderung in `~/.hermes/cron/jobs.json` nachsehen. - Alte Job-Fassungen liegen in jeder Sicherung: `tar -xzf /srv/models/mc2-backups/mc2-state-*.tar.gz ./hermes/cron/jobs.json`. - Tagesaktualität muss man erzwingen: Datum per `date` feststellen lassen, mehrere Suchen verlangen, Meldungen ohne belegbares Datum verwerfen. - Wer einen Werkzeugsatz abschaltet, muss `SOUL.md` mitlesen: Dort standen am 21.08. noch Anweisungen auf abgeschaltete Werkzeuge. ## Abgeschaltet am 21.08. (KISS-Umbau) | Weg | Warum | |---|---| | Cron `morgen-digest` | ging im Daily News Report auf | | Cron `tech-radar` | ging im Stack-Radar auf | | Cron `nacht-wartung` | prüfte Lebenszeichen, nicht Ergebnisse | | Cron `wissens-sync` | war nie gelaufen (kein `last_run_at`) | | Timer `mc2-bagatell` | 15 Nächte hintereinander „0 eingespielt" | | Timer `mc2-selfsmoke` | ging in `stack-ist.sh` auf | | Timer `pbs-backup` | doppelt zu `mc2-backup` und seit 21.08. rot (sein Quellordner fiel mit dem alten Gedächtnis-Dienst weg) | | Timer `mc2-autoupdate` | vom 21.08. bis 24.09. startete der Cron „Updates am Sonntag" das Update; seit 24.09. wieder der Timer | Die Unit-Dateien der abgeschalteten Timer liegen auf der Box noch (disabled), im Repo nicht mehr; `mc2-autoupdate` läuft wieder und liegt im Repo. Die Morgenmeldung um 07:00 (`mc2-morgenmeldung.timer`, seit 24.09.) ersetzt den alten Morgen-Digest nicht inhaltlich: Sie liefert nur die nachts gesammelten Meldungen aus.