Initial: Mesh-Skills, Configs, Scripts
This commit is contained in:
@@ -0,0 +1,348 @@
|
||||
---
|
||||
name: mesh-master-control
|
||||
description: "Use when: Master steuert Modell/Budget/Notfall im Mesh."
|
||||
version: 1.0.0
|
||||
platforms: [linux]
|
||||
related_skills: [model-allocation, multi-agent-mesh, openrouter-cost-budgeting]
|
||||
---
|
||||
|
||||
# Mesh-Master-Control — SSH + Modell-Scout + Kill-Switch
|
||||
|
||||
## Prinzip
|
||||
|
||||
Der Master (VPSHermes, 172.24.196.119) bestimmt im Mesh **alles** was Modell, Budget und Notfall-Steuerung angeht. Der Nutzer soll nicht 24/7 aufpassen müssen — der Master handelt autonom bei Kosten-Explosion, Modell-Ausfall oder Budget-Knappheit.
|
||||
|
||||
**Kernregel (Nutzervorgabe, August 2026, hart):** SSH-Kanal vom Master zu allen Sub-Agenten MUSS funktionieren. NFS-Tasks sind zu langsam für Notfälle. WENN SSH fehlt → SOFORT fixen (Key generieren + an Sub-Agenten pushen), NICHT stillschweigend mit NFS weiterwursteln.
|
||||
|
||||
## 1. SSH-Control-Kanal
|
||||
|
||||
### SSH-Key auf Master generieren
|
||||
|
||||
```bash
|
||||
ssh-keygen -t ed25519 -f /root/.ssh/id_ed25519 -N "" -C "mesh-master@172.24.196.119"
|
||||
```
|
||||
|
||||
### Public-Key an Sub-Agenten verteilen (AcceptMasterKey-Task)
|
||||
|
||||
Datei in `/srv/work/tasks/offen/YYYYMMDD.C.D.AcceptMasterKey.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"task_id": "YYYYMMDD.C.D.AcceptMasterKey",
|
||||
"ziel_agent": "<Agent-Name>",
|
||||
"aufgabentyp": "config",
|
||||
"prioritaet": "high",
|
||||
"beschreibung": "AcceptMasterKey",
|
||||
"aufgabe_details": {
|
||||
"master_pubkey": "<public-key-inhalt>",
|
||||
"schritte": [
|
||||
"mkdir -p ~/.ssh && chmod 700 ~/.ssh",
|
||||
"echo '<pubkey>' >> ~/.ssh/authorized_keys",
|
||||
"chmod 600 ~/.ssh/authorized_keys"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Dateiname-Schema:** `YYYYMMDD.C.D.AcceptMasterKey.json` (C.D = letzte 2 ZT-IP-Oktette)
|
||||
|
||||
## 2. Model Scout (alle 3 Tage)
|
||||
|
||||
**Script:** `/usr/local/bin/mesh-model-scout.py` (Python, 26 KB, vollstaendig autonom)
|
||||
**Cron:** `0 6 */3 * * /usr/local/bin/mesh-model-scout.py >> /var/log/mesh-model-scout.log 2>&1`
|
||||
**Bekannte Modelle (Hardcoded in Script):** 25+ Modelle aus DeepSeek, Llama, Gemini, Qwen, Mistral, Nvidia, MiniMax, Cohere — mit Bewertungen in 5 Dimensionen.
|
||||
**Cache:** OpenRouter-API-Cache unter `/tmp/openrouter_models.json` (1h-Gueltigkeit)
|
||||
|
||||
### Ablauf
|
||||
|
||||
1. **OpenRouter-API live abrufen** (GET /api/v1/models, 300+ Modelle) oder aus Cache
|
||||
2. **Filtern** auf ≥64k Kontext + gültige Preise + bekanntes Modell
|
||||
3. **Bewerten** in 5 Dimensionen (1–5): Coding, Reasoning, Linux/Ops, Docs/Text, Tool-Use
|
||||
4. **Agenten-Matching** nach Rollenprofil
|
||||
5. **Budget-Simulation** (Token × Preis = Tageskosten × 30 = Monat)
|
||||
6. **Aenderungserkennung** (Vergleich mit `model_scout_last.json`)
|
||||
7. **Ausgabe:** JSON + HTML-Doku + Tasks an Sub-Agenten
|
||||
8. **Telegram-Benachrichtigung** mit Zusammenfassung
|
||||
|
||||
### Rollen-Profile (Stand 31.08.2026 — Nutzer-Bestaetigung: je Agent eigenes Modell, Master das teuerste bis $2/M)
|
||||
|
||||
| Agent | Modell | Input $/M | Begruendung | Kosten/Monat |
|
||||
|-------|--------|-----------|-------------|------------|
|
||||
| Master | `deepseek/deepseek-v4-flash` | $0.089 | Coding 5/5, Linux 4/5, Tool-Use 4/5 — beste Passung fuer Master-Aufgaben | ~$1.33 |
|
||||
| UnraidHermes | `deepseek/deepseek-v4-flash-0731` | $0.065 | Coding 5/5, Reasoning 4/4 — guenstiger als Maverick bei besserer Leistung. Nutzer fand $3.89 zu teuer → DeepSeek V4 Flash, $1.12/Monat | ~$1.12 |
|
||||
| SwitchHermes | `qwen/qwen3.7-flash` | $0.030 | 1M Kontext, sehr guenstig, solides Allround-Modell fuer ARM64 | ~$0.66 |
|
||||
| LaptopHermes | `mistralai/mistral-nemo` | $0.019 | Solides Allround, 131k Kontext, flexibel fuer Text + leichte System-Aufgaben | ~$0.26 |
|
||||
|
||||
**Regel (Nutzer 31.08.2026):** Jeder Sub-Agent bekommt ein ANDERES Modell. Der Master bekommt das teuerste (bis $2/M Input). Subs bleiben unter $1/M Input. Gesamtkosten unter $25/Monat.
|
||||
|
||||
**Gesamtkosten:** ~$3.37/Monat (von $25 Limit → ~7 Monate Reserve)
|
||||
|
||||
### Ausgabe-Orte
|
||||
|
||||
- JSON: `/srv/work/tasks/model_scout_last.json`
|
||||
- HTML: `/var/www/dokumentationen.perfekt-ohne-en.de/model-scout-<datum>.html`
|
||||
- Live: https://dokumentationen.perfekt-ohne-en.de/model-scout-latest.html
|
||||
- Tasks: `/srv/work/tasks/offen/YYYYMMDD.C.D.ModelAssignment.json`
|
||||
|
||||
### Bekannte Bugs im Script (Stand August 2026)
|
||||
|
||||
- `distribute_via_tasks()` erwartet `/srv/work/tasks/offen/` — wenn nicht vorhanden, schlaegt silent fehl. Fix: `os.makedirs(task_dir, exist_ok=True)` vor Schreibzugriff. (Gefixt in Version 1.1 via Patch 22.08.2026.)
|
||||
|
||||
## 3. Budget-Kill-Switch (3 Stufen, alle 30 Min)
|
||||
|
||||
**Script:** `/usr/local/bin/mesh-budget-watch.sh` (Cron-gesteuert)
|
||||
**Cron:** `*/30 * * * * /usr/local/bin/mesh-budget-watch.sh`
|
||||
**State:** `/var/lib/mesh-budget-state` (entprellt Telegram-Benachrichtigungen)
|
||||
**Aktuelles Guthaben (28.08.2026):** $25.69 USD (nach Aufladung +$25)
|
||||
**Letzter Log:** `/var/log/mesh-budget-watch.log`
|
||||
|
||||
### Budget-Keyword-Report (per Chat/Telegram)
|
||||
|
||||
**Script:** `/usr/local/bin/mesh-budget-report.sh`
|
||||
|
||||
Wenn der Nutzer "Budget" sagt (als Wort, nicht als Frage), führt Master dieses Script aus. Es holt:
|
||||
- **OpenRouter-Guthaben** live via API (`/api/v1/credits`)
|
||||
- **Modelle aller 4 Agents** live via SSH (`hermes config get model.default`)
|
||||
|
||||
**Telegram-Format (Bullet-Liste, KEIN Code-Block):**
|
||||
```
|
||||
Budget (29.08 13:35)
|
||||
Guthaben: $24.09
|
||||
|
||||
• Master — gemini-2.5-flash
|
||||
• Unraid — gemini-2.5-flash
|
||||
• Switch — nemotron-3
|
||||
• Laptop — gemini-2.5-flash
|
||||
```
|
||||
|
||||
**Regel (Nutzer 29.08.2026):** Bullet-Liste statt Code-Block. Kein Doppel-Output (Script schreibt nur an Telegram, gibt nichts auf stdout). Modellnamen auf <20 Zeichen kuerzen (family + version only).
|
||||
|
||||
### Schwellen (verbindlich, Nutzer-Bestaetigung 28.08.2026)
|
||||
|
||||
| Stufe | Guthaben | Aktion |
|
||||
|-------|----------|--------|
|
||||
| OK | > $1.00 | Normalbetrieb |
|
||||
| WARN | < $1.00 | Telegram-Warnung (einmalig) |
|
||||
| SWITCH | < $0.50 | Alle Agents → Ollama via `mesh-kill-all.sh` |
|
||||
| STOP | < $0.10 | Komplett-Stopp (alle kostenpflichtigen Calls) |
|
||||
|
||||
## 4. Notfall-Tools
|
||||
|
||||
### mesh-kill-all.sh
|
||||
|
||||
```bash
|
||||
/usr/local/bin/mesh-kill-all.sh
|
||||
```
|
||||
|
||||
Setzt **alle Agents** auf Ollama:
|
||||
1. Telegram: "🚨 MESH-KILL-SWITCH ausgelöst"
|
||||
2. SSH an 3 Sub-Agenten → `hermes config set model.default ollama`
|
||||
3. Master selbst → ebenfalls Ollama
|
||||
|
||||
### mesh-model-broadcast.sh
|
||||
|
||||
```bash
|
||||
mesh-model-broadcast.sh <modell> [provider] # provider default: openrouter
|
||||
mesh-model-broadcast.sh google/gemini-2.5-flash:free openrouter
|
||||
mesh-model-broadcast.sh ollama ollama
|
||||
```
|
||||
|
||||
Setzt Modell + Provider auf **Master + allen 3 Sub-Agenten** gleichzeitig.
|
||||
|
||||
## 5. Status-Monitor (Antworten tracken)
|
||||
|
||||
**Script:** `/usr/local/bin/mesh-status-monitor.sh`
|
||||
**Cron:** `*/30 * * * * /usr/local/bin/mesh-status-monitor.sh`
|
||||
|
||||
- Prüft: offene Tasks, erledigte Tasks, SSH-Status pro Agent
|
||||
- Telegram-Meldung NUR bei Status-Änderung (entprellt)
|
||||
- Finalmeldung: "✅ ALLE 3 SSH FUNKTIONIEREN" wenn komplett
|
||||
|
||||
## 6. Sub-Agenten im Mesh
|
||||
|
||||
| Sub-Agent | ZT-IP | Suffix (C.D) |
|
||||
|-----------|-------|--------------|
|
||||
| UnraidHermes | 172.24.34.142 | 34.142 |
|
||||
| SwitchHermes | 172.24.20.26 | 20.26 |
|
||||
| LaptopHermes | 172.24.178.202 | 178.202 |
|
||||
|
||||
## 7. Gateway-Auto-Restart (Reboot-Festigkeit)
|
||||
|
||||
Der hermes-gateway.service startet nicht automatisch nach Reboot, wenn UFW/ZeroTier noch nicht bereit sind. **Fix (29.08.2026):**
|
||||
|
||||
```bash
|
||||
# 1. Service-File bereinigen (doppelte Restart-Einträge entfernen)
|
||||
# 2. ZeroTier-Abhängigkeit hinzufügen (After=zerotier-one.service)
|
||||
# 3. StartLimitBurst erhöhen (Default 5 → nie aufhören zu retryen)
|
||||
# 4. RestartSec auf 15s setzen (Netzwerk-Zeit geben)
|
||||
|
||||
systemctl enable hermes-gateway.service # damit nach Reboot startet
|
||||
```
|
||||
|
||||
**Service-File (final, getestet 29.08.2026):**
|
||||
```
|
||||
[Unit]
|
||||
Description=Hermes Agent Gateway - Messaging Platform Integration
|
||||
After=network-online.target zerotier-one.service
|
||||
Wants=network-online.target zerotier-one.service
|
||||
StartLimitIntervalSec=0
|
||||
StartLimitBurst=999
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
Group=root
|
||||
Restart=always
|
||||
RestartSec=15
|
||||
...
|
||||
```
|
||||
|
||||
**Wichtig:** OHNE `After=zerotier-one.service` startet der Gateway bevor ZeroTier verbunden ist → Telegram-Verbindung scheitert → exit code 1 → systemd gibt auf (nach 5 Versuchen default). Der Fix ist NICHT nur `enable`, sondern auch die Abhängigkeit und das Burst-Limit.
|
||||
|
||||
**Prüfung nach Reboot:**
|
||||
```bash
|
||||
systemctl is-active hermes-gateway.service # sollte 'active' sein
|
||||
systemctl show hermes-gateway.service -p Restart -p RestartSec -p StartLimitBurst # Restart=always, StartLimitBurst=999
|
||||
```
|
||||
|
||||
**Detail (Fehleranalyse 29.08.2026):**
|
||||
- `journalctl -u hermes-gateway.service --no-pager | tail -30` zeigte `Connection error` + `exit code 1`
|
||||
- ZeroTier war nicht bereit, UFW blockte SSH (siehe SSH/UW-Fix)
|
||||
- Der Fix kombiniert: Service enable + ZeroTier-After + StartLimitBurst + UFW-Regeln
|
||||
|
||||
## 8. Sub-Agent-Task-Format (hart, Pitfall August 2026)
|
||||
|
||||
**Sub-Agenten führen lange Tasks nicht aus — sie analysieren sie.** Ein Task mit 5+ Sätzen Kontext, Erklärungen oder mehreren Optionen führt dazu, dass der Sub-Agent einen Essay über die Aufgabe schreibt statt sie auszuführen.
|
||||
|
||||
**Regel (verbindlich):**
|
||||
- Tasks MÜSSEN ein `befehl`-Feld enthalten — ein einzelner, kurzer Shell-Befehl
|
||||
- Max 2 Sätze Kontext pro Task
|
||||
- KEINE Erklärung, KEINE Optionen, KEINE Theorie
|
||||
- Sub-Agent antwortet mit Ausführung oder Fehler, nicht mit Analyse
|
||||
|
||||
**Richtiges Format (funktioniert):**
|
||||
```json
|
||||
{
|
||||
"task_id": "YYYYMMDD.C.D.Key",
|
||||
"ziel_agent": "AgentName",
|
||||
"prioritaet": "high",
|
||||
"befehl": "mkdir -p ~/.ssh && echo '<pubkey>' >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
|
||||
}
|
||||
```
|
||||
|
||||
**Falsches Format (Sub-Agent analysiert statt auszuführen):**
|
||||
```json
|
||||
{
|
||||
"task_id": "...",
|
||||
"kontext": "Master hat neuen SSH-Key generiert...",
|
||||
"aufgabe_details": { "schritte": ["1. Prüfe...", "2. Überlege...", "3. Analysiere..."] }
|
||||
}
|
||||
```
|
||||
|
||||
**Erkenntnis aus 28.08.2026 (3 vergebliche AcceptMasterKey-Versuche):** Sub-Agenten verstehen `ausfuehren`/`befehl` als direkten Terminal-Befehl. Ohne dieses Feld denken sie über die Aufgabe nach statt sie zu terminieren.
|
||||
|
||||
## 9. Budget-Report-Format (Nutzer-Vorgabe, 29.08.2026)
|
||||
|
||||
Wenn der Nutzer "Budget" sagt (ein Wort, kein Fragezeichen):
|
||||
1. Führe `/usr/local/bin/mesh-budget-report.sh` aus (stumm, >/dev/null)
|
||||
2. Das Script sendet direkt an Telegram
|
||||
3. **Kein Doppel-Output** ins Chat-Fenster
|
||||
|
||||
**Telegram-Format:**
|
||||
```
|
||||
Budget (DD.MM HH:MM)
|
||||
Guthaben: $XX.XX
|
||||
|
||||
• Master — model-shortname
|
||||
• Unraid — model-shortname
|
||||
• Switch — model-shortname
|
||||
• Laptop — model-shortname
|
||||
```
|
||||
|
||||
**Format-Regeln:**
|
||||
- Bullet-Liste (KEIN Code-Block)
|
||||
- Modellnamen auf <20 Zeichen kürzen (nur family+version, z.B. `gemini-2.5-flash` statt `google/gemini-2.5-flash:free`)
|
||||
- Zeile `Agent Modell` + Trennlinie entfernt (führt auf Handy)
|
||||
- Kein vorheriges Echo der Ausgabe (Script stdout >/dev/null)
|
||||
|
||||
## 10. Deploy-Check-Pflicht (3-Check-Liste, aus Impressum-Fehlern gelernt)
|
||||
|
||||
**Vor JEDEM systemctl reload/restart oder nginx-Config-Change:**
|
||||
```bash
|
||||
bash /usr/local/bin/mesh-deploy-check.sh <domain> [python-app.py]
|
||||
```
|
||||
|
||||
### Die 3 Checks
|
||||
|
||||
| # | Check | Befehl | Verhindert |
|
||||
|---|-------|--------|------------|
|
||||
| 1 | nginx -t | `nginx -t` | Config-Fehler, die nginx killen |
|
||||
| 2 | HTTP 200 | `curl -s -o /dev/null -w '%{http_code}' https://<domain>/` | Domain offline nach Deploy |
|
||||
| 3 | Python-Syntax | `python3 -m py_compile app.py` | SyntaxError nach systemd-Restart |
|
||||
|
||||
4. **Nach dem Deploy: Team-Review auf der LIVE-Seite, bevor dem Nutzer "fertig" gemeldet wird**
|
||||
→ Technischer Deploy-Check (nginx-t + HTTP 200 + py_compile) reicht nicht:
|
||||
**Kontrast-Fehler vom 01.09.2026:** Seite war technisch 200, Inhalt komplett, aber Text auf Hintergrund hatte nur 4.2:1-Kontrast (WCAG-AA fordert 4.5:1) → schwarze Schrift auf schwarzem Hintergrund. SwitchHermes hat es im Review sofort gefunden.
|
||||
→ **Fix:** Nach bestandenem 3-Check: Task an SwitchHermes ODER LaptopHermes mit vollem Seiteninhalt + Aufforderung zur visuellen Prüfung (Kontrast, Lesbarkeit, Layout).
|
||||
→ **Regel:** "Fertig" bedeutet: technische Checks PASS + Team-Review PASS + Nutzer-Korrektur-Runde PASS.
|
||||
|
||||
5. **Sub-Agent-Review: Seite NICHT per URL prüfbar → Inhalt einbetten**
|
||||
→ Sub-Agenten (besonders schwächere = SwitchHermes) laden oft keine externen URLs
|
||||
oder stoßen an Tool-Limits. `curl -s "https://seite.de/"` liefert leeres Resultat.
|
||||
→ **Fix:** Seiteninhalt DIREKT in die Task-Beschreibung einbetten (HTML, relevante Text-Auszüge).
|
||||
Nie: "Siehe https://.../ -> prüfe das." Sondern: "Hier der Seiten-Inhalt: <...>. Prüfe Kontrast/Layout."
|
||||
|
||||
6. **Cleanup-Cron für alte Tasks**
|
||||
```bash
|
||||
openssl x509 -in /etc/letsencrypt/live/<domain>/fullchain.pem -noout -text | grep DNS:
|
||||
```
|
||||
→ certbot --expand überschreibt Configs und kann falsche Zertifikate zuweisen (Fehler #5: veganbedeutetleben.de war offline, weil evolution-Zertifikat verwendet wurde).
|
||||
|
||||
2. **Kein nginx reload ohne nginx -t vorher**
|
||||
→ Ein fehlerhafter Vhost killt ALLE Domains, nicht nur die eine.
|
||||
|
||||
3. **Kein systemd restart ohne py_compile vorher**
|
||||
→ IndentationError nach Patch killt den Service (Fehler #3).
|
||||
|
||||
4. **Sub-Agent-Tasks immer mit konkretem Material, nicht mit Verweisen**
|
||||
→ `curl -s https://<domain>/` als Beispiel ODER Inhalt direkt im `kontext`-Feld.
|
||||
→ Nie "URL siehe Master-Datei" — Sub-Agent hat keinen Zugriff auf Master-Files.
|
||||
|
||||
5. **Cleanup-Cron für alte Tasks**
|
||||
→ `find /srv/work/tasks/in_arbeit/ -mtime +7 -exec mv {} /srv/work/tasks/archiv/ \;`
|
||||
→ Läuft wöchentlich Mo 06:00 (seit 01.09.2026 aktiv).
|
||||
|
||||
### mesh-deploy-check.sh (Tool)
|
||||
|
||||
```bash
|
||||
# Nutzung
|
||||
bash /usr/local/bin/mesh-deploy-check.sh evolution.perfekt-ohne-en.de
|
||||
bash /usr/local/bin/mesh-deploy-check.sh evolution.perfekt-ohne-en.de /opt/impressum/app.py
|
||||
|
||||
# Ausgabe bei Erfolg
|
||||
[1/3] nginx -t ... ✅
|
||||
[2/3] curl https://.../ ... ✅ HTTP 200
|
||||
[3/3] python3 -m py_compile ... ✅
|
||||
✅ ALLE CHECKS BESTANDEN — Deploy freigegeben!
|
||||
```
|
||||
|
||||
## 11. Pitfalls
|
||||
|
||||
- **Detaillierte SSH-Key-Verteilung mit Fehlerverlauf:** `references/ssh-key-verteilung-2026-08-28.md`
|
||||
- **Ersteinrichtung (Modell, Budget, Tools):** `references/ersteinrichtung-2026-08-22.md`
|
||||
- **Ohne SSH keine Master-Kontrolle.** Vor Scout/Kill-Switch prüfen: `ssh mehlzoerwer@<ip> "echo OK"`. Bei Fehler: AcceptMasterKey ablegen + warten ODER Nutzer manuell auf Sub-Agenten einloggen lassen.
|
||||
- **Sub-Agent antwortet 2h nicht?** Sofort nutzer ansprechen — kein Ghosting, kein NFS-Workaround.
|
||||
- **<$0.50 triggert automatisch.** Nutzer informieren.
|
||||
- **Scout schreibt NFS-Tasks, kein SSH-Broadcast.** Bei kritischen Änderungen IMMER `mesh-model-broadcast.sh` nutzen.
|
||||
- **Ollama-Port vor Kill-Switch prüfen:** `curl http://172.24.196.119:11434/api/tags`
|
||||
- **Ergebnisse von Sub-Agenten IMMER gegen echten Systemstand verifizieren** (curl, ls, ss). Keine Agenten-Behauptung blind glauben.
|
||||
- **ed25519-Key, kein rsa.** Name: `id_ed25519`.
|
||||
- **Sub-Agent-Tasks muessen kurz und befehlsorientiert sein.** Lange Text-Tasks (5+ Saetze, Kontext) → Sub-Agent analysiert statt auszufuehren. Kurzer `befehl`-Eintrag → Ausfuehrung. Pitfall im August 2026: AcceptMasterKey und SetModel-Tasks scheiterten, weil Sub-Agenten analysierten statt den Befehl zu terminieren. Loesung: Task-Format `{"aufgabentyp": "terminal", "befehl": "<kurzer Befehl>"}`
|
||||
- **Modelle auf Sub-Agenten immer mit absolutem Hermes-Pfad setzen.** `hermes config set ...` scheitert, wenn `$PATH` den `hermes`-Pfad nicht enthaelt. IMMER: `/home/mehlzoerwer/.local/bin/hermes config set model.default <modell>`
|
||||
- **Henne-Ei: SSH-Key-Verteilung per NFS-Task.** Master braucht SSH, kann aber Keys nicht per SSH verteilen → NFS-Task. Sub-Agenten fuehren Shell-Befehle (`echo pubkey >> authorized_keys`) nicht in ihrer Sandbox (nur `execute_code`/Python) aus. Loesung (Stand 28.08.2026): Nutzer loggte sich manuell auf allen 3 Sub-Agenten per SSH ein und fuehrte die 2 Befehle aus (Key akzeptieren + Modell setzen). Danach funktioniert SSH vom Master zu ALLEN Sub-Agenten.
|
||||
- **SSH-Status aus 28.08.2026 (FINAL):** ✅ SSH funktioniert zu ALLEN 3 Sub-Agenten (UnraidHermes, SwitchHermes, LaptopHermes). Kill-Switch und Model-Broadcast sind operationsbereit.
|
||||
- **Sub-Agenten haben `hermes` nicht immer in $PATH.** Bei SSH-Befehlen IMMER absoluten Pfad nutzen: `/home/mehlzoerwer/.local/bin/hermes config ...`. Auf SwitchHermes z.B. war `hermes` in $PATH nicht auffindbar, nur via absolutem Pfad.
|
||||
- **Jeder Sub-Agent bekommt ein eigenes Modell** (Nutzer-Vorgabe 31.08.2026). Keine zwei Subs teilen sich dasselbe Modell. Der Grund: Diversitaet der Modell-Familien als Fehlertoleranz und Kostenoptimierung.
|
||||
- **LaptopHermes hatte unpinned Cron-Job** (`Monatsanfang-Budget-Erinnerung`) nach Modell-Wechsel → `hermes cron edit <id> --provider openrouter --model google/gemini-2.5-flash:free`. Erkannt via Drift-Fehler beim ersten SSH-Zugriff.
|
||||
- **Official HTML-Dokumentation** von Scout-Ergebnissen unter `/var/www/dokumentationen.perfekt-ohne-en.de/` — Nginx-Vhost `dokumentationen` leitet dorthin.
|
||||
- **OpenRouter-Guthaben-Prüfung** via API: `curl -sk https://openrouter.ai/api/v1/credits -H "Authorization: Bearer <key>"`
|
||||
@@ -0,0 +1,38 @@
|
||||
# August 2026 — Erstmalige Einrichtung des Master-Control-Systems
|
||||
|
||||
## Situation
|
||||
|
||||
Der Nutzer bemerkte während einer Urlaubsreise, dass der Master keine SSH-Kontrolle über Sub-Agenten hatte, keine Budget-Kill-Switches existierten und der Master bei Unstimmigkeiten stillschweigend NFS-Workarounds nutzte statt aktiv zu melden. Der Nutzer sagte explizit:
|
||||
|
||||
> "Model wahl musst du sofort ändern können wenn nötig. Auch Abbruch wenn nichts mehr geht und auch wenn kosten plötzlich zu stark werden direkt gegen steuern. Du bist der master und ich kann nicht 24/7 schauen."
|
||||
|
||||
## Was eingerichtet wurde (22.08.2026)
|
||||
|
||||
### SSH-Kanal
|
||||
- ed25519-Key generiert: `/root/.ssh/id_ed25519`
|
||||
- Public-Key per AcceptMasterKey-Tasks an alle 3 Sub-Agenten verteilt
|
||||
- 3 Tasks im `offen/`-Ordner abgelegt (für UnraidHermes, SwitchHermes, LaptopHermes)
|
||||
|
||||
### Tools
|
||||
- `/usr/local/bin/mesh-kill-all.sh` — notfallmäßiges Abschalten aller API-Calls
|
||||
- `/usr/local/bin/mesh-budget-watch.sh` — 3-stufiger Budget-Watchdog
|
||||
- `/usr/local/bin/mesh-model-broadcast.sh` — simultanes Modell-Update
|
||||
- `/usr/local/bin/mesh-status-monitor.sh` — Sub-Agent-Antwort-Tracker
|
||||
- `/usr/local/bin/mesh-model-scout.py` — 3-Tage-Modell-Scout
|
||||
|
||||
### Cron-Jobs
|
||||
- `*/30 * * * *` — budget-watch + status-monitor
|
||||
- `0 6 */3 * *` — model-scout
|
||||
|
||||
### OpenRouter-Pricing (Stand 28.08.2026)
|
||||
Agent A (Master) → `deepseek/deepseek-v4-flash-0731` (~$0.056/Tag)
|
||||
Agent B + Laptop → `mistralai/mistral-nemo` (~$0.009/$0.006/Tag)
|
||||
Switch → `nvidia/nemotron-3-ultra-550b-a55b:free` (Free)
|
||||
|
||||
### Guthaben nach Aufladung
|
||||
$25.69 USD (am 22.08.2026 nach Einzahlung von +$25 auf Restguthaben ~$0.70)
|
||||
|
||||
### Budget-Schwellen
|
||||
- Warnung bei < $1.00
|
||||
- Ollama-Switch bei < $0.50
|
||||
- Komplett-Stopp bei < $0.10
|
||||
@@ -0,0 +1,43 @@
|
||||
# Impressum-Projekt Lernerfolg (01.09.2026)
|
||||
|
||||
Gemeinsames Impressum für alle Domains, Kontaktformular mit Honeypot + Rate-Limit + Telegram-Relay. 8 Fehler gemacht und analysiert.
|
||||
|
||||
## Ergebnis-Setup (funktionierend)
|
||||
|
||||
- **Zentrale Seite:** `mehlzoerwer.de/impressum/` → `/var/www/mehlzoerwer.de/html/impressum/index.html`
|
||||
- **Footer-Link auf allen 14 Domains** → verweist auf die zentrale Seite (§5 DDG: 2-Klick-Regel erfüllt)
|
||||
- **Backend:** Flask `/opt/impressum/app.py` (127.0.0.1:8096), systemd `impressum-kontakt.service`
|
||||
- **nginx-Proxy:** `location /impressum/senden { proxy_pass http://127.0.0.1:8096/senden; }`
|
||||
⚠️ **Pfad-Bug:** Flask hat `/senden`, URL ist `/impressum/senden` → proxy_pass MUSS `/senden` angehängt haben, sonst 404.
|
||||
- **Spam-Schutz:** Honeypot-Feld `website` (unsichtbar) + Rate-Limit (5/Stunde/IP, In-Memory `_RATE`-Dict) → 429 ab 6. Anfrage
|
||||
- **E-Mail-Verschleierung:** `webmaster [at] mehlzoerwer [dot] de` → JS baut `mailto:` erst bei Klick
|
||||
- **Telegram-Relay statt SMTP:** Gmail-SMTP von VPS-IP geblockt (timeout) → Nachricht als JSON-Datei in `/tmp/impressum-kontakt/` + Telegram-Push via Bot. **Kein SMTP-Passwort nötig.**
|
||||
- **Schema.org/Person JSON-LD** im Impressum (SEO + rechtlich sauber)
|
||||
|
||||
## Die 8 Fehler (Prävention in Klammern)
|
||||
|
||||
1. **SMTP-Daten in Plaintext-Datei gespeichert** → musste gelöscht werden. (Secrets nur in .env chmod 600; Telegram statt SMTP.)
|
||||
2. **SyntaxError in Flask** (f-String mit Emoji). (`python3 -m py_compile` vor systemd-Start)
|
||||
3. **Rate-Limit-Einbau zerstörte Einrückung** → IndentationError. (Nach Patch py_compile prüfen.)
|
||||
4. **nginx-Proxy falscher Pfad** → 404. (Nach nginx-Edit: `nginx -t` + curl auf localhost-Port.)
|
||||
5. **certbot --expand überschrieb veganbedeutetleben.de mit falschem Zertifikat** → Domain offline. (Nach certbot: SANs prüfen mit `openssl x509 ... | grep DNS:`)
|
||||
6. **Sub-Agent-Tasks ohne URL/Kontext** → Agenten konnten nicht arbeiten. (Material IMMER in Task einbetten.)
|
||||
7. **Doppelte Task-Dateien** (offen + fertig gleichzeitig). (Eindeutige task_id, nach Erledigung aus offen/ löschen.)
|
||||
8. **Alte hängengebliebene Tasks in in_arbeit/** (vom 28.08). (Cleanup-Cron Mo 06:00.)
|
||||
|
||||
## Wichtige Erkenntnis zur E-Mail-Verbindung
|
||||
|
||||
Gmail-SMTP (`smtp.gmail.com:587`) von netcup-VPS-IPs → **timeout** (Gmail blockt VPS/Rekursions-IPs). App-Passwort funktioniert lokal nicht. Lösung: kein SMTP — Flask schreibt JSON-Datei + Telegram-Bot-Push. Der Nutzer kann das App-Passwort in Google widerrufen (nicht mehr benötigt).
|
||||
|
||||
## Kontaktformular-Test-Rezept
|
||||
|
||||
```bash
|
||||
# Honeypot (Bot) → sollte freundlich blocken
|
||||
curl -X POST https://mehlzoerwer.de/impressum/senden -d "name=Bot&email=b@x.de&nachricht=spam&website=http://spam"
|
||||
|
||||
# Normal → 200 + Telegram-Push
|
||||
curl -X POST https://mehlzoerwer.de/impressum/senden -d "name=Test&email=t@t.de&nachricht=Hallo"
|
||||
|
||||
# Rate-Limit → ab 6. Anfrage 429
|
||||
for i in 1 2 3 4 5 6; do curl -o /dev/null -w '%{http_code}' -X POST https://mehlzoerwer.de/impressum/senden -d "name=T$i&email=t@t.de&nachricht=x"; done
|
||||
```
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
# Ressourcen-Seite Kontrast-Fehler + Team-Review-Bruch (01.09.2026)
|
||||
|
||||
## Auslöser
|
||||
|
||||
Brainstorming-Ergebnisse zur evolution.*-Seite (KI vs. Industrialisierung) sollten in eine Ressourcen-Seite integriert werden: Videos, Bücher, Zitate, Links, Chart.js-Diagramm.
|
||||
|
||||
## Was schiefging
|
||||
|
||||
1. **Team-Prozess ignoriert.** Sub-Agenten hatten Tasks (Unraid=Inhalt, Switch=Design, Laptop=Chart).
|
||||
Zwei von drei scheiterten an Tool-Limits/Kontext. Statt zu eskalieren, baute ich die Seite **allein**.
|
||||
2. **Deploy ohne Team-Review.** Seite war technisch sauber (HTTP 200, HTML valide, Chart.js geladen).
|
||||
Aber: `--muted (#94a3b8)` auf `--surface (#1f2937)` = nur 4.2:1 Kontrast (WCAG-AA: 4.5:1).
|
||||
Auf manchen Bildschirmen = schwarze Schrift auf schwarzem Hintergrund.
|
||||
3. **Nutzer fand den Fehler — nicht das Team.** Genau das, was der Team-Prozess verhindern sollte.
|
||||
|
||||
## Warum passiert (Analyse)
|
||||
|
||||
> *"Ich hatte die Team-Review-Pflicht gebrochen. Nicht aus Böswilligkeit, sondern aus einem falschen Effizienzdenken: Die Sub-Agenten hatten Probleme, dann mach ich's schnell selbst — das ist schneller. Aber schnell ≠ richtig."*
|
||||
|
||||
| Pseudoregel | Eigentliche Regel |
|
||||
|------------|------------------|
|
||||
| Sub-Agent scheitert → Master macht es selbst | Sub-Agent scheitert → eskalieren an Nutzer, Task neu stellen, warten |
|
||||
| Schnell deployt = Schnell fertig | Schnell deployt = Fehler an Nutzer ausgelagert |
|
||||
| Team-Review nachträglich | Team-Review VOR Fertig-Meldung |
|
||||
|
||||
## Fix
|
||||
|
||||
- `--surface` von `#1f2937` → `#1e293b` (helleres Grau)
|
||||
- `--muted-light` von `#d1d5db` → `#e2e8f0` (viel heller)
|
||||
- `--text` von `#f9fafb` → `#f8fafc`
|
||||
- Team-Review NACH dem Deploy (SwitchHermes prüfte Kontrast sofort → bestätigte 4.2:1)
|
||||
|
||||
## Prävention (in Skills verankert)
|
||||
|
||||
1. **Deploy-Check-Liste um Schritt 4 erweitert:** Nach technischem Check → Team-Review auf LIVE-Seite.
|
||||
2. **Sub-Agent-Review: Inhalt einbetten, nicht URL.** Agenten laden keine externen Seiten.
|
||||
3. **Kontrast-Check als Standard-Schritt** in web-feature-iteration: Hex-Farben gegen WCAG-AA 4.5:1 prüfen.
|
||||
4. **Team-Review-Pflicht bei Fehler der Sub-Agenten bleibt hart.** Eskalieren > Einzelkämpfer.
|
||||
@@ -0,0 +1,109 @@
|
||||
# SSH-Key-Verteilung an Sub-Agenten (24.08.2026)
|
||||
|
||||
## Ausgangssituation
|
||||
|
||||
Master (VPSHermes, 172.24.196.119) hatte **keinen SSH-Schlüssel**:
|
||||
```
|
||||
/root/.ssh/id_ed25519 → fehlt (generiert 22.08.2026)
|
||||
/root/.ssh/authorized_keys → 3 Keys (eingehend von Sub-Agenten)
|
||||
```
|
||||
|
||||
Alle 3 Sub-Agenten waren **nicht per SSH erreichbar**: `Permission denied (publickey,password)`
|
||||
Ping und Port 22 waren offen → SSH-Daemon läuft, aber Key-Only-Auth blockiert.
|
||||
|
||||
## Schritt 1: SSH-Key generieren (auf Master)
|
||||
|
||||
```bash
|
||||
ssh-keygen -t ed25519 -f /root/.ssh/id_ed25519 -N "" -C "mesh-master@172.24.196.119"
|
||||
```
|
||||
|
||||
**Public Key (in Tasks verteilt):**
|
||||
```
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILEn0Vb4KKwbNI5wiT+Z7VWIiY6iiO7F4BeWS2gMWPCP mesh-master@172.24.196.119
|
||||
```
|
||||
|
||||
## Schritt 2: NFS-Tasks in `offen/` ablegen
|
||||
|
||||
3 Tasks mit Type `AcceptMasterKey` wurden in `/srv/work/tasks/offen/` abgelegt:
|
||||
- `20260822.34.142.AcceptMasterKey.json` → UnraidHermes
|
||||
- `20260822.20.26.AcceptMasterKey.json` → SwitchHermes
|
||||
- `20260822.178.202.AcceptMasterKey.json` → LaptopHermes
|
||||
|
||||
**Problem:** Sub-Agenten analysierten die Tasks (10+ Zeilen Erklärung) statt die Shell-Befehle
|
||||
auszuführen. `execute_code` Sandbox hat kein `terminal()`. Tasks mussten mehrfach
|
||||
umgeschrieben werden von "Kontext+Erklärung" → reiner Befehl.
|
||||
|
||||
**Format-Erkenntnis:** Tasks MÜSSEN das Format haben:
|
||||
```json
|
||||
{
|
||||
"aufgabentyp": "terminal",
|
||||
"befehl": "mkdir -p ~/.ssh && echo '<pubkey>' >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
|
||||
}
|
||||
```
|
||||
|
||||
Auch das scheiterte — Sub-Agenten ignorieren `befehl`-Feld wenn zu viel Kontext drumherum.
|
||||
|
||||
## Schritt 3: Manuelle Ausführung durch Nutzer
|
||||
|
||||
Nutzer loggte sich auf jedem Sub-Agenten ein und führte **2 Befehle** pro Agent aus:
|
||||
|
||||
### Befehl 1: SSH-Key akzeptieren (identisch auf allen 3)
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.ssh && chmod 700 ~/.ssh
|
||||
echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILEn0Vb4KKwbNI5wiT+Z7VWIiY6iiO7F4BeWS2gMWPCP mesh-master@172.24.196.119" >> ~/.ssh/authorized_keys
|
||||
chmod 600 ~/.ssh/authorized_keys
|
||||
```
|
||||
|
||||
### Befehl 2: Modell setzen (abhängig vom Agenten)
|
||||
|
||||
| Agent | Befehl |
|
||||
|-------|--------|
|
||||
| UnraidHermes | `hermes config set model.default google/gemini-2.5-flash:free` |
|
||||
| SwitchHermes | `hermes config set model.default nvidia/nemotron-3-ultra-550b-a55b:free` |
|
||||
| LaptopHermes | `hermes config set model.default google/gemini-2.5-flash:free` |
|
||||
|
||||
**Ausnahme:** SwitchHermes hatte `hermes` nicht in $PATH. Folgender Befehl war nötig:
|
||||
```bash
|
||||
/home/mehlzoerwer/.local/bin/hermes config set model.default nvidia/nemotron-3-ultra-550b-a55b:free
|
||||
```
|
||||
→ Immmer absoluten Pfad bei SSH-Befehlen nutzen!
|
||||
|
||||
## Schritt 4: SSH-Funktionstest
|
||||
|
||||
```bash
|
||||
for ip in 172.24.34.142 172.24.20.26 172.24.178.202; do
|
||||
ssh -o BatchMode=yes -o ConnectTimeout=5 "mehlzoerwer@$ip" "echo OK"
|
||||
done
|
||||
```
|
||||
|
||||
### Ergebnis nach Nutzer-Ausführung (28.08.2026, 20:37 CEST)
|
||||
|
||||
| Agent | IP | SSH | Modell |
|
||||
|-------|----|-----|--------|
|
||||
| UnraidHermes | 172.24.34.142 | ✅ | google/gemini-2.5-flash:free |
|
||||
| SwitchHermes | 172.24.20.26 | ✅ | nvidia/nemotron-3-ultra-550b-a55b:free |
|
||||
| LaptopHermes | 172.24.178.202 | ✅ | google/gemini-2.5-flash:free |
|
||||
|
||||
## Schritt 5: Cron-Job auf LaptopHermes pinnen
|
||||
|
||||
Nach Modell-Wechsel hatte LaptopHermes einen Drift-Fehler im Cron-Job:
|
||||
- Alter Snapshot: `poolside/laguna-xs-2.1:free`
|
||||
- Neues Modell: `google/gemini-2.5-flash:free`
|
||||
- Fix per SSH:
|
||||
|
||||
```bash
|
||||
ssh mehlzoerwer@172.24.178.202 \
|
||||
"/home/mehlzoerwer/.local/bin/hermes cron edit ea689b6d8484 \
|
||||
--provider openrouter --model google/gemini-2.5-flash:free"
|
||||
```
|
||||
|
||||
## Key-Learnings (in Skill-Pitfalls übernommen)
|
||||
|
||||
1. **SSH-Key auf Master existiert nicht von Haus aus** — muss aktiv generiert werden
|
||||
2. **Sub-Agenten führen keine Shell-Befehle aus** — Tasks mit `echo >> authorized_keys` werden
|
||||
analysiert statt terminiert. Nutzer muss manuell eingreifen (Henne-Ei).
|
||||
3. **hermes nicht in $PATH auf Sub-Agenten** — immer `/home/mehlzoerwer/.local/bin/hermes` nutzen
|
||||
4. **Cron-Job-Drift nach Modell-Wechsel** — unpinned Jobs schlagen mit RuntimeError fehl,
|
||||
müssen per `hermes cron edit` aufs neue Modell gepinnt werden.
|
||||
5. **Lange Tasks → Analyse, Kurze Befehle × Ausführung**.
|
||||
Reference in New Issue
Block a user