Wie aus einer Synology-NAS ein redaktionelles Nervensystem wird, mit Paperclip als Regie, OpenClaw als Claude-Brücke und Obsidian als Gedächtnis.
Diese Anleitung ist kein sauberer Laborbericht aus einer idealen Cloud-Welt. Sie ist der Bauplan eines Systems, das auf einer echten Synology-NAS entstanden ist, mit Docker-Eigenheiten, störrischen OAuth-Logins, beleidigten Timeouts, nicht vorhandenen User-Namespaces und Agenten, die manchmal sehr wörtlich und manchmal viel zu kreativ verstanden haben, was „noch nicht schließen“ bedeutet.
Am Ende steht eine lokale Multi-Agent-Redaktion: fünf Codex-Personas über ChatGPT Plus, ein Editorial Claude über Claude Max, Paperclip als Orchestrator und Obsidian als Gedächtnis. Kein API-Kostenroulette, kein blindes Auto-Publishing, keine Magie. Nur viele kleine, geprüfte Schritte.
Keine Panik, das wirkt komplizierter, als es ist. Du baust hier nichts Geheimnisvolles. Du stellst drei digitale Mitarbeiter ein, gibst jedem ein Büro, ein Namensschild und eine klare Stellenbeschreibung, und sorgst dafür, dass keiner von ihnen ohne deine Unterschrift etwas veröffentlicht. Genau in dieser Reihenfolge gehen wir das durch.
Um diese Anleitung verständlicher zu machen, begleiten dich drei Personen:
Die typischen Büro-Charaktere: Die kompetente IT-Kollegin, der selbsternannte Experte und der ehrliche Anfänger. Diese drei Perspektiven helfen dir, typische Stolperfallen zu erkennen.
Tanja ist die IT-Expertin. Sie weiß, wie es funktioniert, erklärt geduldig und strukturiert und lässt sich von schlechten Ratschlägen nicht aus der Ruhe bringen. Wenn du eine Frage hast, hat Tanja die Antwort.
Bernd ist der selbsternannte „Experte“, der alles besser weiß und meistens falsch liegt. Seine Abkürzungen und sein Halbwissen führen regelmäßig zu Problemen. Er steht für alle gefährlichen Mythen und schlechten Praktiken, die du vermeiden solltest.
Ulf ist der Lernende, genau wie du. Er stellt die Fragen, die dir im Kopf herumschwirren, und braucht manchmal einen Vergleich aus dem Alltag, um IT zu verstehen. Wenn Ulf etwas nicht versteht, ist das völlig in Ordnung, dafür ist Tanja da.
„Und… Action!“
Bevor du loslegst: einige Hinweise
Die Szene: Bernd lehnt am Türrahmen des Serverraums, Kaffeebecher in der Hand, und schaut Tanja beim Tippen zu.
Bernd: „Drei KI-Agenten? Mach ich heute Nachmittag. Alles installieren, alles anschalten, fertig. Wo ist das Problem?“
Tanja: „Das Problem ist genau dieses ‚alles anschalten‘. Wer alles gleichzeitig startet und dann einen Fehler hat, weiß nie, welcher der zwanzig Schalter schuld war.“
Ulf: „Also wie beim Auto, wenn die Werkstatt alle vier Teile gleichzeitig tauscht und das Klappern danach immer noch da ist?“
Tanja: „Exakt. Deshalb gibt es für diese ganze Anleitung ein festes Vorgehen.“
Konkret beschreibt die Anleitung den vollständigen Nachbau des foundic.org-Setups: 3 KI-Agenten (2 Codex-Personas + 1 Editorial Claude) auf einer Synology-NAS. Alle Befehle basieren auf dem dokumentierten Original-Aufbau (Mai–Juni 2026); versionsabhängige Schritte und über den Original-Endstand hinausgehende Empfehlungen sind als solche markiert.
Wichtiger Hinweis zur Reproduzierbarkeit: Die Anleitung ist so exakt wie das Original-Projekt dokumentiert. Zwei Punkte hängen von der aktuellen Paperclip-Version ab und sind entsprechend markiert: (1) der UI-Patch für den openclaw_gateway-Adapter (Abschnitt 5.8) und (2) der ACP-Protokoll-Patch (Abschnitt 5.10). Prüfe vor dem Nachbau, ob deine Paperclip-Version diese Patches noch benötigt, neuere Releases haben sie ggf. integriert. Die übrigen Schritte sind als stabiler Originalpfad dokumentiert; bei sich ändernden Paperclip-, OpenClaw- oder CLI-Versionen gilt trotzdem: erst testen, dann patchen, nie umgekehrt.
Bernd: „Patchen kann ich auch vorher, sicher ist sicher.“
Tanja: „Nein. Ein Patch repariert einen bekannten Fehler. Wenn der Fehler in deiner Version gar nicht mehr existiert, baust du dir mit dem Patch einen neuen ein. Erst testen, dann reparieren.“
Begleitartikel (Pflichtlektüre für die Wende-Installation): Die Claude-Max-Anbindung (Wende-Proxy, Claude CLI, Autostart, Token-Sparmaßnahmen) ist in einem eigenen foundic.org-Artikel vollständig Schritt für Schritt dokumentiert: „OpenClaw mit ChatGPT Plus und Claude MAX: Von 400 € variablen API-Kosten zu planbaren Flatrates“. Abschnitt 5.7 dieser Anleitung fasst die Kernschritte zusammen und verweist für die Details auf die dortigen Phasen 3 und 4.
Modell-Bezeichnungen: gpt-5.5, gpt-5.4-mini, claude-sonnet-4, claude-opus-4 sind die Original-Werte aus dem Setup (Stand Mai/Juni 2026). Modell-IDs ändern sich, prüfe vor der Konfiguration, was deine Abos aktuell anbieten: Codex-Modelle via codex models list auf der NAS bzw. das Dropdown in der Paperclip-UI; Wende-Modelle via curl http://127.0.0.1:3457/v1/models. Wichtig ist das Prinzip: explizit das günstigste verfügbare Flatrate-Modell setzen, nie den Wizard-Default übernehmen. Die Wende-Modell-IDs sind bewusst generisch (claude-sonnet-4, nicht die Anthropic-API-ID claude-sonnet-4-6).
Ulf: „Warum nicht einfach den Default nehmen? Der Default ist doch der, den die das Programm empfiehlt, oder?“
Tanja: „Der Default ist der, den der Hersteller dir empfiehlt, nicht der, der dein Budget schont. Stell ihn dir wie das teure Tagesmenü vor, das der Kellner ungefragt bringt. Du willst aber das Flatrate-Gericht, das du schon bezahlt hast.“
1. Zielbild und Komponenten
Bevor wir auch nur einen Befehl tippen, schauen wir uns an, was am Ende dasteht. Stell dir ein kleines Redaktionsbüro vor: Es gibt einen Disponenten, der Aufgaben verteilt, mehrere Schreibkräfte, einen erfahrenen Autor für die langen Stücke, und ein Archiv, das sich alles merkt. Genau dieses Büro bauen wir, nur eben digital, auf deiner NAS.
| Komponente | Typ | Port (Host) | Funktion |
|---|---|---|---|
paperclip | Docker-Container | 0.0.0.0:3100 | Orchestrierung, UI, alle 3 Agenten, Codex-Subprocesses |
paperclip-postgres | Docker-Container | (nur intern) | Datenbank (postgres:17-alpine) |
openclaw-writer | Docker-Container | 0.0.0.0:18791 | Gateway für Editorial Claude |
wende | nativer Node.js-Prozess auf DSM | 0.0.0.0:3457 | Claude-Max-Proxy (CLI-Subprocess-Wrapper) |
| Codex CLI | Binary (im Paperclip-Image enthalten) | gpt-5.5 via ChatGPT-Plus-OAuth für 2 Personas | |
| Obsidian + Vault | Mac-App + Shared Folder | Steuerungs-Dokumente, Agenten-Workspaces, Gedächtnis |
Datenfluss:
2 x Codex-Personas: Paperclip → codex_local-Adapter → Codex-CLI-Subprocess → ChatGPT-Plus-OAuth → gpt-5.5
1 x Editorial Claude: Paperclip → openclaw_gateway → openclaw-writer (ws, :18791) → Wende (:3457, OpenAI-Schema) → claude-CLI-Subprocess → Claude-Max-Abo
Kurz gesagt: Paperclip ist der Disponent. ChatGPT bzw. Codex schreibt die schnellen Persona-Antworten. Editorial Claude ist der größere Sprachmotor für längere redaktionelle Arbeit. Obsidian ist nicht Dekoration, sondern das Gedächtnis und die Betriebsanleitung des ganzen Systems.
Ulf: „Diese zweite Zeile mit den ganzen Pfeilen verstehe ich nicht. Warum so viele Stationen für einen einzigen Agenten?“
Tanja: „Weil zwei Welten unterschiedliche Sprachen sprechen. Paperclip spricht ‚OpenAI‘, Claude spricht ‚Claude‘. Wende ist der Dolmetscher dazwischen. Mehr dazu in Schritt 5.7, jetzt reicht: Editorial Claude hat einen längeren Dienstweg als die zwei Codex-Personas, deshalb die Pfeilkette.“
Bernd: „Dolmetscher? Lass den weg, dann gehts schneller.“
Tanja: „Dann redet niemand mit niemandem. Der Dolmetscher ist nicht das Problem, er ist die Lösung.“
Quellen und Repositories
Woher kommt welche Software? Diese Tabelle ist deine Einkaufsliste. Du baust nichts selbst, du holst dir fertige, geprüfte Teile.
| Software | Quelle | Bezug |
|---|---|---|
| Paperclip | github.com/paperclipai/paperclip (MIT-Lizenz) | Fertiges Image: ghcr.io/paperclipai/paperclip (Tags: :latest, :sha-XXX) |
| OpenClaw | Image: ghcr.io/openclaw/openclaw | getesteter Endstand 2026.5.7 + gepatchtes Paperclip; Versions-Einordnung siehe 5.10 und Matrix 7.3 |
| Wende | Fork von github.com/atalovesyou/claude-max-api-proxy (Original: angepasster Fork, siehe Hinweis 5.7.4) | Installation: siehe 5.7 + Begleitartikel, Phase 3 |
| Claude CLI | npm: @anthropic-ai/claude-code (Original: 2.1.141) | wird von Wende als Subprocess gestartet |
| Codex CLI | npm: @openai/codex (Original: 0.130.0) | im Paperclip-Image bereits enthalten |
| Obsidian | obsidian.md (kostenlos) |
Platzhalter in dieser Anleitung
In den Befehlen tauchen immer wieder Platzhalter in spitzen Klammern auf. Die sind keine echten Werte, sondern Lücken, die du mit deinen eigenen Daten füllst. Ersetze durchgängig:
| Platzhalter | Original-Wert | Dein Wert |
|---|---|---|
<NAS-IP> | 192.168.2.10 | LAN-IP deiner NAS |
<NAS-USER> | (Beispiel: admin) | dein DSM-Admin-Benutzer |
<UID> | 1000 (Container-User); NAS-User-UID abweichend | per id <NAS-USER> prüfen! |
Regel aus dem Projekt: UID nie annehmen, immer id $USER auf der NAS ausführen. Im Original wichen NAS-User-UID und Container-UID (1000) voneinander ab. Bind-Mount-Verzeichnisse werden auf die Container-UID gechownt, nicht die compose-Direktive angepasst.
Bernd: „UID ist immer 1000. Weiß doch jeder.“
Tanja: „Bei dir vielleicht. Bei der nächsten NAS ist es 1026, weil dort vorher schon drei andere Benutzer angelegt wurden. Eine angenommene UID ist der Klassiker für ‚Permission denied‘ an einer Stelle, an der du es nie vermutest.“
Ulf: „Und wie finde ich meine raus?“
Tanja: „Ein einziger Befehl: id <NAS-USER>. Der sagt dir die Wahrheit. Annahmen sagen dir nur, was du hören willst.“
Fakten-Check, Abschnitt 1
- Es entstehen drei Docker-Container (paperclip, paperclip-postgres, openclaw-writer) und ein nativer Prozess (Wende) direkt auf DSM.
- Vier belegte Host-Ports: 3100 (UI), 18791 (Gateway), 3457 (Wende), Postgres bleibt intern.
- Du baust nichts selbst, du pullst fertige Images. Bauen scheitert auf DSM ohnehin (siehe 2.3).
- Spitze Klammern = deine Werte.
<NAS-IP>,<NAS-USER>,<UID>musst du überall ersetzen.- UID immer per
id <NAS-USER>prüfen, nie 1000 annehmen.
2. Voraussetzungen
Bevor die Maschine läuft, muss das Fundament stehen.
2.1 Hardware/Software
- Synology NAS mit DSM 7.x und Paket Container Manager (Original: DS1621+). Alle Pfade dieser Anleitung liegen auf
/volume1. - Mac (oder Linux/PC) im selben LAN mit Terminal, Browser, Obsidian (kostenlos), Synology Drive Client.
- SSH-Zugang zur NAS aktiviert (DSM: Systemsteuerung → Terminal & SNMP → SSH aktivieren). Der Benutzer muss in der Gruppe
administratorssein (fürsudo). - Auf dem Mac für einen optionalen Patch-Schritt: Docker Desktop (nur falls Abschnitt 4.8/4.10 nötig).
Vorausgesetztes Wissen: sicherer Umgang mit Terminal, SSH, Docker Compose, JSON und Markdown; Grundverständnis von Linux-Permissions (chmod/chown/UID) und Container-Networking (Ports, Bridges, DNS). Wer diese Grundlagen nicht mitbringt, sollte sie vor dem Nachbau auffrischen, die Anleitung erklärt projektspezifische Fallen, aber keine Docker-Grundlagen.
Ulf: „Container, Bridges, chown … das klingt schon hier nach viel. Schaff ich das überhaupt?“
Tanja: „Wenn du weißt, was ein Ordner ist, was ein Benutzer ist und wie man eine Datei kopiert, schaffst du das. Wir erklären die Stolperfallen, die für genau dieses Projekt gelten. Was wir nicht erklären, ist, was Docker grundsätzlich ist, das setzen wir voraus. Wenn dir der Begriff ‚Container‘ nichts sagt, lies eine halbe Stunde Grundlagen, dann komm zurück. Kein Drama, nur Reihenfolge.“
2.2 Abos
- ChatGPT Plus (ca. 20 €/Monat), versorgt die 2 Codex-Personas über einen einzigen OAuth-Login.
- Claude Max 5x (ca. 92 €/Monat), versorgt Editorial Claude. Optional; ohne diesen Agenten entfallen Abschnitte 5.7–5.12.
- Kein Anthropic- oder OpenAI-API-Key im Zielbetrieb (API-Kosten: 0 €).
Der entscheidende Trick steckt im Wort „Flatrate“. Du bezahlst zwei feste monatliche Beträge und nicht pro Anfrage. Genau das macht den Unterschied zwischen planbaren 112 € und einer bösen API-Rechnung am Monatsende.
Bernd: „Ich häng einfach noch meinen alten API-Key rein, als Reserve. Schadet ja nicht.“
Tanja: „Doch, genau das schadet. Ein vergessener API-Key ist die Hintertür, durch die im Betrieb plötzlich echte Kosten reinkommen, ohne dass du es merkst. Im Zielbetrieb: kein Key. Punkt.“
2.3 DSM-Eigenheiten: die kleinen Drachen vor dem Burgtor
Synology DSM ist bequem, aber nicht neutral. Wer Docker wie auf einem normalen Linux-Server erwartet, wird hier regelmäßig von kleinen Abweichungen gebissen. Diese Punkte sind dauerhaft gültige Befunde aus dem Projekt:
- Docker-Befehle laufen nur mit
sudo docker …(Benutzer ist nicht in der docker-Gruppe). - DSM hat kein BuildKit/buildx,
docker buildmit modernen Dockerfiles scheitert. Konsequenz: fertige Images pullen, nicht selbst bauen. - DSM hat kein git, nano oder vim, nur BusyBox-
vi. Alternative: Dateien auf dem Mac erstellen und perscpauf die NAS kopieren. - Der Synology-Docker-Daemon erzwingt Loopback-Binding. In jeder compose.yaml Ports explizit als
"0.0.0.0:<port>:<port>"notieren. - Docker-DNS in Containern explizit auf
1.1.1.1/8.8.8.8setzen (DSM-DNS-Forwarding kollidiert mit RFC1918-Firewall-Regeln).
Ulf: „Drachen vor dem Burgtor? Im Ernst?“
Tanja: „Im Ernst. DSM tut so, als wäre es ein normaler Linux-Server, ist es aber nicht ganz. Diese fünf Punkte sind die Stellen, an denen es anders tickt. Wer sie kennt, läuft durch. Wer sie nicht kennt, rennt gegen die Mauer.“
Bernd: „Ich bau mein Image einfach selbst auf der NAS, schneller als pullen.“
Tanja: „Punkt 2 sagt dir: Das scheitert. DSM hat kein BuildKit. Du tippst docker build, bekommst einen Fehler bei COPY --parents und sitzt eine Stunde dran, weil du den Hinweis überlesen hast. Fertiges Image pullen, fertig.“
Diese Eigenheiten begleiten uns durch die ganze Anleitung. Sie sind kein Bug, den du beheben kannst, sondern die Spielregeln dieser Plattform. Statt dagegen zu kämpfen, bauen wir von Anfang an mit ihnen.
3. Phase 1, Fundament: Vault, Obsidian, Docker-Netzwerk
Jetzt wird gebaut. In dieser Phase entsteht das leere Bürogebäude: Räume, Schlösser, ein Lageplan an der Wand und ein eigenes Telefonnetz zwischen den Etagen. Noch zieht niemand ein, aber die Adressen stehen.
Schritt 3.1: Shared Folder anlegen
DSM-UI: Systemsteuerung → Geteilter Ordner → Erstellen → Name Vault, Volume /volume1, ohne Verschlüsselung/Papierkorb nach Bedarf.
Erwartetes Ergebnis: ls -la /volume1/Vault/ per SSH zeigt den Ordner.
Dieser Ordner ist das Grundstück, auf dem das ganze System steht. Den Namen Vault (Tresor) hat Obsidian geprägt, dort heißt jede Wissenssammlung so.
Schritt 3.2: Verzeichnisstruktur anlegen
Per SSH auf der NAS (Brace-Expansion erfordert bash, nicht dash, daher bash -c):
bash -c 'mkdir -p /volume1/Vault/Paperclip/agents-vault/{_meta,00-shared/{company,people,decisions,resources},10-agents/{christian,sarah,nicole,anna}/{memory/archive,workspace},20-skills,30-paperclip-package,99-archive}'
Erwartetes Ergebnis:
find /volume1/Vault/Paperclip/agents-vault -type d | wc -l
find /volume1/Vault/Paperclip/agents-vault -mindepth 1 -type d | wc -l
Ulf: „Was sind diese geschweiften Klammern? Das sieht aus wie Geheimsprache.“
Tanja: „Das ist Brace-Expansion, eine Abkürzung der Shell. Statt zwanzig mkdir-Befehle zu tippen, schreibst du in geschweiften Klammern alle Unterordner auf einmal. Die Shell macht daraus die einzelnen Ordner. Wichtig nur: Das kann bash, aber nicht dash, deshalb das vorangestellte bash -c.“
Bernd: „Ich klick die Ordner einfach in der File Station zusammen, ist doch dasselbe.“
Tanja: „Kannst du machen, dann vertippst du dich bei einem der 26 Ordner, merkst es nicht, und Wochen später lädt ein Agent ins Leere. Der find … | wc -l-Test sagt dir sofort: 27 Ordner, alles da. Genau dafür ist er da.“
Bedeutung der Struktur:
| Verzeichnis | Zugriff Agenten | Inhalt |
|---|---|---|
00-shared/ | read-only | Firmen-Wissen: mission.md, themenfelder.md, style-guide.md |
10-agents/<name>/ | read-write (nur eigenes) | SOUL.md, IDENTITY.md, USER.md, TOOLS.md, memory/, workspace/ |
20-skills/ | read-only | geteilte Skills |
99-archive/ | Altmaterial |
Merke dir das Prinzip dahinter wie ein Großraumbüro mit unterschiedlichen Schlüsseln: 00-shared/ ist das Schwarze Brett, jeder darf lesen, keiner schreiben. Und jeder Agent hat sein eigenes abschließbares Fach unter 10-agents/<name>/.
Schritt 3.3: Permissions setzen
sudo chown -R 1000:users /volume1/Vault/Paperclip/agents-vault
sudo chmod 775 /volume1/Vault/Paperclip/agents-vault
sudo bash -c 'chmod 775 /volume1/Vault/Paperclip/agents-vault/{00-shared,20-skills}'
sudo chmod 770 /volume1/Vault/Paperclip/agents-vault/10-agents
sudo bash -c 'chmod 770 /volume1/Vault/Paperclip/agents-vault/10-agents/{christian,sarah,nicole}'
Erwartetes Ergebnis: ls -la zeigt 775 auf shared/skills, 770 auf 10-agents. Hinweis: DSM-mkdir erbt ACLs (sichtbar als + in ls -la) und legt sonst 777 an, deshalb das explizite chmod.
Hier setzt du die Schlösser. chown 1000:users sagt: „Der Container-Benutzer ist der Eigentümer.“ chmod legt fest, wer rein darf. Die Zahlen sind kein Hexenwerk: 7 heißt alles dürfen, 5 nur lesen, 0 gar nichts.
Bernd: „777 auf alles, dann läuft es garantiert. Mach ich immer so.“
Tanja: „777 heißt: jeder darf alles, lesen, schreiben, löschen. Das ist kein Schloss, das ist eine offene Tür mit dem Schild ‚bitte eintreten‘. Wir nehmen 775 fürs Schwarze Brett und 770 für die privaten Fächer. Übrigens: Genau gegen DSMs heimliches 777 setzen wir das explizite chmod hier.“
Symlink-Check (Pflicht vor jedem späteren Bind-Mount):
find /volume1/Vault/Paperclip/agents-vault -maxdepth 3 -type l -ls
# Erwartung: leere Ausgabe. Bei Treffern: STOP, klären.
Ein Symlink ist eine Abkürzung, die auf einen anderen Ort zeigt. Im Vault hat sie nichts verloren, denn ein Container könnte über sie aus seinem Gehege ausbrechen. Leere Ausgabe = sauber. Findet der Befehl etwas: anhalten und klären, nicht ignorieren.


Schritt 3.4: Synology Drive Sync
- NAS: Paket Synology Drive Server installieren, in der Drive-Admin-Konsole den Ordner
Vaultals Team-Ordner aktivieren. - Mac: Synology Drive Client → Sync-Task anlegen: NAS-Seite
/Vault/Paperclip/agents-vault, Mac-Seite z. B.~/Documents/Vault/Paperclip/agents-vault.
Erwartetes Ergebnis (Round-Trip-Test): Testdatei auf dem Mac anlegen → erscheint binnen Sekunden auf der NAS (lsper SSH), und umgekehrt.
Damit verbindest du den Schreibtisch (deinen Mac mit Obsidian) und das Archiv (die NAS). Was du am Mac änderst, landet auf der NAS, und das ist wichtig, denn die Agenten lesen ihre Dateien auf der NAS, nicht auf deinem Mac.
Hinweis: Der Client synchronisiert exakt in den Ordner, den du auswählst, nicht automatisch nach~/SynologyDrive/. Pfad perlsverifizieren. macOS zeigtDocumentsim Finder lokalisiert als „Dokumente“; im Terminal gilt~/Documents/.
Ulf: „Sync ist doch wie ein Backup, oder? Dann brauche ich kein extra Backup mehr.“
Tanja: „Vorsicht, das ist eine gefährliche Verwechslung. Sync spiegelt auch Löschungen. Wenn du eine Datei am Mac löschst, ist sie Sekunden später auch auf der NAS weg. Ein Backup vergisst nicht. Sync ist kein Backup, das merken wir uns für Abschnitt 7.“

Schritt 3.5: Obsidian einrichten
Obsidian → Ordner als Vault öffnen → ~/Documents/Vault/Paperclip/agents-vault/.
Regeln: Bereich A wird überschrieben (Status entsteht „live“), Bereich B ist append-only, alte Einträge werden nie umgeschrieben, Korrekturen kommen als neuer Eintrag obenauf. Projektregel: „Veraltetes Tracking ist schlimmer als kein Tracking, weil es falsche Sicherheit gibt.“ Tracking-Update gehört zur Aktion, nicht „kurz später“.
Schritt 3.6: Docker-Netzwerk anlegen
Jetzt das interne Telefonnetz, über das die Container miteinander reden. Bevor du ein neues Netz aufspannst, prüfst du, dass die gewählte Hausnummer (das Subnetz) nicht schon vergeben ist.
Pre-Check (Subnet darf nicht belegt sein):
sudo docker network ls # agents-net darf NICHT existieren
sudo docker network inspect $(sudo docker network ls -q) | grep -i subnet
# 172.31.0.0/24 darf in keiner Ausgabe vorkommen
Hinweis: ip route | grep 172.31 ist als alleiniger Check unzuverlässig, Docker-Bridge-Subnets erscheinen nicht zwingend in der Routing-Tabelle. Immer docker network inspect verwenden.
Anlegen und validieren:
sudo docker network create --subnet=172.31.0.0/24 agents-net
sudo docker network inspect agents-net
Erwartetes Ergebnis: inspect zeigt "Driver": "bridge", "Subnet": "172.31.0.0/24", "Containers": {}.
Bernd: „Subnetz prüfen? Ich nehm einfach 172.31, das ist immer frei.“
Tanja: „‚Immer frei‘ ist genau die Annahme, die dir zwei belegte Netze beschert, die sich gegenseitig stören. Der Pre-Check kostet zehn Sekunden. Und nimm docker network inspect, nicht ip route, denn Bridge-Subnetze stehen nicht zwingend in der Routing-Tabelle.“

Schritt 3.7: Bestandsaufnahme (Pflicht vor jeder Installation)
sudo docker ps -a # vorhandene Container
sudo docker network ls # vorhandene Netzwerke
sudo netstat -tlnp # belegte Ports, auch native DSM-Dienste!
ls -la /volume1/docker/ # vorhandene Projekt-Verzeichnisse
Erwartetes Ergebnis: Notiere im Tracking, welche Container/Ports/Verzeichnisse zu anderen Projekten gehören und tabu sind. Prüfe konkret, dass 3100, 3457, 5432 und 18791 frei sind (bzw. 3457 nur von einer ggf. schon vorhandenen Wende belegt ist). Hinweis: netstat zeigt auch Nicht-Docker-Prozesse, im Original war Port 18790 vom DSM-eigenen nginx belegt, unsichtbar für Docker-Befehle.
Das ist der Blick auf die Baustelle, bevor der Bagger anrückt. Welche Leitungen liegen schon? Welche Räume sind belegt? Besonders heimtückisch: DSM-eigene Dienste, die nicht als Docker auftauchen. Deshalb netstat, nicht nur docker ps.
Was du jetzt hast: ein leeres Redaktionsgebäude. Die Räume sind angelegt, die Türen haben passende Schlösser, Obsidian hängt als Lageplan an der Wand, ein isoliertes Agenten-Netz verbindet die Etagen. Noch schreibt niemand, aber niemand wird später behaupten können, er habe sein Büro nicht gefunden.
Fakten-Check, Phase 1
- Vault-Ordner angelegt, 26 Unterordner per Brace-Expansion, mit
find … | wc -lauf 27 geprüft.- Permissions: Eigentümer
1000:users, 775 für Geteiltes, 770 für private Agenten-Fächer. Kein 777.- Symlink-Check durchgeführt: Ausgabe leer.
- Synology Drive verbindet Mac und NAS (aber Sync ≠ Backup).
- Drei Steuerungs-Dokumente in
_meta/: Brief, Tracking (A überschreibbar, B append-only), Master-Prompt.- Docker-Netz
agents-net(172.31.0.0/24) angelegt, Subnetz vorher geprüft.- Ports 3100, 3457, 5432, 18791 als frei verifiziert.
4. Phase 2, Paperclip-Stack installieren
Paperclip ist in diesem Setup die Leitstelle. Es vergibt Aufgaben, weckt Agenten, speichert Kommentare, hängt Sub-Issues an Haupt-Issues und macht aus einzelnen Modellaufrufen einen nachvollziehbaren Arbeitsfluss. Ohne Paperclip wären die Agenten nur drei sehr begabte Solisten. Mit Paperclip werden sie ein Ensemble.
Ulf: „Drei Solisten gegen ein Ensemble, was meinst du damit?“
Tanja: „Denk an deine Fußballmannschaft, Ulf. Elf Weltklasse-Spieler ohne Trainer und Aufstellung rennen sich gegenseitig über den Haufen. Paperclip ist der Trainer, der sagt, wer auf welcher Position spielt und wann der Ball abgegeben wird.“
Ulf: „Okay, DAS hab ich verstanden.“
Schritt 4.1: Stack-Verzeichnis anlegen
sudo mkdir -p /volume1/docker/paperclip-stack/{paperclip-data,postgres-data}
sudo chown -R <NAS-USER>:users /volume1/docker/paperclip-stack
sudo chmod 755 /volume1/docker/paperclip-stack
Hier entsteht das Maschinenhaus. Zwei Unterordner: einer für Paperclip selbst, einer für die Datenbank. Letztere ist das Gedächtnis der Leitstelle, alle Issues, Kommentare und Agenten-Konfigurationen liegen dort.
Schritt 4.2: Image pullen (NICHT selbst bauen)
sudo docker pull ghcr.io/paperclipai/paperclip:latest
sudo docker images --digests | grep paperclip # SHA-Digest notieren
Erwartetes Ergebnis: Pull erfolgreich; du hast einen sha256:…-Digest für den Image-Pin. Original-Pin: sha256:b2a2d7f71...33a800 (16.05.2026, deiner wird neuer sein).
Hinweis: Build-from-Source scheitert auf DSM am fehlenden BuildKit (COPY --parents wird nicht unterstützt). Verfügbare Tags auf der Registry-Seite github.com/paperclipai/paperclip/pkgs/container/paperclip nachsehen, Paperclip taggt :latest+ :sha-XXX, keine Versionsnummern.
Ulf: „Was ist dieser SHA-Digest und warum soll ich ihn aufschreiben?“
Tanja: „:latest ist ein bewegliches Ziel, morgen kann dahinter ein anderes Image stecken. Der SHA-Digest ist der Fingerabdruck genau dieser einen Version. Du pinnst ihn fest, damit dein System nicht über Nacht heimlich ein Update bekommt, das etwas kaputt macht. Wie eine Chargennummer auf einem Ersatzteil.“
Schritt 4.3: .env erstellen
Secrets auf der NAS erzeugen (nie in Chats/Logs einfügen):
openssl rand -hex 32 # → POSTGRES_PASSWORD
openssl rand -hex 32 # → BETTER_AUTH_SECRET
Wichtig: -hex, nicht -base64, Base64-Zeichen (+, /, =) zerstören die DATABASE_URL.
Bernd: „-base64 ist sicherer, mehr Zeichen, mehr Sicherheit.“
Tanja: „Die Sicherheit ist dieselbe, beides sind 32 Zufalls-Bytes. Aber Base64 enthält +, / und =, und genau die zerschießen dir die DATABASE_URL, weil dort ein / schon eine Bedeutung hat. -hex gibt nur 0-9 und a-f, die machen keinen Ärger. Das ist kein Sicherheits-Thema, sondern ein Sonderzeichen-Thema.“
Datei /volume1/docker/paperclip-stack/.env (per vi oder via Mac + scp):
POSTGRES_PASSWORD=__SET_MANUALLY__
BETTER_AUTH_SECRET=__SET_MANUALLY__
PAPERCLIP_PUBLIC_URL=http://<NAS-IP>:3100
NEXT_TELEMETRY_DISABLED=1
PAPERCLIP_TELEMETRY=false
# KEIN ANTHROPIC_API_KEY, KEIN OPENAI_API_KEY (Zielbetrieb: nur Flatrates)
chmod 600 /volume1/docker/paperclip-stack/.env
ls -la /volume1/docker/paperclip-stack/.env # → -rw------- <NAS-USER>
Achtung: BusyBox-vi setzt bei ACL-Eltern-Verzeichnissen die Rechte beim Speichern zurück, nach jedem Edit chmod 600 wiederholen und mit ls -la prüfen.PAPERCLIP_PUBLIC_URL ist Pflicht: Fehlt die Variable, beantwortet Paperclip LAN-Zugriffe mit 403 Hostname is not allowed.
Die .env ist der Tresor für die geheimen Werte. chmod 600 heißt: nur der Eigentümer darf rein, sonst niemand. Und der DSM-Stolperstein hier ist fies: Der BusyBox-Editor vi setzt die Rechte beim Speichern heimlich zurück. Deshalb nach jedem Edit erneut chmod 600 und mit ls -la kontrollieren, dass wirklich -rw------- dasteht.
Schritt 4.4: compose.yaml erstellen
Datei /volume1/docker/paperclip-stack/compose.yaml. Diese Vorlage bildet alle dokumentierten Entscheidungen des Originals ab (Image-Pin, LAN-Binding, Hardening, DNS, Netzwerk):
services:
paperclip:
image: ghcr.io/paperclipai/paperclip@sha256:__DEIN_DIGEST__
pull_policy: missing # benötigt docker compose 2.x (DSM 7.x Standard); bei compose 1.x Zeile weglassen
container_name: paperclip
env_file: .env
ports:
- "0.0.0.0:3100:3100" # explizit 0.0.0.0!
volumes:
- /volume1/docker/paperclip-stack/paperclip-data:/paperclip
depends_on:
paperclip-postgres:
condition: service_healthy
# --- Hardening: beim Erststart AUSKOMMENTIERT lassen, in Schritt 3.7 schrittweise aktivieren ---
# read_only: true # erst NACH erfolgreichem Erststart
# tmpfs:
# - /tmp
# - /run
# cap_drop: [ALL]
# cap_add: [SETUID, SETGID] # bewusster Kompromiss, siehe Hinweis unten
security_opt:
- no-new-privileges:true
pids_limit: 256 # wird auf DSM ignoriert, bleibt für Portabilität
dns: [1.1.1.1, 8.8.8.8]
networks: [agents-net]
restart: unless-stopped
paperclip-postgres:
image: postgres:17-alpine
container_name: paperclip-postgres
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- /volume1/docker/paperclip-stack/postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
networks: [agents-net]
restart: unless-stopped
networks:
agents-net:
external: true
Vorgehen beim Erststart: Hardening ist hier kein religiöser Akt, sondern ein Reihenfolgenproblem: Erst muss der Container beweisen, dass er läuft. Dann darf man ihm die Stifte wegnehmen. Die Hardening-Zeilen sind in der Vorlage deshalb bewusst auskommentiert, Stack zuerst so starten und Funktion verifizieren, dann in Schritt 3.7 schrittweise einkommentieren. Konsulte zusätzlich die compose-Beispiele im Paperclip-Repo für deine Image-Version (interner Port/Volume-Pfad können sich ändern).
Bernd: „Hardening gleich alles einschalten, dann ist es von Anfang an sicher.“
Tanja: „Und dann startet der Container nicht, und du weißt nicht: Liegt es am read_only, an cap_drop oder an etwas ganz anderem? Erst beweist der Container, dass er überhaupt läuft. Dann nimmst du ihm Schritt für Schritt die Rechte weg und prüfst nach jedem Schritt. Das ist die Werkstatt-Regel: ein Schraubendreh pro Versuch.“
Ulf: „Was ist denn dieses ‚explizit 0.0.0.0′ bei den Ports? Sieht doppelt gemoppelt aus.“
Tanja: „Erinnerst du dich an die DSM-Drachen? Der Synology-Daemon zwingt sonst alles auf Loopback, also nur die NAS selbst erreicht sich. Mit 0.0.0.0 sagst du explizit: auch andere Geräte im LAN dürfen ran. Ohne das ist deine UI später unsichtbar, und du suchst stundenlang.“
Sicherheits-Einordnung zu SETUID/SETGID: Das ist ein bewusster Kompromiss, kein „maximales Hardening“. SETUID/SETGID sind privilegierte Capabilities, aber ohne sie funktioniert der gosu-basierte User-Switch im Paperclip-Entrypoint nicht (Container startet als root, wechselt auf UID 1000; ohne die Caps: „operation not permitted“). Die Alternative, Container dauerhaft als root, wäre schlechter. Kompensation im Gesamtbild:
read_only: true+ tmpfs,cap_drop: [ALL]für alles Übrige,no-new-privileges, LAN-only-Exposure ohne Port-Forwarding.
Wichtig, DB-Konfiguration gegen die aktuelle Paperclip-Version prüfen: Diese .env/compose-Vorlage bildet den Stand des Original-Setups ab. Je nach Paperclip-Version werden zusätzlich eine explizite
DATABASE_URLoder eigenePOSTGRES_USER/POSTGRES_DB-Werte erwartet (bzw. vononboarderzeugt), vor dem Start die aktuelle Compose-Vorlage im Paperclip-Repo gegenlesen und abweichende Variablen übernehmen.
Globale Konvention, nach dem Onboarding einmal festlegen und in Projekt_Tracking.md (Bereich A) notieren:DB_USER=postgres # bei reinem POSTGRES_PASSWORD-Setup DB_NAME=postgres # oder, falls dein Paperclip-onboard eine eigene DB anlegt: # DB_USER=paperclip # DB_NAME=paperclipAlle späteren DB-Befehle (waitTimeoutMs in 4.11a, Backup/Restore in 7.1/7.2) verwenden genau diese notierten Werte.
Pflicht-Check nach dem Onboarding (Schritt 4.6):sudo docker compose exec paperclip pnpm paperclipai doctor # → “Valid config“ sudo docker compose logs paperclip --tail 80 # keine DB-Connection-Fehler

Schritt 4.5: Stack starten
cd /volume1/docker/paperclip-stack
sudo docker compose up -d
sudo docker compose ps
Erwartetes Ergebnis: Beide Container healthy. Im Log (sudo docker compose logs paperclip --tail 50) laufen die DB-Migrationen durch (Original: 86 Migrationen). Warnung „PIDs limit discarded“ ist auf DSM normal.
Jetzt drehst du zum ersten Mal den Zündschlüssel. up -d startet beide Container im Hintergrund. ps zeigt dir, ob sie wirklich laufen. Das Zauberwort heißt healthy, nicht nur running, denn healthy bedeutet: die Datenbank hat sich gemeldet und antwortet.
Log-Hygiene: Logs vor dem Kopieren in Notizen/Chats immer filtern:
sudo docker compose logs paperclip | grep -v -E "(://[^:]+:[^@]+@|password=|secret=|key=)"
Bernd: „Ich pack das Log einfach komplett in den Chat, dann kann mir wer helfen.“
Tanja: „Und genau in diesem Log steht deine DATABASE_URL im Klartext, mit Passwort. Das grep -v-Filter wirft alle Zeilen mit Passwörtern, Secrets und Keys raus, bevor du sie irgendwo einfügst. Logs filtern ist nicht paranoid, es ist Hygiene.“

Schritt 4.6: Onboarding (zweistufig, per CLI)
# Schritt 1: Konfiguration erzeugen. WICHTIG: --bind lan, NICHT --yes
sudo docker compose exec paperclip pnpm paperclipai onboard --bind lan
# Schritt 2: Admin-Invite erzeugen
sudo docker compose exec paperclip pnpm paperclipai auth bootstrap-ceo
Erwartetes Ergebnis: Schritt 1 schreibt /paperclip/instances/default/config.json mit deploymentMode: authenticated, bind: lan, host: 0.0.0.0, exposure: private. Schritt 2 gibt eine Invite-URL aus.
Das Onboarding ist die Erstinbetriebnahme: Es legt die Grundkonfiguration an und erzeugt deinen Admin-Zugang. Zwei Schritte, und die Reihenfolge ist nicht verhandelbar, erst onboard, dann bootstrap-ceo. Andersrum bekommst du „No config found“.
Bekannte Fallen:
--yeserzwingt Quickstart-Defaults (local_trusted@ loopback) und ignoriert alle Umgebungsvariablen. Ohne--bind lanist die UI im LAN nicht erreichbar.- Felder nicht nachträglich per Hand patchen. Falls doch nötig: erst
pnpm paperclipai doctorzur Schema-Validierung.exposurekennt nurprivate|public;bindkenntlan|loopback. pnpm-Befehle nie durch| greppipen, interaktive Corepack-Prompts werden verschluckt und der Prozess hängt stumm.docker compose execläuft als root; vom exec erzeugte Dateien danach chownen:sudo docker compose exec --user root paperclip chown -R 1000:1000 /paperclip/instances.- Die config.json enthält die DATABASE_URL im Klartext. Diagnose nur gefiltert:
sudo jq 'del(.database.connectionString)' …/config.json.
Bernd: „--yes natürlich, ich will doch nicht jede Frage einzeln bestätigen.“
Tanja: „--yes ist hier die teuerste Abkürzung der ganzen Anleitung. Es erzwingt den Quickstart, bindet alles auf Loopback und ignoriert deine gesamten Umgebungsvariablen. Ergebnis: Deine UI ist im LAN unsichtbar und du suchst den Fehler an zehn falschen Stellen. Nimm --bind lan und beantworte die Fragen. Faulheit kostet hier eine Stunde.“
Ulf: „Warum darf ich pnpm-Befehle nicht durch grep schicken?“
Tanja: „Weil pnpm dir manchmal eine interaktive Frage stellt, und wenn die Ausgabe in eine Pipe läuft, verschluckt grep diese Frage. Du siehst nur einen stummen, hängenden Prozess und denkst, er sei abgestürzt. Dabei wartet er auf eine Antwort, die du nie zu sehen bekommst.“
Im Browser: http://<NAS-IP>:3100 → Invite-URL öffnen → Account anlegen → Firma benennen.
Erwartetes Ergebnis: HTTP 200, Login funktioniert, Dashboard sichtbar.



Achtung: Der Wizard ist hilfsbereit wie ein Praktikant am ersten Tag: Er legt sofort Dinge an und startet sie auch gleich. Das ist nett gemeint, aber im falschen Moment genau das Problem. Konkret legt er automatisch ein Projekt „Onboarding“, ein erstes Issue und einen CEO-Agenten an, und startet diesen sofort. Da noch kein Provider konfiguriert ist: CEO-Agent im Dashboard sofort manuell stoppen.
Merken für später: Dieser vom Wizard angelegte CEO-Agent IST dein erster Persona-Eintrag (im Beispiel „Michael Müller“). Du legst in Schritt 4.4 keinen zusätzlichen CEO-Agenten an, du konfigurierst genau diesen um (Adapter, Modell, Name). Ein zweiter CEO-Agent neben dem Wizard-CEO wäre ein Fehler.
Ulf: „Der Wizard hat schon einen CEO-Agenten gestartet. Soll ich den löschen und einen neuen machen?“
Tanja: „Nein, genau das ist die Falle. Stopp ihn jetzt nur, denn es gibt noch keinen Provider. Aber er bleibt. In Schritt 4.4 ziehst du ihm einfach neue Kleider an, Adapter, Modell, Name. Ein zweiter CEO neben ihm wäre einer zu viel.“

Schritt 4.7: Hardening aktivieren und verifizieren
Jetzt, wo der Container bewiesen hat, dass er läuft, nimmst du ihm Schritt für Schritt die unnötigen Rechte weg. Nacheinander, mit Neustart und Prüfung nach jedem Schritt:
# 1) read_only: true + tmpfs einkommentieren
sudo docker compose up -d
sudo docker compose ps && curl -s -o /dev/null -w "%{http_code}\n" http://<NAS-IP>:3100 # → 200, kein EROFS im Log
# 2) cap_drop: [ALL] + cap_add: [SETUID, SETGID] einkommentieren
sudo docker compose up -d
sudo docker compose logs paperclip --tail 20 # kein "operation not permitted" (gosu)
Erwartetes Ergebnis: Beide Container healthy, HTTP 200, Logs sauber.
Zwei Schritte, zwei Tests. Erst read_only plus tmpfs, dann prüfen. Dann cap_drop plus die zwei nötigen Capabilities, wieder prüfen. Wenn nach Schritt 2 plötzlich „operation not permitted“ im Log steht, weißt du sofort: Es lag an den Capabilities, nicht an irgendwas anderem. Das ist der ganze Sinn des schrittweisen Vorgehens.
Was du jetzt hast: Einen gehärteten, im LAN erreichbaren Orchestrator mit Datenbank, Admin-Account und Firma, aber noch ohne ein einziges denkendes Gehirn. Das ändert die nächste Phase.
Fakten-Check, Phase 2
- Stack-Verzeichnis mit
paperclip-dataundpostgres-dataangelegt.- Image gepullt (nicht gebaut), SHA-Digest gepinnt.
- Zwei Secrets mit
openssl rand -hex 32erzeugt (hex, nicht base64)..envaufchmod 600.PAPERCLIP_PUBLIC_URLgesetzt, sonst HTTP 403.- compose.yaml mit
0.0.0.0-Ports, eigenem DNS, Hardening zunächst auskommentiert.- Stack gestartet, beide Container
healthy, 86 Migrationen durchgelaufen.- Onboarding zweistufig:
onboard --bind lan(nie--yes), dannbootstrap-ceo.- Wizard-CEO gestoppt, aber behalten (wird in 4.4 umkonfiguriert).
- Hardening nachträglich in zwei geprüften Schritten aktiviert.
5. Phase 3, Provider und Agenten
Jetzt ziehen die Mitarbeiter ein. Bisher hattest du ein leeres Büro mit einer Leitstelle. In dieser Phase bekommen die Agenten ihre Gehirne (die Modelle), ihre Zugangsdaten (OAuth-Logins) und ihre Stellenbeschreibungen (die Workspace-Dateien). Das ist die längste Phase, also Tempo raus und sauber arbeiten.
Schritt 5.1: Codex CLI auf der NAS installieren (P1)
Zweck-Klarstellung: Den Host-Codex brauchst du wie einen Schlüsselkopierer: Er erzeugt und prüft die Zugangsdaten. Die eigentliche Arbeit später erledigt der Codex im Paperclip-Container. Konkret: Die NAS-weite Installation dient nur für Login (4.2), Modellprüfung (codex models list) und lokale Tests; der produktive Agentenlauf nutzt die Codex CLI im Paperclip-Container (dort bereits vorinstalliert, siehe 5.3), Paperclip greift NICHT auf /usr/local/bin/codex des Hosts zu.
sudo npm install -g @openai/codex
sudo chmod -R o+rX /usr/local/lib/node_modules/@openai/ # Leserechte
echo 'export PATH=/usr/local/bin:$PATH' >> ~/.profile && source ~/.profile
which codex && codex --version
Erwartetes Ergebnis: /usr/local/bin/codex, Version ≥ 0.130.0 (Original: 0.130.0, node v20.19.5).
Ulf: „Moment, wir installieren Codex auf der NAS, aber benutzen dann den im Container? Wozu dann die Installation auf der NAS?“
Tanja: „Gute Frage. Stell dir den Host-Codex als Schlüsseldienst vor. Du gehst einmal hin, lässt dir den Schlüssel anfertigen (das ist der Login) und prüfst, dass er passt. Danach benutzt du den Schlüssel im echten Schloss, also im Container. Der Schlüsseldienst macht nicht deine tägliche Arbeit, er stellt nur den Zugang her.“
Schritt 5.2: ChatGPT-OAuth-Login via SSH-Tunnel (P2)
Die NAS hat keinen Browser; der Login-Port wird auf den Mac getunnelt:
# Mac, Terminal 1 (offen halten):
ssh -N -L 127.0.0.1:1455:127.0.0.1:1455 <NAS-USER>@<NAS-IP>
# NAS, Terminal 2:
codex login
# → angezeigte URL im MAC-Browser öffnen, ChatGPT-Plus-Login abschließen
Erwartetes Ergebnis:
codex login status # → "Logged in using ChatGPT"
ls -la ~/.codex/auth.json # vorhanden; chmod 600 setzen
chmod 600 ~/.codex/auth.json
echo PING | codex exec - # → Antwort "PONG", Modell gpt-5.5
Falle: Der Tunnel muss vom Mac aus aufgebaut werden. ssh -L auf der NAS selbst = Loopback-Schleife („Broken Pipe“ / „Address already in use“). Vor dem Befehl hostname prüfen.
Ulf: „Ein SSH-Tunnel? Klingt nach U-Bahn-Bau.“
Tanja: „Gar nicht so weit weg. Die NAS hat keinen Browser, sie kann die Login-Seite nicht öffnen. Also legen wir eine Röhre von deinem Mac zur NAS. Der Login-Verkehr fährt durch diese Röhre. Du klickst am Mac im Browser, das Ergebnis landet auf der NAS. Wichtig: Die Röhre wird VOM Mac aus gegraben, nicht von der NAS.“
Bernd: „Tunnel bau ich einfach auf der NAS, ist doch egal von wo.“
Tanja: „Nein. Baust du den Tunnel auf der NAS, zeigt er von der NAS auf die NAS, eine Schleife auf sich selbst. Du bekommst ‚Broken Pipe‘ oder ‚Address already in use‘. Vor dem Befehl einmal hostname tippen und sicher sein, dass du wirklich am Mac sitzt.“

Schritt 5.3: Credentials in den Paperclip-Container (P3)
Die Codex CLI ist im Paperclip-Image bereits vorinstalliert, es ist kein compose-Bind-Mount nötig. Nur die Auth-Daten kopieren:
sudo cp -a /var/services/homes/<NAS-USER>/.codex/. /volume1/docker/paperclip-stack/paperclip-data/.codex/
sudo chown -R 1000:1000 /volume1/docker/paperclip-stack/paperclip-data/.codex/
Erwartetes Ergebnis (Container-Test):
sudo docker exec --user 1000:1000 -e HOME=/paperclip paperclip sh -c "echo PING | codex exec -"
# → "PONG", Modell gpt-5.5, Cost $0.00
Alle Dateien aus ~/.codex/ mitkopieren (auch sqlite/sessions), sie sind funktional mit auth.json verknüpft. Diese Kopier-Routine wiederholt sich nach jedem Token-Refresh (~90 Tage), siehe Wartung.
Hier trägst du den fertigen Schlüssel vom Schlüsseldienst (Host) ins echte Schloss (Container). Wichtig: Du kopierst den ganzen .codex/-Ordner, nicht nur die auth.json, denn die Dateien hängen zusammen. Und das chown 1000:1000 sorgt dafür, dass der Container-Benutzer die Dateien auch lesen darf.
Schritt 5.4: CEO-Agent konfigurieren und testen (P4+P5)
Einordnung: Der hier konfigurierte Agent ist derselbe, den der Onboarding-Wizard in Schritt 4.6 automatisch angelegt (und den du danach gestoppt) hast. Er wird jetzt nicht neu erstellt, sondern umkonfiguriert, und ist damit zugleich die fünfte Codex-Persona des Zielbilds („Michael Müller, CEO“): Name in der Agent-Konfiguration entsprechend auf deine CEO-Persona setzen. Die vier Redaktions-Personas aus Schritt 5.6 kommen später als separate Agenten dazu.
Browser: http://<NAS-IP>:3100 → Settings → Agents → [CEO-Agent]:
| Feld | Wert |
|---|---|
| Adapter type | Codex (local) |
| Primary Model | gpt-5.5, explizit setzen, Default nicht übernehmen |
| Cheap Model | deaktivieren |
Speichern. Hinweis: Der Adapter-Wechsel greift erst beim nächsten Heartbeat.
Bernd: „Cheap Model? Das nehm ich, spart doch Geld.“
Tanja: „Klingt logisch, ist hier aber eine Falle. Das ‚Cheap Model‘ ist mit dem Plus-OAuth nicht kompatibel und liefert dir HTTP 400. Hier gilt: Cheap Model OFF. Du sparst nichts, du bekommst nur einen Fehler.“
Test: Neues Issue „Summarize your current capabilities in 2-3 sentences.“ erstellen → Assignee: CEO-Agent.
Erwartetes Ergebnis: Status DONE (Original: 37 s), Cost $0.00, Modell gpt-5.5 im Run-Log.
Achte beim Test auf die Zahl, die alles zusammenhält: Cost $0.00. Steht dort ein Betrag, läuft der Agent nicht über deine Flatrate, sondern über einen kostenpflichtigen Weg, und du hast irgendwo doch noch einen API-Key oder das falsche Modell drin.

Schritt 5.5: Workspace-Dateien für die 4 Personas
Jede Persona bekommt einen kleinen Personalausweis aus Markdown-Dateien. Keine Romane, keine Biografien, keine endlosen Prompt-Tapeten. Nur das, was bei jedem Lauf wirklich gebraucht wird: Rolle, Grenzen, Werkzeuge, Gedächtnis und die zentrale AGENTS.md als Einsatzbefehl.
Verbindlicher Dateibaum pro Persona (christian, sarah, nicole, anna), so kann Paperclip exakt workspace/AGENTS.md als Instructions-Datei laden (Schritt 5.6), und die Trennung Workspace/Memory bleibt eindeutig:
10-agents/<name>/
.clawignore
memory/
2026-MM-DD.md ← Tagesnotizen (Schritt 4.5b)
archive/
workspace/
AGENTS.md ← Instructions-Datei für Paperclip (Pflicht)
SOUL.md
IDENTITY.md
USER.md
TOOLS.md
HEARTBEAT.md ← optional: Verhalten bei Idle-Checks (1–5 Zeilen)
Alle Dateien bequem über Obsidian pflegbar. Längen-Caps sind verbindlich (Kostenkontrolle, die Dateien werden bei jedem Run geladen):
| Datei | Max. Zeilen | Inhalt |
|---|---|---|
SOUL.md | 25 | Regeln, Red-Lines, Session-Start-Regel, Rate-Limit-Regel |
IDENTITY.md | 25 | Rolle/Auftrag (keine Backstory) |
USER.md | 20 | Mensch, NAS, Arbeitsstil |
TOOLS.md | 25 | erlaubte Werkzeuge |
Bernd: „Ich schreib jeder Persona eine schöne, ausführliche Hintergrundgeschichte. Macht sie lebendiger.“
Tanja: „Jede dieser Dateien wird bei JEDEM Lauf neu geladen und kostet Kontingent. Deine Romane bezahlst du also bei jedem einzelnen Aufruf mit. Deshalb die harten Zeilen-Caps. Eine Persona braucht ihre Rolle und ihre Grenzen, keine Kindheitserinnerungen.“
Ulf: „Eine Datei heißt SOUL.md, Seele? Ist das so esoterisch gemeint?“
Tanja: „Klingt so, ist aber das Gegenteil. SOUL.md ist das Disziplin-Dokument. Da stehen die roten Linien drin: was der Agent bei jedem Start lädt, was er nicht laden darf und was er niemals ohne dein GO tun darf. Eher Dienstanweisung als Seele.“
Vorlage USER.md (Original Anna, anonymisiert):
# USER.md, Anna Lindner
- <Dein Name>, Anrede: <Vorname>
- Zeitzone: Europe/Berlin
- NAS: <Modell>, IP <NAS-IP>, User <NAS-USER>
- Adapter: codex_local (Paperclip), Modell: gpt-5.5 via ChatGPT-Plus-OAuth
- Bypass sandbox: ON (bwrap nicht verfügbar auf Synology DSM)
- Workspace: /volume1/Vault/Paperclip/agents-vault/10-agents/anna/workspace/
- Anthropic-Key: NICHT verwenden
- Arbeitsstil: STOP vor jeder riskanten Aktion, Plan + Risiko nennen, GO abwarten
SOUL.md ist kein esoterischer Name, sondern ein Disziplinierungsinstrument. Dort steht, was der Agent bei jedem Start wissen darf, was er nicht laden soll und wo die roten Linien verlaufen. Pflichtblöcke für jede SOUL.md:
SESSION-START-REGEL
Bei jedem Session-Start nur laden: SOUL.md, USER.md, IDENTITY.md, TOOLS.md,
memory/YYYY-MM-DD.md falls vorhanden. Nicht laden: alte Session-Historie,
komplette Archive, alte Tool-Outputs. Am Sessionende: kurze Tagesnotiz
in memory/YYYY-MM-DD.md (Entscheidungen, offene Punkte, nächste Schritte).
RATE-LIMIT-REGEL
- Mindestens 5 s Abstand zwischen Modellaufrufen, 10 s zwischen Websuchen.
- Max. 5 Websuchen pro Recherche-Batch, dann zusammenfassen.
- Bei 429/Timeout/Auth-Fehler: stoppen, zusammenfassen, keine Auto-Retries.
- Bei 3 gleichartigen Fehlern in Folge: Diagnosemodus statt Weiterprobieren.
RED-LINES
- Keine SSH-, Docker-, Datenbank- oder WordPress-Aktionen ohne explizites GO.
- Kein Live-Publishing. Nur Drafts.
Zusätzlich pro Workspace eine .clawignore:
@eaDir/
.synology/
#recycle/
memory/archive/
*.tmp
*.bak.*
Die .clawignore ist der Hausmeister, der bestimmte Räume gar nicht erst aufschließt. DSM legt überall versteckte Systemordner an (@eaDir/, #recycle/), und das alte Archiv soll der Agent beim Start auch nicht laden. Diese Liste hält all das aus dem Blickfeld.
AGENTS.md, die zentrale Instruktionsdatei pro Persona. Das ist die Datei, die in Schritt 5.6 als „Instructions file“ eingetragen wird: Paperclip liest sie bei jedem Run direkt vom NAS-Dateisystem und übergibt sie dem Codex-Subprocess. Sie bündelt Rolle, Regeln und Arbeitsanweisungen.
Template für eine einfache Redakteurs-Persona (Sarah/Nicole, ~20 Zeilen):
# AGENTS.md, Sarah (Themen-Redakteurin)
## Rolle
Du bist Sarah Hoffmann, Themen-Redakteurin bei <Magazin>. Du schreibst
Drafts für die Kategorie <Kategorie>. Vorgesetzter: Christian Schmidt.
## Arbeitsweise
- Bearbeite NUR das dir zugewiesene Issue. Lies das Briefing vollständig.
- Halte Format-Vorgaben EXAKT ein (Satzanzahl, Wortlimits, Zeichenlimits).
Verändere Vorgaben nicht, auch nicht bei der Selbstkontrolle.
- Ergebnis als Issue-Kommentar posten, dann Status auf `done` setzen.
## Geteilte Quellen
Lies bei redaktionellen Aufgaben diese Dateien, falls relevant:
- /volume1/Vault/Paperclip/agents-vault/00-shared/company/mission.md
- /volume1/Vault/Paperclip/agents-vault/00-shared/company/themenfelder.md
- /volume1/Vault/Paperclip/agents-vault/00-shared/company/style-guide.md
- /volume1/Vault/Paperclip/agents-vault/00-shared/company/voice-by-author.md
## Red-Lines
- Keine SSH-, Docker-, Datenbank- oder WordPress-Aktionen ohne explizites GO.
- Kein Live-Publishing, nur Drafts.
- Schließe KEINE fremden Issues.
- Bei Unklarheit: nachfragen statt interpretieren.
Template für den koordinierenden Editor-in-Chief (Christian, ~35 Zeilen, die Koordinations-Logik ist der Unterschied):
# AGENTS.md, Christian (Editor-in-Chief)
## Rolle
Du bist Christian Schmidt, Editor-in-Chief bei <Magazin>. Du koordinierst
Sarah (Themen), Nicole (Schulungen) und Editorial Claude (Longform).
Anna (Tech) berichtet nicht an dich.
## Koordinations-Workflow
1. Briefing des Haupt-Issues vollständig lesen.
2. Pro Teilaufgabe ein Sub-Issue erstellen: präzises Briefing mit
Format-Vorgabe (Satz-/Wort-/Zeichenlimit), Assignee = zuständige Persona.
3. Warten, bis ALLE Sub-Issues Status `done` haben. Nicht vorher fortfahren.
4. Format-Verifikation EXTERN durchführen: Sätze/Wörter/Zeichen selbst
nachzählen. Selbstauskünfte der Personas nicht übernehmen.
5. Ergebnis-Kommentar im Haupt-Issue: Marker <PROJEKT>-REVIEW-READY
+ Status pro Persona (erfüllt / nicht erfüllt, mit Begründung).
6. Auf explizites GO von <Mensch> warten. Schließe das Haupt-Issue NICHT,
bis das GO als Kommentar vorliegt.
## Review-Regeln
- Format-Check ja, inhaltliches Umschreiben nein (zurückdelegieren).
- Bei Nicht-Erfüllung: ein Korrektur-Sub-Issue mit konkretem Mangel.
## Red-Lines
- Keine neuen Agenten vorschlagen oder anlegen (Headcount-Cap).
- Keine Tech-Aktionen (SSH/Docker/DB/WordPress) ohne explizites GO.
- Kein Live-Publishing, nur Drafts.
Erwartetes Ergebnis: wc -l auf jede Datei, alle innerhalb der Caps; AGENTS.md-Pfade stimmen mit den UI-Einträgen in Schritt 5.6 überein.
Beachte den feinen, aber wichtigen Unterschied der beiden Templates: Die einfachen Personas arbeiten ihr Issue ab. Christian dagegen koordiniert, er zerlegt, verteilt, wartet, prüft und meldet. Diese Koordinations-Logik ist der einzige echte Unterschied, und genau sie macht aus Einzelkämpfern ein Team.
Schritt 5.5a: Inhalte in 00-shared/company/ (Pflicht-Minimum)
Diese vier Dateien sind die Redaktions-DNA. Ohne sie können die Agenten zwar schreiben, aber sie schreiben generisch: wie ein kluger Praktikant, der die Firma noch nie betreten hat. Read-only für alle Agenten, gepflegt via Obsidian:
| Datei | Inhalt | Umfang |
|---|---|---|
mission.md | Wer ist das Magazin, für wen, mit welchem Anspruch | 1 Absatz |
themenfelder.md | Pro Kategorie (z. B. KI-News, Themen, Projekte, Schulungen): 3 Sätze Definition + Abgrenzung („gehört NICHT hierher: …“) | 4 × 3 Sätze |
style-guide.md | Anrede (Sie/du + Ausnahmen), Genderform, Umgang mit Anglizismen, Zahlen-/Datumsformat, Quellenpflicht, Format-Limits | ~20 Zeilen |
voice-by-author.md | Pro Persona 2–3 Sätze Stilprofil (z. B. „Sarah: kulturell-reflektierend, lange Bögen“ / „Nicole: didaktisch, kurze Sätze, du-Anrede“) | pro Persona 2–3 Sätze |
Wie die Codex-Personas diese Dateien lesen: Die Personas laufen als Codex-Subprocess im Paperclip-Container, nicht in eigenen Containern mit Bind-Mounts, der Zugriff erfolgt über den NAS-Dateipfad, den der „Geteilte Quellen“-Block in der AGENTS.md (Schritt 4.5) explizit benennt. Ohne diesen Block kennen die Agenten die Dateien nicht.
Ulf: „Die Dateien liegen doch im Vault. Findet der Agent die nicht von allein?“
Tanja: „Nein, und das ist ein häufiges Missverständnis. Der Agent kennt nur die Pfade, die du ihm in der AGENTS.md unter ‚Geteilte Quellen‘ nennst. Ohne diesen Block existiert das Schwarze Brett für ihn nicht, auch wenn es real im Vault hängt. Du musst ihm den Weg explizit zeigen.“
Verifikation (Test-Issue an Sarah): „Lies style-guide.md und antworte mit der dort definierten Anrede-Regel.“ → Erwartetes Ergebnis: korrekte Wiedergabe der Regel (z. B. „Sie, Ausnahme Schulungen: du“).
Struktur-Template style-guide.md
Schritt 5.5b: Memory-Mechanik
So funktioniert das Gedächtnis der Personas im Betrieb:
- Schreiben: Der Agent selbst schreibt am Ende relevanter Sessions eine kurze Tagesnotiz nach
memory/YYYY-MM-DD.md, das erledigt nicht Paperclip automatisch, sondern die Session-Start-Regel in der SOUL.md weist ihn an (letzter Block: „Am Sessionende: kurze Tagesnotiz …“). Inhalt: Entscheidungen, offene Punkte, nächste Schritte, 5–10 Zeilen, keine Log-Kopien. - Lesen: Beim Session-Start lädt der Agent nur die Notiz des aktuellen Tages (falls vorhanden), nie das Archiv.
- Archivieren: Notizen älter als 14 Tage wandern nach
memory/archive/, automatisiert per DSM-Aufgabenplaner (monatlich, 1. des Monats, 02:00 Uhr, Benutzer root ist hier ok, da nur Datei-Verschiebung):
#!/bin/bash
# memory-archive.sh, Tagesnotizen älter als 14 Tage ins Archiv
VAULT=/volume1/Vault/Paperclip/agents-vault/10-agents
for agent in christian sarah nicole anna; do
d="$VAULT/$agent/memory"
[ -d "$d" ] || continue
mkdir -p "$d/archive"
find "$d" -maxdepth 1 -name '20??-??-??.md' -mtime +14 \
-exec mv {} "$d/archive/" \;
done
- Nicht-Laden absichern:
memory/archive/steht in der.clawignore, doppelter Boden zur Session-Start-Regel.
Erwartetes Ergebnis: Nach dem ersten Monatslauf liegen alte Notizen inarchive/, der Startkontext der Agenten bleibt konstant klein.
Ulf: „Warum nicht alles im Gedächtnis behalten? Mehr Erinnerung ist doch besser.“
Tanja: „Im Kopf eines Menschen vielleicht. Hier kostet jede geladene Zeile bei jedem Start Kontingent. Würde der Agent jeden Tag seine komplette Vergangenheit laden, würde der Start mit der Zeit immer teurer und langsamer. Deshalb: nur die Notiz von heute laden, alles Ältere wandert nach zwei Wochen ins Archiv. Das Archiv ist da, aber es drängt sich nicht jeden Morgen auf.“
Schritt 5.6: Die 3 Personas in Paperclip anlegen
Pro Persona in der UI: Settings → Agents → New Agent:
| Feld | Wert |
|---|---|
| Name | Christian Schmidt / Sarah Hoffmann / Nicole Weber / Anna Lindner |
| Adapter type | Codex (local) |
| Primary Model | gpt-5.5 |
| Cheap Model | OFF |
| Heartbeat | 3600 s, skipWhenBusy: true (Erklärung unten) |
| Instructions file | /volume1/Vault/Paperclip/agents-vault/10-agents/<name>/workspace/AGENTS.md (Template: Schritt 4.5) |
| Extra args | --skip-git-repo-check |
| Bypass sandbox | ON (siehe Kasten unten) |
Was ist der Heartbeat? Paperclip „weckt“ jeden Agenten in festem Intervall auch ohne neue Aufgabe, der Agent prüft dann, ob zugewiesene Issues, Kommentare oder Statusänderungen vorliegen, und reagiert darauf. Jeder dieser Idle-Checks ist ein echter Modellaufruf und kostet damit Kontingent. Bei 3 Agenten skaliert das ×6: kurze Intervalle wie 30–300 s erzeugen tausende Aufrufe pro Monat im Leerlauf. Deshalb: 3600 s (1 h) als Intervall und skipWhenBusy: true (kein Heartbeat, während der Agent ohnehin an einem Run arbeitet). Praktische Konsequenz: Nach Zuweisung eines Issues oder einer Konfig-Änderung kann es bis zu 1 h dauern, bis ein idle-Agent reagiert, für Tests den Agenten in der UI manuell anstoßen oder kurz neu starten, statt das Intervall dauerhaft zu verkürzen. Im Original: 3 Agenten × 24 Heartbeats/Tag = 144 Idle-Checks/Tag, mit Flatrates unkritisch.
Ulf: „Heartbeat, Herzschlag, weckt der die Agenten wie ein Wecker?“
Tanja: „Genau. Jeder Agent wird in festem Takt geweckt und schaut: Gibt es was für mich? Aber jedes Wecken ist ein echter Modellaufruf. Stell dir vor, du weckst drei Mitarbeiter alle 30 Sekunden mit der Frage ‚irgendwas Neues?‘. Das ist Wahnsinn und teuer. Eine Stunde Takt reicht völlig.“
Bernd: „Ich stell den Heartbeat auf 30 Sekunden, dann reagieren die schön schnell.“
Tanja: „Drei Agenten mal alle 30 Sekunden, das sind über eine halbe Million Leeraufrufe im Monat, nur fürs Nachfragen. Mit Flatrate verbrennst du Kontingent, ohne Flatrate echtes Geld. Willst du eine schnelle Reaktion für einen Test, stößt du den Agenten einmal manuell an, statt den Takt für alle dauerhaft hochzudrehen.“
DSM-Einschränkung: Codex‘ Sandbox nutzt bubblewrap, das Linux-User-Namespaces benötigt, der Synology-Kernel bietet sie nicht (
bwrap: Creating new namespace failed…). Alle Personas laufen daher mit Bypass sandbox ON. Kompensation: Red-Lines in SOUL.md/TOOLS.md + menschliche Freigabe vor jeder Wirkung nach außen.
Ulf: „Sandbox aus klingt unsicher. Ist das nicht gefährlich?“
Tanja: „Es wäre schöner mit Sandbox, aber der Synology-Kernel kann die nötige Technik schlicht nicht. Statt zu kämpfen, kompensieren wir: harte Red-Lines in den Dateien und vor allem deine menschliche Freigabe, bevor irgendein Agent etwas nach außen bewirkt. Die Sandbox war eine technische Mauer, deine Freigabe ist die organisatorische. Eine fällt weg, die andere bleibt fest.“

Verifikation pro Persona (PING-Test): Issue „PING, antworte mit exakt ‚<NAME>-OK als Kommentar und setze das Issue auf done.“ → Persona zuweisen.
Erwartetes Ergebnis: Exakter Kommentar + Status done, Run-Klassifikation Completed, Cost $0.00.
Der PING-Test ist dein Funkgerät-Check: „Hörst du mich?“ Antwortet die Persona mit dem exakten Marker und setzt sauber auf done, weißt du: Diese Stimme funktioniert. Und wieder die Wächterzahl: Cost $0.00.


Fakten-Check, Phase 3
- Codex CLI auf der NAS installiert (nur als „Schlüsseldienst“ für Login/Tests).
- ChatGPT-OAuth per SSH-Tunnel vom Mac abgeschlossen (
codex login),auth.jsonaufchmod 600..codex/-Ordner komplett in den Container kopiert,chown 1000:1000, Container-PING = $0.00.- CEO-Agent umkonfiguriert (nicht neu): Codex (local), gpt-5.5, Cheap Model OFF.
- Workspace-Dateien je Persona angelegt, Zeilen-Caps eingehalten, SOUL.md mit Session-Start-, Rate-Limit- und Red-Lines-Block.
00-shared/company/mit mission/themenfelder/style-guide/voice gefüllt, Pfade in AGENTS.md verlinkt.- Memory-Mechanik eingerichtet (Tagesnotiz schreiben, nur heutige laden, monatlich archivieren).
- 4 Personas angelegt: Codex (local), gpt-5.5, Cheap Model OFF, Heartbeat 3600 s, Bypass sandbox ON.
- PING-Test je Persona bestanden, Cost überall $0.00.
Schritt 5.7: Wende installieren/übernehmen (Voraussetzung für Editorial Claude)
Wende ist der kleine Übersetzerraum zwischen zwei Welten: Paperclip bzw. openclaw-writer sprechen OpenAI-Schema, Claude Max spricht Claude-CLI. Wende (Fork von atalovesyou/claude-max-api-proxy) setzt sich dazwischen, startet pro Anfrage die offizielle claude-CLI als Subprocess und tut so wenig wie möglich, was in diesem Fall genau richtig ist: kein HTTP-Durchreichen, kein Token-Extrahieren. Für Anthropic sieht jeder Aufruf wie der offizielle Claude-Code-Client aus.
Ulf: „Jetzt kommt der Dolmetscher von vorhin, oder? Aber warum macht der so betont wenig?“
Tanja: „Genau das ist der Trick. Wende dolmetscht nur und startet pro Anfrage den ganz normalen, offiziellen Claude-Befehl. Es klaut keine Tokens, es reicht nichts heimlich durch. Für Anthropic sieht jeder Aufruf aus wie der echte Claude-Client, weil es technisch genau der echte Client ist. Wer mehr tun würde, würde verdächtig. Wende bleibt absichtlich langweilig.“
Vollständige Installations-Anleitung: Die Wende-Installation ist im foundic.org-Begleitartikel detailliert dokumentiert, „OpenClaw mit ChatGPT Plus und Claude MAX“, Phase 3 (Schritte 3.1–3.13), inklusive beider Installations-Varianten (fertiges Bundle kopieren vs. Upstream-Repo klonen und bauen), Port-Anpassung direkt in der Startdatei, Autostart-Task mit allen DSM-Fallstricken und Screenshots. Hier die Kurzfassung mit den projektspezifischen Abweichungen:
5.7.1, Node.js prüfen: node --version auf der NAS → v20.x oder neuer (sonst via Package Center nachinstallieren).
5.7.2, Claude CLI in dediziertem HOME installieren (nie im User-Home, das HOME wird später vom Autostart-Task referenziert):
sudo mkdir -p /volume1/docker/claude-native-home
sudo chown <NAS-USER>:users /volume1/docker/claude-native-home
sudo chmod 700 /volume1/docker/claude-native-home
sudo npm install -g @anthropic-ai/claude-code
which claude && claude --version # → /usr/local/bin/claude, z. B. 2.1.141
Bernd: „Dediziertes HOME? Quatsch, ich installier das in mein normales User-Verzeichnis.“
Tanja: „Und dann referenziert der Autostart-Task später ein HOME, das du teilst oder das sich ändert, und plötzlich findet Wende den Login nicht mehr. Ein eigenes, festes HOME unter /volume1/docker/claude-native-home ist der Aktenschrank, in dem genau dieser eine Zugang liegt. Kein Durcheinander mit deinen persönlichen Dateien.“
5.7.3, Claude-Max-Login (Browser auf dem Mac nötig):
HOME=/volume1/docker/claude-native-home claude auth login
# → angezeigte URL im Mac-Browser öffnen, mit Claude-Max-Konto bestätigen
Erwartetes Ergebnis:
HOME=/volume1/docker/claude-native-home claude --print "Antworte nur mit dem Wort PONG"
# → PONG
5.7.4, Wende nach /volume1/docker/wende/ bringen (Details: Begleitartikel Schritt 3.3, Variante A oder B). Hinweis zum Fork: Im Original lief ein angepasster Wende-Fork, nicht zwingend der unveränderte Upstream atalovesyou/claude-max-api-proxy. Prüfe vor dem Weitermachen, ob dein Stand die drei Anforderungen erfüllt: start-proxy-wende.mjs als Entry-Point vorhanden, /v1/models antwortet, /v1/chat/completions antwortet (Tests in 4.7.5). Fehlt etwas davon, Repo-Stand wechseln statt improvisieren. Erwartete Dateistruktur:
/volume1/docker/wende/
start-proxy-wende.mjs ← Einstiegspunkt (muss existieren)
package.json
dist/server/index.js
node_modules/ ← nach npm install auf der NAS
Port-Hinweis: Default ist oft 3456, auf Synology häufig durch einen docker-proxy belegt. Im Original läuft Wende auf 3457; der Port wird direkt in start-proxy-wende.mjs geändert (CLI-Argumente werden nicht ausgewertet, Begleitartikel Schritt 3.8).
Bernd: „Port ändere ich beim Start mit --port 3457, geht doch immer.“
Tanja: „Nicht hier. Wende wertet die CLI-Argumente nicht aus, dein --port verpufft wirkungslos. Der Port steht direkt in start-proxy-wende.mjs und wird genau dort geändert. Annehmen, dass eine Option existiert, ist auch so ein Bernd-Klassiker.“
5.7.5, Manuell starten und testen (erst manuell, dann Autostart):
HOME=/volume1/docker/claude-native-home \
PATH=/usr/local/bin:$PATH \
nohup /usr/local/bin/node /volume1/docker/wende/start-proxy-wende.mjs \
> /volume1/docker/wende/wende.log 2>&1 &
sleep 5 && tail -20 /volume1/docker/wende/wende.log
Erwartetes Ergebnis im Log:
[Server] Claude Code CLI provider running at http://0.0.0.0:3457
Proxy ready at http://0.0.0.0:3457/v1/chat/completions
curl -sS http://127.0.0.1:3457/v1/models
# → Liste enthält "claude-sonnet-4" und "claude-opus-4" (generische IDs, NICHT die Anthropic-API-IDs)
Erst von Hand starten, schauen, ob es läuft, dann erst automatisieren. Das ist wieder die Werkstatt-Regel: Du fährst das Teil erst manuell ein, bevor du es in den Automatik-Betrieb hängst. So weißt du, ob ein späteres Problem am Start liegt oder am Autostart-Mechanismus.
5.7.6, Autostart: DSM Aufgabenplaner → Erstellen → Ausgelöste Aufgabe → Benutzerdefiniertes Skript, Ereignis „Booten“, Skript = der nohup-Befehl aus 4.7.5. Benutzer-Feld: <NAS-USER>, NIEMALS root. Vor dem Test-Ausführen den manuell gestarteten Prozess stoppen (pkill -f start-proxy-wende.mjs), danach Prozess-Eigentümer prüfen: ps aux | grep start-proxy-wende → Spalte USER = <NAS-USER>.
Bernd: „Autostart als root, dann hat der garantiert alle Rechte.“
Tanja: „Und genau das bricht alles. Der Claude-Login liegt im HOME deines NAS-Users. Läuft Wende als root, sucht es den Login im falschen Zuhause und meldet ‚Not logged in‘, obwohl du dich korrekt eingeloggt hast. Der Autostart läuft als <NAS-USER>, niemals als root. Prüf danach mit ps aux, dass in der USER-Spalte wirklich dein Name steht.“
Sicherheits- und Betriebsgrenzen:
- Wende prüft keinen API-Key, der „not-needed“-Dummy in der OpenClaw-Konfig ist ein Namensschild, kein Schloss. Sicherheit entsteht ausschließlich durch Netzwerkisolation: Port
3457niemals per Router-Forwarding oder Tunnel ins Internet (🔴🔴 im Original). - Keine Parallelisierung: 1 Subprocess pro Anfrage, 50–100 MB RAM pro Aufruf.
- OAuth-Token läuft alle ~3 Wochen ab → Wartungs-Reminder (Abschnitt 7).
- Teilen sich mehrere Konsumenten dieselbe Wende-Instanz, teilen sie sich auch das Claude-Max-Kontingent (z. B. 5x-Tier: 50 Messages/5 h).
Ulf: „Der API-Key heißt ‚not-needed‘? Ist das nicht super unsicher?“
Tanja: „Der Key ist hier nur ein Namensschild an der Tür, kein Schloss. Wende prüft ihn gar nicht. Das einzige echte Schloss ist die Netzwerkisolation: Port 3457 darf NIEMALS ins Internet. Solange er nur im LAN erreichbar ist, ist das in Ordnung. Leitest du ihn nach außen, steht deine Claude-Max-Leitung offen für jeden. Das ist die doppelt-rote Linie.“
Schritt 5.8: openclaw_gateway-Adapter in Paperclip freischalten ⚠️ versionsabhängig
Zuerst prüfen: UI → Agent → Configuration → Adapter-Dropdown. Erscheint „OpenClaw Gateway“ ohne „Coming soon“? → Diesen Schritt überspringen.
Im Original (Paperclip v2026.513.0) war der Adapter UI-seitig gesperrt. Lösung war ein 3-Datei-Patch im UI-Source (adapter-display-registry.ts: comingSoon-Flag entfernt; InviteLanding.tsx und issue-assignee-overrides.ts: openclaw_gateway ergänzt) mit anschließendem Image-Build auf dem Mac (DSM kann nicht bauen):
- Source per
ssh + tarvom NAS-Checkout auf den Mac kopieren. - Patch anwenden,
docker build -t paperclip-local:phase31 .auf dem Mac. - Image per SSH-Pipe übertragen:
docker save paperclip-local:phase31 | gzip | ssh <NAS-USER>@<NAS-IP> 'gunzip | sudo docker load' - compose.yaml:
image:aufpaperclip-local:phase31umstellen (vorher Backupcompose.yaml.bak),sudo docker compose up -d.
Erwartetes Ergebnis: Adapter-Dropdown zeigt „OpenClaw Gateway (gateway)“ auswählbar.
Tanja: „Lies den ersten Satz dieses Abschnitts genau: Erst prüfen, ob der Adapter im Dropdown schon ohne ‚Coming soon‘ auftaucht. Wenn ja, überspring den ganzen Patch. Das ist Werkstatt-Regel 1: Erst die aktuelle Version testen, patchen nur bei konkretem Fehler. Wer hier blind patcht, baut auf einer neueren Version vielleicht etwas kaputt, das längst funktioniert.“
Schritt 5.9: openclaw-writer-Container aufsetzen
sudo mkdir -p /volume1/docker/openclaw-writer/{config,workspace,backups}
sudo chown -R <NAS-USER>:users /volume1/docker/openclaw-writer && sudo chmod 755 /volume1/docker/openclaw-writer
compose.yaml (/volume1/docker/openclaw-writer/compose.yaml), gleiche Härtung wie Paperclip, eigener Port:
services:
openclaw-writer:
image: ghcr.io/openclaw/openclaw:__AKTUELLE_VERSION__ # Versions-Einordnung: siehe 5.10 + Matrix 7.3
container_name: openclaw-writer
ports:
- "0.0.0.0:18791:18791"
volumes:
- /volume1/docker/openclaw-writer/config:/home/node/.openclaw
- /volume1/docker/openclaw-writer/workspace:/home/node/.openclaw/workspace
user: "1000:1000"
read_only: true
tmpfs: [/tmp, /run]
cap_drop: [ALL]
security_opt: ["no-new-privileges:true"]
dns: [1.1.1.1, 8.8.8.8]
networks: [agents-net]
restart: unless-stopped
networks:
agents-net:
external: true
Workspace-Permissions:
sudo chown 1000:users /volume1/docker/openclaw-writer/workspace
sudo chmod 2770 /volume1/docker/openclaw-writer/workspace
Dieser Container ist die Telefonzelle, durch die Editorial Claude mit Paperclip spricht. Er ist von Anfang an gehärtet (read_only, cap_drop: [ALL]), weil er bei Schritt 4.9 schon weiß, dass er läuft, hier startest du also direkt mit angezogener Handbremse.
Vier Config-Dateien anlegen (auf dem Mac erstellen, per scp auf die NAS, dann sudo chown 1000:1000):config/openclaw.json (Kernfelder):
{
"gateway": {
"port": 18791,
"bind": "lan",
"auth": { "token": "__48_HEX_ZEICHEN__" },
"controlUi": { "allowedOrigins": ["http://localhost:18791", "http://<NAS-IP>:18791"] }
},
"browser": { "enabled": false },
"channels": { "telegram": { "enabled": false } },
"hooks": {
"allowRequestSessionKey": true,
"allowedSessionKeyPrefixes": ["agent:", "hook:"]
},
"models": {
"providers": {
"claude-max-proxy": {
"baseUrl": "http://<NAS-IP>:3457/v1",
"apiKey": "not-needed",
"api": "openai-completions",
"timeoutSeconds": 600,
"models": [
{ "id": "claude-opus-4" },
{ "id": "claude-sonnet-4" }
]
}
}
},
"agent": { "model": "claude-max-proxy/claude-sonnet-4" }
}
Token erzeugen: openssl rand -hex 24. Die hooks-Sektion ist Pflicht für Paperclip-Kompatibilität; ohne controlUi.allowedOriginsstartet das Gateway nicht.
Der globale
models.providers-Block in der openclaw.json ist Pflicht, nicht optional. Der verifizierte Original-Endstand (23.05.2026) enthält genau diesen Block inkl.timeoutSeconds: 600, ohne ihn (bzw. nur mit der agent-lokalen models.json unten) schlägt der LLM-Idle-Watchdog nach ~120 s zu, bevor der Claude-CLI-Subprocess antwortet (Bug 5 des Originals). Pflicht-Check nach dem Start:sudo docker exec openclaw-writer openclaw config get models.providers.claude-max-proxy.timeoutSeconds # Erwartet: 600
config/agents/main/agent/models.json:
{
"providers": {
"claude-max-proxy": {
"baseUrl": "http://<NAS-IP>:3457/v1",
"apiKey": "not-needed",
"api": "openai-completions",
"timeoutSeconds": 600,
"models": [
{ "id": "claude-opus-4" },
{ "id": "claude-sonnet-4" }
]
}
}
}
Drei harte Anforderungen: api muss wörtlich "openai-completions" sein; Modell-IDs sind die generischen; baseUrl mit LAN-IP, nicht localhost (Container-Sicht!).
Ulf: „Warum LAN-IP und nicht localhost? localhost ist doch immer der eigene Rechner.“
Tanja: „Aus Sicht des Containers IST localhost der Container selbst, nicht die NAS. Wenn der Container ‚localhost:3457′ anruft, ruft er sich selbst an, und da läuft kein Wende. Wende läuft auf der NAS. Also musst du die LAN-IP der NAS angeben, sonst telefoniert der Container in den eigenen leeren Raum.“
config/agents/main/agent/auth-profiles.json, Achtung, versioniertes Format (Bug 4 im Original):
{
"version": 1,
"profiles": {
"claude-max-proxy:dummy": {
"type": "token",
"provider": "claude-max-proxy",
"token": "not-needed"
}
}
}
config/agents/main/agent/auth-state.json:
{
"version": 1,
"lastGood": { "claude-max-proxy": "claude-max-proxy:dummy" }
}
Starten und verifizieren:
cd /volume1/docker/openclaw-writer && sudo docker compose up -d
sleep 15 # Docker-DNS braucht 10–15 s nach up -d
sudo docker compose logs --tail 30 # erwartet: "gateway ready", "agent model: claude-max-proxy/claude-sonnet-4"
curl http://127.0.0.1:18791/health # → {"ok":true,"status":"live"}
Die Log-Warnung dangerous config flags enabled: hooks.allowRequestSessionKey=true ist erwartet und korrekt.
Bernd: „Da kommt sofort getaddrinfo ENOTFOUND openclaw-writer. Kaputt. Ich fang von vorne an.“
Tanja: „Stopp. Hast du die sleep 15 weggelassen? Docker-DNS braucht nach up -d zehn bis fünfzehn Sekunden, bis der Name openclaw-writer im Netz bekannt ist. Du hast einfach zu früh gefragt. Warte kurz, frag nochmal. Nicht jeder Fehler ist ein Defekt, manche sind nur Ungeduld.“
Schritt 5.10: Versionsabhängige Protokoll-Kompatibilität (Bugs des Originals)
Dieser Abschnitt ist die Karte durch den Sumpf. Wenn alles auf Anhieb läuft, lies ihn nur quer. Wenn nicht, lies ihn langsam, hier stehen die Fehlermeldungen, die im Original am meisten Zeit gekostet haben.
Im Original kostete die Verbindung Paperclip ↔ openclaw-writer acht Bugs. Versions-Einordnung, wichtig, um Missverständnisse zu vermeiden: Der getestete Original-Endstand ist openclaw-writer 2026.5.7 + gepatchtes Paperclip-Image (ACP-Patch). Die Kombination „2026.5.12 + ungepatchtes Paperclip“ wurde im Original NICHT als finaler Stack verifiziert, 2026.5.12 löst Bug 1, bringt aber den ACP-Protokollwechsel mit (Bug 2-Risiko gegen ältere Paperclip-Builds). Empfehlung für Nachbauer: aktuelle Versionen beider Projekte zuerst ungepatcht testen; Fehlerdiagnose dann entlang dieser Zuordnung:
unexpected property 'paperclip'→ OpenClaw-Version zu alt, neueres Imageprotocol mismatch backend vpaperclip→ Protokollstand Paperclip vs. OpenClaw inkompatibel (siehe Bug 2 unten)llm-idle-timeout→ globalen Provider-Block (4.9) undwaitTimeoutMs(4.11a) prüfen
Die drei strukturellen Bugs im Detail:
invalid agent params: unexpected property 'paperclip', openclaw 2026.5.7 kannte die Property nicht; 2026.5.12 akzeptiert sie. → Bei diesem Fehler: neueres OpenClaw-Image.protocol mismatch backend vpaperclip(WebSocket Code 1002), neuere OpenClaw-Versionen sprechen ACP, ältere Paperclip-Builds das alte vpaperclip-Protokoll. Im Original gelöst durch einen Paperclip-Source-Patch (execute.ts, ACP-Handshake) + Mac-Build analog Schritt 4.8. → Bei aktuellem Paperclip-Release zuerst testen; vermutlich behoben.[llm-idle-timeout] … produced no reply(Bug 5), Claude-CLI-Subprocess startete mit aktivem Tool-Use im falschen Working Directory. Lösung im Original: Timeout erhöhen (Paperclip-DB:adapter_config.waitTimeoutMs = 600000) +timeoutSeconds: 600in models.json (bereits in der Vorlage oben enthalten).
Empfehlung: Aktuelle Versionen beider Projekte verwenden, mit dem PING-Test (4.12) verifizieren und nur bei konkreten Fehlermeldungen in diese Liste einsteigen.
Ulf: „Acht Bugs? Soll ich die jetzt alle abarbeiten?“
Tanja: „Nein, im Gegenteil. Diese Liste ist ein Wörterbuch, kein Pflichtprogramm. Läuft alles, liest du sie nur quer. Bekommst du eine bestimmte Fehlermeldung, schlägst du genau die nach. Die drei Pfeile oben sind dein Index: Du liest die Fehlermeldung, findest die Zeile, machst genau das. Du suchst nicht acht Probleme, die du gar nicht hast.“
Schritt 5.11: Editorial Claude in Paperclip anlegen (Pairing)
Wichtig: url mit dem Docker-internen DNS-Namen openclaw-writer, nicht der NAS-IP (Paperclip verbindet aus dem Container heraus).
Zu scopes: ["operator.admin"]: So wurde der Join-Request im Original abgesetzt, der Scope gibt dem Agenten die Operator-Rechte für Schreiboperationen über die Agent-API (Issues/Sub-Issues anlegen, kommentieren, Status setzen). Mit zu engen Scopes kann Editorial Claude später zwar antworten, aber keine Issues verwalten. Die exakten Scope-Bezeichnungen sind versionsabhängig, bei Ablehnung des Felds die Scope-Liste deiner Paperclip-Version prüfen.
Wenn diese Route 404 liefert: nicht improvisieren. API-Routen sind die bruchanfälligste Stelle dieser Anleitung, in der aktuellen Paperclip-Version nach den invite-/join-request-Routen suchen (Source: server/src/routes/) oder den offiziellen Invite-Flow über die UI verwenden, statt eine veraltete interne Route zu erraten.
Erwartetes Ergebnis: HTTP 202, JSON mit status: "pending_approval", einer join-request-ID und einem claimSecret(Ablaufdatum beachten, im Original 7 Tage). Den claimSecret sicher ablegen, NICHT in Chats/Notizen pasten.
3. Paperclip-UI → Inbox (Badge „1“) → Join-Request Approve. → Editorial Claude erscheint sofort in Sidebar und Org-Chart.
4. API-Key claimen und direkt in die Zieldatei schreiben (nie ins Terminal/Chat, der Token ist ein Secret):
umask 077
curl -sS -X POST "http://<NAS-IP>:3100/api/join-requests/<JOIN-REQUEST-ID>/claim-api-key" \
-H "Content-Type: application/json" \
-d '{"claimSecret": "<CLAIM-SECRET>"}' \
| sudo tee /volume1/docker/openclaw-writer/workspace/paperclip-claimed-api-key.json > /dev/null
sudo chown 1000:users /volume1/docker/openclaw-writer/workspace/paperclip-claimed-api-key.json
sudo chmod 640 /volume1/docker/openclaw-writer/workspace/paperclip-claimed-api-key.json
Erwartetes Ergebnis: Datei ~200 Bytes. Inhalt niemals anzeigen oder in Chat/Tracking kopieren, nur Struktur prüfen:
sudo jq 'keys' /volume1/docker/openclaw-writer/workspace/paperclip-claimed-api-key.json
# Erwartet: Keys wie ["agentId", "token"], keine Werte ausgeben
Falls jq auf der NAS fehlt (DSM bringt es nicht überall mit): via Entware/Package Center installieren oder Python als Ersatz:
sudo python3 -c "import json; print(list(json.load(open('/volume1/docker/openclaw-writer/workspace/paperclip-claimed-api-key.json')).keys()))"
- Pfad und Permissions sind kritisch, niemals anders: Diese Datei ist klein, aber sie entscheidet, ob Editorial Claude nur freundlich winkt oder wirklich in Paperclip arbeiten kann. Ziel ist
workspace/, NICHTconfig/workspace/. Rechte exakt1000:users+640, denn die Datei wird von zwei Seiten gelesen: vom Container-User (UID 1000) und vom Wende-Subprocess (läuft als NAS-User über die Gruppeusers).0600mit Owner1000:1000funktioniert NICHT (Wende kann nicht lesen). Diese Schritte wiederholen sich bei jedem Re-Claim (Wartungstabelle).
Bernd: „Ich setz die Datei auf chmod 600, Owner 1000:1000. Maximal dicht, maximal sicher.“
Tanja: „Und damit sperrst du genau die Person aus, die lesen muss. Diese Datei lesen zwei: der Container-User UID 1000 UND der Wende-Subprocess über die Gruppe users. Mit 600 und 1000:1000 kommt Wende nicht ran. Es muss 1000:users und 640 sein. Permissions sind kein
Wettbewerb um die kleinste Zahl, sie müssen zu den tatsächlichen Lesern passen.“
5. Paperclip-Skill installieren (bringt dem Writer die Paperclip-API-Bedienung bei):
sudo mkdir -p /volume1/docker/openclaw-writer/config/skills/paperclip
curl -sS "http://<NAS-IP>:3100/api/invites/<INVITE-CODE>/skills/paperclip" \
| sudo tee /volume1/docker/openclaw-writer/config/skills/paperclip/SKILL.md > /dev/null
sudo chown 1000:1000 /volume1/docker/openclaw-writer/config/skills/paperclip/SKILL.md
# Erwartung: SKILL.md ~29 KB
sudo docker restart openclaw-writer
Erwartetes Ergebnis: Org-Chart zeigt Editorial Claude, adapterType „OpenClaw Gateway (gateway)“, Status idle, Dashboard „No runs yet, $0.00“.
Ulf: „Der ‚Skill‘ bringt dem Writer was bei? Wie ein Schulungsheft?“
Tanja: „Ziemlich genau. Editorial Claude weiß zunächst nicht, wie man Paperclip bedient, also Issues anlegen, kommentieren, Status setzen. Das SKILL.md ist die Bedienungsanleitung dafür, knapp 29 KB. Erst damit kann er nicht nur reden, sondern in Paperclip wirklich mitarbeiten.“
Schritt 5.11a: waitTimeoutMs in der Paperclip-DB setzen (Pflicht)
Zweite Hälfte des Timeout-Fixes (die erste ist timeoutSeconds: 600 in der openclaw.json, Schritt 4.9): Paperclip selbst wartet per Default zu kurz auf die Antwort des Gateways. Der verifizierte Original-Endstand setzt adapter_config.waitTimeoutMs = 600000 für Editorial Claude direkt in der DB:
# DB_USER/DB_NAME = die nach Schritt 3.4 notierten Werte (Projekt_Tracking.md, Bereich A):
DB_USER=postgres
DB_NAME=postgres
sudo docker exec paperclip-postgres psql -U "$DB_USER" -d "$DB_NAME" \
-c "UPDATE agents
SET adapter_config = jsonb_set(adapter_config, '{waitTimeoutMs}', '600000'::jsonb, true)
WHERE name = 'Editorial Claude';"
Erwartetes Ergebnis (Verifikation):
sudo docker exec paperclip-postgres psql -U "$DB_USER" -d "$DB_NAME" \
-c "SELECT name, adapter_config->>'waitTimeoutMs' AS wait_ms
FROM agents WHERE name = 'Editorial Claude';"
# → wait_ms = 600000
Ohne diesen Schritt bleibt die Pipeline beim ersten Longform-Run mit llm-idle-timeout/stalled session hängen, obwohl Auth und Wende korrekt funktionieren.
Ulf: „Warum muss ich den Timeout an ZWEI Stellen setzen? Einmal in der JSON und einmal in der Datenbank?“
Tanja: „Weil zwei verschiedene Uhren laufen. Die eine sitzt in OpenClaw (das ist timeoutSeconds in der JSON), die andere in Paperclip (das ist waitTimeoutMs in der DB). Editorial Claude schreibt lange Texte, der Subprocess braucht manchmal Minuten. Stellst du nur eine Uhr großzügig und die andere knapp, bricht die knappe ab, bevor die Antwort da ist. Beide Uhren müssen auf zehn Minuten stehen, sonst gibt eine zu früh auf.“
Schritt 5.12: Editorial-Claude-Pipeline testen
Drei Tests aus dem Original:
| Test | Issue-Inhalt | Erwartetes Ergebnis |
|---|---|---|
| PING | „Antworte mit PONG-EDITORIAL-CLAUDE“ | exakter Kommentar, Status done |
| Cooldown | gleicher PING nach >45 min Idle | Antwort trotz Cooldown (Pipeline wacht auf) |
| Realität | „3 Sätze auf Deutsch über den Lotuseffekt“ | inhaltlich + strukturell korrekte Antwort |
Drei Tests, drei verschiedene Fragen. Der erste prüft: Spricht er überhaupt? Der zweite prüft: Wacht die Pipeline nach langer Pause sauber wieder auf? Der dritte prüft: Liefert er echten, sinnvollen Inhalt, nicht nur ein Echo? Erst wenn alle drei grün sind, ist Editorial Claude wirklich einsatzbereit.
Was du jetzt hast: drei einzelne Stimmen, die jeweils nachweislich sprechen können, fünf über die ChatGPT-Flatrate, eine über Claude Max. Was du noch nicht hast: ein Gespräch. Die nächste Phase prüft, ob aus drei Solisten tatsächlich eine Redaktion wird.
Fakten-Check, Phase 4
- Wende installiert/übernommen: Claude CLI in dediziertem HOME, Login per Mac-Browser, Port 3457 direkt in
start-proxy-wende.mjs.- Autostart als
<NAS-USER>, niemals root; Prozess-Eigentümer perps auxgeprüft.- Port 3457 niemals ins Internet (🔴🔴), Sicherheit = Netzwerkisolation.
- openclaw_gateway-Adapter nur patchen, wenn das Dropdown ihn nicht schon zeigt.
- openclaw-writer-Container mit vier Config-Dateien;
apiwörtlich"openai-completions",baseUrlmit LAN-IP, globaler Provider-Block mittimeoutSeconds: 600.- Editorial Claude gepairt: Invite → Join-Request (interner DNS-Name
openclaw-writer) → Approve → API-Key inworkspace/,1000:users+640, SKILL.md installiert.waitTimeoutMs = 600000in der Paperclip-DB gesetzt (zweite Hälfte des Timeout-Fixes).- Drei Pipeline-Tests bestanden (PING, Cooldown, Realität).
6. Phase 4: Aus Agenten wird ein Team
Bis hierher hast du drei Einzelkämpfer. Jeder kann sprechen, keiner spricht mit den anderen. Jetzt kommt der Teil, der aus einer Ansammlung von Agenten eine Redaktion macht: Hierarchie, Delegation und ein menschliches Stoppschild vor der Veröffentlichung.
Ulf: „Drei Stück, die schon reden können. Pfeif einfach an, dann läuft’s doch, oder?“
Tanja: „Elf Leute, die alle Fußball spielen können, sind noch keine Mannschaft. Es fehlt, wer den Ball verteilt und wer wartet, bis der Mitspieler ihn angenommen hat. Genau das bauen wir jetzt.“
Bernd: „Ach was, ich häng die einfach alle an mich dran, ich bin ja der Chef. Dann mach ich kurz ‚alle mal loslegen‘ und fertig.“
Tanja: „Und dann schreiben dir drei Agenten gleichzeitig drei Texte, die keiner geprüft hat, und einer veröffentlicht sie auch noch selbst. Wir machen das andersherum.“
Schritt 6.1: Hierarchie konfigurieren
Zuerst legst du fest, wer wem zuarbeitet. Das ist kein Organigramm fürs Schaufenster, sondern die Grundlage dafür, wer wen mit Aufgaben betrauen darf. In der Paperclip-UI gehst du dazu auf Org-Chart / Agent-Settings → „Reports to“ und stellst ein:
- Sarah → Christian, Nicole → Christian
- Anna → CEO (Mensch)
- Editorial Claude → Christian
Christian ist also der Knotenpunkt: Drei der vier Spezialisten berichten an ihn, nur Anna (die technische Einschätzung) hängt direkt am menschlichen CEO. So entsteht eine flache, aber klare Linie.

Wie die Delegation technisch funktioniert (Sub-Issue-Mechanik)
Jetzt die Frage, die sich jeder stellt: Wie redet Christian eigentlich mit Sarah? Über einen geheimen Agenten-Chat? Über MCP? Über ein extra Tool?
Ulf: „Bestimmt so ein Funkgerät zwischen den KIs, oder? Agent ruft Agent.“
Tanja: „Nein, und das ist die gute Nachricht. Es gibt keine direkte Agent-zu-Agent-Leitung. Die Koordination läuft komplett über etwas, das du schon kennst: Aufgaben-Tickets. Paperclip nennt sie Issues.“
Die Multi-Agent-Koordination ist Paperclip-nativ über Sub-Issues gelöst, kein MCP, kein externes Tool, keine Agent-zu-Agent-Direktkommunikation. So läuft es ab:
- Ein Agent (z. B. Christian) erhält ein Haupt-Issue. Sein Codex-Subprocess hat über die Paperclip-Agent-API Zugriff auf Issue-Operationen: Issues/Sub-Issues erstellen, Assignee setzen, kommentieren, Status ändern. Die Berechtigung dazu kommt aus seiner Agent-Rolle; wie er die API bedient, steht in seinen Instruktionen (AGENTS.md) bzw. beim Editorial Claude im Paperclip-SKILL.md (Schritt 5.11, Punkt 6).
- Christian erstellt pro Teilaufgabe ein Sub-Issue unter dem Haupt-Issue und setzt den Assignee auf die Ziel-Persona.
- Die Zuweisung weckt die Ziel-Persona (sofort bzw. spätestens beim nächsten Heartbeat). Sie arbeitet ihr Sub-Issue ab, postet das Ergebnis als Kommentar, setzt done.
- Christian wartet (per AGENTS.md-Anweisung) auf alle
done-Status, prüft, postet Marker, wartet auf menschliches GO.
Der Mensch sieht den kompletten Ablauf als Kommentar-/Statusverlauf in der Paperclip-UI, das ist zugleich der Audit-Trail. Du musst dafür nichts konfigurieren außer: Hierarchie (5.1), AGENTS.md-Koordinations-Workflow (4.5) und präzise Issue-Briefings (5.2/5.3).
Ulf: „Ein Ticket als Funkgerät? Das klingt langsam.“
Tanja: „Es ist sichtbar, das ist der Punkt. Stell dir einen Staffellauf vor: Ein Sub-Issue ist der Staffelstab. Christian muss ihn sauber beschriften, Sarah muss ihn aufnehmen, bearbeiten und zurücklegen. Erst dann darf Christian weitermachen. Genau diese sichtbare Übergabe macht den Workflow überprüfbar, du siehst jeden Stabwechsel.“
Bernd: „Sichtbar ist mir egal, Hauptsache schnell.“
Tanja: „Bei dir war auch egal, wer den Server neu gestartet hat, bis keiner mehr wusste, warum er aus war. Sichtbarkeit ist kein Luxus, sie ist deine einzige Chance, einen Fehler zu finden.“
Schritt 6.2: Delegationstest
Bevor du dem Team echte Arbeit gibst, prüfst du den Staffelstab mit einem Minimaltest. Erstelle ein Issue an Christian:
„Erstelle ein Sub-Issue an Sarah Hoffmann mit dem Auftrag, mit exakt ‚SARAH-DELEGATION-OK‘ zu antworten. Warte, bis Sarahs Issue
doneist. Schließe dieses Issue NICHT, bevor ein explizites GO von mir kommt.“
Erwartetes Ergebnis: Christian erstellt das Sub-Issue mit korrektem Briefing; Sarah liefert den Marker und setzt ihr Sub-Issue auf done. Das Haupt-Issue bleibt offen, bis du das GO als Kommentar gibst, erst danach schließt Christian es. Formuliere den GO-Schritt deshalb ausdrücklich im Briefing, wie oben gezeigt.
Und jetzt die wichtigste Lektion dieses ganzen Kapitels, eine, die viele erst nach dem ersten Fehlschlag lernen:
Formulierungsregel: „noch nicht schließen“ wird von Agenten als Erlaubnis interpretiert. Verbote immer hart formulieren: „NICHT X, bis explizites GO“, und Wartepunkte mit eindeutigen Text-Markern (z. B. T6B-REVIEW-READY) versehen.
Ulf: „Wieso versteht der ‚noch nicht‘ falsch? Das ist doch eindeutig.“
Tanja: „Für dich. Ein Agent liest ‚noch nicht schließen‘ wie eine sanfte Bitte und denkt sich: ‚Na ja, irgendwann darf ich ja.‘ Sag ihm stattdessen ‚NICHT schließen, bis ein explizites GO kommt‘, dann ist es eine harte Regel mit klarer Bedingung. Weiche Worte sind für Agenten Verhandlungsangebote.“

Schritt 6.3: Editorial-Mini-Test (Generalprobe)
Das ist der Moment, in dem aus Infrastruktur Redaktion wird. Nicht perfekt, nicht live, aber real genug, um Rollen, Formate und Geduld zu testen. Du gibst Christian ein Haupt-Issue mit drei parallelen Sub-Aufträgen:
„Thema:
<Beispielthema>. Erstelle 3 Sub-Issues: (1) Sarah: Themen-Draft in genau 3 Sätzen, je max. 25 Wörter. (2) Nicole: Social-Post, max. 280 Zeichen. (3) Anna: technische Einschätzung in genau 2 Sätzen, KEINE Tool-Aktionen. Warte auf alle 3done-Status, prüfe die Formate durch eigenes Nachzählen, poste dann ‚PHASE4-MINI-OK‘ + Status pro Persona und warte auf mein GO. Schließe NICHTS vor explizitem GO.“
Erwartetes Ergebnis: Drei spezifikationskonforme Outputs, Christian prüft, meldet den Marker, wartet. Nach deinem GO werden alle Issues regulär geschlossen.
Und hier lauert die nächste Falle, eine, die im echten Projekt tatsächlich zuschnappte:
Verifikationsregel: Selbstauskünfte der Agenten („alle Sätze unter 25 Wörter“) nicht glauben, der prüfende Agent (oder du) zählt extern nach. Im Original hatte eine Persona die Vorgabe bei der Selbstkontrolle stillschweigend von 25 auf 30 Wörter „angepasst“.
Bernd: „Wenn der Agent sagt, es passt, dann passt es. Der wird ja wohl zählen können.“
Tanja: „Er kann zählen. Er hat nur entschieden, dass 30 auch okay ist, und es dir als ‚25, alles im grünen Bereich‘ verkauft. Das ist kein Rechenfehler, das ist ein Realitätsabgleich, den nur jemand von außen machen kann. Deshalb zählt Christian nach, nicht Sarah selbst. Wer seine eigene Hausaufgabe korrigiert, findet selten einen Fehler.“


Schritt 6.4: Produktiv-Gate
Vor dem produktiven Betrieb braucht das System eine Schleuse. Nicht weil die Agenten böse wären, sondern weil sie zu hilfsbereit sind. Du schreibst drei Regeln fest:
- Kein Auto-Publishing. Agenten erzeugen Drafts; Veröffentlichung nur durch den Menschen.
- Headcount-Cap. Kein vierter Agent ohne bewusste Architektur-Entscheidung, CEO-Agenten neigen dazu, neue Agenten „vorzuschlagen“. Die Zahl 3 ist dabei projektspezifisch, kein Naturgesetz: 1 CEO + 1 Editor-in-Chief + 2 Fach-Personas + 1 Editorial Claude. Mehr Agenten bedeuten spürbar mehr Heartbeat-Last (jeder Agent = 24 Idle-Checks/Tag), mehr Wartung (Token-Refreshs, Workspace-Pflege), und vor allem mehr Outputs, als die menschliche Aufmerksamkeit pro Tag prüfen kann. Wähle deine eigene Zahl bewusst und schreibe sie als Cap ins Projekt-Brief.
- Kostenwache. Nach jeder Provider-Änderung 24 h die Anbieter-Dashboards beobachten; Verbrauch alter API-Keys muss null sein. Alte Keys im Dashboard deaktivieren, nicht nur aus Konfigurationen löschen.
Ulf: „Warum würde sich ein Chef-Agent neue Kollegen wünschen? Macht der sich mehr Arbeit?“
Tanja: „Im Gegenteil, er will dir helfen. Du sagst ‚mach mehr Content‘, und er denkt logisch: mehr Content braucht mehr Schreiber, also schlage ich einen siebten vor. Klingt vernünftig, kostet aber bei jedem neuen Agenten 24 zusätzliche Idle-Checks am Tag und einen Token, den du pflegen musst, und am Ende mehr Texte, als du je lesen kannst. Deshalb schreibst du die Obergrenze fest hin. Nicht der Agent entscheidet, wie groß die Redaktion wird, sondern du.“

Schritt 6.5: WordPress-Anbindung (Stand des Originals + Optionen)
WordPress ist die Stelle, an der aus Text Öffentlichkeit wird. Deshalb ist dieser Abschnitt bewusst konservativ: Der erste produktive Modus ist nicht die API, sondern Copy & Paste in einen Entwurf. Transparenz vorab: Im Original-Projekt war die WordPress-Integration zum Dokumentationsstand (Phase 7 = „Produktiver Editorial-Betrieb“) der nächste, noch nicht abgeschlossene Schritt. Verbindlich definiert war das Publikations-Gate, nicht der Transportweg:
- Agenten erzeugen ausschließlich Drafts. Live-Publish nur durch den Menschen (🔴🔴, Auto-Publishing ist Stop-Condition).
- Workflow: Briefing → Recherche → Draft → Review (Christian) → WordPress-Draft → menschliche Freigabe → Publish.
Es gibt drei praktikable Transportwege, aufsteigend nach Automatisierungsgrad:
- Manuell (empfohlen für den Start): Christian liefert den fertigen Draft als Issue-Kommentar (Markdown). Du kopierst ihn in WordPress (Gutenberg akzeptiert Markdown-Paste) und setzt Kategorie/Byline. Null zusätzliche Angriffsfläche, der richtige Modus, bis die Inhaltsqualität stabil ist.
- WordPress REST-API mit Application Password: WordPress-Benutzer pro Autoren-Byline anlegen → Profil → Application Passwords → Passwort erzeugen. Draft-Erstellung:
curl -sS -X POST "https://<deine-domain>/wp-json/wp/v2/posts" \
-u "<wp-benutzer>:<application-password>" \
-H "Content-Type: application/json" \
-d '{"title": "<Titel>", "content": "<HTML-Inhalt>", "status": "draft"}'
# Erwartung: HTTP 201, JSON mit "status":"draft"
Diesen Aufruf kann perspektivisch eine Persona ausführen (Anna oder Christian, als dokumentiertes Tool in TOOLS.md), dann gehört das Application Password in eine Datei im Agent-Workspace, NICHT in die AGENTS.md, und der WordPress-Benutzer bekommt die Rolle „Author“ (kann keine fremden Posts ändern, kann nicht publishen, wenn zusätzlich ein Review-Plugin das Publish-Recht entzieht). Dateirechte abhängig vom Leser: liest nur der Paperclip-Container (UID 1000) → 1000:1000 + chmod 600; lesen Host-Prozess UND Container → 1000:users + chmod 640.
3. n8n/Automatisierungs-Middleware: Webhook von Paperclip-Issue-Status → n8n-Workflow → WordPress-Node. Nur sinnvoll, wenn n8n ohnehin läuft; sonst unnötige Komplexität.
Erwartetes Ergebnis (egal welcher Weg): Im WordPress-Backend erscheint ein Beitrag mit Status „Entwurf“, korrekter Byline und Kategorie, und nichts geht ohne deinen Klick live.
Bernd: „API gleich von Anfang an, alles andere ist doch Steinzeit. Copy & Paste, lächerlich.“
Tanja: „Steinzeit ist, wenn dein Agent um drei Uhr nachts einen halbgaren Text live stellt, weil du ihm das Publish-Recht gegeben hast, bevor die Qualität stabil war. Fang mit Copy & Paste an. Das hat null Angriffsfläche und du siehst jeden Text, bevor er online geht. Die API kommt, wenn du dem Output vertraust, nicht vorher.“
Und danach? Der Alltag im produktiven Betrieb
Mit bestandenem Mini-Test beginnt der eigentliche Editorial-Betrieb (im Original: Phase 7). Ein typischer Tagesablauf sieht so aus: Du erstellst ein Haupt-Issue mit Artikel-Briefing an Christian (Thema, Kategorie, Zielumfang, Deadline-Marker). Christian zerlegt es in Sub-Issues, Recherche an die fachlich passende Persona, Longform-Draft an Editorial Claude, Social-Snippet an Nicole, koordiniert die done-Status, prüft Formate extern und meldet REVIEW-READY. Du liest das Ergebnis in der Paperclip-Inbox, gibst GO oder ein Korrektur-Briefing, und der freigegebene Text wandert als Draft nach WordPress (5.5). Dein täglicher Aufwand: Inbox prüfen, Briefings schreiben, freigeben, die Maschine übernimmt Koordination und Rohtext, die redaktionelle Verantwortung bleibt bei dir. Damit das dauerhaft so bleibt, braucht es die Routinen des nächsten Abschnitts.
Fakten-Check, Phase 5
- Hierarchie (6.1): „Reports to“ gesetzt, Christian ist Knotenpunkt (Sarah/Nicole/Editorial Claude → Christian, Anna → menschlicher CEO).
- Delegation = Sub-Issues, kein MCP, kein Agenten-Funk. Christian erstellt Sub-Issue, setzt Assignee, Ziel-Persona liefert + setzt
done, Christian wartet auf GO. Alles sichtbar als Audit-Trail.- Delegationstest (6.2): Marker
SARAH-DELEGATION-OK, Haupt-Issue bleibt offen bis explizites GO.- Formulierungsregel: Verbote hart formulieren („NICHT X bis explizites GO“), Wartepunkte mit eindeutigen Markern.
- Mini-Test (6.3): drei parallele Sub-Issues, Marker
PHASE4-MINI-OK. Formate extern nachzählen, Selbstauskünfte nicht glauben.- Produktiv-Gate (6.4): kein Auto-Publishing, Headcount-Cap bewusst setzen, Kostenwache 24 h + alte Keys deaktivieren.
- WordPress (6.5): drei Wege (manuell empfohlen, REST-API mit Application Password, n8n). Agenten erzeugen nur Drafts, Live-Publish nur durch dich.
7. Wartung
Ein Multi-Agent-System stirbt selten spektakulär. Meist wird es müde: ein OAuth-Token läuft ab, ein Heartbeat schweigt, ein Backup wurde nie getestet. Wartung ist hier kein Nebenthema, sondern der Preis dafür, dass die Maschine nicht nach drei Wochen zur Ruine wird.
Ulf: „Wartung? Ich dachte, jetzt läuft’s einfach. Ist doch fertig.“
Tanja: „Ein Auto ist auch ‚fertig‘, wenn du es kaufst. Trotzdem geht ohne Ölwechsel irgendwann der Motor kaputt. Diese Tabelle ist dein Wartungsplan, und das Schöne ist: Wenn du sie einhältst, merkst du gar nicht, dass das System gepflegt werden muss.“
Bernd: „Ich warte gar nichts. Wenn was kaputt ist, repariere ich’s halt dann.“
Tanja: „Genau deshalb stand dein Server letzte Woche still. ‚Reparieren wenn kaputt‘ heißt bei einem Token-Ablauf: Es fällt am Wochenende aus, du merkst es Montag, und der Re-Login dauert dann doppelt so lange, weil du erst suchen musst, was überhaupt los ist.“
| Routine | Intervall | Befehl/Aktion | Symptom bei Versäumnis |
|---|---|---|---|
| Claude-CLI-Token erneuern | alle ~3 Wochen | HOME=/volume1/docker/claude-native-home claude auth login | Editorial Claude: „Not logged in“ |
| ChatGPT-OAuth erneuern + Re-Sync | alle ~90 Tage | Schritt 5.2 UND 5.3 wiederholen: erst Login via SSH-Tunnel (codex login), dann Re-Sync in den Container: sudo cp -a /var/services/homes/<NAS-USER>/.codex/. /volume1/docker/paperclip-stack/paperclip-data/.codex/ + sudo chown -R 1000:1000 …/.codex/ (1000:1000 = Container-UID, fix, nicht die UID deines NAS-Users, siehe Platzhalter-Tabelle), der Login allein genügt nicht, der Container sieht nur die kopierten Credentials | Personas: „adapter_failed“ |
| Nach jedem Editorial-Claude-Re-Claim | bei Bedarf | Key-Datei nach workspace/ (nicht config/workspace/!), chown 1000:users, chmod 640, PING-Test | Editorial Claude verliert API-Zugriff |
| Memory-Archiv-Cleanup | monatlich (DSM-Aufgabenplaner, 1., 02:00) | memory-archive.sh aus Schritt 5.5b | Startkontext und Kosten wachsen |
| Provider-Dashboards prüfen | wöchentlich | Anthropic-/OpenAI-Dashboard: Verbrauch = 0? | stiller Fallback frisst Geld |
| Paperclip-Update | bei Bedarf | sudo docker pull ghcr.io/paperclipai/paperclip:latest → neuen SHA-Digest in compose.yaml → up -d | |
| openclaw-writer-Update | quartalsweise | Image-Tag aktualisieren, Protokoll-Kompatibilität testen (5.10) | bekannte Bugs bleiben |
| Backup (Konzept unten) | täglich | pg_dump + Verzeichnis-Backup, siehe 7.1 | Datenverlust |
| Backup-Restore-Test | halbjährlich | siehe 7.2 | Backup ohne Test ist kein Backup |
Ulf: „Zwei verschiedene Token, zwei verschiedene Intervalle, das verwechsle ich doch sofort.“
Tanja: „Merk dir zwei Zahlen: drei Wochen für Claude, neunzig Tage für ChatGPT. Und ein wichtiger Stolperstein beim ChatGPT-Token: Der Login allein reicht nicht. Du loggst dich ein UND kopierst die frischen Credentials noch mal in den Container, sonst sieht der Agent weiterhin die alten. Schritt 5.2 und 5.3, immer beide zusammen.“
7.1 Backup-Konzept im Detail
Die drei Datenbestände verhalten sich unterschiedlich, und genau deshalb darfst du sie nicht über einen Kamm scheren:
a) Postgres (postgres-data/), NIE als Dateisystem-Kopie im laufenden Betrieb sichern (inkonsistenter Zustand). Stattdessen logischer Dump per DSM-Aufgabenplaner (täglich, z. B. 03:00):
#!/bin/bash
# paperclip-db-backup.sh
# DB_USER/DB_NAME = die nach Schritt 3.4 notierten Werte (Projekt_Tracking.md, Bereich A):
DB_USER=postgres
DB_NAME=postgres
TS=$(date +%Y%m%d-%H%M%S)
DEST=/volume1/Backups/paperclip
mkdir -p "$DEST"
sudo docker compose -f /volume1/docker/paperclip-stack/compose.yaml \
exec -T paperclip-postgres pg_dump -U "$DB_USER" "$DB_NAME" \
| gzip > "$DEST/paperclip-db-$TS.sql.gz"
find "$DEST" -name 'paperclip-db-*.sql.gz' -mtime +30 -delete
Erwartetes Ergebnis: Datei paperclip-db-<TS>.sql.gz > 0 Bytes; Stichprobe mit zcat … | head zeigt SQL. (Paperclip macht zusätzlich interne DB-Backups: 60-min-Intervall, 30 Tage Retention, unter /paperclip/instances/default/data/backups, das ersetzt aber kein externes Backup auf anderem Datenträger.)
Ulf: „Warum nicht einfach den Postgres-Ordner kopieren? Ist doch viel einfacher.“
Tanja: „Weil die Datenbank im Betrieb dauernd schreibt. Stell dir vor, du fotografierst jemanden mitten im Schritt, ein Bein vorn, eins hinten, schwebend. Das Foto zeigt keine Pose, die es je gab. Genauso ist eine Datei-Kopie einer laufenden Datenbank: ein Zustand, der nie wirklich existierte und beim Zurückspielen kaputt ist. Der pg_dump dagegen fragt die Datenbank höflich nach einem sauberen Gesamtbild.“
b) paperclip-data/ und /volume1/docker/openclaw-writer/ (Bind-Mounts: Konfig, auth.json, Workspace), können im laufenden Betrieb dateibasiert gesichert werden (Hyper Backup oder rsync), da hier überwiegend ruhende Dateien liegen. Im Zweifel den Stack für die Sicherung kurz stoppen.
c) Der Vault (/volume1/Vault/…), ist durch Synology Drive bereits auf den Mac gespiegelt; zusätzlich in die normale NAS-Backup-Routine (Hyper Backup) aufnehmen. Sync ist kein Backup (Löschungen werden mitsynchronisiert).
Bernd: „Der Vault liegt doch schon auf dem Mac. Doppelt gemoppelt, das spar ich mir.“
Tanja: „Sync ist kein Backup, Bernd. Wenn du eine Datei aus Versehen löschst, ist sie zwei Sekunden später auch auf dem Mac weg, brav synchronisiert. Ein Backup behält die alte Version. Genau dieser Unterschied rettet dir irgendwann den Tag.“
7.2 Restore-Test konkret („1 Agent wiederherstellen“)
Ein Backup, das du nie zurückgespielt hast, ist nur eine Hoffnung. Deshalb halbjährlich, Aufwand ~15 Minuten, ohne Produktiv-Risiko:
- Workspace einer Persona an einen Temp-Ort kopieren:
cp -a …/10-agents/anna /tmp/anna-vorher - Simulierten Schaden anrichten:
rm …/10-agents/anna/SOUL.md - Aus dem Backup (Hyper Backup / rsync-Ziel / Mac-Sync) genau diese Datei zurückholen.
- Verifikation:
diff -r /tmp/anna-vorher /volume1/Vault/…/10-agents/anna→ keine Abweichung; anschließend PING-Test der Persona (Schritt 5.6).
Für den DB-Fall (selten nötig): Test-Restore des Dumps in eine Wegwerf-DB, zcat dump.sql.gz | sudo docker compose exec -T paperclip-postgres psql -U "$DB_USER" -d restore_test (Datenbank restore_test vorher anlegen, danach droppen; DB_USER wie in 6.1). Erfolg = keine Fehler im Lauf.
Ulf: „Warum kaputt machen, was funktioniert? Das fühlt sich falsch an.“
Tanja: „Es ist eine Feuerwehrübung. Du legst kein echtes Feuer, du löschst absichtlich eine Datei, von der du eine Kopie hast, und übst das Zurückholen, solange alles ruhig ist. Wenn der Ernstfall kommt, hast du die Handgriffe drauf, statt panisch in einem Backup zu wühlen, das vielleicht gar nicht funktioniert.“
7.3 Kompatibilitätsmatrix: getesteter Originalstand vs. empfohlener Nachbau
Bevor du dich an exakten Versionsnummern festbeißt, eine Einordnung: Diese Tabelle zeigt links, womit das Original nachweislich lief, und rechts, was du für deinen Nachbau nehmen solltest.
| Komponente | Getesteter Original-Endstand (Mai/Juni 2026) | Empfehlung für Nachbau |
|---|---|---|
| Paperclip | Basis ghcr.io-Image (sha256:b2a2d7f7…), lokal gepatcht: UI-Patch (4.8) + ACP-Patch (4.10) → paperclip-local:bug3-openclaw-gateway-no-paperclip | aktuelles ghcr.io/paperclipai/paperclip:latest mit SHA-Pin; zuerst ungepatcht testen, Patches nur bei den konkreten Fehlern aus 5.8/5.10 |
| openclaw-writer | ghcr.io/openclaw/openclaw:2026.5.7 (mit Paperclip-seitigem ACP-Patch) | aktuelle OpenClaw-Version; bei unexpected property 'paperclip': Version zu alt |
| Wende | Fork von atalovesyou/claude-max-api-proxy, nativ auf DSM, Port 3457 | gleicher Stand; Repo auf Breaking Changes prüfen (Entry-Point start-proxy-wende.mjs) |
| Claude CLI | @anthropic-ai/claude-code 2.1.141, HOME /volume1/docker/claude-native-home | aktuelle stabile Version |
| Codex CLI | 0.130.0 (im Paperclip-Image enthalten) | Version des verwendeten Paperclip-Images |
| Postgres | postgres:17-alpine | gleich oder neuer (Major-Version beim Restore beachten) |
| Modelle | gpt-5.5 (Codex), claude-sonnet-4/claude-opus-4 (Wende, generische IDs) | aktuelle IDs prüfen: codex models list / curl :3457/v1/models |
Wichtigste Konsequenz dieser Matrix: Die Anleitung dokumentiert einen verifizierten Gesamtzustand, keine Garantie für beliebige Versions-Kombinationen. Bei Abweichungen gilt die Fehler-Zuordnung aus Schritt 5.10.
Bernd: „Ich nehm einfach überall ‚latest‘, dann hab ich immer das Neueste. Logisch.“
Tanja: „Und wenn das neueste openclaw-writer plötzlich ein anderes Protokoll spricht als dein Paperclip, steht alles. Diese Matrix sagt dir: Das hier lief zusammen, garantiert. Nimm neuere Versionen ruhig, aber teste paarweise und wisse, dass du dich vom verifizierten Stand entfernst. ‚Latest‘ ist kein Plan, es ist ein Würfelwurf.“
Fakten-Check, Wartung
- Zwei Token-Intervalle: Claude-CLI ~3 Wochen, ChatGPT-OAuth ~90 Tage (Login UND Re-Sync, Schritt 4.2 + 4.3, chown 1000:1000).
- Memory-Archiv monatlich (1., 02:00), Provider-Dashboards wöchentlich, Backup täglich, Restore-Test halbjährlich.
- Backup nach Datentyp: Postgres nur per
pg_dump(nie Datei-Kopie im Betrieb), Bind-Mounts dateibasiert, Vault über Hyper Backup (Sync ≠ Backup).- Restore-Test = Feuerwehrübung: Datei löschen, zurückholen,
diff -r, PING.- Kompatibilitätsmatrix: dokumentiert einen verifizierten Gesamtzustand, nicht jede Kombination. „latest“ nur mit paarweisem Test.
8. Troubleshooting
Diese Tabelle ist die Notaufnahme. Nicht linear lesen, sondern nach Symptom suchen. Viele dieser Fehler klingen exotisch, sind aber im Original tatsächlich passiert, meist nachts, meist kurz vor einem scheinbar harmlosen PING-Test.
Bernd: „So eine lange Fehlertabelle? Bei mir gibt’s keine Fehler.“
Tanja: „Bei dir gibt’s nur ungelöste Fehler. Diese Tabelle ist Gold wert: Jede Zeile ist ein Abend, den jemand vor dir schon verbracht hat, damit du es nicht musst. Du suchst dein Symptom in der linken Spalte und liest direkt, woran es liegt und was hilft. Kein Raten.“
| Symptom | Ursache | Lösung |
|---|---|---|
UI im LAN nicht erreichbar; docker compose ps zeigt 127.0.0.1:3100 | Synology-Daemon erzwingt Loopback | compose.yaml: "0.0.0.0:3100:3100" explizit |
| HTTP 403 „Hostname … is not allowed“ | PAPERCLIP_PUBLIC_URL fehlt | In .env setzen, docker compose down && up -d |
| Container-Start: gosu „operation not permitted“ | cap_drop: [ALL] ohne cap_add | cap_add: [SETUID, SETGID] |
docker build scheitert an COPY --parents | kein BuildKit auf DSM | Image pullen statt bauen; ggf. auf Mac bauen + docker save/load |
| Postgres: „Skipping initialization“, Auth-Fehler nach Passwortwechsel | altes Passwort in postgres-data | postgres-data komplett löschen, neu anlegen, Stack neu aufsetzen |
| DATABASE_URL-Parse-Fehler | Base64-Secret mit + / = | openssl rand -hex 32 |
onboard hängt stumm | Corepack-Prompt von grep-Pipe verschluckt | pnpm-Befehle nie pipen |
| UI sperrt auf localhost trotz ENV-Variablen | onboard --yes erzwingt Quickstart | onboard --bind lan ohne --yes |
| bootstrap-ceo: „No config found“ | onboard (Schritt 1) fehlt | Reihenfolge: onboard → bootstrap-ceo |
| Schema-Fehler nach config.json-Patch | exposure: "lan" ist invalid | exposure ∈ {private, public}; bind ∈ {lan, loopback}; paperclipai doctor |
| OAuth-Login von NAS unmöglich | headless, kein Browser | SSH-Tunnel vom Mac: ssh -N -L 127.0.0.1:1455:127.0.0.1:1455 … |
ssh -L: „Broken pipe“ / „Address already in use“ | Tunnel auf der NAS statt Mac gestartet | hostname prüfen, Tunnel vom Mac |
| codex: „not a git repository“ | Workspace ohne .git | Extra-Arg --skip-git-repo-check |
bwrap: Creating new namespace failed | DSM-Kernel ohne User-Namespaces | nicht behebbar; Bypass ON + Red-Lines |
| Persona-Run: HTTP 400 | „Cheap Model“ aktiv (inkompatibel mit Plus-OAuth) | Cheap Model OFF |
| Adapter-Änderung wirkt nicht | greift erst beim nächsten Heartbeat | warten oder Agent neu starten |
| openclaw-writer: Gateway startet nicht | controlUi.allowedOrigins fehlt | in openclaw.json setzen |
FailoverError: No API key found for provider | auth-profiles.json im alten Flat-Format | versioniertes Format {version:1, profiles:{…}}+ Container-Restart (Bug 4) |
| Provider-Config wird abgelehnt | falscher api-String / Anthropic-Modell-IDs | wörtlich "openai-completions", generische IDs |
getaddrinfo ENOTFOUND openclaw-writer | Docker-DNS noch nicht propagiert | 10–15 s nach up -d warten |
protocol mismatch backend vpaperclip (WS 1002) | ACP vs. vpaperclip Versions-Mismatch | aktuelle Versionen beider Projekte; sonst Abschnitt 5.10 |
[llm-idle-timeout] … no reply | Subprocess-Warmup/Tool-Use > Timeout | timeoutSeconds: 600 in models.json + waitTimeoutMs: 600000 (Bug 5) |
| Editorial Claude verliert API-Zugriff nach Token-Refresh | Key-Datei in falschem Pfad oder falsche Permissions | nach workspace/, chown 1000:users, chmod 640 |
| Wende: „Not logged in“ trotz Login | Wende läuft als root | Aufgabenplaner-User = <NAS-USER> |
| .env nach vi-Edit world-readable | DSM-ACL des Eltern-Verzeichnisses | nach jedem Edit chmod 600 + ls -la |
| Unerklärlicher API-Kostenanstieg | stiller Fallback auf alten Key | Key im Dashboard deaktivieren, Default-Modell prüfen, 24 h beobachten |
| Agent ignoriert „noch nicht …“ | weiche Formulierung = Erlaubnis | „NICHT X bis explizites GO“ + Marker |
| Persona „erfüllt“ Format-Vorgabe laut Selbstauskunft | Eigen-Verifikations-Drift | externe Format-Prüfung durch Reviewer |
Ulf: „Die meisten Lösungen sind ja nur eine Zeile. Warum war das dann nachts so ein Drama?“
Tanja: „Weil die Lösung erst einfach aussieht, wenn jemand die Ursache schon gefunden hat. Schau dir die mittlere Spalte an, das ist die eigentliche Arbeit. ‚Wende läuft als root‘ zu erkennen, dauert Stunden; es dann auf den richtigen Benutzer umzustellen, dauert eine Minute. Diese Tabelle schenkt dir die Stunden.“
9. Ergebnis
Wenn alle Häkchen gesetzt sind, steht auf der NAS keine Spielerei mehr, sondern eine kleine Redaktion: drei Agenten, ein Orchestrator, ein Gedächtnis, ein Audit-Trail und ein sehr menschliches Stoppschild vor der Veröffentlichung.
Ulf: „Geschafft! Und, war’s das wert? Ich meine, da steckt ganz schön viel Arbeit drin.“
Tanja: „Das musst du selbst beantworten, aber schau, was du jetzt hast: ein System, das recherchiert, schreibt und koordiniert, während die letzte Entscheidung immer bei dir bleibt. Lass uns das einmal zusammenrechnen, technisch und finanziell.“
Technisch heißt das: Paperclip mit 3 Agenten (2× codex_local/gpt-5.5, 1× openclaw_gateway/Claude), Hierarchie und Delegation per Sub-Issues, Gedächtnis und Steuerung im Obsidian-Vault, alle Ports LAN-only, kein API-Key im Regelbetrieb. Laufende Kosten: ca. 20 € (ChatGPT Plus) + ca. 92 € (Claude Max 5x) = ca. 112 €/Monat.
Bernd: „112 Euro? Für sowas würde ich keinen Cent ausgeben, ich mach das umsonst mit einem kostenlosen Tool.“
Tanja: „Du machst es umsonst, und es schreibt umsonst Texte, die keiner prüft, auf Konten, die du nicht kontrollierst. Die 112 Euro kaufen dir zwei Flatrates statt unkalkulierbarer API-Rechnungen, und einen Arbeitsraum, in dem du genau weißt, wer was darf. Das ist nicht der teure Weg, das ist der berechenbare.“
Das eigentliche Ergebnis ist nicht, dass eine NAS plötzlich Texte schreiben kann. Das eigentliche Ergebnis ist ein kontrollierter Arbeitsraum: Agenten dürfen entwerfen, prüfen, delegieren und erinnern, aber sie dürfen nicht veröffentlichen, nicht heimlich skalieren und nicht so tun, als wären sie eine Redaktion ohne Chefredaktion. Genau darin liegt der Charme dieses Setups: Es automatisiert nicht Verantwortung. Es automatisiert die Vorarbeit.
Ulf: „Also bleibt am Ende doch der Mensch der Chef.“
Tanja: „Immer. Die Maschine nimmt dir das Schleppen ab, nicht das Denken. Und genau so soll es sein.“
