# Runbook: BMAD Phase 4 Automation in Paperclip aufsetzen End-to-End-Anleitung, um von einer leeren Paperclip-Instanz zu einem laufenden BMAD-Phase-4-Autopilot mit drei Agents zu kommen. Arbeite sie in dieser Reihenfolge ab – jeder Schritt hat einen Verifikations-Check am Ende. **Zeit-Abschätzung:** 45-90 Min, wenn OpenCode und Paperclip schon installiert sind. Plus die Zeit, die BMAD für Phase 1-3 und manuelles Sprint Planning gebraucht hat. ## Voraussetzungen - BMAD V6 Phase 1-3 abgeschlossen: - `_bmad-output/planning-artifacts/PRD.md` - `_bmad-output/planning-artifacts/architecture.md` - Eine Epic-Quelle (siehe README für unterstützte Varianten) - **Sprint Planning manuell durchgeführt:** Du hast `bmad-sprint-planning` selbst ausgeführt, und `_bmad-output/implementation-artifacts/sprint-status.yaml` existiert. Der Supervisor erwartet diese Datei und weigert sich zu starten, wenn sie fehlt. - OpenCode CLI installiert, `opencode auth login` durchgeführt, Zugriff auf die gewünschten Modelle (das starke Code-Modell für Dev UND ein anderes Modell für QA) bestätigt. - Paperclip installiert und laufend (`paperclipai` lokal oder remote). - `PAPERCLIP_API_URL` und `PAPERCLIP_API_KEY` als Env-Variablen gesetzt. - Git-Worktree des Projekts ist clean. ## Schritt 1: Paperclip-Adapter-Schema live abfragen Das Schema für `opencode_local` variiert leicht zwischen Paperclip- Versionen. Hol dir die kanonische Form für deine Installation: ```bash curl -sS "$PAPERCLIP_API_URL/llms/agent-configuration.txt" \ -H "Authorization: Bearer $PAPERCLIP_API_KEY" | less curl -sS "$PAPERCLIP_API_URL/llms/agent-configuration/opencode_local.txt" \ -H "Authorization: Bearer $PAPERCLIP_API_KEY" ``` Vergleich die Felder mit `config/agents.jsonc`. Besonders relevant: - Wie heißt das Modell-Pinning-Feld? (`env.OPENCODE_MODEL`, `model`, `runtimeModel`, …) – beide Worker brauchen ein explizites Pinning. - Wird `sessionBehavior: "new"` unterstützt oder heißt es anders (`fresh-always`, `no-resume`, …)? **Verifikation:** Du hast Klarheit über die Pflicht- und Optional-Felder. ## Schritt 2: Skills in Paperclips Skill-Library einspielen Drei SKILL.md-Dateien müssen in deine Company-Skill-Library: 1. `skills/monitor-bmad-progress/SKILL.md` 2. `skills/execute-bmad-dev-tasks/SKILL.md` 3. `skills/execute-bmad-qa-tasks/SKILL.md` **Variante A – via Paperclip-UI:** Company → Skills → Create New Skill, Inhalt hineinkopieren. Der Skill-Name muss exakt zum `name:` im YAML-Frontmatter passen. **Variante B – via API:** Endpoint aus deiner Installation abfragen: ```bash curl -sS "$PAPERCLIP_API_URL/llms/skills-api.txt" \ -H "Authorization: Bearer $PAPERCLIP_API_KEY" ``` **Verifikation:** ```bash curl -sS "$PAPERCLIP_API_URL/api/skills" \ -H "Authorization: Bearer $PAPERCLIP_API_KEY" \ | jq '.[] | select(.name | startswith("monitor-bmad") or startswith("execute-bmad-dev") or startswith("execute-bmad-qa")) | .name' ``` Drei Namen müssen zurückkommen. ## Schritt 3: Company anlegen Im Paperclip-UI: **+ Company**. - **Name:** "BMAD Phase 4 – " - **Mission:** "Automatisierte Ausführung der BMAD-V6-Implementation- Phase mit Dev/QA-Rollen-Trennung." - **Projekt-Pfad (cwd / project_root):** Dein BMAD-Projektverzeichnis. ```bash curl -sS "$PAPERCLIP_API_URL/api/companies" \ -H "Authorization: Bearer $PAPERCLIP_API_KEY" \ | jq '.[] | select(.name | contains("BMAD Phase 4"))' ``` Notiere `companyId` – brauchst du für alle folgenden Calls. ## Schritt 4: Supervisor hiren ```bash export COMPANY_ID="" export PROJECT_ROOT="/srv/projects/" curl -sS -X POST "$PAPERCLIP_API_URL/api/agents" \ -H "Authorization: Bearer $PAPERCLIP_API_KEY" \ -H "Content-Type: application/json" \ -d @- <", "budget": {"monthlyUsd": 20} } EOF ``` Notiere die `agentId` – Dev und QA referenzieren sie als `reportsTo`. ## Schritt 5: Dev-Worker hiren ```bash curl -sS -X POST "$PAPERCLIP_API_URL/api/agents" \ -H "Authorization: Bearer $PAPERCLIP_API_KEY" \ -H "Content-Type: application/json" \ -d @- <", "adapterType": "process", "adapterConfig": { "adapter": "opencode_local", "cwd": "$PROJECT_ROOT", "sessionBehavior": "new", "env": {"OPENCODE_MODEL": ""}, "heartbeat": {"enabled": false} }, "runtimeConfig": {"maxTurns": 300, "timeoutMs": 2700000}, "desiredSkills": ["execute-bmad-dev-tasks"], "prompt": "", "budget": {"monthlyUsd": 300, "perTaskUsdMax": 10} } EOF ``` ## Schritt 6: QA-Engineer hiren **Wichtig:** Das Modell MUSS sich nachweislich vom Dev-Modell unterscheiden. Sonst verliert das adversariale Review seinen Wert. ```bash curl -sS -X POST "$PAPERCLIP_API_URL/api/agents" \ -H "Authorization: Bearer $PAPERCLIP_API_KEY" \ -H "Content-Type: application/json" \ -d @- <", "adapterType": "process", "adapterConfig": { "adapter": "opencode_local", "cwd": "$PROJECT_ROOT", "sessionBehavior": "new", "env": {"OPENCODE_MODEL": ""}, "heartbeat": {"enabled": false} }, "runtimeConfig": {"maxTurns": 200, "timeoutMs": 1800000}, "desiredSkills": ["execute-bmad-qa-tasks"], "prompt": "", "budget": {"monthlyUsd": 150, "perTaskUsdMax": 5} } EOF ``` **Verifikation Schritt 4-6:** ```bash curl -sS "$PAPERCLIP_API_URL/api/companies/$COMPANY_ID/agents" \ -H "Authorization: Bearer $PAPERCLIP_API_KEY" \ | jq '[.[] | {name, role, reportsTo, model: .adapterConfig.env.OPENCODE_MODEL}]' ``` Drei Agents, Supervisor top-level, Dev und QA beide unter Supervisor, mit unterschiedlichen Modellen bei Dev/QA. ## Schritt 7: Smoke-Test der beiden Worker Bevor echte Arbeit reinkommt: je ein Dummy-Task an Dev und QA. **Dev-Smoke:** ```bash curl -sS -X POST "$PAPERCLIP_API_URL/api/issues" \ -H "Authorization: Bearer $PAPERCLIP_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "companyId": "'$COMPANY_ID'", "title": "Smoke test Dev: write hello-dev.txt", "description": "Erzeuge hello-dev.txt im Projekt-Root mit Inhalt \"dev online\". Dann status=success melden.", "assignedAgentId": "" }' ``` **QA-Smoke:** ```bash curl -sS -X POST "$PAPERCLIP_API_URL/api/issues" \ -H "Authorization: Bearer $PAPERCLIP_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "companyId": "'$COMPANY_ID'", "title": "Smoke test QA: read hello-dev.txt", "description": "Lies hello-dev.txt, bestätige Inhalt, KEINE Änderungen. status=success mit dem gelesenen Text melden.", "assignedAgentId": "" }' ``` Beide Runs mit `exitCode: 0`. Räume `hello-dev.txt` danach auf. **NICHT weitermachen**, bevor beide Smoke-Tests grün sind. ## Schritt 8: Bootstrap-Task einspielen Jetzt der eigentliche Start: Supervisor baut die Task-Hierarchie aus den BMAD-Planning-Artefakten. ```bash curl -sS -X POST "$PAPERCLIP_API_URL/api/issues" \ -H "Authorization: Bearer $PAPERCLIP_API_KEY" \ -H "Content-Type: application/json" \ -d @bootstrap/initial-task.json ``` (Vorher in `initial-task.json` die `companyId` und `assignedAgentId` eintragen – letzteres ist die Supervisor-ID aus Schritt 4.) **Erwartung (im Paperclip-UI):** - Bootstrap-Task: `ready` → `in-progress` → `completed` - Child-Issues entstehen pro Story: - `create-story (X.Y)` — Dev-Worker - `dev-story (X.Y)` — Dev-Worker - `code-review (X.Y)` — QA-Engineer - Pro Epic zusätzlich `retrospective (Epic N)` — QA-Engineer - Supervisor postet Comment: Epics, Stories, `epic_source_layout` - Nur der erste `create-story`-Task ist auf `ready`, alle anderen `blocked` mit Dependencies **Mögliche Abbrüche beim Bootstrap:** - `sprint_status_missing` → Sprint Planning nicht vorab ausgeführt. Lauf `bmad-sprint-planning` manuell, starte neu. - `no_epic_source_found` → keine der vier Epic-Layouts gefunden. Prüfe `_bmad-output/planning-artifacts/`. - `sprint_status_inconsistent` → Stories im sprint-status.yaml passen nicht zur Epic-Quelle. - `planning_incomplete` → PRD.md oder architecture.md fehlt. ## Schritt 9: Erste Story durchlaufen lassen Der Supervisor setzt automatisch den ersten `create-story`-Task auf `ready`, sobald Bootstrap fertig ist. Der Dev-Worker sollte ihn binnen Sekunden aufgreifen. **Happy Path für Story 1.1 → 1.2 → …:** 1. Dev: `create-story (1.1)` → Story-Datei existiert → completed 2. Dev: `dev-story (1.1)` → Implementierung, Commits, Tests → completed 3. QA: `code-review (1.1)` → verdict=approved → completed 4. ERST JETZT: Dev: `create-story (1.2)` → ... **Keine Parallelität über Story-Grenzen hinweg.** Policy C (Strikte Story-Ordnung) verhindert, dass `create-story (1.2)` startet, solange Story 1.1 nicht approved ist. Die einzige Gleichzeitigkeit: während Dev `dev-story (1.2)` macht, kann QA theoretisch `code-review (1.1)` noch am Laufen haben – aber das passiert in der Praxis nicht, weil Policy C auch das verhindert (Story 1.2 rührt sich ja erst, wenn Story 1.1 approved, d.h. code-review completed ist). In der Praxis läuft also zu jedem Zeitpunkt EIN Task. Beide Agents sind selten gleichzeitig beschäftigt. Das ist bewusste Verlangsamung zugunsten sauberer Sequenzierung. **Bei needs-rework:** 1. QA: `code-review (1.1)` → verdict=needs-rework → completed 2. Supervisor legt an: - `dev-story (1.1) retry 1` (Dev) — mit Findings als Metadata - `code-review (1.1) retry 1` (QA) — blockiert auf den Retry-Dev 3. Benachrichtigung an Operator: "Story 1.1 Retry 1/3 — N HIGH, M MEDIUM" Bei Retry-Limit (3) erreicht → Eskalation mit vier Handlungsoptionen. **Epic-Übergang:** Nach `code-review` der letzten Story im Epic: 1. QA: `retrospective (Epic 1)` → completed 2. Erst jetzt wird der erste `create-story`-Task des nächsten Epics ready gesetzt. Davor: blocked durch Single-Epic-Policy. ## Schritt 10: Häufige Fehler **BMAD-Skill fragt interaktiv zurück:** Prompt in Dev- oder QA-Skill präzisieren oder `--non-interactive` an den BMAD-Skill-Aufruf anhängen. **OpenCode-Session hängt > Timeout:** Task-Timeout → SIGTERM. Supervisor markiert als `failed, reason=timeout` und versucht Re-Schedule. Nach 3 Timeouts am gleichen Task: Eskalation. Bei wiederholten Timeouts an einer Story: Story zu groß, manuell splitten. **Dev und QA nutzen versehentlich dasselbe Modell:** Supervisor merkt das am `model_used`-Feld in den Agent-Reports und informiert einmalig im Status-Report. Kein Abbruch – aber das Review ist dadurch schwächer. Korrigiere die `env.OPENCODE_MODEL`-Werte in den Agent-Configs. **`concurrent_task`-Fehler:** Ein Agent hat zwei Tasks gleichzeitig. Sollte durch Policy B nie passieren. Wenn doch: Sofort-Stopp, Paperclip-Audit-Log prüfen, dann neu starten. Möglicherweise Supervisor-Bug oder Paperclip-Atomicity- Issue. **`sessionBehavior: "new"` wird ignoriert:** Schema-Name in deiner Paperclip-Version abweichend. In agents.jsonc anpassen basierend auf Schritt 1. **Operator ändert sprint-status.yaml mid-run:** Supervisor erkennt das am Timestamp, eskaliert. Besser: Workflow stoppen, anpassen, neu bootstrappen. **QA findet NIE etwas:** Entweder QA-Modell ist zu permissiv (Modell-Upgrade) oder die Stories sind tatsächlich trivial (akzeptabel, dann warning_zero_findings regelmäßig). Nach 3-5 approved-ohne-Findings: Stichprobe auf die Implementierung werfen. ## Schritt 11: Patrol verstehen Der Supervisor läuft nicht nur bei Events (`task_completed`), sondern patrouilliert alle 15 Minuten (konfigurierbar in agents.jsonc `heartbeat.intervalSec`). Das sorgt für maximale Autonomie: wenn ein Agent hängt oder ein Ready-Setting verloren geht, bemerkt und behebt der Supervisor das, ohne dass du eingreifen musst. **Was du in Paperclip sehen wirst:** - **Patrol ohne Funde:** Keine Comments. Stille Einträge im Audit-Trail ("Patrol OK"). Das ist der Normalfall bei gesundem Lauf. - **Patrol mit autonomer Aktion:** Ein Comment am Parent-Issue im Format: ``` ### Patrol-Report – Graph-Status: 5/20 completed, 1 in-progress, 0 ready, 14 blocked Aktuelle Story: Epic 1 Story 1.3, Task dev-story Gefundene Blocker: stuck_in_progress_task (story 1.3, 47 min) Autonome Aktionen: reset-to-ready für task dev-story (1.3) Offene Eskalationen: keine ``` - **Patrol mit Eskalation:** Comment mit `attention_required=true` – das heißt, du musst ran. Z.B. bei dirty worktree oder Retry-Limit. **Was Patrol autonom auflöst:** | Blocker | Aktion | | --- | --- | | Task hängt in-progress ohne Heartbeat | als failed markieren, ready reset, normaler Retry-Pfad | | Task ready, aber kein Agent zugewiesen | manuelles Re-Assignment an zuständigen Agent | | Vorgänger completed, Folge blocked | Ready-Check nachholen, falls passt → ready setzen | | Zwei Tasks mit identischem Kompositschlüssel | jüngeren cancellen, älteren behalten | | Goal offen, aber kein aktiver Task | nächsten korrekten Task identifizieren und ready setzen | | Dirty worktree (uncommitted changes) | WIP-Commit mit erkennbarer Message, Flow weiter (kein Code-Verlust) | **Was Patrol NICHT autonom macht (immer Eskalation):** - Retry-Limit erreicht (inhaltliche Entscheidung nötig) - Fehlender Agent (Governance-Entscheidung) - Meta-Stall > 1 h trotz Patrol-Aktionen (autonome Mittel erschöpft) **Besonderheit Dirty Worktree:** Wenn der Supervisor uncommittete Changes im Projekt findet (typisch nach einem abgebrochenen Dev-Task), macht er einen automatischen WIP-Commit mit Message `wip: patrol-auto-commit from {task_type} (story {story_id})`. Damit ist der Worktree wieder clean, der Workflow läuft weiter, und du behältst die Änderungen vollständig im Git-History. Du solltest solche WIP-Commits später manuell prüfen – entweder revertst du sie und lässt den Dev-Agent sauber neu arbeiten, oder du behältst sie, falls der Inhalt sinnvoll ist. Diese landen als Info-Notiz mit `attention_required=false`. Du wirst sie im Log sehen, aber sie stören deinen Schlaf nicht. **Wenn du Patrol vorübergehend abschalten willst:** In `agents.jsonc` beim Supervisor `heartbeat.enabled: false` setzen. Dann läuft er wieder nur event-basiert – aber rechne damit, dass Hänger dann liegen bleiben, bis du sie manuell lösst. ## Schritt 12: Reporting einrichten (optional) Der Supervisor postet Status-Reports als Comments auf das Parent-Issue. Für Push-Notifications: - Paperclip-UI → Company → Integrations → Webhook auf `issue_comment_created` für das Phase-4-Parent-Issue. - Alternativ: Im Supervisor-Prompt Hook einbauen, der bei `attention_required=true` einen connected MCP (Slack, Email) triggert. ## Was danach? Sobald Story 1.1 einmal sauber durchgelaufen ist, ist die Schleife bewiesen. - **Cost-Dashboard täglich prüfen:** Retry-Spiralen sind der teuerste Failure-Mode. 3-Retry-Limit deckelt, aber früh eingreifen lohnt sich. - **Nach 3 Stories manuelle Stichprobe:** Qualität auf deinem Level? - **QA-Findings-Muster beobachten:** Wenn eine Finding-Klasse immer wiederkehrt → `project-context.md` erweitern, damit der Dev die Konvention von Anfang an einhält. ## Zweites BMAD-Projekt automatisieren Paperclip unterstützt mehrere Companies pro Installation: 1. Neue Company anlegen 2. Die drei Skills sind instance-weit verfügbar, kein Re-Upload 3. Drei neue Agents hiren mit neuem `cwd` 4. Bootstrap wie in Schritt 8 Die SKILL.md-Dateien sind projekt-agnostisch. Nur `cwd` der Agents ändert sich.