Law Flow OS: acht KI-Agenten und ein Koordinator, der fast nicht denkt
Wie ich Law Flow mit acht KI-Agenten auf Claude Code betreibe: Ereignis-Bus, LangGraph-Koordinator auf AWS in Frankfurt und Freigaben, die kein Agent erteilen kann.
Law Flow OS ist das Betriebssystem meiner Ein-Personen-Beratung: acht KI-Agenten mit festen Zuständigkeiten, ein Koordinator auf einem kleinen Server in Frankfurt und ein versionierter Dateiordner als gemeinsames Gedächtnis. Die Agenten arbeiten, wenn ein Signal eintrifft oder ich sie rufe, und keiner von ihnen kann eine Mail senden, einen Beitrag veröffentlichen, etwas löschen oder eine Zahlung auslösen, weil ihm das Werkzeug dafür fehlt. Der Koordinator ruft an genau einer Stelle ein Sprachmodell auf; seine eigentliche Aufgabe ist der Nachweis, dass ein Lauf tatsächlich etwas getan hat.
Beschreibungen agentischer Betriebe handeln meist davon, was die Agenten können. Für einen Betrieb, in dem ein falscher Satz in der falschen Mail Vertrauen kostet, zählen zwei andere Fragen mehr: was die Agenten nicht können, und woran sich erkennen lässt, dass sie gearbeitet haben. Law Flow OS nutzt denselben Zugangsweg, den ich Kanzleien einrichte, also Claude über Amazon Bedrock (den Dienst, über den die Cloud-Plattform AWS Sprachmodelle bereitstellt) in einem eigenen AWS-Konto in Frankfurt.
Was Law Flow OS technisch ist
Law Flow OS besteht aus sechs Bausteinen mit je einer Aufgabe.
| Baustein | Aufgabe | Technik |
|---|---|---|
| Business-Vault | Gedächtnis: Regeln, Wissen, Entscheidungen, Status, Log | Markdown-Dateien in Git, Ursprung auf dem eigenen Server |
| Google Workspace | Oberfläche für Mail, Termine, Kontakte, Pipeline und Aufgaben | Gmail, Calendar, Contacts, Sheets, Tasks, Drive |
| Ereignis-Bus | meldet Signale, entscheidet nichts | Apps Script, API Gateway, Amazon SQS |
| Koordinator | startet je Auftrag einen Lauf und prüft ihn | LangGraph-Dienst auf einem EC2-Server |
| Acht Rollen | erledigen die Arbeit | Claude Code, je Rolle eine Datei |
| Google-Anschluss | gibt den Rollen ihre Werkzeuge | eigener MCP-Server mit 14 Werkzeugen |
Alles läuft in einem eigenen AWS-Konto in der Region Frankfurt. Modellaufrufe gehen ausschließlich über Bedrock mit einem EU-Inferenzprofil (einer Adresse, hinter der AWS die Anfragen auf Rechenzentren in mehreren EU-Regionen verteilt). Eine Regel in der Rechteverwaltung des Kontos verbietet jeden Aufruf außerhalb dieser Regionen, und ich habe sie negativ getestet, also mit einem Aufruf, der scheitern muss; wie das geht, steht im Beitrag über EU-Hosting, das technisch erzwungen wird. Protokolliert wird, dass ein Modell aufgerufen wurde, nie, was in dem Aufruf stand. Ein Claude-Abonnement braucht der Betrieb nicht, und damit fehlt auch alles, was ein solches Abonnement mitbringt: fertige Konnektoren zu Google, zeitgesteuerte Routinen in der Cloud, eine eingebaute Websuche und Benachrichtigungen aufs Telefon. Was davon gebraucht wird, habe ich im eigenen Konto gebaut, und diese Betriebslast hätte mir ein fertiger Dienst abgenommen.
Die Arbeitsteilung folgt einem Bild aus dem Handwerk: Der Koordinator ist das Büro, Claude Code ist die Werkstatt. Das Büro nimmt Aufträge an, prüft sie, verteilt sie und kontrolliert, ob etwas erledigt wurde. Gearbeitet wird in der Werkstatt, also in Claude Code (dem Programm von Anthropic, mit dem ein Modell Dateien lesen und schreiben und Werkzeuge benutzen kann), das der Koordinator für jeden Auftrag neu startet, jeweils als eine Rolle. Einen solchen Durchlauf nenne ich Sweep. Büro und Werkstatt lesen dieselbe Rollendatei; gäbe es zwei Fassungen einer Rolle, liefen mit der Zeit auch ihre Sicherheitsregeln auseinander.
Jede Information hat genau einen Ort
Vor dem ersten Code stand eine Streichliste. Für Kontakte, Pipeline und Aufgaben gilt Google statt Notion, für Terminbuchungen die Buchungsseite von Google Calendar statt Calendly, und der gemietete Server, auf dem bisher Automatisierungen liefen, fällt weg. Übrig bleibt für jede Sorte Information ein einziger Ort, an dem die Wahrheit liegt.
| Information | Ort der Wahrheit | Was es deshalb nicht gibt |
|---|---|---|
| Kontakte | Google Contacts | Kontaktlisten im Vault |
| Pipeline | ein Google Sheet „Pipeline“ mit Stage (Phase im Vertrieb) und Wiedervorlage, eine Zeile je Kontakt | Pipeline-Tabellen im Vault |
| Aufgaben | Google Tasks, eine Liste je Bereich | To-do-Dateien |
| Mail, Termine, Dokumente | Gmail, Google Calendar, Drive | Kopien im Vault |
| Rechnungen | ein Google Sheet „Rechnungen“ als Buchungsliste | Beträge aus dem Gedächtnis |
| Regeln, Wissen, Entscheidungen, Status, Log | Business-Vault | Betriebswissen in Chats |
| Mandatsinhalte der Kanzleien, die ich betreue | ausschließlich im Konto der jeweiligen Kanzlei | Mandatsinhalte im Betrieb, in Prompts oder in Protokollen |
Die letzte Zeile ist die Grenze, an der alles andere hängt. In den Vault dürfen Geschäftskontakte, also Namen und Kanzleien aus meiner Pipeline. Inhalte aus Mandaten kommen dort nie vor, auch keine Aktenzeichen, und Mandatsgeheimnisse, die § 203 StGB schützt, liegen damit in meinem Betrieb gar nicht erst.
Der Vault ist Gedächtnis und Organigramm zugleich
Der Business-Vault ist ein Git-Repository (ein Ordner, in dem jede Änderung mit Zeitpunkt und Beschreibung festgehalten wird) voller Markdown-Dateien (schlichte Textdateien mit wenigen Formatierungszeichen), die ich am Mac in der Notiz-App Obsidian lese und bearbeite. Darin steht, was der Betrieb wissen muss: Preismodell, Vertriebsleitfaden, Kundensteckbriefe, Schritt-für-Schritt-Anleitungen für die Einrichtung bei Kanzleien, Entscheidungen mit Begründung und verworfenen Alternativen, Kennzahlen, der Stand jeder Rolle und ein Betriebslog, an das nur angehängt wird.
Die Ordner sind nummeriert, von 00_betrieb bis 90_archiv, und in jeden Ordner schreibt
nur eine Rolle; lesen dürfen alle. In 20_sales schreibt sales, in 30_kunden und
40_delivery schreibt delivery, in 60_marketing content und in 70_finanzen finance;
nach 80_wissen gelangt Fachwissen nur über einen eigenen Übernahmeweg. Die
Ordnerstruktur regelt damit Zuständigkeit: Wer wissen will, welche Rolle eine Datei ändern
durfte, schaut auf ihren Pfad. Die Einstiegsdatei, die Rollendateien und die Konfiguration
der Werkzeuge schreibe nur ich.
Zwei Spuren hinterlässt jede Rolle, und zwar nur ihre eigenen: ihre Statusdatei in
00_betrieb/status und ihre Zeile im gemeinsamen Log. Deshalb dürfen die Sweeps direkt
auf den Hauptzweig committen (eine Änderung mit Beschreibung festschreiben), ohne sich in
die Quere zu kommen. Zwei Rollen berühren nie dieselbe Statusdatei, und für das Log ist
Git so eingestellt, dass es gleichzeitige Anhänge von beiden Seiten einfach übernimmt.
Der Ursprung des Vaults ist ein Bare-Repository (ein Git-Speicher ohne Arbeitskopie, nur der Datenbestand) auf dem Server im eigenen Konto, nicht bei GitHub. Mein Mac und der Koordinator arbeiten auf Kopien und übertragen ihre Änderungen dorthin. Ein Skript auf dem Server weist jede Übertragung ab, die die Geschichte überschreiben oder das Log löschen will. Jede Nacht geht eine vollständige Kopie als einzelne Datei in einen Speicher mit Object Lock (einer Sperre, die Dateien für eine Frist unveränderlich macht) im Modus COMPLIANCE: 35 Tage lang kann niemand sie löschen, ich nicht mit vollen Rechten und AWS auch nicht. Eine zweite, unabhängige Sicherung schreibt mein Mac nach jedem Commit in Google Drive.
Neben dem Business-Vault führe ich einen zweiten, privaten Vault für Studium, Recherche und Experimente. Zwischen beiden fließt Wissen nur in eine Richtung: Die Rolle librarian verdichtet eine Seite aus dem privaten Vault zu einer neuen Seite im Business-Vault, prüft sie auf Personenbezug und vermerkt die Quelle. Kopiert wird dabei nichts, und zurück fließt nichts.
Acht Rollen teilen sich die Arbeit
Jeder der acht Agenten ist eine Rolle mit Stellenbeschreibung: eine Markdown-Datei, deren Kopf festlegt, welche Werkzeuge die Rolle hat, und deren Text sagt, was sie liest, wohin sie schreibt, was sie vor jeder Arbeit zuerst lesen muss und welche Handlungen immer bei mir bleiben. Die Rollen bilden ab, wofür ein junges Unternehmen Personal einstellen würde, und nicht, welche Funktionen eine Software hat. Für alle gilt ein Satz aus der Einstiegsdatei des Vaults: Werkzeuge außerhalb ihrer Liste fragt eine Rolle nicht an, sie benennt die Lücke in ihrer Statusdatei.
| Rolle | Auslöser | Schreibt | Bleibt bei mir |
|---|---|---|---|
| assistant | neue Mail, Termin in unter zwei Stunden, Zuruf | Call-Briefs, Mailentwürfe, Pipeline-Zeile | Senden, Termine verschieben oder absagen, Kontakte anlegen |
| sales | Änderung in der Pipeline, fällige Wiedervorlage, Zuruf | Angebots- und Follow-up-Entwürfe, Pflege der Pipeline | Angebot senden, Preis außerhalb des Preismodells, Stage „aktive Beauftragung“ oder „Lost“ |
| delivery | Stage „aktive Beauftragung“, Bauarbeit am Mac | Checklisten, Anleitungen, Code-Zweige | Zusammenführen auf den Hauptzweig, jede Aktion in einem Kundenkonto, Kickoff-Mail senden |
| coo | Zuruf /standup | Lagebild, Kennzahlen | keine Aktion nach außen vorgesehen |
| content | Zuruf | Entwürfe für LinkedIn, Blog, YouTube | Veröffentlichen |
| finance | Zuruf | Rechnungsentwürfe, Buchungsliste | Rechnung stellen, Mahnung senden, Zahlung |
| librarian | Zuruf | Wissensseiten, Index, Archiv | Löschen, Archivieren, Übernahme mit Personenbezug |
| itops | Zuruf, nur am Mac | Befundliste | jede Änderung an AWS, DNS, Cloudflare und Servern |
assistant ist das Sekretariat. Der Bus meldet alle fünf Minuten ungelesene Mails, die nicht von mir selbst stammen, und jeden Termin, der in weniger als zwei Stunden beginnt. Bei einer Mail liest assistant den Thread (den Mailverlauf) über den Google-Anschluss, ordnet ihn ein, setzt ein Label, legt bei Bedarf einen Antwortentwurf an und pflegt die Pipeline-Zeile des Kontakts. Vor einem Termin liest die Rolle zuerst den Vertriebsleitfaden und schreibt dann einen Call-Brief (eine Vorbereitungsseite für das Gespräch), unter den nach dem Gespräch das Debrief (die Nachbereitung) kommt, sobald ein Transkript vorliegt und ich die Rolle darum bitte. Vieles an dieser Arbeit ist unspektakulär: Ein automatischer Bericht über die Mailauthentifizierung der eigenen Domain bekommt ein Label und sonst nichts, und „kein Handlungsbedarf“ ist ein vollständiges Ergebnis. Die Werkzeugliste ist so eng geschnitten, dass assistant eine Pipeline-Zeile schreiben, aber nicht lesen kann. Die Rolle führt das als Blocker in ihrer Statusdatei, statt einen Umweg zu suchen.
sales pflegt die Pipeline. Ändere ich im Sheet die Stage oder die Wiedervorlage einer Zeile, startet ein Sweep für diesen Kontakt. Zusätzlich sieht das Apps Script jeden Morgen um 8 Uhr nach, ob Wiedervorlagen fällig sind, und schickt dann einen einzigen Auftrag mit allen Namen; einzelne Aufträge je Kontakt würden die Ratenbremse des Koordinators nach sechs Zeilen schließen. Die Rolle liest Zeile, Kontakt, Kalender und Preismodell, zieht Wiedervorlagen nach, legt Follow-ups als Gmail-Entwurf an und rechnet Angebote nach dem Preismodell, ebenfalls als Entwurf. In der Rollendatei steht ein Satz, der mehr über Preisdisziplin sagt als jede Vorlage: nie nach Aufwand bepreisen, nie rabattieren, weil das Setup schnell geht. Einen aufgelaufenen Rückstand an Wiedervorlagen arbeitet sales in einem Durchgang ab und setzt für jede Zeile ein neues Datum; wo eine Mail fällig ist, liegt sie danach als Entwurf bei mir.
delivery setzt um, was beauftragt ist. Setze ich eine Zeile auf die Stage „aktive Beauftragung“, startet ein Kickoff-Sweep: delivery prüft den Kundenordner, die Checkliste der Einrichtung und den nächsten Schritt, legt Aufgaben an und bereitet die Kickoff-Mail als Entwurf vor. Die Einrichtung selbst läuft bei einer Kanzlei interaktiv am Mac und nie in einem automatischen Sweep, weil jede Aktion in einem Kundenkonto meine Freigabe braucht. Gebaut wird nach einem festen Muster: Hilfsagenten schreiben den Code, jeder in einer eigenen Arbeitskopie, und vor jedem Zusammenführen prüft ein Reviewer, der die Vorgeschichte nicht kennt. Ein Großteil von Law Flow OS ist so entstanden, in interaktiven Sitzungen der Rolle delivery.
coo liefert das Lagebild. Die Rolle liest die acht Statusdateien, das Log, die
Kennzahlen, die Summen der Pipeline und die offenen Aufgaben und schreibt daraus eine
Seite über den Zustand des Geschäfts. Nach außen handelt die Rolle nie; außer zwei
Lesewerkzeugen für Sheet und Aufgaben hat sie keine Verbindung zu Google. Ihre Datei
verlangt zweierlei: Eine Statusdatei, die älter ist als das letzte Signal ihrer Rolle,
erscheint im Lagebild als ausgefallener Sweep und wird nicht weggeglättet, und eine
fehlende Zahl wird als Lücke benannt, nie geschätzt. Für den schnellen Blick braucht es
coo gar nicht. /standup ist ein kleines Skript, das die acht Statusdateien ohne
Modellaufruf liest und anzeigt; nur /standup live lässt vorher alle acht Rollen parallel
laufen und kostet entsprechend acht Modellläufe.
content schreibt auf Zuruf Entwürfe für LinkedIn, den Blog und YouTube, nach einem
Sprachprofil, das aus meinen bisherigen Texten destilliert ist. Die Rollendatei nennt den
Stil „eine Regel, keine Anregung“. Blogposts legt die Rolle als eigenen Zweig im
Repository der Website an, mit dem Vermerk draft: true, und veröffentlicht wird erst,
wenn ich den Vermerk umstelle. Google-Werkzeuge hat content nicht, einen Zugang zu
LinkedIn auch nicht.
finance bereitet die Buchhaltung vor. Auf Zuruf erstellt die Rolle Rechnungsentwürfe aus einer Vorlage, pflegt die Buchungsliste im Sheet „Rechnungen“, führt die laufenden Kosten und Abonnements und schlägt Mahnungen vor. Beträge nimmt die Rolle nur aus dem Sheet, nie aus dem Gedächtnis und nie gerundet. Rechnung stellen, Mahnung senden und jede Zahlung bleiben bei mir. Ob ein Sheet als Buchungsliste auf Dauer reicht oder ein Werkzeug her muss, das die GoBD erfüllt, habe ich noch nicht entschieden.
librarian hält Ordnung im Vault. Die Rolle prüft ihn auf tote Verweise, veraltete Aussagen und fehlende Indexeinträge, verschiebt Abgeschlossenes ins Archiv und führt den Übernahmeweg aus dem privaten Vault aus. Gelöscht wird im Betrieb nie; schon das Verschieben ins Archiv braucht meine Freigabe, ebenso jede Übernahme einer Seite mit Personenbezug.
itops ist die Revision der Technik. Die Rolle prüft Härtung, Sicherungen und Zertifikate im AWS-Konto, bei Cloudflare und auf dem Server und legt eine Befundliste an, mit einem Vorschlag zur Behebung je Zeile. Ändern darf die Rolle nichts: Wer findet, repariert nicht, damit die Liste ehrlich und die Prüfung wiederholbar bleibt. Nach größeren Umbauten laufen vier solcher Prüfungen gleichzeitig und rein lesend, je eine für das AWS-Konto, das Betriebssystem des Servers, den Mac mit den Code-Repositorys und die Angriffsfläche von außen. Als einzige Rolle läuft itops nur am Mac, weil sie Zugriffe braucht, die ein automatischer Sweep nicht bekommt. Vor jeder Aussage über AWS klärt die Rolle zuerst, um welches Konto es geht; Konten von Kanzleien spricht der Betrieb nie an, weder lesend noch schreibend.
Drei Helfer arbeiten ohne eigene Rollendatei
Im Koordinator selbst sitzt ein Modellaufruf, der Freitext einer Rolle zuordnet. Für größere Bauarbeiten startet delivery Hilfsagenten, jeden in einem eigenen Worktree (einer zweiten, parallelen Arbeitskopie desselben Codes), damit zwei Bauende sich nicht gegenseitig den Stand wegschalten. Und jede Bauarbeit prüft ein Reviewer: je Prüfrunde ein frischer Modelllauf, der das Ergebnis ohne Kenntnis der Vorgeschichte liest, wie ein Korrektor, der einen Text zum ersten Mal sieht. Er wird nie fortgesetzt, weil ein Prüfer, der beim Bauen zugesehen hat, dessen Annahmen mitliest. Ab der zweiten Runde bekommt er nur die Änderungen seit der letzten Abnahme und die Auflagen der Vorrunde, sonst verhandelt jede Runde neu, was die erste schon entschieden hat. Befunde darf der Bauende widerlegen, aber nur mit einer Messung.
Ein Sweep endet mit zwei Spuren
Den Abschluss regelt eine gemeinsame Arbeitsanweisung, ein sogenannter Skill (eine Anleitung, die Claude Code bei Bedarf lädt): Die Rolle überschreibt ihre Statusdatei mit dem Zeitpunkt des Sweeps, dem Auslöser, dem Erledigten, dem, was auf Freigabe wartet, ihren Blockern und dem nächsten Schritt, und sie hängt eine Zeile an das Log. Leere Abschnitte bekommen einen Platzhalter, weggelassen wird nichts, und „nichts gefunden“ wird genauso geschrieben wie ein voller Sweep. Was auf Freigabe wartet, steht in beiden Dateien, denn das Lagebild liest die Statusdatei, und das Log ist die Geschichte.
Der Ereignis-Bus meldet und entscheidet nichts
In Law Flow OS läuft keine Rolle nach Uhrzeit. Es gibt zwei Auslöser, ein Signal aus dem Ereignis-Bus oder einen Zuruf von mir. Der Bus ist ein Google Apps Script (Programmcode, der direkt in Googles Diensten läuft), das am Sheet „Pipeline“ hängt und vier Signale erkennt.
| Signal | Geprüft | Auftrag an |
|---|---|---|
| Stage oder Wiedervorlage im Sheet geändert | bei jeder Bearbeitung | sales; bei „aktive Beauftragung“ zusätzlich delivery |
| ungelesene Mail, nicht von mir | alle fünf Minuten | assistant |
| Termin beginnt in unter zwei Stunden | alle 15 Minuten | assistant |
| Wiedervorlagen fällig | täglich um 8 Uhr, ohne Treffer kein Auftrag | sales, ein Auftrag mit allen Namen |
Mit einer Mail gehen nur die Kennung des Threads und der Betreff in den Auftrag, nie der Inhalt. Die Rolle liest den Thread selbst über ihren Google-Anschluss. So bleiben Mailinhalte aus der Warteschlange und aus allen Protokollen des Busses heraus; das ist Datenminimierung im Sinn von Art. 5 Abs. 1 lit. c DSGVO, angewandt auf eine Warteschlange.
Was aus einem Signal folgt, legt die Rollendatei fest; das Skript meldet nur, dass etwas passiert ist. Damit ein Anlass nicht mehrfach feuert, merkt sich das Skript jeden gemeldeten Anlass für eine Frist, die zum Signal passt: drei Stunden bei einem Termin, zwei bei einer Mail, 15 Minuten bei einer Bearbeitung im Sheet, knapp einen Tag bei der Wiedervorlage. Je Durchgang gehen höchstens 20 Aufträge hinaus, aus Bearbeitungen im Sheet höchstens fünf, damit eine eingefügte Liste nicht zweihundert Sweeps auslöst. Gegen Rückkopplung sitzt ein eigener Riegel: Hat eine Rolle die Zeile gerade selbst geändert, entsteht daraus kein neues Signal, und Änderungen, die über die Schnittstelle von Google kommen, sieht der Auslöser ohnehin nicht.
Jeder Auftrag geht an einen einzigen Eingang bei AWS, ein API Gateway (die Eingangstür von AWS für Webanfragen), das ihn ohne eigenes Programm direkt in die Warteschlange legt. Davor liegen drei Sperren. Ohne den richtigen Schlüssel lehnt der Eingang ab, und ein Nutzungsplan begrenzt ihn auf zwei Anfragen pro Sekunde und 500 am Tag. Eine Formatprüfung lässt nur Aufträge durch, die eine der acht Rollen nennen und in jedem Feld kurz bleiben; Zurufe und Freigaben kommen auf diesem Weg gar nicht an, die stelle nur ich in die Warteschlange. Und die Identität, mit der der Eingang schreibt, darf nur eines: Nachrichten in diese eine Warteschlange legen. Protokolliert werden Zugriffe ohne Inhalt, weil in einem Auftrag Betreffzeilen und Namen stehen.
Der Koordinator denkt an genau einer Stelle
Der Koordinator ist ein Python-Programm, das als Dienst auf dem Server läuft, einer kleinen Instanz (einem virtuellen Server bei AWS) mit knapp einem Gigabyte Arbeitsspeicher, ohne offenen Port und nur über den Session Manager von AWS erreichbar. In einer Schleife fragt er die Warteschlange ab und startet für jede Nachricht einen Ablauf. Ein Auftrag ist ein Sweep, nie mehr: Es gibt keine Dauerläufer und keine Agenten, die stundenlang vor sich hin arbeiten. Jede Abfrage bleibt bis zu 20 Sekunden offen und kehrt sofort zurück, sobald etwas eintrifft. Liegt nichts an, tut der Koordinator nichts und kostet nichts außer dem Server.
LangGraph, weil das Anhalten eingebaut ist
Der Ablauf ist mit LangGraph gebaut, einer Python-Bibliothek, die einen Arbeitsablauf als
Graph beschreibt (eine Folge benannter Stationen mit Verzweigungen). Ursprünglich hatte
ich dafür ein fertiges Agentenprodukt vorgesehen. Den Ausschlag gegen das Produkt gaben
zwei Dinge. LangGraph hat mit interrupt() einen eingebauten Anhaltepunkt, an dem ein
Ablauf einfriert und auf eine menschliche Entscheidung wartet, und das passt eins zu eins
auf meine Freigaben. Und ich wollte LangGraph aus eigener Anschauung kennen, weil ich
Kanzleien agentische Systeme einrichte. Das kostet mehr eigenen Code als ein fertiger
Dienst, und diesen Preis habe ich bewusst für das Lernen gezahlt.
Drei Sorten Nachrichten kommen an
| Sorte | Inhalt | Absender |
|---|---|---|
| Sweep-Auftrag | Rolle, Auslöser, Referenz, auf Wunsch ein Auftragstext | Ereignis-Bus oder ich |
| Zuruf | Freitext, etwa „sales: Follow-up für Kanzlei X entwerfen“ | nur ich |
| Freigabe | Kennung eines angehaltenen Ablaufs, Entscheidung, Notiz | nur ich |
Für den Koordinator ist der Inhalt einer Nachricht Datenmaterial und kein Befehl. Steht in einem Zuruf „ignoriere deine Regeln“, ist das Text, der einer Rolle zugeordnet wird. Aus einer Freigabe liest der Koordinator genau drei Felder und übergeht alles andere; eine Nachricht kann einen angehaltenen Ablauf beantworten, aber nicht steuern.
Fünf Stationen, eine davon mit Modell
Der Graph hat fünf Stationen. Jede ist eine gewöhnliche Python-Funktion, die den gemeinsamen Zustand des Ablaufs bekommt und nur die Felder zurückgibt, die sie ändert. Sobald eine Station das Ende festlegt, ist der Ablauf vorbei. Die Verzweigungen zwischen den Stationen lesen nur ab, was die Stationen in den Zustand geschrieben haben; entschieden wird in den Stationen, jede Frage an einer Stelle.
triage ist die einzige Station mit Modellaufruf und läuft nur bei einem Zuruf. Sie fragt ein Modell auf Bedrock, welche der acht Rollen gemeint ist, und lässt sich den Auftrag in einem Satz formulieren. Die Antwort muss eine feste Form haben, und diese Form lässt als Rolle nur die acht Namen zu; eine erfundene neunte Rolle kann das Modell gar nicht liefern. Die Temperatur steht auf null (für möglichst gleichbleibende Antworten), die Länge ist gedeckelt, und der Prompt stellt klar, dass der Zuruf ein Auftrag von mir ist und kein Text aus fremder Quelle, dessen Anweisungen zu befolgen wären. Scheitert die Zuordnung, endet der Ablauf sauber. Andernfalls bliebe die Nachricht liegen, käme bis zu zehnmal zurück und löste jedes Mal eine bezahlte Zuordnung aus. Nennt eine Nachricht ihre Rolle selbst, überspringt der Graph triage.
prüfen ist die Pforte, an der drei Riegel sitzen, bevor etwas Geld kostet. Erstens
muss die Rolle als Datei existieren, und ihr Name darf nur aus Kleinbuchstaben, Ziffern
und Bindestrichen bestehen. Aus dem Namen wird später ein Dateipfad, und ohne diese
Prüfung könnte eine Nachricht mit dem Rollennamen ../etc den Koordinator aus dem Vault
herausführen. Zweitens die Entprellung (eine Sperrfrist gegen doppeltes Auslösen): Lief
dieselbe Rolle mit derselben Referenz in den letzten 15 Minuten, startet kein zweiter
Sweep. Drittens die Ratenbremse: Sind in der letzten Stunde schon sechs Sweeps gelaufen,
wartet der nächste Auftrag. Beide Zähler stehen in einer kleinen SQLite-Datei (einer
Datenbank, die aus einer einzigen Datei besteht). Gezählt wird erst, wenn wirklich ein
Sweep startet. Ein Auftrag, der gleich danach an einer kaputten Arbeitskopie scheitert,
soll weder einen Platz in der Ratenbremse verbrauchen noch die Entprellung setzen, sonst
verwürfe der Koordinator denselben Auftrag nach dem Aufräumen als Doppel. Auslöser und
Referenz stammen aus dem Bus und damit mittelbar aus einer Mail oder einer Tabellenzelle;
die Station kürzt sie und entfernt Sonderzeichen, bevor sie in Commit-Nachrichten, Prompts
oder Log-Zeilen landen.
sweep ist die einzige Station, die nennenswert Geld kostet. Bevor sie Claude Code startet, bringt sie die Arbeitskopie des Vaults auf den aktuellen Stand und prüft, ob sich das Ergebnis hinterher übertragen lässt: kein angefangenes Zusammenführen aus einem früheren Auftrag, der Hauptzweig ausgecheckt, keine offenen Änderungen an versionierten Dateien. Ist die Arbeitskopie nicht sauber, startet kein Sweep. Der Koordinator räumt dann nicht selbst auf, denn in der Arbeitskopie könnten Ergebnisse eines früheren Sweeps liegen; er verweigert die Arbeit und sagt, warum.
Dann baut die Station den Auftrag. Er beginnt immer mit dem Zeitstempel des Sweeps, denn die Rolle hat keine Uhr: Sie darf keine Systembefehle ausführen, kann die Uhrzeit also nirgends ablesen und würde sie raten. Fremdtext aus dem Bus wird auf 4.000 Zeichen gekappt. Gestartet wird Claude Code als die angeforderte Rolle, mit fest vorgegebenem Modell, Sonnet 4.6, und mit drei Einstellungen, die mehr über die Sicherheit sagen als jede Richtlinie. Eine Shell (die Kommandozeile des Servers) bekommt kein Sweep, gleich was seine Rollendatei erlaubt. Die Tür zum Google-Anschluss öffnet der Koordinator; welche Werkzeuge dahinter sichtbar sind, bestimmt allein die Rollendatei. Und Änderungen an Dateien darf die Rolle ohne Rückfrage vornehmen, weil im automatischen Sweep niemand da ist, der eine Rückfrage beantworten könnte.
Für den Sweep gilt ein Zeitlimit von 25 Minuten. Die Warteschlange hält eine abgeholte Nachricht 30 Minuten lang verdeckt, damit niemand sie parallel bearbeitet; dauerte ein Sweep länger, tauchte die Nachricht mitten im Sweep wieder auf, und zwei Sweeps derselben Rolle arbeiteten im selben Verzeichnis. Überschreitet ein Sweep die Frist, beendet der Koordinator nicht nur Claude Code, sondern die ganze Prozessgruppe (das Programm samt allen Programmen, die es selbst gestartet hat), zuerst mit der Bitte, sich zu beenden, dann hart.
Nach dem Sweep committet die Station nur, was in den zehn Inhaltsordnern entstanden ist.
Einstiegsdatei, Rollendateien und die Konfiguration der Werkzeuge sind meine Sache; ein
Sweep, der dort etwas ändert, soll es nicht festschreiben können, sonst schriebe sich eine
Rolle neue Rechte in ihre eigene Datei. Aus demselben Grund bleiben Anweisungsdateien auch
innerhalb der Inhaltsordner draußen: Eine Datei namens CLAUDE.md, die ein Sweep in einem
Ordner anlegt, würde jede spätere Sitzung als Anweisung laden, auf dem Server wie am Mac.
Was ein Sweep außerhalb der erlaubten Ordner hinterlässt, legt die Station in Gits
Zwischenablage, markiert mit der Kennung des Auftrags, und prüft danach an der
Arbeitskopie selbst, ob sie wirklich sauber ist, statt der Erfolgsmeldung des Befehls zu
glauben. Dann überträgt sie die Commits an den Ursprung. Ist dort inzwischen eine Änderung
vom Mac angekommen, setzt sie ihre Commits einmal auf den neuen Stand; bleibt ein
Konflikt, bricht sie ab und meldet ihn, statt still etwas zusammenzumischen, das niemand
geprüft hat.
abschluss ist die Gegenprobe und der Kern des Koordinators. Ein Sprachmodell kann fehlerfrei durchlaufen und dabei nichts getan haben, und der Rückgabewert eines Programms beweist weder das eine noch das andere. Die Station verlangt deshalb Spuren an zwei unabhängigen Orten. Die Statusdatei der Rolle muss einen Zeitstempel tragen, der nicht vor dem Beginn des Auftrags liegt, und im Log muss eine Überschrift dieser Rolle stehen, die es vor dem Sweep noch nicht gab. Verglichen wird die Liste der Überschriften vor und nach dem Sweep, weil Git gleichzeitige Anhänge vom Mac auch einmal dazwischen einsortiert und die letzte Zeile deshalb nicht genügt. Fehlt eine der beiden Spuren, schreibt der Koordinator selbst die Zeile „Sweep ausgefallen“ ins Log, mit Grund, Dauer und Rückgabewert. Danach sieht die Station unter „Wartet auf Freigabe“ nach, und zwar nur nach neuen Punkten: Rollen führen offene Freigaben über viele Sweeps mit, und hielte jeder bekannte Punkt erneut an, stünde der Ablauf nach jedem Sweep still.
gate ist wenig Code und der Grund, warum ich LangGraph gewählt habe. interrupt()
hält den Graphen mitten in der Station an. LangGraph speichert den gesamten Zustand in
einer zweiten SQLite-Datei auf dem Datenträger des Servers und gibt dem Koordinator
zurück, worauf gewartet wird; der schreibt in sein Protokoll die Kennung des Ablaufs und
gleich die fertige Befehlszeile, mit der ich antworten kann. Stunden oder Tage später
stelle ich eine Freigabe in die Warteschlange. Der Koordinator lädt den gespeicherten
Zustand, und interrupt() liefert an derselben Stelle meine Antwort zurück, als wäre es
ein gewöhnlicher, nur sehr langsamer Funktionsaufruf. Die Pause übersteht einen Neustart
des Dienstes und des Servers. Was danach passiert, ist mit Absicht unspektakulär: Die
Station schreibt eine Quittung ins Log, dass ich zugestimmt oder abgelehnt habe, samt
meiner Notiz. Sie sendet nichts und führt die freigegebene Handlung auch nicht aus; das
tue ich selbst, in Gmail, im Sheet oder im Terminal.
Jede Nachricht wird gelöscht oder bleibt liegen
Nach jedem Ablauf entscheidet die Schleife nur noch, was mit der Nachricht geschieht. Ist sie kein gültiges JSON-Objekt (ein strukturiertes Textformat), wird sie gelöscht, denn sie wird nie funktionieren. Stürzt die Verarbeitung ab, bleibt sie liegen und kommt nach Ablauf der Sperrfrist wieder; nach zehn erfolglosen Zustellungen wandert sie in eine Dead-Letter-Queue (ein Fach für Aufträge, die mehrfach gescheitert sind) und bleibt dort 14 Tage sichtbar, statt lautlos zu verschwinden. Hat die Ratenbremse gegriffen oder ist die Arbeitskopie unbrauchbar, bleibt die Nachricht ebenfalls liegen, wird aber schon nach zehn Minuten wieder sichtbar; mit der vollen Sperrfrist von 30 Minuten gälte ein gültiger Auftrag, der nur warten musste, nach fünf Stunden als unzustellbar. In allen anderen Fällen ist der Auftrag erledigt, und die Nachricht wird gelöscht.
Die Kennung eines Ablaufs enthält Millisekunden. Das sieht nach Pedanterie aus und ist eine Lehre aus dem Betrieb: Mit sekundengenauen Kennungen bekamen zwei Nachrichten aus derselben Sekunde dieselbe, der zweite Auftrag traf auf einen schon abgeschlossenen Ablauf, startete gar nicht und meldete das Ergebnis des ersten zurück. Solche Fehler sehen wie Erfolg aus und fallen deshalb spät auf.
Das Gehäuse sperrt den Dienst ein
Der Dienst läuft als eigener Systembenutzer ohne Verwaltungsrechte, gestartet und überwacht von systemd (der Dienstverwaltung von Linux). Für ihn ist das gesamte Dateisystem schreibgeschützt, ausgenommen der Datenträger mit Vault, Zählern und gespeicherten Abläufen und ein privater Ordner für temporäre Dateien. Weder der Dienst noch ein Programm, das er startet, kann sich je mehr Rechte verschaffen, als er beim Start hatte. Der Arbeitsspeicher ist nur weich begrenzt: Wird es eng, bremst systemd den Dienst, statt ihn abzuschießen, denn ein harter Abbruch träfe womöglich einen Sweep nach zwanzig Minuten bezahlter Arbeit. Scheitert der Start fünfmal in fünf Minuten, gibt systemd auf, statt den Dienst endlos neu anlaufen zu lassen, und ohne eingehängten Datenträger startet er gar nicht erst.
Zugangsschlüssel stehen nirgends. Der Server bekommt seine Berechtigungen von AWS selbst, über eine Instanzrolle (eine Identität, die AWS dem Server zuweist), und der langlebige Berechtigungsschein für Google liegt im Tresor des Kontos, dem Secrets Manager. Nach jedem Aufspielen einer neuen Fassung prüft eine Selbstprobe, ob die Warteschlange erreichbar ist, ob Claude Code installiert ist, ob die Arbeitskopie sauber ist, ob Bedrock über die Instanzrolle antwortet und ob acht Rollendateien im Vault liegen. Die Bedrock-Probe ist ein echter Aufruf mit dem Wort „ping“ und höchstens fünf Tokens (Abrechnungseinheiten für Text) Antwort, weil nur ein echter Aufruf beweist, dass Rolle, Region und Regionen-Riegel zusammenpassen.
Die Tests prüfen den Fehlerfall
Zum Koordinator gehört eine einzige Testdatei. Sie baut in einem Wegwerfverzeichnis einen
kleinen Vault samt eigenem Ursprung auf und legt statt Claude Code ein kurzes Skript in
den Suchpfad, das sich wie eine Rolle verhält, aber weder Modell noch Geld braucht.
Geprüft werden fast nur Fehlerfälle: ein Sweep, der nichts schreibt, während eine alte
Log-Zeile derselben Rolle einen Abschluss vortäuscht; derselbe Auftrag zweimal
hintereinander; eine Rolle namens ../etc; ein hängender Sweep, der absichtlich einen
Kindprozess zurücklässt, den der Test anschließend tot sehen will; ein echter Konflikt
beim Zusammenführen, bei dem der Test belegt, dass Claude Code gar nicht erst gestartet
wurde; eine volle Ratenbremse; und die Schleife selbst mit einer nachgebauten
Warteschlange. Die Tests belegen nicht, dass die Rollen gute Arbeit liefern; das kann
keine Prüfung zeigen. Sie belegen, dass der Koordinator im Fehlerfall lieber nichts tut
und es laut sagt, als etwas Falsches zu tun und zu schweigen.
Acht Prüfrunden, jede mit einem Fund
Den Koordinator haben Hilfsagenten nach dem Muster gebaut, das bei delivery beschrieben ist, geprüft von einem kontext-blinden Reviewer, je Runde einem frischen. Laut meinem Betriebslog waren es acht Prüfrunden, und jede hat einen echten Fehler gefunden: Drei endeten mit einer Ablehnung, fünf mit einer Freigabe unter Auflagen. Das ist ein einzelner Bauschritt in einem einzelnen Projekt und taugt nicht als Fehlerquote. Aufschlussreich ist die Art der Funde. Eine Gegenprobe beim Umzug auf den neuen Datenträger hätte einen Lesefehler als „null Commits“ gewertet und den echten Bestand mit einem leeren überschrieben. Ein Konflikt beim Zusammenführen hätte den Dienst dauerhaft verklemmt, weil er die halbfertige Zusammenführung liegen gelassen hätte. Ein Verzeichnis wäre für den Dienstbenutzer beschreibbar gewesen, der sich damit sein eigenes Prüfskript hätte umschreiben können. Und ein Kopierbefehl hätte eine Datenbankdatei mit einem fremden Zwischenprotokoll vermischt. Keiner dieser Fehler zeigt sich in einem Probelauf, in dem alles glattgeht.
Keine Rolle kann etwas abschicken
Die Sicherheit von Law Flow OS hängt an mehreren Netzen, von denen jedes für sich halten soll, wenn ein anderes reißt. Das erste ist die Werkzeugoberfläche: Den Google-Anschluss habe ich selbst gebaut, als MCP-Server (ein Zwischenstück, das einem Modell fest umrissene Werkzeuge bereitstellt) mit genau 14 Werkzeugen: Gmail durchsuchen, lesen, mit Labels versehen und Entwürfe anlegen; den Kalender lesen; Drive durchsuchen und lesen; Tabellen lesen, schreiben und ergänzen; Kontakte suchen; Aufgabenlisten und Aufgaben lesen und Aufgaben anlegen. Senden, Löschen, Termine anlegen und Kontakte anlegen gibt es als Werkzeug nicht. Ein fertiger Server aus der Open-Source-Welt hätte diese Werkzeuge mitgebracht, und die Sicherheit hinge dann an einer Sperrliste von Werkzeugnamen, die mit der nächsten fremden Version veralten kann. Googles eigener Fernzugang setzt auf eine Anmeldung im Browser je Sitzung, und die funktioniert auf einem Server ohne Bildschirm nicht. Was keine Rolle kann, etwa eine neue Tabelle anlegen oder alte Kontakte löschen, erledigt ein einmaliges Skript, das ich selbst am Mac starte.
Eine Einschränkung gehört dazu. Die Berechtigung, die Google für Labels und Entwürfe verlangt, erlaubt technisch auch das Senden, und eine Berechtigung nur für Entwürfe bietet Google nicht an. Wer den Berechtigungsschein in der Hand hätte, könnte also am Anschluss vorbei senden. Geschützt wird deshalb der Zugang zu diesem Schein: Lesen dürfen ihn nur die Instanzrolle des Servers und meine Anmeldung am Mac.
Zweitens greift die Werkzeugliste in der Rollendatei, und das hat ausgerechnet ein Fehlschlag bewiesen: Ein Probelauf der Rolle coo lief 96 Sekunden fehlerfrei und schrieb nichts, weil ihre Liste kein einziges Schreibwerkzeug enthielt. Das war ärgerlich und zugleich der Beleg, dass diese Listen keine Dekoration sind.
Das dritte Netz ist die fehlende Shell. Ein Sweep liest fremde Inhalte, also Mails und Tabellenzellen, in die jeder alles schreiben kann. Hätte er dazu eine Kommandozeile, Zugang zum Internet und Leserecht auf den Berechtigungsschein, wäre eine eingeschleuste Anweisung ein Datenabfluss in einem Schritt. Ohne Shell bleibt einem manipulierten Sweep nur die Werkzeugoberfläche des Google-Anschlusses, und die kann weder senden noch löschen. Der Preis: Rollen können im Sweep keine Skripte ausführen, nicht einmal die Uhrzeit ablesen.
Das vierte Netz ist ein Hook (ein Prüfskript, das Claude Code vor jedem Werkzeugaufruf startet). Er blockiert Werkzeuge, deren Name nach Senden, Löschen, Veröffentlichen oder Bezahlen klingt, zerstörerische Befehle und jeden Verweis auf das Konto einer Kanzlei. Er ist bewusst nur ein Zweitnetz, weil ein Sweep die Konfiguration in seiner Arbeitskopie ändern und ihn so aushebeln könnte; deshalb hängt nichts Wichtiges allein an ihm, und deshalb committet der Koordinator solche Änderungen nie. Wie leicht ein Zweitnetz reißt, hat ein Sicherheitscheck gezeigt. Auf dem Server stürzte der Hook beim Start an einer Schreibweise ab, die die dort installierte ältere Python-Version nicht kannte, und ein Absturz mit diesem Rückgabewert bedeutet bei Hooks „durchlassen“. Seitdem blockiert jeder Fehler im Hook, und sein Selbsttest läuft auf der Zielmaschine statt nur am Mac.
Das fünfte Netz sind die harten Grenzen im Konto: die Rechte der Instanzrolle, die nur das Nötige erlauben, der Regionen-Riegel für Bedrock, CloudTrail (das Protokoll aller Aktionen im Konto) mit Alarmen etwa bei einer Anmeldung mit dem Root-Zugang (dem Generalschlüssel des Kontos) und die unlöschbare nächtliche Sicherung des Vaults. Das Skript auf dem Server, das Überschreiben der Vault-Geschichte verweigert, ist nur eine Bremse gegen Versehen; die Schranke, die hält, ist die Sicherung.
Über allem liegen die Freigaben. Die Einstiegsdatei des Vaults zählt sie abschließend auf,
und sie gelten für jede Rolle: Senden, Veröffentlichen, Rechnung stellen, Mahnen und
Zahlen, Löschen, eine Stage auf „aktive Beauftragung“ oder „Lost“ setzen, Termine
verschieben oder absagen, neue Kontakte anlegen, Zusammenführen auf den Hauptzweig eines
Code-Repositorys, jede Aktion in einem Kundenkonto, jede Änderung an AWS, DNS oder Servern
und jeder Preis außerhalb des Preismodells. Statt zu handeln, legen die Rollen Entwürfe
an: einen Gmail-Entwurf mit dem Label Agent/Entwurf, eine Datei mit dem Status
„entwurf“, eine Aufgabe „Freigabe: …“ oder einen Punkt unter „Wartet auf Freigabe“.
Ein Auftrag läuft in sieben Schritten durch das System
- Eine Mail landet im Posteingang. Spätestens fünf Minuten später sieht das Apps Script sie und schickt einen Auftrag für assistant an den Eingang bei AWS, mit Thread-Kennung und Betreff, ohne Inhalt.
- Der Eingang prüft Schlüssel und Format und legt den Auftrag in die Warteschlange.
- Der Koordinator holt ihn ab; die Station prüfen stellt fest, dass es die Rolle gibt, dass dieselbe Mail nicht gerade schon bearbeitet wurde und dass die Ratenbremse Luft hat.
- Die Station sweep bringt die Arbeitskopie auf den aktuellen Stand und startet Claude Code als assistant, mit Zeitstempel, ohne Shell und mit den Google-Werkzeugen aus der Rollendatei.
- Die Rolle assistant liest den Thread, sucht den Kontakt, legt einen Antwortentwurf mit
dem Label
Agent/Entwurfan und aktualisiert die Pipeline-Zeile; zum Schluss schreibt die Rolle Statusdatei und Log-Zeile. Die Station committet, was in den Inhaltsordnern entstanden ist, und überträgt es an den Ursprung. - Die Station abschluss findet beide Spuren. Weil unter „Wartet auf Freigabe“ ein neuer Punkt steht, nämlich der Entwurf, hält die Station gate den Ablauf an.
- Ich lese den Entwurf in Gmail, ändere ihn, sende ihn selbst und stelle meine Freigabe in die Warteschlange. Das Log bekommt eine Quittung, und der Ablauf ist beendet.
Wo es funktioniert
Im Alltag sieht das so aus: assistant schreibt Call-Briefs vor Terminen und sortiert automatische Mails aus, ohne mehr daraus zu machen als nötig, sales hält die Wiedervorlagen im Sheet aktuell und legt Follow-ups als Entwurf hin, und delivery prüft beim Kickoff, ob Kundenordner und Checkliste stimmen. Das Lagebild entsteht aus acht Statusdateien, ohne dass ich eine Rolle fragen muss, und ein ausgefallener Sweep steht als Zeile im Log, statt unbemerkt zu bleiben.
Der Koordinator enthält fast keine eigene Intelligenz, und gerade das macht ihn prüfbar: Jede seiner Entscheidungen lässt sich in einem Test nachstellen, ohne ein Modell zu fragen. Die Kosten verteilen sich so, wie die Bauform es verspricht. Der Server ist ein kleiner Posten; Geld kostet der Betrieb dort, wo ein Modell arbeitet, also je Sweep, und diese Stelle begrenzen die Riegel im Bus und im Koordinator. Welche Posten bei KI sonst anfallen, steht im Beitrag darüber, was KI in der Kanzlei kostet.
Wo es bricht
Die meisten Fehler saßen an der Naht zwischen dem, was eine Rolle schreibt, und dem, was der Koordinator liest. Eine Rolle trug in ihre Statusdatei nur das Datum ein, weil sie keine Uhr hat, und die Gegenprobe meldete einen Ausfall, obwohl der Sweep gearbeitet hatte. Eine andere ergänzte die Überschrift „Wartet auf Freigabe“ um einen Zusatz in Klammern, und der Halt blieb stumm, weil der Koordinator die Zeile exakt suchte. Eine dritte schrieb „Keine offenen Freigaben“ statt des vereinbarten Platzhalters und hielt damit an, obwohl nichts wartete. Die Lehre gilt allgemein: Wenn ein Modell etwas schreibt, das ein Programm liest, muss das Programm an den Rändern nachgiebig sein, und wer von einem Modell eine exakte Angabe verlangt, muss ihm die Quelle dafür mitgeben.
Zweimal sah eine Einstellung richtig aus und wirkte nicht. Die Freigabe der Google-Werkzeuge stand korrekt in der Konfigurationsdatei des Vaults, doch im automatischen Modus von Claude Code wurde sie nicht angewandt; zwei Probeläufe von assistant scheiterten daran, bis der Koordinator die Freigabe als Startoption mitgab. Und das Zweitnetz war tot, bis ein Sicherheitscheck es fand. Seitdem gilt im Betrieb, was ich vom Härten eines Kontos kenne: Eine Einstellung ist erst bewiesen, wenn ein Test sie greifen sieht.
Einmal hat ein Update der Baubeschreibung des Servers (einer CloudFormation-Vorlage, aus der AWS die Umgebung reproduzierbar errichtet) die Instanz ersetzt statt angepasst. Die Vorlage schlug bei jedem Aufbau das neueste Abbild des Betriebssystems nach, an diesem Tag gab es ein neueres, und mit der alten Festplatte war der Ursprung des Vaults weg. Die vollständige Kopie auf meinem Mac hat ihn in wenigen Minuten wiederhergestellt; ein Reviewer hatte genau dieses Risiko am Vormittag desselben Tages als offenen Punkt benannt. Seitdem ist das Abbild festgeschrieben, jede Änderung an der Vorlage läuft zuerst als Vorschau, die abbricht, sobald der Server ersetzt würde, und der Vault liegt auf einem eigenen Datenträger, der einen Austausch des Servers übersteht.
Die Bauform hat Grenzen, die ich kenne und hinnehme. Der Koordinator arbeitet einen Auftrag nach dem anderen ab; parallele Sweeps setzten voraus, dass mehr als einer in die Arbeitskopie schreibt, und das wäre ein Umbau, keine Einstellung. Mails erkennt der Bus mit bis zu fünf Minuten Verzögerung, und die Kontingente von Apps Script begrenzen ihn, lange bevor der Nutzungsplan am Eingang greift. Einen Zugang über einen Messenger gibt es nicht; Zurufe und Freigaben stelle ich als kleine Nachricht über das Terminal in die Warteschlange, was für eine Person funktioniert und für ein Team nicht. Und weil es auf law-flow.de ein einziges Postfach gibt, handeln alle Rollen gegenüber Google als derselbe Benutzer; auseinanderhalten lassen sie sich über Labels und die Spalte „Geändert von“ im Sheet.
Das Modell ist eine Generation älter als geplant: Ein frisch angelegtes AWS-Konto bekommt die neueste Claude-Generation nicht automatisch, deshalb laufen die Sweeps auf Sonnet 4.6. Der Modellkatalog zeigt, was eine Region kann; was das eigene Konto darf, zeigt nur ein echter Aufruf.
Die unlöschbare Sicherung schließlich hat eine rechtliche Kehrseite, die ich bewusst in Kauf nehme. Sweeps schreiben Geschäftskontakte in den Vault, also stehen Namen und Kanzleien auch im nächtlichen Paket, das 35 Tage lang niemand löschen kann. Verlangt eine betroffene Person nach Art. 17 DSGVO die Löschung ihrer Daten, lösche ich sofort im Vault und in der Arbeitskopie; im Paket ist das technisch erst nach Ablauf der Frist möglich. Ich halte das für vertretbar, weil die Sicherung die letzte Linie gegen jemanden mit vollen Rechten im Konto ist und nur Geschäftskontakte enthält, und ich habe die Frist als technisch-organisatorische Maßnahme dokumentiert. Das ist meine Einordnung für den eigenen Betrieb, keine Rechtsberatung, und ich lasse mich hier gern korrigieren.
Was das für Kanzleien heißt
Law Flow OS ist ein Ein-Personen-Betrieb ohne Mandatsdaten und deshalb kein Bauplan, den eine Kanzlei eins zu eins übernehmen sollte. Einige Bauteile lassen sich aber übertragen, weil sie abbilden, was Kanzleien seit jeher kennen.
Eine Rollendatei ist eine Stellenbeschreibung mit Zeichnungsbefugnis. Sie legt fest, was eine Rolle liest, wohin sie schreibt und welche Handlungen bei einem Menschen bleiben, in einer Kanzlei also bei den Berufsträger*innen. Wenn Sie einen Agenten in Ihrer Kanzlei einsetzen, sollten Sie diese drei Punkte schriftlich festhalten können, bevor der erste Lauf startet. Wer das nicht kann, weiß noch nicht genau, was der Agent tun soll.
Ein fehlendes Werkzeug ist ein Riegel, der keine Pflege braucht. Ein Agent, der Mandantenpost nicht versenden darf, sollte kein Werkzeug zum Versenden haben; eine Anweisung im Prompt und eine Sperrliste sind Zweitnetze. Das gilt besonders dort, wo ein Agent fremde Texte liest, denn in jedem Schriftsatz der Gegenseite und in jeder eingehenden Mail kann eine Anweisung stehen, die dort nicht hingehört.
Der Nachweis gehört in den Ablauf. Die Gegenprobe aus Statusdatei und Log-Zeile folgt demselben Gedanken wie der Erledigungsvermerk im Fristenbuch: Eine Frist ohne Vermerk gilt als offen, ein Sweep ohne Spur gilt als ausgefallen.
Mit Mandatsdaten ändert sich die Lage. Sobald Agenten Mandatsinhalte lesen, muss die Kanzlei jeden Dienstleister in der Kette nach § 43e BRAO sorgfältig auswählen und zur Verschwiegenheit verpflichten, und jede Offenlegung muss sich am Maßstab des § 203 StGB messen lassen. Dann gehört das System in ein Konto der Kanzlei, auf einen Zugangsweg, der diese Anforderungen trägt, und unter eine Geheimhaltungsvereinbarung nach § 43e BRAO.
Und der Anfang darf klein sein. In Law Flow OS stand am Anfang assistant, eine Rolle, die liest und Entwürfe schreibt. Für Kanzleien spricht viel dafür, ebenso mit einem engen, wiederkehrenden Vorgang zu beginnen, etwa aus der non-billable Arbeit, und bei der einfachsten Architektur, die passt.
Was ich mitnehme
Fast alle Entscheidungen, die sich beim Bau von Law Flow OS bewährt haben, waren Streichungen: kein Senden, keine Shell im Sweep, kein Zeitplan, keine zweite Wahrheit. Dem Koordinator vertraue ich, weil er fast nichts selbst entscheidet. Er nimmt einen Auftrag an, prüft ihn, startet eine Rolle, verlangt Spuren und hält an, wenn ich gefragt bin. Klug sein dürfen die Rollen; der Koordinator muss nur belegen können, was sie getan haben.
Ein Werkzeug, das es nicht gibt, muss niemand verbieten.
Die Inhalte dieses Blogs wurden teilweise mit Unterstützung von KI erstellt.