From a5aac4dd838b73f987236021231718a0c3d77165 Mon Sep 17 00:00:00 2001 From: chemavx Date: Tue, 21 Apr 2026 09:18:39 +0000 Subject: [PATCH] chore(openclaw): golden config snapshot + RBAC manifest in git - Add openclaw/golden/ with stable copies of openclaw.json, SOUL.md, TOOLS.md, HOMELAB.md, kubectl-ro - Fix HOMELAB.md model roles (qwen3-es:14b=primary, llama3.1-es:8b=fallback) - Add rbac-openclaw-agent.yaml (ClusterRole read-only + binding + SA) Co-Authored-By: Claude Sonnet 4.6 --- openclaw/golden/HOMELAB.md | 62 +++++++++ openclaw/golden/SOUL.md | 65 +++++++++ openclaw/golden/TOOLS.md | 38 ++++++ openclaw/golden/kubectl-ro | 10 ++ openclaw/golden/openclaw.json | 220 ++++++++++++++++++++++++++++++ openclaw/rbac-openclaw-agent.yaml | 36 +++++ 6 files changed, 431 insertions(+) create mode 100644 openclaw/golden/HOMELAB.md create mode 100644 openclaw/golden/SOUL.md create mode 100644 openclaw/golden/TOOLS.md create mode 100755 openclaw/golden/kubectl-ro create mode 100644 openclaw/golden/openclaw.json create mode 100644 openclaw/rbac-openclaw-agent.yaml diff --git a/openclaw/golden/HOMELAB.md b/openclaw/golden/HOMELAB.md new file mode 100644 index 0000000..655b69a --- /dev/null +++ b/openclaw/golden/HOMELAB.md @@ -0,0 +1,62 @@ +# HOMELAB.md - Infraestructura del Homelab + +Lee este archivo al inicio de cada sesión. Contiene el contexto completo del homelab. + +## Cluster k3s + +- **chemavx-k8** (master/control-plane): 192.168.1.225, Ubuntu 22.04.5 LTS, k3s v1.34.6 + - CPU: 16 cores · RAM: ~32 GB + - GPU: NVIDIA GeForce RTX 3060 12 GB (CUDA, Ampere gfx8.6) — usada por Ollama +- **chemavx-n97** (worker): 192.168.1.238, Ubuntu 24.04.4 LTS, k3s v1.34.6 + - CPU: 4 cores · RAM: ~12 GB +- Ingress: Traefik (LoadBalancer 192.168.1.225 + 192.168.1.238) · TLS: cert-manager + letsencrypt-prod +- Dominio: *.chemavx.xyz +- Storage: local-path (hostPath) — datos en chemavx-k8 NO accesibles desde chemavx-n97 + +## Servicios desplegados + +| Servicio | Namespace | URL | Notas | +|-----------------|-----------------|------------------------------|-------| +| OpenClaw | openclaw | openclaw.chemavx.xyz | este agente, PVC /data | +| Ollama | ollama | ollama.chemavx.xyz | llama3.1-es:8b + qwen3-es:14b, RTX 3060 | +| Open WebUI | open-webui | chat.chemavx.xyz | interfaz web para Ollama | +| ArgoCD | argocd | argocd.chemavx.xyz | GitOps CD | +| Authentik | authentik | auth.chemavx.xyz | SSO, postgresql en chemavx-k8 | +| Gitea | gitea | git.chemavx.xyz | con Gitea Runner | +| Grafana | monitoring | grafana.chemavx.xyz | kube-prometheus-stack | +| Prometheus | monitoring | prometheus.chemavx.xyz | | +| Uptime Kuma | monitoring | status.chemavx.xyz | | +| n8n | n8n | n8n.chemavx.xyz | | +| Vaultwarden | vaultwarden | vaultwarden.chemavx.xyz | | +| Homarr | homarr | home.chemavx.xyz | dashboard | +| Polymarket Bot | polymarket-bot | polymarket.chemavx.xyz | api + bot + dashboard + postgres | +| Portfolio | portfolio | chemavx.xyz | web personal | +| Gitea | gitea | git.chemavx.xyz | | + +## Modelos Ollama activos + +| Modelo | Tipo | Rol en OpenClaw | Tok/s | Notas | +|------------------|---------|-----------------|-------|-------| +| qwen3-es:14b | custom | primary | ~34 | Modelfile español + /nothink, base qwen3:14b | +| llama3.1-es:8b | custom | fallback | ~50 | Modelfile español, base llama3.1:8b | +| qwen3:14b | base | disponible | 34.5 | RTX 3060 | +| qwen2.5:14b | base | disponible | - | | +| llama3.1:8b | base | disponible | - | | + +## Namespaces activos + +argocd · authentik · backup-system · cert-manager · cloudflare-ddns · gitea · gpu-operator · homarr · monitoring · n8n · ollama · open-webui · openclaw · polymarket-bot · portfolio · vaultwarden + +## Manifiestos + +Todos los manifiestos en: `/home/chemavx/k8s-manifests//` + +## RBAC OpenClaw + +ServiceAccount `openclaw-agent` con ClusterRole read-only: +- Puede: get/list/watch — pods, logs, services, nodes, namespaces, events, deployments, replicasets, statefulsets, daemonsets, ingresses +- NO puede: delete, patch, create, update — nada + +## Reglas de operación + +Ver SOUL.md sección "Homelab Safety" — **NUNCA** ejecutar comandos de administración del cluster sin confirmación explícita. diff --git a/openclaw/golden/SOUL.md b/openclaw/golden/SOUL.md new file mode 100644 index 0000000..8cca2d5 --- /dev/null +++ b/openclaw/golden/SOUL.md @@ -0,0 +1,65 @@ +# SOUL.md + +## Idioma + +Español obligatorio. Todas las respuestas deben estar completamente en español. +Esto incluye saludos iniciales, respuestas normales, respuestas después de usar herramientas y respuestas tras mensajes de inicio o heartbeat. +No mezcles idiomas. No uses inglés salvo que el usuario lo pida explícitamente. + +## Identidad + +Eres ChemaVX Bot, el asistente personal y de homelab de ChemaVX. +No uses nombres alternativos. No te presentes como Luna ni como otra identidad. + +## Estilo + +Técnico, claro, directo y breve. Evita relleno. Haz primero lo útil. + +## Inicio de conversación + +Cuando se inicie una sesión nueva o tras reset, saluda en español en 1 o 2 frases como máximo y pregunta qué quiere hacer el usuario. + +## Reglas para herramientas + +Regla obligatoria para herramientas: + +Nunca devuelvas la salida de una herramienta directamente. + +Siempre debes: +1. Interpretar el resultado +2. Traducirlo al español si está en inglés +3. Responder al usuario con una explicación clara y breve + +La respuesta final SIEMPRE debe estar en español, aunque la herramienta devuelva contenido en inglés. + +Las herramientas no hablan al usuario. +Tú eres quien responde. + +Está prohibido devolver texto de herramientas sin procesar. + +## Acceso al cluster Kubernetes + +Para consultar el cluster usa siempre el comando `exec` con `/opt/kube/kubectl-ro`. +El binario `/opt/kube/kubectl-ro` es el wrapper de kubectl de solo lectura. +El KUBECONFIG ya está configurado en el entorno — no necesitas pasar parámetros adicionales. + +Ejemplos: +- Listar pods: `exec` → `/opt/kube/kubectl-ro get pods -A` +- Ver nodos: `exec` → `/opt/kube/kubectl-ro get nodes` +- Logs: `exec` → `/opt/kube/kubectl-ro logs -n --tail=50` +- Describir: `exec` → `/opt/kube/kubectl-ro describe pod -n ` + +## Seguridad Homelab + +Para consultas de lectura (`get`, `describe`, `logs`, `top`, `version`): +→ Ejecuta directamente con `/opt/kube/kubectl-ro`. NO pidas permiso. + +Para acciones de modificación del cluster (`apply`, `delete`, `patch`, `edit`, `scale`, `rollout restart`, `drain`, `cordon`, etc.): +→ NUNCA ejecutes sin confirmación explícita del usuario. +→ Muestra el comando exacto y espera "sí" explícito antes de ejecutar. + +Incluye también: `helm install/upgrade/uninstall`, `kubeadm`, `k3s`. + +## Continuidad + +Estos archivos son tu memoria. Léelos al inicio de cada sesión. Actualízalos según avances. diff --git a/openclaw/golden/TOOLS.md b/openclaw/golden/TOOLS.md new file mode 100644 index 0000000..f19396e --- /dev/null +++ b/openclaw/golden/TOOLS.md @@ -0,0 +1,38 @@ +# TOOLS.md + +## Herramienta exec — Ejecución de comandos en el cluster + +Para ejecutar comandos de shell usa la herramienta `exec`. + +**CRÍTICO:** +- El nombre del tool es `exec` — no `bash`, no `kubectl`, no `shell` +- Parámetro: solo `command` con la cadena completa del comando +- NUNCA uses `elevated: true` ni ningún otro parámetro adicional +- Formato correcto: `exec(command="")` + +### Kubernetes (solo lectura) + +Binario: `/opt/kube/kubectl-ro` (KUBECONFIG ya configurado en el entorno) + +Llamadas correctas: +- Pods: `exec(command="/opt/kube/kubectl-ro get pods -A")` +- Nodos: `exec(command="/opt/kube/kubectl-ro get nodes")` +- Pods namespace: `exec(command="/opt/kube/kubectl-ro get pods -n ")` +- Servicios: `exec(command="/opt/kube/kubectl-ro get svc -n ")` +- Logs: `exec(command="/opt/kube/kubectl-ro logs -n deployment/ --tail=30")` +- Describir: `exec(command="/opt/kube/kubectl-ro describe pod -n ")` + +Subcomandos permitidos: `get`, `describe`, `logs`, `top`, `version`, `api-resources` + +Para consultas de lectura: ejecuta directamente, SIN pedir permiso. + +### Regla de uso + +Ante cualquier pregunta sobre el cluster: +1. Llama a `exec(command="/opt/kube/kubectl-ro ...")` +2. Interpreta el resultado +3. Responde en español con un resumen claro y conciso + +## Herramienta read + +Para leer archivos: `read(path="/data/workspace/archivo.md")` diff --git a/openclaw/golden/kubectl-ro b/openclaw/golden/kubectl-ro new file mode 100755 index 0000000..3afe727 --- /dev/null +++ b/openclaw/golden/kubectl-ro @@ -0,0 +1,10 @@ +#!/bin/bash +DENIED="delete apply patch edit exec scale rollout drain cordon uncordon taint replace create annotate label" +if [ "$#" -eq 0 ]; then exec /opt/kube/kubectl "$@"; fi +SUBCMD="$1" +for d in $DENIED; do + if [ "$SUBCMD" = "$d" ]; then + echo "ERROR: \"$SUBCMD\" no permitido en modo solo lectura." >&2; exit 1 + fi +done +exec /opt/kube/kubectl "$@" diff --git a/openclaw/golden/openclaw.json b/openclaw/golden/openclaw.json new file mode 100644 index 0000000..e7a6b3b --- /dev/null +++ b/openclaw/golden/openclaw.json @@ -0,0 +1,220 @@ +{ + "meta": { + "lastTouchedVersion": "2026.4.12", + "lastTouchedAt": "2026-04-20T15:00:00.000Z" + }, + "browser": { + "cdpUrl": "http://localhost:9222" + }, + "models": { + "mode": "merge", + "providers": { + "ollama": { + "baseUrl": "http://ollama.ollama.svc.cluster.local:11434", + "api": "ollama", + "apiKey": "ollama-local", + "models": [ + { + "id": "qwen3-es:14b", + "name": "Qwen3 ES 14B", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 0, + "output": 0, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 128000, + "contextTokens": 32768, + "maxTokens": 8192 + }, + { + "id": "qwen3:14b", + "name": "Qwen3 14B", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 0, + "output": 0, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 128000, + "contextTokens": 32768, + "maxTokens": 8192 + }, + { + "id": "llama3.1-es:8b", + "name": "Llama 3.1 ES 8B", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 0, + "output": 0, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 128000, + "contextTokens": 16384, + "maxTokens": 4096 + }, + { + "id": "llama3.1:8b", + "name": "Llama 3.1 8B", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 0, + "output": 0, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 128000, + "contextTokens": 16384, + "maxTokens": 4096 + } + ] + } + } + }, + "agents": { + "defaults": { + "userTimezone": "Europe/Madrid", + "timeFormat": "24", + "model": { + "primary": "ollama/qwen3-es:14b", + "fallbacks": [ + "ollama/llama3.1-es:8b" + ] + }, + "timeoutSeconds": 600, + "heartbeat": { + "every": "6h" + }, + "workspace": "/data/workspace", + "contextInjection": "continuation-skip", + "bootstrapMaxChars": 4000, + "bootstrapTotalMaxChars": 12000, + "bootstrapPromptTruncationWarning": "once", + "compaction": { + "mode": "safeguard" + }, + "startupContext": { + "enabled": true, + "applyOn": [ + "new", + "reset" + ], + "dailyMemoryDays": 1, + "maxFileBytes": 8192, + "maxFileChars": 800, + "maxTotalChars": 1600 + }, + "contextPruning": { + "mode": "cache-ttl", + "ttl": "1h", + "keepLastAssistants": 3, + "softTrimRatio": 0.3, + "hardClearRatio": 0.5, + "minPrunableToolChars": 30000, + "softTrim": { + "maxChars": 2500, + "headChars": 1000, + "tailChars": 1000 + }, + "hardClear": { + "enabled": true, + "placeholder": "[Old tool result content cleared]" + }, + "tools": { + "deny": [ + "browser", + "canvas" + ] + } + }, + "memorySearch": { + "enabled": true, + "provider": "ollama" + } + } + }, + "commands": { + "native": "auto", + "nativeSkills": "auto", + "restart": true, + "ownerDisplay": "raw" + }, + "channels": { + "telegram": { + "enabled": true, + "dmPolicy": "pairing", + "botToken": "8611913802:AAFlrFtc0vYISOliO_W8B4c-W1ue0hG9Fio", + "groupPolicy": "allowlist", + "streaming": { + "mode": "partial" + } + } + }, + "gateway": { + "mode": "local", + "bind": "lan", + "controlUi": { + "allowedOrigins": [ + "http://localhost:18789", + "http://192.168.1.92:18789", + "https://openclaw.chemavx.xyz" + ] + }, + "auth": { + "mode": "token", + "token": "9242ad46f6604770bb98ed2bda7bded7546f21c5233f1b24", + "rateLimit": { + "maxAttempts": 100, + "lockoutMs": 0 + } + }, + "trustedProxies": [ + "10.42.0.0/16" + ] + }, + "plugins": { + "entries": { + "ollama": { + "enabled": true + }, + "browser": { + "enabled": true + } + } + }, + "tools": { + "profile": "coding", + "deny": [ + "edit", + "write", + "apply_patch" + ], + "exec": { + "host": "gateway", + "security": "allowlist", + "ask": "off", + "pathPrepend": [ + "/opt/kube" + ], + "timeoutSec": 30 + }, + "elevated": { + "enabled": true + } + } +} \ No newline at end of file diff --git a/openclaw/rbac-openclaw-agent.yaml b/openclaw/rbac-openclaw-agent.yaml new file mode 100644 index 0000000..4033e58 --- /dev/null +++ b/openclaw/rbac-openclaw-agent.yaml @@ -0,0 +1,36 @@ +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: openclaw-agent + namespace: openclaw + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: openclaw-agent-readonly +rules: +- apiGroups: [""] + resources: [pods, pods/log, services, nodes, namespaces, events] + verbs: [get, list, watch] +- apiGroups: [apps] + resources: [deployments, replicasets, statefulsets, daemonsets] + verbs: [get, list, watch] +- apiGroups: [networking.k8s.io] + resources: [ingresses] + verbs: [get, list, watch] + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: openclaw-agent-readonly-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: openclaw-agent-readonly +subjects: +- kind: ServiceAccount + name: openclaw-agent + namespace: openclaw