docs: LICENCE.md-Feature, .gitignore, Single-GPU-Doku

- pi-coder-judge-extension.ts: licenceMd() + writeLicenceMd() — erzeugt
  proprietäre LICENCE.md in der Doku-Phase (nur wenn noch nicht vorhanden)
- tests: Guards und pure-logic-Tests für LICENCE.md ergänzt (38 Tests, alle grün)
- .gitignore: Node, TypeScript-Artefakte, Backups, Editor-Dateien, OS-Metadaten
- README.md + BEDIENUNGSANLEITUNG.md: vollständig auf Single-GPU-Architektur
  aktualisiert (ein Server, System-Prompt-Rollen, kein Quick-Judge,
  PASS WITH CONCERNS-Verhalten, LICENCE.md in /update_doku, start-single.sh)
- SINGLE_SERVER_PLAN.md: entfernt (umgesetzt, kein Mehrwert mehr)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-06-15 05:03:50 +02:00
commit 485ab30265
7 changed files with 297 additions and 357 deletions

View file

@ -1,8 +1,8 @@
# Bedienungsanleitung: pi_coder
pi_coder ist ein Werkzeug, das zwei lokale KI-Modelle als **Coder** und **Judge** einsetzt,
um Software automatisch zu schreiben, zu prüfen und zu verbessern — alles gesteuert über
einfache Slash-Kommandos in der pi-Agent-Oberfläche.
pi_coder ist ein Werkzeug, das ein lokales KI-Modell abwechselnd als **Coder** und **Judge**
einsetzt, um Software automatisch zu schreiben, zu prüfen und zu verbessern — alles gesteuert
über einfache Slash-Kommandos in der pi-Agent-Oberfläche.
---
@ -25,17 +25,22 @@ einfache Slash-Kommandos in der pi-Agent-Oberfläche.
## 1. Konzept: Coder und Judge
pi_coder verwendet zwei Rollen:
pi_coder verwendet zwei Rollen — bedient von **einem einzigen Modell**, das je nach Aufgabe
eine andere Persona annimmt:
**Coder** (Port 8001): Schreibt und repariert Code. Liest die Aufgabe aus `TASK.md`,
implementiert sie, führt Tests aus und erstellt Git-Commits.
**Coder-Persona**: Schreibt und repariert Code. Liest die Aufgabe aus `TASK.md`, implementiert
sie, führt Tests aus und erstellt Git-Commits.
**Judge** (Port 8002): Überprüft den Code mit dem Blick eines skeptischen Senior-Entwicklers.
**Judge-Persona**: Überprüft den Code mit dem Blick eines skeptischen Senior-Entwicklers.
Prüft Korrektheit, Robustheit, Randfälle, Sicherheit und Produktionsreife. Gibt ein Urteil:
- `PASS` — Code ist in Ordnung
- `PASS WITH CONCERNS` — grundsätzlich akzeptabel, aber mit Anmerkungen
- `PASS WITH CONCERNS` — hat Anmerkungen, die behoben werden müssen (wird wie `FAIL` behandelt,
außer du verwendest `--approve-concerns`)
- `FAIL` — enthält Blocker, die behoben werden müssen
Die Umschaltung zwischen den Rollen erfolgt über unterschiedliche System-Prompts, die die
Extension automatisch vor jeder Inference einsetzt. Es läuft kein zweiter Server.
Der Grundgedanke: Coder und Judge haben keine „Höflichkeitsschranke" zueinander —
der Judge kritisiert direkt und konkret, der Coder repariert ohne Widerspruch.
@ -47,14 +52,14 @@ der Judge kritisiert direkt und konkret, der Coder repariert ohne Widerspruch.
```bash
cd ~/pi_coder
./start-servers.sh
./start-single.sh
```
Ausgabe bei Erfolg:
```
[*] Starte beide Server parallel ...
[✓] Coder (:8001) bereit
[✓] Judge (:8002) bereit
[*] Verwende HF_HOME = /home/.../huggingface
[*] GPU device = 1
[✓] Single-Server (:8001) bereit
```
Dauer: bis zu 5 Minuten (Modell wird in GPU-VRAM geladen; neuere llama.cpp-Versionen
@ -68,8 +73,7 @@ prüfen beim Start die VRAM-Verfügbarkeit, was zusätzliche Zeit kostet).
```
=== LLaMA-Server Status ===
qwen36-27b-coder (Port 8001): Container=RUNNING HTTP=OK
qwen36-27b-judge (Port 8002): Container=RUNNING HTTP=OK
qwen36-27b-single (Port 8001): Container=RUNNING HTTP=OK
```
### pi agent öffnen
@ -86,53 +90,41 @@ pi
## 3. Server starten und stoppen
### GPU-Zuordnung (3-GPU-Setup)
### GPU-Zuordnung
Bei einem System mit drei GPUs sind die Rollen fest in den Startskripten verankert —
**keine manuelle Konfiguration nötig:**
Der Server läuft standardmäßig auf **GPU 1** (überschreibbar):
| GPU | Modell | Rolle |
|-----|--------|-------|
| GPU 0 (NVIDIA T600) | — | Display / Monitor — wird von den Skripten nicht angetastet |
| GPU 1 (RTX 3090, 24 GB) | Qwen3.6-27B | **Coder** (Port 8001) |
| GPU 2 (RTX 3090, 24 GB) | Qwen3.6-27B | **Judge** (Port 8002) |
```bash
./start-single.sh # GPU 1 (Standard)
GPU_DEVICE=0 ./start-single.sh # GPU 0
```
Jeder Server bekommt seine eigene GPU exklusiv — so gibt es keinen VRAM-Konflikt,
auch wenn beide gleichzeitig laufen.
Auf einem System mit mehreren GPUs empfiehlt es sich, GPU 0 (Display) freizuhalten
und GPU 1 für den KI-Server zu verwenden.
**Wichtig:** Andere GPU-Prozesse (z. B. TTS-Dienste, Ollama) auf GPU 1 oder GPU 2 können
VRAM belegen und dazu führen, dass ein Server nicht startet. Im Zweifel prüfen:
**Wichtig:** Andere GPU-Prozesse (z. B. TTS-Dienste, Ollama) auf der verwendeten GPU
können VRAM belegen und dazu führen, dass der Server nicht startet. Im Zweifel prüfen:
```bash
nvidia-smi --query-gpu=index,name,memory.used,memory.free --format=csv
```
### Beide starten (empfohlen)
### Server starten
```bash
cd ~/pi_coder
./start-servers.sh
./start-single.sh
```
Erwartete Ausgabe:
```
[*] Starte beide Server parallel ...
[✓] Coder (:8001) bereit
[✓] Judge (:8002) bereit
[*] Verwende HF_HOME = /home/.../huggingface
[*] GPU device = 1
[✓] Single-Server (:8001) bereit
```
Dauer: bis zu 5 Minuten. Danach sind beide Modelle im VRAM und sofort antwortbereit.
Dauer: bis zu 5 Minuten. Danach ist das Modell im VRAM und sofort antwortbereit.
### Einzelnen Server neu starten
Z.B. wenn nur der Judge-Server abgestürzt ist:
```bash
./start-judge.sh # Port 8002, GPU 2
# oder:
./start-coder.sh # Port 8001, GPU 1
```
### Beide stoppen
### Server stoppen
```bash
./stop-servers.sh
@ -149,7 +141,7 @@ Z.B. wenn nur der Judge-Server abgestürzt ist:
Falls die GGUF-Datei an einem anderen Ort liegt:
```bash
HF_HOME=/mnt/daten/huggingface ./start-servers.sh
HF_HOME=/mnt/daten/huggingface ./start-single.sh
```
---
@ -235,7 +227,7 @@ Der Judge:
3. Führt Tests aus
4. Gibt ein strukturiertes Urteil aus
**Beispiel-Ausgabe PASS:**
**Beispiel-Ausgabe PASS WITH CONCERNS:**
```
Urteil: PASS WITH CONCERNS
@ -326,17 +318,22 @@ Empfohlene Sofortmaßnahmen: keine
- `--continue` — überspringt die Implementierungsphase und startet direkt mit dem
Judge→Fix-Zyklus ab dem aktuellen Code-Stand. Nützlich wenn man bereits manuell
`/coder`, `/judge` und `/fix` durchgeführt hat und den Rest automatisieren möchte.
Im `--continue`-Modus werden Coder- und Judge-Server gleichzeitig geprüft.
- `--interactive` — pausiert nach erstem PASS für einen menschlichen Checkpoint.
Details: siehe [Interactive-Modus](#interactive-modus) weiter unten.
- `--no-tests` — überspringt die automatische Test-Erkennung. Sinnvoll wenn keine
Test-Suite vorhanden ist oder Tests über externe Infrastruktur laufen.
- `--approve-concerns` — behandelt „PASS WITH CONCERNS" wie „PASS": kein ShipIt-Call,
direktes SHIP. Für Projekte, bei denen du dem Judge-Urteil vertraust.
direktes SHIP. Standardmäßig löst PASS WITH CONCERNS immer einen Coder-Fix aus.
- `--test-cmd "befehl"` — überschreibt die automatische Test-Erkennung mit einem
eigenen Befehl (z.B. `--test-cmd "pytest tests/ -x"`).
- `--test-timeout N` — maximale Laufzeit pro Test-Befehl in Sekunden (Standard: 120).
### PASS WITH CONCERNS — wichtig
Ohne `--approve-concerns` gilt `PASS WITH CONCERNS` **wie `FAIL`** — der Coder bekommt
einen Fix-Auftrag und der Loop geht weiter. Erst sauberes `PASS` beendet die Schleife.
Mit `--approve-concerns` gilt PASS WITH CONCERNS als bestanden.
### Beispiel: einfacher Auftrag
```
@ -346,31 +343,33 @@ Empfohlene Sofortmaßnahmen: keine
Was im Hintergrund passiert:
```
Phase 1: Coder implementiert...
Phase 2: Runde 1/2: Quick-Check (kompakter Erstcheck)...
Phase 2: Runde 1/2: Judge — TASK.md + letzter Commit + Tests...
→ Urteil: FAIL (2 Blocker)
Phase 3: Runde 1/2: Coder fixt...
Phase 4: Runde 2/2: Judge — TASK.md + letzter Commit + Tests...
→ Urteil: PASS WITH CONCERNS
✓ PASS WITH CONCERNS nach Runde 2
Finale ShipIt-Prüfung... (nur bei PASS WITH CONCERNS, nicht bei klarem PASS)
→ SHIP
→ Urteil: PASS
✓ PASS nach Runde 2 → SHIP
[Dialog: Version → v0.1.0 (empfohlen)]
```
**Runde 1 = Quick-Check:** Kompakter Prompt ohne TASK.md-Analyse — erkennt offensichtliche
Fehler schnell. Erst ab Runde 2 (oder bei `--continue`) kommt der vollständige Judge-Prompt.
Bei `PASS WITH CONCERNS` (ohne --approve-concerns):
```
→ Urteil: PASS WITH CONCERNS (Major: fehlendes --help)
Phase 3: Runde 2/2: Coder fixt Concerns...
Phase 4: Runde 3/3: Judge...
→ Urteil: PASS
✓ PASS → SHIP
```
Bei klarem `PASS` entfällt die ShipIt-Runde — es wird direkt SHIP ausgelöst.
Mit `--approve-concerns` gilt das auch für `PASS WITH CONCERNS`.
Während des Ablaufs zeigt die Statuszeile die aktuelle Phase — mit laufendem Timer,
der beweist, dass die LLM tatsächlich arbeitet (und nicht hängt):
Während des Ablaufs zeigt die Statuszeile die aktuelle Phase — mit laufendem Timer:
```
◉ Coder implementiert: Login-Flow mit JWT [01:23]
◉○ Runde 1/2: Quick-Check [00:47]
●◉ Runde 2/2: Coder fixt — fehlendes Null-Check [01:05]
●● ✓ PASS nach Runde 2/2 — ShipIt…
◉○ Runde 1/2: Judge — TASK.md + letzter Commit + Tests [00:47]
●◉ Runde 1/2: Coder fixt — fehlendes Null-Check [01:05]
●● ✓ PASS nach Runde 2/2 — SHIP
🚀 SHIP produktionsreif
```
@ -392,6 +391,7 @@ Nach SHIP werden automatisch ausgeführt:
1. Code-Kommentare einfügen
2. README.md schreiben
3. BEDIENUNGSANLEITUNG.md schreiben
4. LICENCE.md anlegen (falls noch nicht vorhanden)
### Vom manuellen Workflow in den automatischen wechseln
@ -415,7 +415,8 @@ Stand und der Fix-Zyklus läuft automatisch bis PASS oder max. N Runden.
### Loop-Erkennung
Wenn zweimal hintereinander genau dieselben Blocker auftreten, bricht `/optimize` ab:
Wenn zweimal hintereinander genau dieselben Blocker oder Concerns auftreten, bricht
`/optimize` ab:
```
⚠ Derselbe Blocker tritt erneut auf Schleife abgebrochen. Bitte manuell prüfen.
```
@ -563,11 +564,14 @@ Fix: Validierung in die Funktion generate_password() verschieben statt in parse_
## 8. Dokumentation generieren: /update_doku
Nach Abschluss der Entwicklung (nach `/shipit` oder `/optimize`) erstellt `/update_doku`
drei Dinge automatisch:
vier Dinge automatisch:
1. **Code-Kommentare** — erklärt das WARUM in den Quelldateien (Deutsch)
2. **README.md** — Entwicklerperspektive: Installation, Build, Verwendung
3. **BEDIENUNGSANLEITUNG.md** — Endnutzerperspektive: einfach, ohne Jargon
4. **LICENCE.md** — proprietäre Lizenz mit aktuellem Jahr und Inhaber aus `git config user.name`
(wird nur angelegt wenn noch keine `LICENCE.md` vorhanden ist — existierende Lizenzen
werden nie überschrieben)
```
/update_doku
@ -582,6 +586,7 @@ Nur geänderte Quelldateien werden neu kommentiert — unveränderte bleiben una
Code-Kommentare: keine Änderungen seit letztem Lauf übersprungen.
README.md: 2 Datei(en) geändert wird geprüft
BEDIENUNGSANLEITUNG.md: 2 Datei(en) geändert wird geprüft
LICENCE.md: bereits vorhanden übersprungen.
```
### Zusammen mit /optimize
@ -772,7 +777,7 @@ Die Checkboxen werden automatisch abgehakt:
# Für Projekte wo "PASS WITH CONCERNS" ausreicht:
/optimize "Kleines Refactoring" --approve-concerns
# Kombination: kein Test, kein ShipIt bei Concerns, 1 Runde
# Kombination: kein Test, PASS WITH CONCERNS akzeptieren, 1 Runde
/optimize "Typo-Fix in Fehlermeldungen" --rounds 1 --no-tests --approve-concerns
```
@ -851,7 +856,7 @@ Die Checkboxen werden automatisch abgehakt:
ls $HF_HOME/models/qwen3/
# Oder mit explizitem Pfad starten:
HF_HOME=/korrekter/pfad ./start-servers.sh
HF_HOME=/korrekter/pfad ./start-single.sh
```
### Server startet nicht / HTTP nicht erreichbar
@ -864,26 +869,26 @@ HF_HOME=/korrekter/pfad ./start-servers.sh
1. Zu wenig VRAM — Container bricht beim Laden ab:
```bash
docker logs qwen36-27b-coder | tail -50
docker logs qwen36-27b-single | tail -50
# Suche nach: "CUDA out of memory" oder "failed to allocate"
```
→ Kontext reduzieren: `-c 32768` statt `-c 131072`
→ Kontext reduzieren: `-c 65536` statt `-c 262144` in `start-single.sh`
2. GPU nicht verfügbar:
```bash
nvidia-smi # alle drei GPUs sichtbar?
# GPU 1 (Coder) testen:
nvidia-smi # GPU sichtbar?
# GPU 1 testen:
docker run --gpus '"device=1"' --rm nvidia/cuda:12.0-base nvidia-smi
# GPU 2 (Judge) testen:
docker run --gpus '"device=2"' --rm nvidia/cuda:12.0-base nvidia-smi
# Andere GPU testen:
GPU_DEVICE=0 ./start-single.sh
```
3. Port bereits belegt:
3. Port 8001 bereits belegt:
```bash
ss -tlnp | grep 800[12]
ss -tlnp | grep 8001
docker ps -a # alter Container noch vorhanden?
./stop-servers.sh
./start-servers.sh
./start-single.sh
```
### "Agent is already processing a prompt"
@ -914,8 +919,8 @@ Lies die Datei neu ein und wende die Änderungen als unified diff mit apply_patc
⚠ Derselbe Blocker tritt erneut auf Schleife abgebrochen.
```
**Ursache:** Der Coder kann einen bestimmten Blocker nicht beheben — z.B. weil die
Aufgabe einen Widerspruch enthält oder ein externes System fehlt.
**Ursache:** Der Coder kann einen bestimmten Blocker oder Concern nicht beheben — z.B.
weil die Aufgabe einen Widerspruch enthält oder ein externes System fehlt.
**Lösung:** Manuell eingreifen:
```
@ -927,9 +932,14 @@ Dann den Blocker analysieren und entweder:
- Die Aufgabe in TASK.md präzisieren
- Bei komplexen Aufgaben mit mehr Runden wiederholen: `/optimize --continue --rounds 5`
Falls der Judge wiederholt Concerns findet, die du akzeptierst:
```
/optimize --continue --approve-concerns
```
### Server läuft, aber pi wechselt nicht das Modell
**Ursache:** `models.json` wurde nach einer Änderung nicht neu deployt.
**Ursache:** `models.json` oder `settings.json` wurde nach einer Änderung nicht neu deployt.
**Lösung:**
```bash