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 <noreply@anthropic.com>
This commit is contained in:
@@ -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/<namespace>/`
|
||||
|
||||
## 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.
|
||||
@@ -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 <ns> <pod> --tail=50`
|
||||
- Describir: `exec` → `/opt/kube/kubectl-ro describe pod -n <ns> <pod>`
|
||||
|
||||
## 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.
|
||||
@@ -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="<comando completo>")`
|
||||
|
||||
### 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 <ns>")`
|
||||
- Servicios: `exec(command="/opt/kube/kubectl-ro get svc -n <ns>")`
|
||||
- Logs: `exec(command="/opt/kube/kubectl-ro logs -n <ns> deployment/<nombre> --tail=30")`
|
||||
- Describir: `exec(command="/opt/kube/kubectl-ro describe pod -n <ns> <pod>")`
|
||||
|
||||
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 <subcomando> ...")`
|
||||
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")`
|
||||
Executable
+10
@@ -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 "$@"
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user