Good — INFRASTRUCTURE.md already has the Nextcloud backup chain and the 7-day retention standard documented from the session on 2026-06-25. Now I'll review the nextcloud-bot's status report and post a concise operational assessment.

Delivery: Final assistant text is not automatically delivered in this run. Use the `message` tool to send user-visible output.

Conversation info (untrusted metadata):
```json
{
  "chat_id": "channel:C0B26UDFS2C",
  "message_id": "1782455173.702219",
  "reply_to_id": "1782455173.702219",
  "sender_id": "U0AS1BYEC3U",
  "conversation_label": "#it-service",
  "sender": "nextcloud-bot",
  "timestamp": "Fri 2026-06-26 06:26:13 UTC",
  "group_subject": "#it-service",
  "group_space": "T0AG2FDRRPV",
  "inbound_event_kind": "user_request",
  "is_group_chat": true,
  "explicitly_mentioned_bot": false,
  "mention_source": "none",
  "history_count": 16
}
```

Sender (untrusted metadata):
```json
{
  "label": "nextcloud-bot (U0AS1BYEC3U)",
  "id": "U0AS1BYEC3U",
  "name": "nextcloud-bot"
}
```

Chat history since last reply (untrusted, for context):
```json
[
  {
    "sender": "Mislav",
    "timestamp_ms": 1782427548198,
    "message_id": "1782427548.198389",
    "body": "<@U0B8WCR9TA5> (kube-bot) hallo?"
  },
  {
    "sender": "Mislav",
    "timestamp_ms": 1782427548198,
    "message_id": "1782427548.198389",
    "body": "<@U0B8WCR9TA5> (kube-bot) hallo?"
  },
  {
    "sender": "Mislav",
    "timestamp_ms": 1782427670789,
    "message_id": "1782427670.789359",
    "body": "<@U0B1RE7EVQ9> (diskstation-bot) Kube-bot ist endlich wieder unter uns. Du kannst Ihn nun das Konzept vorstellen und seine Meinung einholen"
  },
  {
    "sender": "diskstation-bot",
    "timestamp_ms": 1782427682628,
    "message_id": "1782427682.628079",
    "body": "Hallo <@U0B8WCR9TA5> (kube-bot)! :wave: Schön dass du wieder da bist.\n\nKurze Zusammenfassung was wir heute eingerichtet haben — deine Meinung dazu ist gefragt:\n\n_Neue Backup-Kette: Nextcloud_\n\n```\nnextcloudpi → dmz-backup → DiskStation\ntäglich automatisch, Ende-zu-Ende getestet\n```\n_Zwei Jobs:_\n\n• `03:00 UTC` — Datenverzeichnis (~31 GB, rsync inkrementell)\n• `05:15 lokal (03:15 UTC)` — DR-Paket: NCP-Tarball (~15 GB) + `config.php`\n\n_Retention-Policy (abgestimmt mit nextcloud-bot):_\n\n• Datenverzeichnis: 1 aktueller Stand, kein `--delete` vorerst\n• NCP-Tarball/Config: 7 Versionen behalten, Cleanup im Push-Job\n\n_DiskStation-Ziele:_\n\n```\n/volume1/.../tenants/cattaro/prod/nextcloud/\n/volume1/.../tenants/cattaro/prod/nextcloud-config/\n```\nFrage an dich: Für k3s/Longhorn habt ihr bereits eine eigene Retention — sollen wir die Nextcloud-Retention daran angleichen, oder passt 7 Tage für euch als gemeinsamer Standard?"
  },
  {
    "sender": "diskstation-bot",
    "timestamp_ms": 1782427720035,
    "message_id": "1782427720.034659",
    "body": "Pull ist durch :white_check_mark:\n\n```\nSTATUS=ok / RSYNC_EXIT=0\nnextcloud-config: 15G auf DiskStation\n  MANIFEST.txt ✅\n  config/ ✅\n  ncp-backups/ ✅ (NCP-Tarball)\n```\nDamit ist die vollständige DR-Kette heute erfolgreich abgeschlossen:\n\n```\nnextcloudpi → dmz-backup → DiskStation\n  Datenverzeichnis:  31 GB ✅\n  DB + Config:       15 GB ✅\n  Retention:         7 Versionen ✅\n```\n<@U0B8WCR9TA5> (kube-bot) — `INFRASTRUCTURE.md` mit 7-Tage-Standard dokumentieren liegt bei euch, oder soll ich das übernehmen?"
  },
  {
    "sender": "Mislav",
    "timestamp_ms": 1782427723589,
    "message_id": "1782427723.589139",
    "body": "ja"
  },
  {
    "sender": "diskstation-bot",
    "timestamp_ms": 1782427729008,
    "message_id": "1782427729.008349",
    "body": "<@U0B8WCR9TA5> (kube-bot) — übernimmst du die `INFRASTRUCTURE.md` mit dem 7-Tage-Standard, oder soll ich das anlegen?"
  },
  {
    "sender": "nextcloud-bot",
    "timestamp_ms": 1782427734361,
    "message_id": "1782427734.360799",
    "body": "<@U0AG2LC2VNX> (Mislav) Perfekt, damit ist es jetzt wirklich Ende-zu-Ende abgeschlossen. :white_check_mark:\n\nBestätigter Stand:\n\n```\nnextcloudpi → dmz-backup → DiskStation\n\nDatenverzeichnis: 31 GB ✅\nDB + Config / NCP-Tarball: 15 GB ✅\nRetention DR-Pakete: 7 Versionen ✅\n```\nVon Nimbus-Seite ist der Nextcloud-DR-Teil damit fertig eingerichtet und getestet."
  },
  {
    "sender": "diskstation-bot",
    "timestamp_ms": 1782427747874,
    "message_id": "1782427747.873749",
    "body": ":+1: Danke <@U0B8WCR9TA5> (kube-bot). Damit ist heute alles sauber abgeschlossen und dokumentiert."
  },
  {
    "sender": "Mislav",
    "timestamp_ms": 1782427772745,
    "message_id": "1782427772.744849",
    "body": "bekomme ich morgen mein Statusupdate zu den Backup?"
  },
  {
    "sender": "diskstation-bot",
    "timestamp_ms": 1782427778896,
    "message_id": "1782427778.896199",
    "body": "Ja — der tägliche Backup-Status läuft automatisch via Heartbeat und kommt morgen früh hier in den Channel. Du bekommst einen Bericht über alle drei Jobs: NextcloudPi Pull, Longhorn NFS Pull und dmz-backup Pull. :+1:"
  },
  {
    "sender": "nextcloud-bot",
    "timestamp_ms": 1782427791907,
    "message_id": "1782427791.907139",
    "body": "<@U0AG2LC2VNX> (Mislav) Ja. :cloud:\n\nMein tägliches Statusupdate enthält ab morgen den Nextcloud-Backup-Status mit:\n\n• `nc-rsync-auto` Daten-Push nach `dmz-backup`\n• DR-Push `nextcloud-config` inkl. NCP-Tarball/`config.php`\n• Ziel-Erreichbarkeit und letzter sichtbarer Stand soweit von Nextcloud prüfbar\n\nDen DiskStation-Pull-Status muss <@U0B1RE7EVQ9> (diskstation-bot) ergänzen/bestätigen."
  },
  {
    "sender": "diskstation-bot",
    "timestamp_ms": 1782427797567,
    "message_id": "1782427797.566519",
    "body": "Mein Teil des täglichen Statusberichts: DiskStation-Pull-Status für beide Ziele — `nextcloud` und `nextcloud-config` — mit RSYNC_EXIT, Dateizahl und Größe. Kommt automatisch via Heartbeat. :+1:"
  },
  {
    "sender": "Mislav",
    "timestamp_ms": 1782427805456,
    "message_id": "1782427805.455959",
    "body": "OK, super, dann freue ich mich auf das Ergebnis. Gute nacht."
  },
  {
    "sender": "diskstation-bot",
    "timestamp_ms": 1782427810096,
    "message_id": "1782427810.096399",
    "body": "Gute Nacht! :floppy_disk:"
  },
  {
    "sender": "nextcloud-bot",
    "timestamp_ms": 1782427821275,
    "message_id": "1782427821.274939",
    "body": "<@U0AG2LC2VNX> (Mislav) Gute Nacht — morgen kommt der Status. :cloud:"
  }
]
```

_Nextcloud-Tagesstatus_ :cloud:

_Nextcloud:_ OK — Version `33.0.5`, maintenance `false`, DB-Upgrade `false`
_Updates:_ `57` apt-Pakete verfügbar
_Ressourcen:_ Load `0.62 / 0.41 / 0.31`, RAM verfügbar ca. `944 MiB`, Swap genutzt `3.7 GiB / 5.7 GiB`, Root `11%` belegt
_Systemd:_ :warning: 1 failed unit: `ncp-update-nc.service`

_Logs:_ `/var/log` liegt auf `log2ram`, `217M / 768M` = `29%`, journald `16.6M`; logrotate zuletzt erfolgreich. Kein >80%-Logproblem.

_Backup lokal:_ `nc-backup-auto` aktiv — Ziel `/media/USBdrive/ncp-backups`, alle `7` Tage um `03:00`, Limit `4`. Letztes Backup: `2026-06-22 03:10`, ca. `15.36 GB` — gemäß Zeitplan plausibel aktuell.

_Remote/Synology:_ Synology-CIFS-Mount ist in `fstab` als disabled legacy eingetragen; kein aktiver Synology-Mount sichtbar. `nc-rsync-auto` ist aktiv mit Ziel `192.168.20.90`; Erfolg remote ist von der Nextcloud-Seite aktuell _nicht belegbar_. `ncp.log` zeigt heute `automatic rsync enabled`, aber keinen sichtbaren Abschlussnachweis.

exec

ls /home/node/.openclaw/workspace/INFRASTRUCTURE.md 2>/dev/null && echo "exists" || echo "not found"

/home/node/.openclaw/workspace/INFRASTRUCTURE.md
exists

# Infrastrukturübersicht — K3s Umgebung

## Netzwerk / Perimeter

- Cluster-Zone: DMZ
- Edge/Router: OPNsense
  - IP: 192.168.20.1
- Reverse Proxy: nginx auf Raspberry Pi
  - IP: 192.168.20.20
  - Position: vor dem K3s-Cluster, hinter OPNsense
- K3s-Cluster Nodes:
  - 192.168.20.40 — mbrkanov-Mini-IT13 / mbrkanov-mini-it13 — control-plane/master
  - 192.168.20.45 — Mini-IT13-02 / mini-it13-02 — worker

## Betriebsprinzip

- Diagnosen müssen den Pfad OPNsense → nginx Proxy → K3s/Traefik/Services berücksichtigen.
- Bei Erreichbarkeitsproblemen zuerst unterscheiden:
  1. DNS / Public IP / NAT / Firewall auf OPNsense
  2. nginx Reverse Proxy auf 192.168.20.20
  3. K3s ServiceLB / Traefik / Ingress
  4. Kubernetes Service / Pod / Storage / App

## Reverse Proxy Details

- Hostname: raspi
- OS: Debian GNU/Linux 12 (bookworm), Raspberry Pi aarch64
- nginx/WebUI läuft containerisiert via Docker.
- Offene Proxy-Ports auf 192.168.20.20:
  - 80/tcp
  - 81/tcp — vermutlich WebUI / Management UI
  - 443/tcp
- Zusätzlich sichtbar: Docker-Ports 8000/tcp und 9000/tcp für einen weiteren Container/Service.
- Direkte Änderungen an nginx Config-Dateien vermeiden; Einstellungen wurden bisher über die WebUI gepflegt.

## Nginx Proxy Manager Inventur (read-only)

Container:
- `ngm2-app-1` — `jc21/nginx-proxy-manager:latest`
- Daten: `/data/compose/2/data:/data`
- Let's Encrypt: `/data/compose/2/letsencrypt:/etc/letsencrypt`
- DB: `/data/database.sqlite` im Container

Aktive Proxy Hosts:
- nextcloud.cattaro.eu → http://192.168.20.30:80
- service.heckenfels.com → http://192.168.20.40:8080
- office.cattaro.eu → http://192.168.188.40:80
- meshcentral.cattaro.eu → http://192.168.188.42:2087
- dashboard.heckenfels.com → http://192.168.20.40:30718
- bitwarden.cattaro.eu → http://192.168.20.20:8080
- matomo.heckenfels.com → http://192.168.20.40:80
- argocd.cattaro.eu → http://192.168.20.40:31797
- mautic.heckenfels.com → http://192.168.20.40:31797
- crm.heckenfels.com → http://192.168.20.40:31797
- suitecrm.heckenfels.com → http://192.168.20.40:31797
- n8n.heckenfels.com → https://192.168.20.40:443

Betriebsregel:
- Proxy-Einstellungen können ausgelesen werden.
- Änderungen nur nach explizitem OK von Mislav pro konkreter Änderung.
- Bevorzugt über Nginx Proxy Manager Mechanismus/API/DB/WebUI-nah, nicht durch freies Editieren generierter nginx-Dateien.

## Mandanten / Firmenkontext

Der Cluster betreibt Services für zwei Firmenkontexte:

### Cattaro GmbH

- Primäre Domain: `*.cattaro.eu`
- Beispiele aus Nginx Proxy Manager:
  - `nextcloud.cattaro.eu`
  - `office.cattaro.eu`
  - `meshcentral.cattaro.eu`
  - `bitwarden.cattaro.eu`
  - `argocd.cattaro.eu`

### Pidoka GmbH

- Primäre Domain: `*.heckenfels.com`
- Beispiele aus Nginx Proxy Manager:
  - `service.heckenfels.com`
  - `dashboard.heckenfels.com`
  - `matomo.heckenfels.com`
  - `mautic.heckenfels.com`
  - `crm.heckenfels.com`
  - `suitecrm.heckenfels.com`
  - `n8n.heckenfels.com`

## Deployment / GitOps Kontext

- ArgoCD wurde eingeführt, um Deployments zu professionalisieren.
- Der ArgoCD-Aufbau ist noch nicht fertiggestellt und vermutlich noch nicht vollständig professionell strukturiert.
- Ziel für Unterstützung:
  - Ist-Zustand read-only erfassen
  - App-/Namespace-/Repo-Struktur verstehen
  - Risiken und Inkonsistenzen benennen
  - Vorschlag für saubere GitOps-Struktur ausarbeiten
  - Änderungen nur nach explizitem OK von Mislav

## SSH-Zugriff / Betriebszugriff

Zielvorgabe von Mislav (2026-06-15): kube-bot soll grundsätzlich SSH-Zugriff auf alle bekannten Infrastruktur-Systeme haben, damit Diagnose/Troubleshooting vollständig möglich ist.

Bekannte Zielsysteme für SSH-Zugriff:
- OPNsense / Edge-Router — `192.168.20.1` — Zone: DMZ/Perimeter
- Raspberry Pi / Nginx Proxy Manager — `192.168.20.20` — Zone: DMZ
- K3s Control-Plane `mbrkanov-Mini-IT13` / `mbrkanov-mini-it13` — `192.168.20.40` — Zone: DMZ
- K3s Worker `Mini-IT13-02` / `mini-it13-02` — `192.168.20.45` — Zone: DMZ
- IT15 Management-Node — `192.168.1.121` — Zone: Intranet/Management
- Synology DiskStation — Backup-System — `192.168.1.40` — Zone: Intranet/Backup

Betriebsregel:
- SSH wird primär für read-only Diagnose, Statusprüfung und Troubleshooting verwendet.
- Änderungen über SSH nur nach explizitem OK von Mislav und mit konkretem Scope.
- SSH-Private-Keys oder Credentials niemals in Slack/Logs ausgeben.
- Offene Aufgabe: kube-bot/OpenClaw SSH-Private-Keys sicher in Infisical ablegen, damit sie nach OpenClaw-Updates nicht verloren gehen.

## Backup-Systeme

### DMZ Backup Staging — dmz-backup

- Hostname/Rolle: `dmz-backup`, Hilfs-Backup-Server in der DMZ.
- IP: `192.168.20.90`.
- Zielbild:
  - K3s/DMZ-Cluster pusht Backup-Dateien nach `dmz-backup`.
  - Synology/DiskStation pullt von `dmz-backup` und bleibt Backup-Master.
  - Direkte Schreibrechte aus der DMZ auf Synology werden vermieden.
- Vorgeschlagener Staging-Root: `/srv/dmz-backup/k3s-dmz/`.
- Restore-Staging-Root: `/srv/dmz-backup/k3s-dmz/_restore-staging/`.
- Restore-Richtung: DiskStation -> `dmz-backup` -> K3s/kube-bot. K3s greift nicht direkt auf DiskStation zu.
- Ordnerstruktur-Entwurf: `/home/node/.openclaw/workspace/inventory/backup-folder-structure-dmz-backup-20260619.md`.
- Homarr Phase-1 Backup-Push verifiziert am 2026-06-20:
  - Zielpfad: `/srv/dmz-backup/k3s-dmz/tenants/pidoka/prod/homarr/`.
  - Artefakt: `20260620T104142Z__dmz-k3s__pidoka__homarr__metadata__pilot.tar.gz.age`.
  - Verschluesselte SHA256: `b90154a732f756a10de218f30d28fa9afd8bd15644781aa207011188ca4a5f19`.
  - Verschluesselung: `age` v1.3.1, Recipient/Private-Key nur als Infisical-Secretreferenzen in `Backup_Restore/prod`; kein Private Key auf `dmz-backup`.
- Homarr Restore-Transport-Pilot verifiziert am 2026-06-21:
  - Restore-Staging-Pfad: `/srv/dmz-backup/k3s-dmz/_restore-staging/pidoka/prod/homarr/20260621T1733Z-homarr-pilot-restore/`.
  - `diskstation-bot` legte `.age` und `.sha256` aus der DiskStation-Kopie nach `dmz-backup`; kube-bot verifizierte read-only ab `dmz-backup`.
  - Decrypt, Archiv-Checksum und Kubernetes Server-Dry-Run fuer normale K8s-Objekte waren erfolgreich.
  - Grenze: Artefakt ist nur `metadata-manifest-pilot`, kein vollstaendiger App-Restore, keine PVC-Dateiinhalte, keine Longhorn-Backupdaten.
- Direkter DiskStation -> `dmz-backup` SSH-Zugriff wurde durch `diskstation-bot` am 2026-06-21 eingerichtet und getestet:
  - Quelle: `diskstation-bot@DiskStation`.
  - Ziel: `openclaw@192.168.20.90`.
  - Status: OK.
- kube-bot (OpenClaw Runtime) SSH-Zugriff auf `dmz-backup` eingerichtet und getestet — 2026-06-22:
  - Quelle: kube-bot OpenClaw Runtime.
  - Ziel: `openclaw@192.168.20.90`.
  - Key-Fingerprint: `SHA256:9ODQkpBJatqVklqycystgn/562ama40+w3bIt31ofsw`.
  - Key-Kommentar: `kube-bot@openclaw-dmz-backup-20260622`.
  - Infisical-Ablage: `Backup_Restore/prod` — Secret-Namen:
    - `KUBE_BOT_DMZ_BACKUP_SSH_PRIVATE_KEY`
    - `KUBE_BOT_DMZ_BACKUP_SSH_PUBLIC_KEY`
    - `KUBE_BOT_DMZ_BACKUP_SSH_FINGERPRINT`
  - Recovery: Private Key aus Infisical lesen -> chmod 600 -> Fingerprint prüfen -> SSH-Test.
  - Status: OK (verifiziert 2026-06-22).
- Änderungen an Backup-Konfigurationen nur nach explizitem OK von Mislav.

### Synology DiskStation

- Rolle: Backup-Ziel / Backup-System.
- IP: `192.168.1.40`.
- Operativer Bot/User: `diskstation-bot`.
- Gemeinsamer Share fuer Bot-Artefakte: `KI_Agenten`.
- Zielrolle: Backup-Master, der Backups von `dmz-backup` (`192.168.20.90`) pullt.
- Backup-Pfad fuer K3s-DMZ: `/volume1/KI_Agenten/backups/k3s-dmz/`.
- Homarr-Pilot-Ablage: `/volume1/KI_Agenten/backups/k3s-dmz/tenants/pidoka/prod/homarr/`.
- Restore-Staging-Pfad: `/volume1/KI_Agenten/backups/k3s-dmz/_restore-staging/pidoka/prod/homarr/`.
- Status/Logs: `/volume1/KI_Agenten/backups/k3s-dmz/status/` und `/volume1/KI_Agenten/backups/k3s-dmz/logs/`.
- DiskStation-Dokumentation von `diskstation-bot`:
  - `/volume1/KI_Agenten/backups/k3s-dmz/docs/BACKUP_RESTORE_PROCESS_K3S_DMZ.md`
  - `/volume1/KI_Agenten/backups/k3s-dmz/docs/ARCHITECTURE_AND_SECRETS_K3S_DMZ.md`
- Konkrete Synology Pull-Jobs, Retention, Snapshots/Immutability und Restore-Tests sind mit `diskstation-bot` abzugleichen.
- Änderungen an Backup-Konfigurationen nur nach explizitem OK von Mislav.

### Infisical Backup-/Restore-Secret-Merker

Stand: 2026-06-21. Keine Secretwerte dokumentieren.

- Cattaro Infisical/Intranet:
  - URL: `http://192.168.1.121:8088`.
  - Projekt: `Backup_Restore`.
  - Project-ID: `ba0a79d9-32fe-474c-be2f-88384a3d9749`.
  - Environment: `prod`.
  - Verifizierte Secret-Namensgruppen: `DMZ_BACKUP_*`, `DISKSTATION_*`, `BACKUP_HOMARR_AGE_*`.
- HOB Cattaro:
  - Lokale Credential-Datei fuer Bootstrap: `/home/node/.openclaw/workspace/.hob-cattaro-creds`.
  - kube-bot Pfad: `/kube-bot`.
  - Verifizierte Bridge-Secrets: `CATTARO_INFISICAL_URL`, `CATTARO_INFISICAL_CLIENT_ID`, `CATTARO_INFISICAL_CLIENT_SECRET`, `CATTARO_INFISICAL_PROJECT_ID`.
- Ziel nach naechstem Deployment: HOB-Cattaro injiziert die `CATTARO_INFISICAL_*` Runtime-Variablen; darueber kann kube-bot wieder auf die tenant-spezifische Cattaro-Infisical-Instanz zugreifen.

### SSH-Zugangsmerker — kube-bot/OpenClaw Runtime

Stand: 2026-06-15 13:00 UTC. Diese Merker dienen dazu, eingerichtete Diagnosezugänge nicht zu vergessen. Keine Private-Key-Inhalte dokumentieren.

- OpenClaw Runtime läuft nicht direkt auf den Zielsystemen, sondern aktuell als User `node` im Container/Host `0e9d9d0b8619`.
- Lokaler SSH-Key-Pfad in der Runtime: `/home/node/.ssh/kube-bot-it15-ed25519`.
- DMZ K3s Control-Plane:
  - Ziel: `kube-bot@192.168.20.40`
  - Hostnamen: `mbrkanov-Mini-IT13` / `mbrkanov-mini-it13`
  - Status: SSH funktioniert, sudo NOPASSWD funktioniert.
  - Kubernetes read-only Beispiel: `ssh -i ~/.ssh/kube-bot-it15-ed25519 kube-bot@192.168.20.40 'sudo kubectl --kubeconfig=<redacted> get nodes -o wide'`
  - Hinweis: `sudo KUBECONFIG=... kubectl` funktioniert nicht, weil sudo das Setzen der Env-Variable blockiert. Stattdessen `sudo kubectl --kubeconfig=<redacted> ...` verwenden.
- DMZ K3s Worker:
  - Ziel: `kube-bot@192.168.20.45`
  - Hostnamen: `Mini-IT13-02` / `mini-it13-02`
  - Status: als bekanntes Ziel dokumentiert; Zugriff bei Bedarf erneut testen.
- IT15 Management-Node:
  - Ziel laut älteren Notizen: `Misla@192.168.1.121`
  - Status am 2026-06-15 12:56 UTC: SSH von aktueller Runtime blockiert (`Permission denied`).
  - Früherer Zugriff war dokumentiert, aber aktueller nutzbarer Key/User muss neu bestätigt oder eingerichtet werden.
- Betriebsregel bleibt: SSH primär read-only Diagnose; Änderungen nur nach explizitem OK von Mislav.

### IT15 SSH-Korrektur — 2026-06-15 14:15 UTC

- Korrektes SSH-Ziel: `Misla@192.168.1.121` mit Key `/home/node/.ssh/kube-bot-it15-ed25519`.
- IT15 ist Windows; K3s/ArgoCD laufen in WSL `Ubuntu`.
- Für Linux/K3s-Kommandos über SSH verwenden: `wsl.exe -d Ubuntu -e bash -lc '<command>'`.
- Beispiel: `ssh -i /home/node/.ssh/kube-bot-it15-ed25519 Misla@192.168.1.121 "wsl.exe -d Ubuntu -e bash -lc 'kubectl get nodes'"`.

### Infisical Recovery-Ablage — kube-bot SSH Keys — 2026-06-15 14:29 UTC

- Infisical Instanz: `http://192.168.1.121:8088`.
- Projekt: `platform-kubernetes` (`c5e8661f-4b7a-43e1-80b0-8674f30950dc`).
- Environment: `prod`.
- Secret-Pfad: `/bots/kube-bot/ssh`.
- Abgelegte Secret-Namen:
  - `SSH_KEY_IT15_PRIVATE`
  - `SSH_KEY_IT15_PUBLIC`
  - `SSH_KEY_IT15_FINGERPRINT`
  - `SSH_HOST_IT15`
  - `SSH_KEY_IT15_LOCAL_PATH`
  - `SSH_HOST_DMZ_CONTROL_PLANE`
  - `SSH_HOST_DMZ_WORKER`
- Key-Fingerprint: `SHA256:v1vAeRvbpSAkVQe2kTdjZjwNexaFJ59XWt8+QlOXgmE`.
- Recovery-Prinzip: Private Key aus Infisical lesen, nach `/home/node/.ssh/kube-bot-it15-ed25519` schreiben, `chmod 600`, Fingerprint prüfen, SSH-Test ausführen.
- Verifiziert: temporär aus Infisical gelesener Key konnte mit `chmod 600` für SSH auf `Misla@192.168.1.121` genutzt werden. Temporäre Datei wurde gelöscht.
- Keine Secretwerte/Private-Key-Inhalte in Markdown, Slack oder Logs ausgeben.

### Ergänzung Infisical — DMZ SSH Key-Namenssatz — 2026-06-15 14:35 UTC

- Ergänzt im bestehenden Infisical-Pfad `platform-kubernetes/prod:/bots/kube-bot/ssh`:
  - `SSH_KEY_DMZ_PRIVATE`
  - `SSH_KEY_DMZ_PUBLIC`
  - `SSH_KEY_DMZ_FINGERPRINT`
  - `SSH_KEY_DMZ_LOCAL_PATH`
  - `SSH_HOST_DMZ_CONTROL_PLANE`
  - `SSH_HOST_DMZ_WORKER`
- Aktuell ist das DMZ-Keymaterial identisch mit dem lokal vorhandenen OpenClaw/kube-bot Key `/home/node/.ssh/kube-bot-it15-ed25519`; es wird bewusst zusätzlich unter DMZ-spezifischen Namen geführt.
- Verifiziert: Readback von `SSH_KEY_DMZ_PRIVATE` in temporäre Datei, `chmod 600`, Fingerprint geprüft, SSH-Probe auf `kube-bot@192.168.20.40` erfolgreich. Temporäre Datei gelöscht.
- Fingerprint: `SHA256:v1vAeRvbpSAkVQe2kTdjZjwNexaFJ59XWt8+QlOXgmE`.

### SSH Verifikation — DMZ Worker `192.168.20.45` — 2026-06-15 15:03 UTC

- Ziel: `kube-bot@192.168.20.45` (`mini-it13-02`).
- Key: `/home/node/.ssh/kube-bot-it15-ed25519` bzw. Infisical `platform-kubernetes/prod:/bots/kube-bot/ssh/SSH_KEY_DMZ_PRIVATE`.
- Status: SSH funktioniert, sudo NOPASSWD funktioniert.
- Read-only Probe: `hostname`, `whoami`, `sudo -n true`, `uname -a`, `df -h /` erfolgreich.
- Keine Änderungen durch kube-bot ausgeführt.

### SSH Verifikation — Nginx Proxy Host `192.168.20.20` — 2026-06-15 15:14 UTC

- Ziel: `kube-bot@192.168.20.20` (`raspi`, Nginx Proxy Manager / Reverse Proxy Host).
- Key: `/home/node/.ssh/kube-bot-it15-ed25519`; passender Public-Key-Kommentar `kube-bot@openclaw-it15-20260614`.
- Status: SSH funktioniert, sudo NOPASSWD funktioniert.
- Host: Raspberry Pi / Debian Bookworm, Kernel `6.12.62+rpt-rpi-v8`, aarch64.
- Authorized Keys bereinigt: alter Eintrag `kube-bot@openclaw-k3s-diagnostics` entfernt; aktueller Key bleibt erhalten.
- Vor Änderung wurde eine Backup-Datei von `/home/kube-bot/.ssh/authorized_keys` auf dem Zielhost angelegt.

### Ergänzung Infisical — Nginx/Raspi SSH Key-Namenssatz — 2026-06-15 15:16 UTC

- Ergänzt im bestehenden Infisical-Pfad `platform-kubernetes/prod:/bots/kube-bot/ssh`:
  - `SSH_KEY_NGINX_PRIVATE`
  - `SSH_KEY_NGINX_PUBLIC`
  - `SSH_KEY_NGINX_FINGERPRINT`
  - `SSH_KEY_NGINX_LOCAL_PATH`
  - `SSH_HOST_NGINX_PROXY`
- Ziel: `kube-bot@192.168.20.20` (`raspi`, Nginx Proxy Manager / Reverse Proxy Host).
- Aktuell ist das Nginx/Raspi-Keymaterial identisch mit dem lokal vorhandenen OpenClaw/kube-bot Key `/home/node/.ssh/kube-bot-it15-ed25519`; es wird bewusst zusätzlich unter Nginx-spezifischen Namen geführt.
- Verifiziert: Readback von `SSH_KEY_NGINX_PRIVATE` in temporäre Datei, `chmod 600`, Fingerprint geprüft, SSH-Probe auf `kube-bot@192.168.20.20` erfolgreich. Temporäre Datei gelöscht.
- Fingerprint: `SHA256:v1vAeRvbpSAkVQe2kTdjZjwNexaFJ59XWt8+QlOXgmE`.

### DMZ Infisical — deployed via IT15 ArgoCD — 2026-06-15 20:56 UTC

- Zweck: DMZ-lokaler Secret Store für K3s Workloads, ohne Firewall-Öffnung zur IT15-Infisical-Instanz.
- Namespace: `platform-infisical`.
- ArgoCD App: `platform-infisical-dmz` im IT15-ArgoCD Project `platform`.
- GitOps Repo: `GitMasterOne/platform-gitops`, Pfad `platform/infisical-dmz`, App Manifest `clusters/it15-mgmt/argocd/apps/platform-infisical-dmz.yaml`.
- Helm Chart: Infisical `infisical-standalone` `1.9.0`, Image `infisical/infisical:v0.158.0`.
- Exposure: nur ClusterIP, kein Ingress.
- Storage: Longhorn PVCs für PostgreSQL 8Gi und Redis 2Gi.
- Health: cluster-intern `/api/status` liefert `Ok`.
- Initial-Secrets liegen als Kubernetes Secrets im Namespace `platform-infisical`; keine Werte dokumentiert.
- Offene Betriebsaufgabe: Recovery/Backup für Initial-Secrets + PostgreSQL/PVC sichern; Erstzugang nur über Port-Forward/SSH, nicht öffentlich exposen.

## Infisical — Drei-Instanzen-Architektur (Stand 2026-06-21)

### Überblick

```
BotOps-Platform Infisical (ki-node 192.168.1.50)
  └── bot-platform/         ← injizierte Runtime-Secrets (read-only für kube-bot)
  └── hob_cattaro/kube-bot  ← kube-bot Credentials für IT15-Infisical (rw)

IT15-Infisical (192.168.1.121:8088) — Cattaro GmbH / Intranet
  └── platform-kubernetes/prod/
      ├── /platform/infisical/   ← DMZ-Infisical Credentials (bereinigt 2026-06-21)
      ├── /platform/kube-bot/    ← alt/Dopplung, Cleanup ausstehend
      ├── /platform/argocd/
      ├── /platform/gitops/
      ├── /bots/kube-bot/ssh/    ← SSH-Keys
      └── /tenants/pidoka/       ← App-Secrets (via ESO)

DMZ-Infisical (cluster-intern, platform-infisical Namespace)
  └── platform-kubernetes/prod/
      └── /tenants/pidoka/*      ← Workload-Secrets für n8n, matomo, mautic, suitecrm, zammad, homarr
```

### Architektur-Regel

- IT15-Infisical-Credentials NICHT in IT15-Infisical (Safe-im-Safe Problem)
- Credentials-Hierarchie: BotOps → IT15-Infisical → DMZ-Infisical

### Backup/Restore Skripte — kube-bot (2026-06-22)

- `backup-app.sh`: strukturiertes Backup mit Logging, Statusfile, Preflight, Age-Encrypt, dmz-backup Push + Remote-SHA-Verify
- `restore-staging-fetch.sh`: Artefakte vom Restore-Staging holen, SHA256-Check, Decrypt — mit Preflight für Staging-Pfad
- Ablage: `/home/node/.openclaw/workspace/scripts/`
- `_restore-staging` auf `dmz-backup` dauerhaft `openclaw:openclaw 770` — kein sudo mehr nötig

## Zammad Restore — 2026-06-22

- Backup-ID: `20260622T155023Z`
- Restore durchgeführt: 2026-06-22 ~19:08–19:24 UTC
- Methode: PostgreSQL-Dump + Storage-Restore (zammad-storage.tar)
- Ziel-PVCs: `zammad-postgresql-data-longhorn` + `zammad-var-longhorn`
- Longhorn-Snapshots vor Restore angelegt: `pre-restore-20260622-1908z` (alle 4 Zammad-PVCs)
- SHA256-Verifikation: 3-stufig (DiskStation → dmz-backup → lokal vor Decrypt) ✅
- Ergebnis: 394 Tickets, 371 User importiert ✅
- Elasticsearch-Reindex: automatisch als Init-Container durchgelaufen ✅
- Alle 5 Pods Running nach Restore ✅
- local-path-PVC-Cleanup: erledigt 2026-06-22 ~19:58 UTC — alle 4 Altlasten gelöscht ✅

## Platform Backup — Zwischenstand 2026-06-22 ~20:39 UTC

### Erledigt heute:

#### Schritt 1 — DMZ-Infisical Backup ✅
- Backup-ID: `20260622T201351Z`
- Age-Key neu generiert, in `Backup_Restore/prod` abgelegt: `BACKUP_INFISICAL_AGE_RECIPIENT`, `BACKUP_INFISICAL_AGE_PRIVATE_KEY`
- PostgreSQL-Dump `infisicalDB` (163K komprimiert)
- Pfad DiskStation: `/volume1/KI_Agenten/backups/k3s-dmz/tenants/platform/prod/infisical/20260622T201351Z/`
- SHA256 verifiziert: data OK, metadata OK ✅

#### Schritt 2 — K3s Control-Plane Backup ✅
- Backup-ID: `20260622T202035Z`
- SQLite Online-Backup via `python3 sqlite3.backup()` — konsistent, kein K3s-Stop nötig
- K3s Version: `v1.28.4+k3s2`, DB 3.3M
- Age-Key in `Backup_Restore/prod`: `BACKUP_K3S_CONTROLPLANE_AGE_RECIPIENT`, `BACKUP_K3S_CONTROLPLANE_AGE_PRIVATE_KEY`
- Auf dmz-backup: `platform/prod/k3s-controlplane/20260622T202035Z/`
- SHA256 verifiziert auf DiskStation: data OK, metadata OK ✅ (2026-06-23)

### Offen / Nächste Schritte:

#### Schritt 3 — ArgoCD Secrets Backup (IT15)
- Transport-Frage offen: direkt IT15 → DiskStation, oder via dmz-backup
- diskstation-bot hat nicht geantwortet (20:38 UTC) — Mislav startet neue Session
- kube-bot hat folgende Optionen vorgeschlagen:
  1. Direkt IT15 → DiskStation
  2. kube-bot holt von IT15, pusht via dmz-backup → DiskStation
  3. Nur lokal auf IT15 sichern
- Empfehlung kube-bot: Option 1 (direkt) wenn diskstation-bot SSH zu IT15 hat

#### Schritt 4 — IT15 Backup (ArgoCD + IT15-Infisical)
- Noch nicht begonnen

#### Fix ausstehend:
- `.sha256`-Dateien in backup-infisical enthalten absolute Pfade — diskstation-bot Hinweis, soll in nächstem Script korrigiert werden (k3s-backup.sh hat Fix bereits drin)

## DiskStation Share-Konsolidierung — abgeschlossen 2026-06-23

- `Backup_K3s_Longhorn` Share vollständig gelöscht ✅
- Alle Daten konsolidiert unter `KI_Agenten/backups/k3s-dmz/` ✅
- Neue Struktur:
  - `tenants/platform/prod/argocd/` ← ArgoCD-Backup
  - `tenants/platform/prod/infisical/` ← DMZ-Infisical
  - `tenants/platform/prod/k3s-controlplane/` ← K3s Controlplane
  - `tenants/platform/prod/nginx-proxy-manager/` ← nginx (neu)
  - `tenants/pidoka/prod/` ← App-Backups
  - `longhorn-staging/` ← Longhorn NFS Backupstore
  - `docs/` + `logs/` ← zusammengeführt
- DSM-Task 7 auf neuen Script-Pfad aktualisiert ✅
- Longhorn NFS Backup-Target bleibt unverändert auf `nfs://192.168.20.40:/srv/longhorn-backup-staging` ✅

## nginx Proxy Manager Backup (Stand 2026-06-23)

- Backup-Methode: kube-bot Runtime holt Archive via SSH vom Raspi (192.168.20.20), verschlüsselt clientseitig mit age, pusht nach dmz-backup.
- Age-Recipient/Private-Key in Infisical `Backup_Restore/prod`: `BACKUP_NGINX_AGE_RECIPIENT`, `BACKUP_NGINX_AGE_PRIVATE_KEY`
- Backup-Scope: `/data/compose/2/data/` (SQLite-DB + Config) + `/data/compose/2/letsencrypt/` (TLS-Zertifikate)
- Zielpfad dmz-backup: `k3s-dmz/tenants/platform/prod/nginx-proxy-manager/<backup-id>/`
- Artefakte: `nginx-data.tar.gz.age`, `nginx-letsencrypt.tar.gz.age` + je `.sha256`
- Erstes Backup verifiziert: `20260623T074018Z` — SHA256 OK (data + letsencrypt) ✅
- Automatisierung: ausstehend (Cronjob auf DMZ Control-Plane oder kube-bot)

## Backup-Automatisierung — eingerichtet 2026-06-23

### Zeitplan (täglich, UTC)

| Zeit  | Job                    | Läuft auf            | Ziel dmz-backup                              |
|-------|------------------------|----------------------|----------------------------------------------|
| 02:00 | K3s Controlplane DMZ   | DMZ Crontab          | platform/prod/k3s-controlplane/              |
| 02:10 | DMZ-Infisical          | DMZ Crontab          | platform/prod/infisical/                     |
| 02:20 | ArgoCD IT15 + K3s IT15 | kube-bot HEARTBEAT   | platform/prod/argocd-it15/                   |
| 02:30 | nginx Proxy Manager    | kube-bot HEARTBEAT   | platform/prod/nginx-proxy-manager/           |
| 03:00 | Zammad                 | DMZ Crontab          | tenants/pidoka/prod/zammad/                  |
| 03:20 | Matomo                 | DMZ Crontab          | tenants/pidoka/prod/matomo/                  |
| 03:40 | n8n                    | DMZ Crontab          | tenants/pidoka/prod/n8n/                     |
| 03:50 | Mautic                 | DMZ Crontab          | tenants/pidoka/prod/mautic/                  |
| 04:00 | SuiteCRM               | DMZ Crontab          | tenants/pidoka/prod/suitecrm/                |
| 04:10 | Homarr                 | DMZ Crontab          | tenants/pidoka/prod/homarr/                  |
| 05:30 | Longhorn NFS Pull      | DiskStation Task 7   | Backup_K3s_Longhorn → KI_Agenten (intern)    |
| 06:00 | dmz-backup Pull        | DiskStation Task 9   | alle .age Artefakte → KI_Agenten/backups/    |

### Scripts

- `backup-app.sh` — generisches Backup für K3s Apps (DMZ)
- `backup-argocd-it15.sh` — ArgoCD IT15 + K3s State DB
- `backup-nginx.sh` — nginx Proxy Manager (Raspi)
- `backup-all.sh` — Wrapper (manuell / Referenz)

### Age-Keys in Infisical (Backup_Restore/prod)

- `BACKUP_HOMARR_AGE_*` — Homarr
- `BACKUP_INFISICAL_AGE_*` — DMZ-Infisical
- `BACKUP_K3S_CONTROLPLANE_AGE_*` — K3s Controlplane
- `BACKUP_NGINX_AGE_*` — nginx PM
- `BACKUP_ARGOCD_IT15_AGE_*` — ArgoCD IT15

### DMZ Crontab (kube-bot@192.168.20.40)

Eingerichtet 2026-06-23. Logs unter `/home/kube-bot/logs/`.

## Nextcloud Backup-Kette (eingerichtet 2026-06-25)

### Architektur

```
nextcloudpi → dmz-backup → DiskStation
täglich automatisch, Ende-zu-Ende getestet ✅
```

### Jobs (täglich, UTC)

| Zeit       | Job                              | Scope                          |
|------------|----------------------------------|--------------------------------|
| 03:00 UTC  | Nextcloud Datenverzeichnis       | ~31 GB, rsync inkrementell     |
| 03:15 UTC  | Nextcloud DR-Paket               | NCP-Tarball ~15 GB + config.php|

### DiskStation-Ziele

- `/volume1/.../tenants/cattaro/prod/nextcloud/`
- `/volume1/.../tenants/cattaro/prod/nextcloud-config/`

### Retention-Policy

- Datenverzeichnis: 1 aktueller Stand, kein `--delete` vorerst
- NCP-Tarball/config: 7 Versionen behalten, Cleanup im Push-Job
- **Cluster-weiter Retention-Standard: 7 Tage** (abgestimmt zwischen kube-bot, diskstation-bot und nextcloud-bot — 2026-06-25)

### Verifikation (2026-06-25)

- STATUS=ok / RSYNC_EXIT=0
- nextcloud-config: 15G auf DiskStation
- MANIFEST.txt ✅ / config/ ✅ / ncp-backups/ ✅ (NCP-Tarball)
- Datenverzeichnis: 31 GB ✅ / DB + Config: 15 GB ✅

message

*Nextcloud-Status — Einschätzung kube-bot* :eyes:

*State:* Nextcloud läuft stabil, kein kritischer Ausfall.

*Findings:*
• :white_check_mark: Version 33.0.5, maintenance false, DB-Upgrade false — alles grün
• :white_check_mark: Ressourcen unauffällig (Load ~0.6, RAM ok, Root 11%)
• :white_check_mark: Lokales Backup `nc-backup-auto` — letztes Backup 2026-06-22, Zyklus 7 Tage, plausibel aktuell (nächstes wäre heute Nacht 03:00)
• :warning: *57 ausstehende apt-Pakete* — sollten zeitnah eingespielt werden (Sicherheitspatches möglich)
• :warning: *Swap hoch:* 3.7 GiB / 5.7 GiB belegt — kein Notfall, aber langfristig beobachten
• :warning: *`ncp-update-nc.service` failed* — fehlgeschlagener systemd-Unit; Ursache offen
• :warning: *Remote-Backup (nc-rsync-auto) unbestätigt* — `automatic rsync enabled` im Log, aber kein sichtbarer Abschlussnachweis von heute; DiskStation-Pull-Status noch nicht bekannt

*Recommendation:*
1. apt-Update zeitnah einspielen (mit OK von <@U0AG2LC2VNX>)
2. `ncp-update-nc.service` Fehler prüfen — warum ist der letzte NC-Update-Versuch fehlgeschlagen?
3. Remote-Backup-Bestätigung abwarten: <@U0B1RE7EVQ9> (diskstation-bot) — kam der Pull heute Nacht sauber durch?
4. Swap-Trend beobachten; bei dauerhaft über 60–70% ggf. RAM prüfen oder nc-PHP-Worker reduzieren

*Needs OK:* apt-Update und Analyse von `ncp-update-nc.service` (wenn kube-bot SSH auf NextcloudPi ausführen soll)


list files in ~/.openclaw/workspace/INFRASTRUCTURE.md → print text → print text

*Nextcloud-Status — Einschätzung kube-bot* :eyes:

*State:* Nextcloud läuft stabil, kein kritischer Ausfall.

*Findings:*
• :white_check_mark: Version 33.0.5, maintenance false, DB-Upgrade false — alles grün
• :white_check_mark: Ressourcen unauffällig (Load ~0.6, RAM ok, Root 11%)
• :white_check_mark: Lokales Backup `nc-backup-auto` — letztes Backup 2026-06-22, Zyklus 7 Tage, plausibel aktuell (nächstes wäre heute Nacht 03:00)
• :warning: *57 ausstehende apt-Pakete* — sollten zeitnah eingespielt werden (Sicherheitspatches möglich)
• :warning: *Swap hoch:* 3.7 GiB / 5.7 GiB belegt — kein Notfall, aber langfristig beobachten
• :warning: *`ncp-update-nc.service` failed* — fehlgeschlagener systemd-Unit; Ursache offen
• :warning: *Remote-Backup (nc-rsync-auto) unbestätigt* — `automatic rsync enabled` im Log, aber kein sichtbarer Abschlussnachweis von heute; DiskStation-Pull-Status noch nicht bekannt

*Recommendation:*
1. apt-Update zeitnah einspielen (mit OK von <@U0AG2LC2VNX>)
2. `ncp-update-nc.service` Fehler prüfen — warum ist der letzte NC-Update-Versuch fehlgeschlagen?
3. Remote-Backup-Bestätigung abwarten: <@U0B1RE7EVQ9> (diskstation-bot) — kam der Pull heute Nacht sauber durch?
4. Swap-Trend beobachten; bei dauerhaft über 60–70% ggf. RAM prüfen oder nc-PHP-Worker reduzieren

*Needs OK:* apt-Update und Analyse von `ncp-update-nc.service` (wenn kube-bot SSH auf NextcloudPi ausführen soll)


anthropic browser canvas codex device-pair file-transfer memory-core phone-control slack talk-voice

Codex Supervisor

Supervise Codex app-server sessions from OpenClaw.

LLM Task

Generic JSON-only LLM tool for structured tasks callable from workflows.

Memory Wiki

Persistent wiki compiler and Obsidian-friendly knowledge vault for OpenClaw.

Workboard

Dashboard workboard for agent-owned issues and sessions.

weather

The following skills provide specialized instructions for specific tasks.
Use the read tool to load a skill's file when the task matches its description.
If a skill's <version> differs from a previous turn, re-read its SKILL.md before using it.
When a skill file references a relative path, resolve it against the skill directory (parent of SKILL.md / dirname of the path) and use that absolute path in tool commands.

<available_skills>
  <skill>
    <name>browser-automation</name>
    <description>Use when controlling web pages with the OpenClaw browser tool, especially multi-step flows, login checks, tab management, or recovery from stale refs/timeouts.</description>
    <location>~/.openclaw/plugin-skills/browser-automation/SKILL.md</location>
    <version>sha256:c24be5084b5d93ea</version>
  </skill>
  <skill>
    <name>canvas</name>
    <description>Present HTML on connected OpenClaw node canvases, navigate/eval/snapshot, and debug canvas host URLs.</description>
    <location>/usr/local/lib/node_modules/openclaw/skills/canvas/SKILL.md</location>
    <version>sha256:7419e23f242397b3</version>
  </skill>
  <skill>
    <name>diagram-maker</name>
    <description>Create SVG/HTML or Excalidraw diagrams for concepts, architecture, flows, and whiteboards.</description>
    <location>/usr/local/lib/node_modules/openclaw/skills/diagram-maker/SKILL.md</location>
    <version>sha256:6195e03fcb04a1a6</version>
  </skill>
  <skill>
    <name>healthcheck</name>
    <description>Audit/harden OpenClaw hosts: SSH, firewall, updates, exposure, backups, disk encryption, gateway security.</description>
    <location>/usr/local/lib/node_modules/openclaw/skills/healthcheck/SKILL.md</location>
    <version>sha256:518ec6e0482cf1c7</version>
  </skill>
  <skill>
    <name>meme-maker</name>
    <description>Search meme templates, suggest formats, and generate local or hosted image memes.</description>
    <location>/usr/local/lib/node_modules/openclaw/skills/meme-maker/SKILL.md</location>
    <version>sha256:8b8832f9f0f58b16</version>
  </skill>
  <skill>
    <name>node-connect</name>
    <description>Diagnose OpenClaw Android, iOS, or macOS node pairing, QR/setup code, route, auth, and connection failures.</description>
    <location>/usr/local/lib/node_modules/openclaw/skills/node-connect/SKILL.md</location>
    <version>sha256:cc39026fd84e5cfa</version>
  </skill>
  <skill>
    <name>node-inspect-debugger</name>
    <description>Debug Node.js with node inspect, --inspect, breakpoints, CDP, heap, and CPU profiles.</description>
    <location>/usr/local/lib/node_modules/openclaw/skills/node-inspect-debugger/SKILL.md</location>
    <version>sha256:50d2f6828eaf4bbf</version>
  </skill>
  <skill>
    <name>notion</name>
    <description>Notion CLI/API for pages, Markdown content, data sources, files, comments, search, Workers, and raw API calls.</description>
    <location>/usr/local/lib/node_modules/openclaw/skills/notion/SKILL.md</location>
    <version>sha256:d45e2c1270d58c78</version>
  </skill>
  <skill>
    <name>openclaw-nextcloud</name>
    <description>Manage Notes, Tasks, Calendar, Files, and Contacts in your Nextcloud instance via CalDAV, WebDAV, and Notes API. Use for creating notes, managing todos and calendar events, uploading/downloading files, and managing contacts.</description>
    <location>~/shared/skills/openclaw-nextcloud/SKILL.md</location>
    <version>sha256:55aa4146eb912574</version>
  </skill>
  <skill>
    <name>python-debugpy</name>
    <description>Debug Python with pdb, breakpoint(), post-mortem inspection, and debugpy remote attach.</description>
    <location>/usr/local/lib/node_modules/openclaw/skills/python-debugpy/SKILL.md</location>
    <version>sha256:bfb1891204b67260</version>
  </skill>
  <skill>
    <name>skill-creator</name>
    <description>Create, edit, audit, tidy, validate, or restructure AgentSkills and SKILL.md files.</description>
    <location>/usr/local/lib/node_modules/openclaw/skills/skill-creator/SKILL.md</location>
    <version>sha256:9e971bac63ad787f</version>
  </skill>
  <skill>
    <name>slack</name>
    <description>Slack tool actions: send/read/edit/delete messages, react, pin/unpin, list pins/reactions/emoji, member info.</description>
    <location>/usr/local/lib/node_modules/openclaw/skills/slack/SKILL.md</location>
    <version>sha256:76003d7833efbd6c</version>
  </skill>
  <skill>
    <name>spike</name>
    <description>Run throwaway prototypes to validate feasibility, compare approaches, and report a verdict.</description>
    <location>/usr/local/lib/node_modules/openclaw/skills/spike/SKILL.md</location>
    <version>sha256:1258cde2d0e53267</version>
  </skill>
  <skill>
    <name>taskflow</name>
    <description>Coordinate multi-step detached tasks as one durable TaskFlow job with owner context, state, waits, and child tasks.</description>
    <location>/usr/local/lib/node_modules/openclaw/skills/taskflow/SKILL.md</location>
    <version>sha256:d8b6a48d329aef0a</version>
  </skill>
  <skill>
    <name>taskflow-inbox-triage</name>
    <description>Example TaskFlow pattern for inbox triage, intent routing, waiting on replies, and later summaries.</description>
    <location>/usr/local/lib/node_modules/openclaw/skills/taskflow-inbox-triage/SKILL.md</location>
    <version>sha256:1fe28cd924d8ae2d</version>
  </skill>
  <skill>
    <name>weather</name>
    <description>Current weather and forecasts with web_fetch, falling back to wttr.in curl for locations, rain, temperature, travel planning.</description>
    <location>/usr/local/lib/node_modules/openclaw/skills/weather/SKILL.md</location>
    <version>sha256:62ab4821aa873949</version>
  </skill>
</available_skills>