# AGENTS.md – Arbeitsweise für Coding-Agenten (Claude Code, Codex, Hermes …) Dieses Repo beschreibt den Proxmox-/k3s-Cluster **knaster** und den Router-Service `knaster`. Wer hier als Agent arbeitet, ändert **Infrastruktur, die läuft**. Erst lesen: [project-map.md](project-map.md) (was wo läuft), [known-issues.md](known-issues.md) (bekannte Fallen), der Aufbauplan [docs/superpowers/plans/2026-10-12-aufbau-cluster-knaster.md](docs/superpowers/plans/2026-10-12-aufbau-cluster-knaster.md) (was offen ist) und [docs/BETRIEB.md](docs/BETRIEB.md) (wie man es betreibt). ## Sprache und Stil - Deutsch in Doku, Kommentaren, Commit-Nachrichten und Antworten; Umlaute ausschreiben (ä, ö, ü, ß). - Code so schreiben wie der umgebende Code: Kommentardichte, Benennung, Muster (Playbook-Kopf mit Zweck und Aufruf, Manifest-Kopf mit Zweck und Herkunft). - Daten mit Datum notieren (`19.10.`), keine relativen Angaben („gestern“). ## Der Weg jeder Änderung 1. **Im Repo ändern** (auf dem Admin-Laptop bzw. dem Gerät der verwaltenden Person). Nie direkt auf ops oder in einer VM editieren; `/root/cluster-knaster` auf ops und `/opt/knaster/repo` auf infra sind Kopien. 2. **Prüfen:** `make test` (bzw. `pytest core`), `make lint`, bei Ansible `ansible-playbook --syntax-check` auf ops, bei Prometheus `promtool check config`/`check rules` (läuft im Prometheus-Image auf infra). 3. **Committen und pushen** (Branch laut Plan, derzeit `plan/aufbau-2026-10-12`). Nur eigene Dateien stagen – es arbeiten oft mehrere Sitzungen parallel im selben Repo. Vor dem Push `git pull --rebase`. 4. **Auf ops ausrollen:** `ssh ops`, `cd /root/cluster-knaster && git pull`, dann in `platform/proxmox/ansible` das passende Playbook. `kubectl`, `tofu` und Ansible gibt es **nur auf ops**. 5. **Live prüfen** (Pods bereit, Dienst antwortet, Prometheus-Ziel `up`) und erst dann abhaken. 6. **Plan und Doku nachziehen:** Checkbox im Aufbauplan mit Datum und Befund, Betriebswissen in `docs/BETRIEB.md`, neue Fallen in `known-issues.md`, neue Dienste/Adressen in `project-map.md`. ## Zugang - Einstieg ist **ops** (`192.168.100.173`, Bastion). Von dort erreicht man alle Knoten, VMs und infra mit dem Schlüssel `root@ops`; Ansible-Inventar `platform/proxmox/ansible/inventory.yml` (+ `inventory.generated.yml`). - Wer verwaltet, steht in `sites/knaster/proxmox.yaml` unter `access.ops_ssh_keys` (Playbook `playbooks/admins.yml`, Übergabe: BETRIEB §15). Proxmox-Weboberfläche nur mit persönlichem Konto und TOTP. - Muster für Befehle vom Laptop: `ssh ops ''`, `ssh ops 'cd /root/cluster-knaster/platform/proxmox/ansible && ansible-playbook playbooks/.yml'`. In Ansible-Ad-hoc-Befehlen keine Go-Templates (`{{.Names}}`) – Ansible wertet `{{ }}` selbst aus; besser ein kleines Skript mit `-m script`. ## Feste Regeln - **Keine Geheimnisse im Repo.** Tokens und Passwörter liegen auf ops unter `/root/.config/knaster/` (0600), im LXC infra unter `/opt/knaster/infra/.env` bzw. `secrets/`, beim Menschen in Password Depot. Playbooks lesen sie von dort, Ausgaben mit `no_log: true`. - **Dry-Run:** Healer und Router laufen mit `KNASTER_DRY_RUN=true`, `enabled_actions: []`. Nicht ohne ausdrückliche Freigabe des Nutzers ändern. - **IP-Literale statt DNS-Namen** in Konfigurationen (Netz `192.168.100.0/24`, Gateway `.1`, DNS `.120`). Adressen der GPU-VMs und der k3s-VM kommen per DHCP; Prometheus-Ziele deshalb per file_sd, nicht fest. - **GPUs:** In jeder GPU-VM ist Index 0 die Quadro M4000, Index 1 die P2000 (gpu-pve52 hat nur die M4000). `nvidia.com/gpu` in k3s vergibt **nur die M4000**. Die P2000 gehört llama.cpp (fest per UUID). Neue GPU-Pods bekommen also eine M4000; eine P2000 nur nach Absprache. - **Was nach k3s umgezogen ist, nicht wieder per Compose starten:** `playbooks/nex-speech.yml` und `playbooks/gpu-llamacpp.yml` brechen ab (Schalter nur für den Rückweg). - **Images pinnen** (exakte Version, kein `latest`); bei k3s-Pods mit eigenem Build `imagePullPolicy: Never` und Import per `docker save | k3s ctr images import -` (Muster: Rolle `nex-speech-k3s`, `gpu-llamacpp` `tasks/k3s.yml`). - **Infra-LXC hat 4 GB RAM:** neue Prometheus-Jobs mit `metric_relabel_configs` auf das Nötige begrenzen. - **Nach außen wirkende oder schwer umkehrbare Schritte** (Produktion auf appsrv08, DNS/DHCP, Löschen, Firewall, Neustart von Knoten) vorher mit dem Nutzer abstimmen. Die Firewall-Rolle hat einen Totmannschalter, trotzdem vorher prüfen, dass die eigene Adresse in `firewall.management` steht. - **Namespace `nex`** gehört NEX (nex-admin legt dort Agenten an). Änderungen dort mit dem NEX-Team abstimmen. ## Muster im Repo | Aufgabe | Vorlage | |---|---| | Neuer Dienst in k3s | `deploy/k8s//` + `playbooks/-k3s.yml` (z. B. `nex-searxng`, `monitoring`) | | Dienst mit GPU/Host-Netz in einer VM | `deploy/k8s/nex-speech/`, `deploy/k8s/llamacpp/llamacpp.yaml.j2` | | Zugang für eine Anwendung zur k8s-API | `deploy/k8s/nex/admin-access.yaml` (ServiceAccount, Role, Token-Secret), Token-Datei auf ops | | Neues Prometheus-Ziel | `deploy/prometheus/prometheus.yml`; wechselnde Adressen über `platform/proxmox/scripts/monitoring-targets.py` | | Neuer Alert | `deploy/prometheus/alerts.yml` **und** passende Regel in `config/healer-rules.yaml` (Test erzwingt das) | | Grafana-Dashboard | `deploy/grafana/dashboards/*.json`, Datasource-uid `prometheus`, Herkunft in `provisioning/dashboards/knaster.yml` | ## Testen unter Windows - `.venv\Scripts\python -m pytest core` – `test_tts_server` scheitert unter Windows (kein Piper), das ist bekannt. - `yamllint` meldet auf geänderten Dateien „wrong new line character“, weil Git die Arbeitskopie mit CRLF auscheckt. Für eine echte Prüfung den Stand aus Git prüfen: `git show HEAD: | .venv/Scripts/yamllint -s -c .yamllint.yml -`.