- UnitConfig.Approvals: Operationen, Hoechstzahl je Tag, Stunden je Freigabe; nur der
Mensch setzt sie (OrgAdministration.SetApprovals mit Audit, Teilmengenregel nach oben,
Senken oben senkt unten mit; Agentenaenderungen/Sonderbudget nie freigebbar)
- LeadApprovals: Vorlage geht an die naechste Leitung, deren Einheit die Operation
erlaubt; nie eigene Aufrufe, nie eine Leitung mit Fremdinhalt, Tagesdeckel, Frist.
Entscheidung ueber Escalation approve_call/reject_call, im Audit als lead:<id>
- Der Mensch sieht alles und kann zuerst entscheiden; danach wird die Leitungsaufgabe
geschlossen. Nach der Frist nur noch der Mensch.
- StagedCalls: Approver, ApproverUntil, ApproverTaskId (Nachruestung)
- WebUI: Hinweis "bei Leitung" in der Freigabestelle, Zaehler ohne diese, Quote je
Leitung; Karte in der Organisationsansicht; i18n en/de
- Tests: LeadApprovalsTests (13), OrgAdministrationTests (+2)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- cases.top in instance.json: Human | Agent | HumanFirst, agentId, humanFirstHours
- TopRole: der entscheidende Agent steht in keiner Einheit, liest keine Fremdinhalte
und hat nur Taskboard, Escalation, Memory, FileRW, AgentComm; geprueft beim Setzen,
bei jeder Zustellung und vor jeder Entscheidung
- CaseDesk: was bisher an der Spitze beim Menschen landete, geht nach Einstellung an
den Agenten; Tagesdeckel und Frist gehen weiter an den Menschen. handle verwehrt,
forward geht an den Menschen. Mensch zuerst: Uebergabe nach Ablauf, eigene Frist.
Der Mensch kann einen Fall des Agenten selbst entscheiden.
- Beschluesse des Agenten: ByTopAgent, zum Lesen vorgelegt; jeder Beschluss laesst
sich mit Begruendung zuruecknehmen und bindet dann niemanden mehr
- Briefing fuer den Agenten an der Spitze, auch ohne Einheiten
- OrgAdministration.SetTop mit Audit; Werkzeugsperre und Verschiebesperre
- WebUI Vorgaenge: Reiter Spitze, Lesen/Zuruecknehmen, Zaehler; i18n en/de
- Tests: TopRoleTests (15), OrgAdministrationTests (+2)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Aufgabentyp meeting mit Teilnehmerliste (Frontmatter, SQLite, Taskboard-Werkzeug,
WebUI). MeetingRunner: jeder Teilnehmer einmal in Reihenfolge, Beitraege
gerahmt als Daten des Verfassers, danach schliesst die Leitung mit Ergebnis und
Aufgaben. Protokoll schreibt die Instanz in den Bereich der Einheit der Leitung.
Teilnehmer nur aus dem Adressbuch der Leitung, hoechstens 12.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Eine fremde Laufzeit oder der eigene Claude Code des Menschen spricht per MCP
mit der Instanz. Der Server bietet genau die Werkzeuge des Agenten hinter dem
Token an; jeder Aufruf laeuft durch die Engine wie ein Aufruf des eigenen
Modells (Rechtetor, Vorpruefung, Werkzeugrechte, Staging, Audit mit Quelle
mcp, Rahmung), und der Aufrufer gilt als Leser fremder Inhalte (#715).
Eigener Socket mcp.sock statt manager.sock: ueber den Instanz-Socket antwortet
die Verwaltung ohne Token, ueber mcp.sock gibt es nur /mcp und nur mit
MCP-Token. Lauf-Tokens nur im Speicher, enden mit dem Lauf; persoenliche Tokens
(hoechstens 90 Tage, widerrufbar, nur als SHA-256) in der Agentenansicht.
Transporte: HTTP auf mcp.sock, Weboberflaeche und Manager (/mcp/{instanz}),
stdio ueber ClawdDotNet --mcp-bridge (Token nur aus Umgebung oder 0600-Datei).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Eine Aufgabe, deren eigene Schaetzung (gemessen, Geschwister oder Autor)
ueber der Haelfte der Tageskostengrenze liegt, bekommt zuerst einen
Planungslauf: teilen (Teile unter der Elternaufgabe) oder Sonderbudget
beantragen. Danach wartet sie auf ihre Teile bzw. die Freigabe und laeuft
einmal zum Zusammenfuehren.
Sonderbudget ueber Escalation.request_budget, ausnahmslos freigabepflichtig
(auch gegen Werkzeugkonfiguration und Dauerfreigabe). Laeufe im Baum ziehen
den Topf statt der Tagesgrenzen, tragen BudgetPot in Verbrauch und Beleg und
sind in der Kostenanalyse (nach Budget) und auf der Aufgabenkarte gesondert
sichtbar. Aufgebraucht zaehlen sie wieder gegen den Tag.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Aktionen describe (alle Spalten einer freigegebenen Tabelle, mit dem Satz, dass nicht
Genanntes nicht existiert) und tables (freigegebene Tabellen, vorhanden oder fehlend)
- "Unknown column" / "no such table" usw. werden mit dem Vorhandenen beantwortet -
MySQL, Postgres, SQL Server, SQLite; nur fuer freigegebene Tabellen
- SQLite als Datenbanktyp; die Abfragen schreibt das Werkzeug selbst, PRAGMA bleibt im
Agenten-SQL verboten
- MongoDB: describe nennt die Felder aus den Dokumenten
- describe/tables sind Lesezugriffe (Freigabeschluessel select), Vorpruefung der Tabelle
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- /api/cases (offen/alle), /api/cases/{id}/decide, /api/cases/{id}/statement, /api/decisions
- Ansicht "Vorgaenge": offene Faelle mit Verlauf je Ebene (Lauf-Links), Frist und
"Mensch gerufen"; Reiter Beschluesse mit Reichweite; Zaehler in der Seitenleiste
- Konzept Abschnitt 5: Umsetzung
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Werkzeugkontext kennt Lauf und Aufgabe des Laufs (RunId, RunTaskId); die
Delegationskette traegt den Lauf des Aufrufers weiter (RunId, CallerRunId)
- Aufgaben tragen origin_run / origin_task (Datei, DB, Taskboard "Arose from"),
gestempelt, nie vom Agenten behauptet
- Kommentare nennen den Lauf, in dem sie geschrieben wurden
- Laufbeleg: CallerRunId; Laufansicht fuehrt zu "Delegiert von" und "Delegiert an"
- #677: task_update ersetzt den Rumpf nicht mehr, Abnahmekriterien aendert nur der
Ersteller; Kommentare der Fremdinhalt-Stufe auf fremden Aufgaben kommen gerahmt an
- WebUI: Herkunft auf der Aufgabenkarte mit Link zum Lauf
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- IAgentTool.ReadsForeignContent: Werkzeuge mit Aussenkontakt erklaeren sich selbst
(WebFetch, WebMonitor, DirectAPI, Mail, RocketChat, Telegram, TelegramClient,
SocialMediaManager, FTP, Database); AgentConfig.TreatAsForeignReader kann nur verschaerfen
- ReportingLine: Stufe aus den Werkzeugen, "wer steht darueber", Pruefung des Wegs nach oben
(nie Aenderungen an Aufgaben darueber, nur eine Ebene hoch, Fremdinhalt-Stufe gar kein
Freitext) und Rahmung als untrusted_content
- Engine: Nachricht und Spawn nach oben geprueft, Text der Fremdinhalt-Stufe kommt gerahmt an
- Taskboard: task_create/update/comment, reopen und die Dubletten-Notiz folgen dem Berichtsweg
- Dispatcher: Aufgaben von Agenten der Fremdinhalt-Stufe gehen gerahmt in den Lauf
- TaskReports: Erledigt-Signal und Systemmeldung (in Pruefung, blockiert, abgebrochen) an den
Auftraggeber, je Zustand einmal, gesammelt in einer offenen Aufgabe je Empfaenger
- OrgBriefing nennt den Berichtsweg; WebUI zeigt Stufe und Schalter am Agenten
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- TaskBoard: das Brett einer Aufgabe wird nicht gespeichert, es folgt aus
der Organisation - Einheit des Zustaendigen, sonst des Anlegers. Offene
Aufgaben ziehen damit beim Umzug mit. Sichtbar: das eigene Brett, fuer eine
Leitung alle darunter, und was man selbst angelegt hat (nach oben
Gereichtes bleibt im Blick).
- TaskItem.CreatedBy, in der Datei als created_by und in der DB. Ein Import
aus einer Datei ohne das Feld behaelt, was die DB weiss.
- Taskboard-Tool: task_list, task_find und die Dublettenpruefung sehen nur
die eigenen Bretter - eine aehnliche Buchhaltungsaufgabe haelt keine
Marketingaufgabe auf und bekommt keinen Kommentar von dort. task_update und
task_comment antworten auf eine fremde Aufgabe wie auf eine unbekannte.
- TaskboardService.ListAsync mit Sichtfilter: erst filtern, dann kappen.
- WebUI: jede Aufgabe nennt ihr Brett, ein Filter waehlt eines aus.
- Konzept (Abschnitt 3) und Einrichtungshandbuch nachgetragen.
Ohne Einheiten aendert sich nichts - ein Brett fuer alle.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rueckmeldung zur Teamuebersicht: wirkte veraltet, und die Verbindungen
zwischen den Einheiten fehlten - zugeklappte Container versteckten ganze
Ebenen, man haette sich bis zum Problem durchklicken muessen.
- Jede Einheit ist immer eine Karte, verbunden als Organisationsbaum
(ELK layered, orthogonale Linien, eckige Anschluesse). Keine Ebene wird
versteckt. Zugeklappt wird nur die Agentenliste grosser Einheiten: sie
zeigt, wer Aufmerksamkeit braucht, und "+n weitere".
- Eine Linie traegt die Farbe des dringlichsten Zustands darunter - eine
rote Linie fuehrt von oben zum Problem.
- Links ein Strukturbaum mit Suche (Agent, Einheit, Modell) und
Zustandsfilter; Treffer werden hervorgehoben, der Weg dorthin geoeffnet,
der Rest abgeblendet. Enter springt zum ersten Treffer.
- Leinwand mit Punktraster, Verschieben und Zoomen, schwebende Leisten
(Live-Verbindungen, Einpassen, Zoom). Live-Verbindungen laufen von Zeile
zu Zeile, gebuendelt mit Zaehler.
- Hausstil bleibt (Radius 0, App-Akzent), hell und dunkel, bis Handybreite.
- Cytoscape und cytoscape-elk entfernt: ein Canvas-Knoten kann keine
Agentenliste, Suche oder den Hausstil tragen. Karten sind jetzt HTML.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- TaskSchedule.OccurrencesBetween zaehlt, wie oft eine Aufgabe bis zu einem
Zeitpunkt noch laeuft, einschliesslich eines jetzt faelligen Laufs.
- BudgetHeadroom (ILateRunGate): Ein mitgenommener oder nachzuholender Lauf
startet nur, wenn er in den Spielraum passt: Grenze minus Verbrauch minus
Reservierung minus Bedarf der restlichen geplanten Laeufe bis Mitternacht
minus 10 % Reserve. Das gilt je Agent und je Instanz, fuer Kosten und Tokens.
Anderes Spaetwerk zaehlt nicht als Bedarf, sonst blockierten sich
mitgenommene Aufgaben gegenseitig.
- Der Scanner fragt den Spielraum nur fuer Spaetwerk und protokolliert, wenn es
warten muss. Die Engine gibt ihren BudgetGuard heraus, damit Scanner und
Engine dieselben Reservierungen sehen.
- Ersetzt den pauschalen 25-%-Anteil aus dem Konzept (dort nachgezogen): Ein
fester Anteil ist an vollen Tagen zu viel, an ruhigen zu wenig.
Drei weitere stille Kappungen bei 500 beseitigt (ListAllAsync, ungekappt):
Kostenprognose (Aufgaben ueber 500 fehlten), Waisenabgleich beim Import und
task_find aus #674, wo Dubletten unter aelteren Aufgaben mit niedriger
Prioritaet unsichtbar wurden.
Tests: BudgetHeadroomTests (9), Scanner-Pforte (1), Dublette hinter 500
Aufgaben (1). 1.257 gruen.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Festlegung des Nutzers: Einheiten-Einstellungen sind entweder Sammelwerte, die in
die Agenten geschrieben werden (Vorgabe nur fuer neue Mitglieder, Warnung bei
Ausreissern wie Spezialisten), oder Regeln ohne Gegenstueck am Agenten
(Rechte-Obergrenze, beim Schreiben geprueft; Parallelitaet je Einheit).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Zeitlich flexible Arbeit mit Frist statt Termin fuellt ungenutztes Tagesbudget
(Backfilling); ob Platz ist, entscheidet der Code aus Restbudget und Prognose.
Grossaufgaben werden geteilt oder bekommen ein vom Menschen freigegebenes
Sonderbudget als eigenen Topf.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 8a: Was liegen bleibt, wenn das Budget endet. Ist-Zustand nachgesehen
(einmalige Aufgaben werden still nachgeholt, wiederkehrende verfallen still),
Vorschlag expire / catch_up_once / carry_over je Agent, der neue Tag hat
Vorfahrt, Vermerk an der Aufgabe und als Tageszusammenfassung, Vorbeugen
ueber die Prognose aus #608, Budgetreservierung als Rest aus #682.
- 3: Festlegung des Nutzers, dass Einheiten keine eigene Konfiguration
speichern; Einstellungen fuer eine Einheit werden gesammelt in die Agenten
geschrieben. Drei Kollisionen als offen markiert: Rechte-Obergrenze,
Parallelitaet je Einheit, Grenzen der Leitung.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 7a Fremde Laufzeiten: Claude Code u. a. als Laufzeit der
Entwicklungsabteilung; gilt als weniger vertrauenswuerdig (Worktree/
Sandbox, Freigabelisten statt Rechte-Umgehung, Ergebnis ist ein Vorschlag,
nach aussen nur ueber den ClawdDotNet-MCP-Server). Vorbehalte Kontingent
und Nutzungsbedingungen als offene Entscheidung.
- 9a Von Paperclip gelernt: Zielkette mit Pruefung ruhender Aufgabenbaeume,
Rueckmeldung nach Vertrauensstufe (fremder Text steigt nicht in der
Hierarchie auf), Courier Pattern; bewusst nicht uebernommen: Rechte-
Umgehung als Voreinstellung, firmenweite Sichtbarkeit.
- 10a Das Lagebild: Teamuebersicht mit Layout aus der Struktur,
aufklappbaren Einheiten, Problemzustaenden aus dem Code und Seitenleiste
vor dem Chat; Stufe 0 ohne Einheiten.
- Reihenfolge, offene Entscheidungen und Itemliste nachgezogen.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Die Begruendung zum Vergleich vom 2026-09-18 (OpenClaw 2.0, Grok Bot) lag
unversioniert im Arbeitsbaum, zusammen mit der erzeugten Kopie vom
2026-09-19. Beides gehoert ins Repository - die Begruendung, weil sie von
Hand geschrieben ist und bleibt, die Kopie, weil sie den Stand zeigt.
Der Block zwischen den dc:roadmap-Markern bleibt erzeugt und wird beim
naechsten Lauf ueberschrieben; die heute angelegten Items #673 bis #704 sind
darin noch nicht enthalten.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Der Agent schickt Platzhalter, ClawdDotNet setzt sie im Werkzeug ein. Der
Ansatz ist richtig, loest aber weniger als er verspricht - die sieben
Luecken dazwischen sind die Arbeit. Die beiden wichtigsten: Ersetzt wird an
benannten Stellen je Werkzeug, nie als Suchen-und-Ersetzen ueber alle
Argumente; und jedes Geheimnis wird an ein Ziel gebunden, sonst schuetzt der
Platzhalter den Wert vor dem Modell und liefert ihn an den Angreifer.
Die Datei lag bisher unversioniert im Arbeitsbaum, obwohl fuenf Items
(#651-#659) ueber doc_anchor auf sie verweisen. Damit war die Begruendung
fuer niemanden ausserhalb dieses Rechners lesbar - genau das, was die
Regeln in CLAUDE.md verhindern sollen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Die Abstimmung zaehlt keine Meinungen, sondern erzwingt unabhaengige
Pruefungen aus verschiedenen Datenquellen. Daraus folgt die Regel, an der
alles haengt: Es wird BLIND abgestimmt. Sieht ein Stimmberechtigter die
Stimme eines anderen, stimmt ein guenstiges Modell dem zu, was es gerade
gelesen hat - aus vier Pruefungen werden eine und drei Echos. Damit ist die
Abstimmung das Gegenstueck zur Besprechung, wo jeder die Beitraege sieht.
Und eine Kehrtwende bei #700: Vorgeschlagen war eine Frist mit Kehrbesen
fuer Audit und Receipts. Richtig ist das Gegenteil. In einem Buero voller
Menschen geht taeglich verloren, warum etwas so entschieden wurde - hier
nicht. Bei hundert Agenten sind es 3,3 GB im Jahr; dafuer wirft man kein
Wissen weg. Was bleibt, ist ein Archiv: heiss und kalt trennen, verdichtete
Werte immer behalten, Geheimnisse gar nicht erst hineinschreiben, gezielt
loeschen koennen.
Folge: Die 14-Tage-Voreinstellung der Prompt-History gehoert auf unbegrenzt.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Der Ordner SharedWorkspace wird zu SharedWorkspaces: mehrere benannte
Bereiche mit Eigentuemer und Mitgliederliste, je Einheit einer als
Normalfall, abteilungsuebergreifende ausdruecklich. Das Recht steht am
Bereich, nicht am Agenten - Marketing sieht die Ablage der Buchhaltung
nicht, und erfaehrt auch nicht, dass es sie gibt.
Zwei offene Fragen entschieden:
- Budgets bleiben am Agenten. Die Einheit rechnet auf und meldet
Abweichungen vom eigenen Verlauf. Damit entfaellt die Zuteilungsrechnerei,
und ein Umzug aendert keine einzige Grenze.
- Eine Eskalation, die nicht geloest werden kann, darf es nicht geben. Nach
einer Frist wird der Mensch gerufen, der entscheidet oder Stellungnahmen
anfordert. "Bleibt sichtbar liegen" war zu schwach.
Neu: Die Doctrine.md gibt einer Leitung ein Steuermittel neben Identity und
Soul - eine Ebene tief, kurz, gedeckelt, und freigabepflichtig, wenn der
schreibende Lauf fremde Inhalte gelesen hat.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Der Baum ist beliebig tief schachtelbar, und Einheiten wie Agenten muessen
sich nachtraeglich verschieben lassen - bei gestoppter Instanz, mit
Unterrichtung der Betroffenen und Eintrag im Audit. Das Konzept setzte das
schon voraus ("wer mehr Reichweite geben will, verschiebt im Baum"), ohne es
je zu beschreiben.
Beim Gegenlesen gefunden und aufgeloest:
- "Nur nach oben" gegen "zurueckgeben": Die zweite Antwort der Leitung ist
eine ENTSCHEIDUNG, die den Vorgang schliesst. Verboten ist der ungeloest
zurueckwandernde Vorgang.
- Konflikt gegen "nie ueber Ebenen hinweg": Ein Konflikt klettert nicht, er
wird zugestellt. Die Zustaendigkeit ergibt sich rechnerisch aus dem Baum;
dazwischenliegende Ebenen werden vermerkt, nicht befragt.
- Die Ausnahmen von "ein Agent kennt nur seine Einheit" stehen jetzt
vollstaendig beisammen - vier, alle lesend, keine gibt einen neuen
Gespraechspartner. Verstreute Ausnahmen vermehren sich.
- Stale Verweis "Vorbedingung fuer Stufe 4" auf Stufe 5 berichtigt, die
Kontrollpflicht vor die Oberflaeche gezogen.
Vier Punkte als zu grob markiert und mit Vorschlag versehen: Budget als
Deckel oder Zuteilung, woraus eine Freigabegrenze besteht, wie ein
Beschluss wirksam wird, was die Eskalationsgrenze tut, wenn sie greift.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Eine Meldung, die vier Ebenen durchlaeuft, wird viermal neu formuliert.
Das faellt nicht auf, weil es keinen Fehler gibt, den man finden koennte -
alle arbeiten korrekt, und die Spitze entscheidet ueber eine Nacherzaehlung
der Nacherzaehlung.
Die Regel: Jede Weitergabe haengt an, sie ersetzt nicht. Der Verweis auf
den Ursprung wandert mit, der Inhalt bleibt liegen und wird geholt, wer ihn
braucht. Eine Zusammenfassung darf danebenstehen, nie anstelle. Dieselbe
Festlegung wie beim Aufgabenrumpf (#677), hier fuer den Weg.
Beim Skriptfehler heisst das: Der Sandbox-Runner legt Exit-Code, stderr,
Aufrufparameter, Dauer und RunId unter scripts/<id>/fehler/ ab - nicht der
Agent. Der Zugang folgt dem Skript statt der Abteilung, damit der
Entwickler alle Fehlschlaege seines Werkzeugs sieht, ohne in fremde
Arbeitsbereiche zu duerfen. Durch die Befehlskette geht nur noch der
Verweis.
Nebenbei zwei doc_anchors nachgezogen, die durch fruehere Umnummerierung
ins Leere zeigten (#687, #688).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Korrektur der gestrigen Fassung: Dort stand, der zustaendige Agent schreibe
und pflege sein Skript selbst. Ein Anzeigen-Agent, der programmiert und
beliebigen Code ausfuehrt, hat Rechte, die seine Arbeit nicht braucht.
Die Lieferkette: Bedarfsmeldung mit ausgearbeiteter Beschreibung an die
eigene Leitung, von dort an die Entwicklung, dort schreiben und testen,
Pruefung und Freigabe nach #657, Zuteilung an genau diesen einen Nutzer.
Fehler gehen ueber dieselbe Kette zurueck.
Technisch folgt daraus, dass scripts.run kein Schalter sein darf, sondern
eine Liste benannter Skripte - ein Ja/Nein waere die Hintertuer, die die
Trennung gerade schliesst.
Und ein zweiter Gewinn, der als Entwurfsziel gelten soll: Der Agent, der
fremde Inhalte liest, ist nie der Agent, der ausfuehrbaren Code
hervorbringt.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Korrektur der vorigen Fassung: Plattformen werden NICHT angebunden, auch
nicht als MCP-Server je Plattform - das verlagert die Pflege nur nach
aussen. Das Produkt gibt Faehigkeiten (API, Webseite, Datenbank, Mail); was
spezifisch ist, schreibt sich die Instanz selbst. Damit sind Sandbox (#654),
Shell (#196) und Skriptpruefung (#657) nicht nur Sicherheitsvorhaben,
sondern der eigentliche Werkzeugkasten. Die Reihenfolge bleibt zwingend:
erst die Sandbox, dann das Schreiben.
Neu: Eine Leitung delegiert nicht nur, sie prueft stichprobenartig (#693) -
gegen AuditLog und Transkripte, nie gegen die Selbstauskunft, denn ein
Modell hat am 14.09. dreizehn Werkzeugantworten erfunden. Aus einem Befund
folgen abgestufte Mittel: meist ein schaerferer Auftragstext, seltener ein
anderes Modell, zuletzt Stilllegung. Vorgeschlagen von der Leitung,
ausgefuehrt nach Freigabe.
Dazu der A/B-Vergleich im Betrieb (#694), gemessen an Dingen, die das
Modell nicht selbst behauptet.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Das Produkt bringt Baum, Mittel, Werkzeugkasten und Grenzen mit; welche
Abteilungen es gibt, ist eine Zeile in einer Datei. Im Code steht nirgends
das Wort "Einkauf". Daraus folgt die Organisationsvorlage (#691) - ein
ganzes Haus als weitergebbare Datei.
Der Eskalationsfall aus dem Vorschlag zerfaellt in drei Mittel (#689):
Eskalation geht nach oben, ein Konflikt wird bei der niedrigsten gemeinsam
uebergeordneten Stelle entschieden - eine Regel, die fuer jedes Organigramm
gilt, ohne dass jemand Wege konfiguriert -, und ein Beschluss ist dauerhaft,
sonst wird dieselbe Frage naechste Woche erneut durch vier Ebenen getragen.
Die Spitze ist eine Rolle, kein CEO-Agent (#690): Mensch, Agent oder Mensch
mit Frist. Wer entscheidet, fuehrt nicht aus und aendert die Struktur nicht.
Vorbedingung des ganzen Falls: Das Datenbank-Werkzeug kann heute nicht nach
dem Schema fragen (#676). "Ich finde kein Feld dafuer" ist damit eine
Vermutung, und eine Organisation soll keine Einbildungen eskalieren.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Die Regel im InstanceSetupGuide war in der Beobachtung richtig und in der
Folgerung falsch: quadratisch steigen die Verbindungen, nicht die Agenten.
Ein Agent, der drei Nachbarn und eine Leitung kennt, kostet gleich viel, ob
die Instanz zehn oder hundert Agenten hat.
docs/Organisation-Konzept.md haelt fest, was heute bei 50 Agenten bricht
(flaches Adressbuch, synchrones send_message, Delegationstiefe 3,
unbegrenzte Parallelitaet, Kappung bei 500, zwei Arbeitsbereiche, ein Brett,
zwei Budgetebenen, eine Freigabe-Warteschlange) und schlaegt die fehlende
Ebene vor: die Einheit.
Zwei davon sind schon heute Fehler und gehoeren sofort behoben (#682).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Zwei Nutzervorschlaege aus dem Testbetrieb, beide mit Ankern im Bestand:
Die Aufsicht ist das dritte Profil des AgentInspector (#204), neben dem
Security-Profil (#658); die Werkzeugproben fuellen Stufe 2 des Probelaufs
fuer neue Agenten (#649) und loesen den "Evals-Test-Runner" aus dem
Orchestrator-Konzept ein.
Zwei Entscheidungen tragen die Dokumente:
- Erkennen ist Code (#646), Deuten ist Modell (#680). Wer das verwischt,
bezahlt ein Sprachmodell fuers Zeilenzaehlen.
- Die Eignungsprobe gehoert zum Werkzeug, nicht in eine zentrale Liste,
und wird gegen das Audit geprueft, nie gegen die Selbstauskunft.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Die Betriebskontrolle im Testbetrieb meldete Stundendateien als fehlend, die
es gab: 105 Eintraege in der Reihenfolge des Dateisystems, vierzeilig als
eingeruecktes JSON. list liefert jetzt die 50 zuletzt geaenderten Eintraege,
neueste zuerst, eine Zeile je Eintrag, mit Gesamtzahl im Kopf; pattern, sort,
order und limit steuern das.
Dabei aufgefallen (#675): Directory.GetFiles wertet Trennzeichen im Muster
aus - pattern "../*" fuehrte an der Pfadpruefung vorbei aus dem Verzeichnis
heraus, in list wie in read_many. Muster mit '/', '\' oder '..' werden jetzt
abgewiesen.
Und derselbe Befund ist keine zweite Aufgabe (#674): task_find beantwortet
die Frage vor dem Anlegen, task_create legt bei gleichbedeutendem Titel einer
offenen Aufgabe keine zweite an, sondern vermerkt das erneute Auftreten an
der bestehenden. force=true geht trotzdem, Erledigtes blockiert nichts.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
#663: Neue Aktion read_many liest mehrere Dateien in einem Aufruf - entweder
paths (Liste) oder path (Verzeichnis) mit pattern. Gedeckelt auf 50 Dateien und
200.000 Zeichen; was nicht mehr hineinpasst, wird namentlich genannt, damit der
Agent gezielt nachholen kann. Anlass: Der Tagesabschluss im Testbetrieb las 24
Stundendateien einzeln und starb zweimal an der Schrittgrenze - die soll
Endlosschleifen abfangen, nicht ehrliche Arbeit.
#662: Schlaegt read oder list fehl, weil der Pfad im anderen Workspace liegt,
sagt die Fehlermeldung das - aber nur, wenn der Agent diesen Workspace auch
benutzen darf. Guenstige Modelle vergassen workspace "shared" regelmaessig und
verbrauchten mit jedem Rateversuch einen Schritt.
Dateipruefung, Endungen und Workspace-Grenze gelten in read_many unveraendert;
eine verbotene Endung wird uebergangen statt den Lauf zu kippen.
Version 0.1.14.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
#643: Entscheidungen wecken den Agenten nur noch bei Ablehnung oder gescheiterter
Ausfuehrung, gesammelt in einer Aufgabe je Agent (5 min Ruhefenster), frisch per
@new:agent statt im fortgefuehrten Chatverlauf. Eine einmalige Aufgabe, deren Lauf
wegen Budget oder Herunterfahren gar nicht stattfand, bleibt faellig (Wiedervorlage
nach 30 min) statt mit gesetztem Marker liegenzubleiben.
#641: Rechte stehen in der Werkzeugkonfiguration des Agenten (erlaubt/verboten).
Erlaubtes laeuft, Nicht-Erlaubtes wird einzeln vorgelegt statt verweigert, Verbotenes
gar nicht erst. "Gleichartiges kuenftig erlauben" erteilt eine widerrufbare
Dauerfreigabe je Agent/Werkzeug/Operation; nach drei gleichartigen Freigaben schlaegt
die Oberflaeche sie vor. Aenderungen an Agenten bleiben ausnahmslos freigabepflichtig.
Database: Operation ist das SQL-Schluesselwort; die eigene Zugriffspruefung greift nur
noch ohne Freigabestelle (AgentToolContext.FreigabeGeprueft). WebUI: Rechte-Tabelle je
Werkzeug, Dauerfreigaben mit Widerruf.
Version 0.1.11.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Engine: leere Antworten nachfassen, Aufgaben enden mit Ergebniszeile (EmptyResponse/Incomplete),
gleiche Fehlschlaege erkennen (RepeatedFailure), Zeitzeile vor Chatnachrichten,
Werkzeugergebnisse gerahmt, Vorpruefung vor dem Staging, Belegkosten wie RunUsage
- Staging: gescheiterte Freigaben als Failed; AgentEditor-Aenderungen freigabepflichtig,
Selbstbearbeitung gesperrt (allowSelfEdit)
- Taskboard: Termine beim Anlegen pruefen, naechster/letzter Lauf, pausieren, Sofortlauf,
Kostenprognose, Hinweis auf wachsenden Kontext; Jobs-Reiter und /api/jobs entfernt
- Release: Instanzmanager samt Weboberflaeche im Paket, setup.json fragt manager.json ab,
Token nicht mehr ins systemd-Journal
Version 0.1.6.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Eine Sicherung des Managers ist jetzt als Ganzes mit dem Lizenzschluessel
verschluesselt. Beim Zurueckspielen wird der eigene Schluessel probiert; passt er
nicht, fragt die Oberflaeche nach dem Lizenzschluessel der Quellinstallation.
Der Lizenzschluessel ist der eine Wert, den jede Installation ohnehin hat, und er
liegt im Manager, nicht neben den Archiven. Damit faellt der Grund weg, aus dem die
taegliche Sicherung bisher keine Zugangsdaten enthielt: Eine Passphrase haette
gespeichert werden muessen, und neben den Sicherungen waere sie wirkungslos
gewesen. Jetzt reisen die Zugangsdaten mit, und eine Sicherung uebersteht den
Maschinenwechsel ohne Passphrase.
LicenseBackupCipher: eigener Behaelter .clawdbak. Kopf mit Schluesselprobe, das
Manifest als eigener Abschnitt, das ZIP in 1-MiB-Stuecken mit AES-256-GCM und
Endmarke. PBKDF2 aus Lizenzschluessel und festem Salt, der Schluessel normiert.
Kein RAR (braucht das lizenzpflichtige Herstellerprogramm), kein ZIP mit Kennwort
(kann .NET nicht schreiben, ZipCrypto ist gebrochen, und mit abgeleitetem
Schluessel braechte 7-Zip-Vertraeglichkeit nichts).
Zurueckspielen: Die Schluesselprobe laeuft VOR dem Anhalten der Instanz. Passt
der Schluessel nicht, antwortet der Endpunkt mit 422 und dem Code fremde_lizenz,
und ein Fenster verlangt den Schluessel der Quelle.
ManagerBackups: Gefuehrte Instanzen sichern sich nicht mehr selbst, weil nur der
Manager den Schluessel hat; er liest ihre Einstellungen aus InstanceSettings.json.
Einmal am Tag auch ueber einen Neustart des Managers hinweg. Ohne Lizenzschluessel
wird nichts gesichert, auch nicht ersatzweise unverschluesselt.
FTP (FluentFTP, schon im Loesungsbaum): TLS wo angeboten, requireTls erzwingt es;
Upload unter .part-Namen und danach umbenannt; Aufraeumen auf dem Server je
Instanz; ein gescheiterter Upload laesst die lokale Sicherung stehen. Das
Kennwort liegt verschluesselt in manager.json und geht nie an die Oberflaeche.
Welche Datei zu welcher Instanz gehoert, entscheidet ein Zeitstempel nach dem
Namen und nicht das Praefix - Test und Test_2 werden nicht mehr verwechselt.
Grenze, bewusst und dokumentiert (Konzept 9.10): Wer Lizenzschluessel und Archiv
hat, hat die Zugangsdaten. Der Schluessel ist dem Hersteller bekannt und gilt fuer
alle Instanzen einer Installation.
Nicht ueber die Oberflaeche abgenommen: Fenster fuer die fremde Lizenz und FTP
gegen einen echten Server stehen als Block H in #537.
860 Tests gruen, 0 Warnungen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
SecretKeyStore.Wrap band den Hauptschluessel unter Windows per DPAPI ans
Benutzerkonto und gab ihn sonst ungewrappt zurueck - eine Zeile, die man beim
Lesen ueberspringt und die auf dem Zielsystem "im Klartext" bedeutet.
Dahinter steht jetzt ein SecretKeyRing: derselbe Hauptschluessel, mehrfach
verpackt, je Fach ein ISecretProvider (dpapi, passphrase, file). Fuer Aufrufer
aendert sich nichts - GetOrCreateKey gibt weiterhin 32 Byte zurueck. Genau dafuer
war die Naht da.
WARUM MEHRERE FAECHER UND NICHT EIN BESSERES
Ein Schluessel an der Maschine ueberlebt keinen Umzug; einer an einer Passphrase
verlangt bei jedem Start jemanden, der tippt - und Dauerbetrieb ohne Menschen ist
der Zweck (#214). Der Bund entscheidet sich nicht: Im Alltag oeffnet das
Maschinenfach ohne Rueckfrage, nach einem Umzug die Passphrase, und beide fuehren
zu DEMSELBEN Schluessel. Alle enc:v2-Werte bleiben lesbar.
Und deshalb darf die Schluesseldatei jetzt ueberhaupt in eine Sicherung: Sobald
ein Wiederherstellungsfach da ist, steht der Hauptschluessel in keiner Fassung im
Klartext darin.
Nicht zu verwechseln mit der Sicherung mit Passphrase: Die schluesselt jeden WERT
einzeln ins Archiv um, fuer den Transport einer Instanz. Das Wiederherstellungs-
fach schluesselt den HAUPTSCHLUESSEL um, damit eine bestehende Installation
weiterlaeuft - unbeaufsichtigt ueber CLAWD_SECRET_PASSPHRASE. Die Unterscheidung
steht in docs/Roadmap.md bei #190.
Beide Altformate werden uebernommen: 32 rohe Byte werden zum Fach file, ein
DPAPI-Block zum Fach dpapi. Derselbe Schluessel, nur anders verpackt.
Zwei Zusagen, mit Tests festgehalten:
- Geht KEIN Fach auf, wird abgebrochen statt ein neuer Schluessel erzeugt. Ein
neuer Hauptschluessel machte jeden bestehenden Wert wortlos unlesbar.
- Ein Umzug legt den Schluessel NICHT im Klartext ab, nur damit der naechste Start
bequemer wird.
Beim automatischen Weg wird nur hinzugefuegt, nie weggenommen; weggenommen wird
nur in SetRecoveryPassphrase, wo ein Mensch gerade getippt hat.
#190 bleibt offen: Unter Linux greift weiterhin das Fach file. Neu ist, dass es
beim Start als Warnung im Protokoll steht statt unsichtbar zu sein. Womit das
Maschinenfach dort gefuellt wird, ist Entscheidung #180 - diese Schnittstelle ist
die Stelle, an der die Antwort eingesetzt wird.
834 Tests gruen, 0 Warnungen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Mit E-M3 wanderte die Lizenzpruefung in den Manager: Eine gefuehrte Instanz prueft
nicht mehr selbst, weil der Manager es zentral getan hat. Woran sie "gefuehrt"
erkannte, war der Schalter --managed - und ein Schalter ist keine Erkennung.
ClawdDotNet --managed startete damit eine Instanz ganz ohne Lizenzpruefung. Vor
E-M3 gab es die Luecke nicht; sie ist mit der Zentralisierung entstanden.
ManagerHandshake unterschreibt Instanzverzeichnis und Ablauf mit HMAC-SHA256. An
die Signierstelle kommt der Manager nur, wenn seine Lizenzpruefung bestanden hat -
StartInstanceAsync weist vorher mit StartRefusal.NoLicense ab. Dass die
Unterschrift existiert, ist der Beweis.
- Gebunden an das Verzeichnis, und geprueft wird gegen das tatsaechliche, nicht
gegen das behauptete: Sonst unterschriebe man das Argument statt der Sache.
- Fuenf Minuten gueltig, der Ablauf geht in die Unterschrift ein.
- Ueber die Umgebung statt ueber die Befehlszeile: Eine Befehlszeile steht in
jeder Prozessliste.
- Ungueltig heisst "nicht gefuehrt", nicht Abbruch. Dann prueft die Instanz ihre
Lizenz selbst - der Weg von vor E-M3, also kein neuer Fehlerfall.
AppHost.IsManaged ist jetzt der gepruefte Befund. CanSwitchInstance und der
Wechseldialog haengen daran statt am Schalter.
Die Grenze steht ausdruecklich im Konzept (9.9): Der Schluessel liegt in jeder
ausgelieferten Programmdatei. Es geht um den gewoehnlichen Weg an der Lizenz
vorbei, nicht um jemanden mit Werkzeugen und Willen.
Abgenommen an echten Prozessen, Unterschrift fuer den Positivfall unabhaengig in
Python gerechnet: ohne Unterschrift "Lizenz erforderlich"; mit gueltiger kommt die
Instanz hoch; Unterschrift fuer ein fremdes Verzeichnis und hochgedrehter Ablauf
scheitern beide.
820 Tests gruen, 0 Warnungen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Weboberflaeche (#531): X-Instanz an der einen fetch-Stelle, Instanzauswahl in der
Kopfzeile, Verwaltungsansicht mit Anlegen/Starten/Anhalten/Fenster, Herkunft der
Ereignisse, Sicherungs- und Einstellungsansicht. 402/409/502 werden eigen behandelt.
Sicherungen im Manager (#530): Auflisten, Anlegen, Wiederherstellen, Loeschen. Das
Zurueckspielen haelt die Instanz vorher an und startet sie danach wieder.
Geordnetes Ende (Konzept 9.8). Zwei Befunde waren der Anlass:
Der Manager konnte eine Instanz MIT FENSTER nie geordnet beenden.
Control.ShutdownRequested war nur in HeadlessRun verdrahtet, nicht in der
Avalonia-Anwendung - und ein Fenster ist die Vorgabe. Die Bitte wurde mit 202
beantwortet, niemand hoerte zu, und der Manager schoss den Prozess nach Ablauf
seiner Frist jedes Mal ab.
InstanceSupervisor.StopAsync hielt Socket-Schweigen fuer einen Todesnachweis und
meldete "beendet", ohne den Prozess anzufassen. Bei einer verstummten Instanz ist
der Socket von vornherein still - der Neustart haette einen zweiten Prozess auf
dieselbe state.db gesetzt. Genau der Schaden, gegen den #528 gebaut ist.
- ShutdownCoordinator: erst die Tuer schliessen, dann auf offene Arbeiten warten,
Frist zwei Minuten. Vorher brach TaskScanner.DisposeAsync mitten in ProcessAsync
ab, sodass die Aufgabe bis zum Lease-Ablauf auf "running" stehenblieb.
- GET /api/instanz/puls hinter dem Socket-Gate: Phase und offene Arbeiten. Weiter
gefragt statt gemeldet - ein Puls, den die Instanz von sich aus schickt, fehlt
genau dann, wenn sie haengt.
- Eskalationsleiter: drei Durchgaenge ohne Antwort, einmal um ein Ende bitten,
nach 30s beenden und den Vollzug abwarten, gemeldet als Absturz.
- EnsureDeadAsync vor jedem Start.
Weiteres aus dem Review:
- .gitignore verankert: "Instances/" passte auch auf src/ClawdDotNet.Core/Instances/.
InstanceEndpoint.cs und InstanceLayout.cs waren dadurch nie eingecheckt.
- Das WebUI-Token stand im Protokoll des Managers. Konsole ja, Datei nein.
- Ein Klick auf "Instanz anlegen" loeste requestSubmit() zweimal aus.
- [Obsolete] auf WebServerPort wieder entfernt: sechs Warnungen, die niemand
abstellen konnte, solange E-M5 nicht fertig ist.
- Die Wiederherstellung bricht nicht mehr ab, wenn der Browser weggeht.
- Entwicklungspfade zum Instanzmanager aus Segmenten statt mit Rueckstrichen, und
der Port kommt aus manager.json statt fest aus der Zeile.
Offen und gemeldet: --managed hebelt die Lizenzpruefung aus (#535).
806 Tests gruen, 0 Warnungen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Der C#-Teil des Instanzmanagers ist fertig; was fehlt, ist die
Oberflaeche. Abschnitt 11 im Konzeptpapier ist die Uebergabe dafuer: der
Auftrag in einem Satz, die harte Grenze (keine .cs-Datei, git status darf
nur wwwroot zeigen), die vollstaendige API mit den Antwortcodes, die eine
eigene Behandlung verdienen, eine Reihenfolge, zwei Fallen und die drei
Punkte, die ausdruecklich liegen bleiben, weil sie C# sind.
Der WebUI-Leitfaden war an vier Stellen ueberholt und haette den naechsten
Agenten in die Irre geschickt: wwwroot liegt nicht mehr in
ClawdDotNet.Web, die Oberflaeche laeuft nicht mehr im Prozess der Instanz,
Port und Token stehen in manager.json statt in InstanceSettings.json, und
es gibt nicht mehr ein /api fuer eine Instanz. Ein Korrekturblock steht
jetzt vorweg und verweist auf Abschnitt 11; der Rest des Leitfadens - kein
innerHTML, kein Paketmanager, Token nur im sessionStorage, Farben aus
app.css - gilt unveraendert.
Die Arbeit selbst ist #531 und steht auf der Roadmap. Was nur in einer
Datei steht, ist keine eingeplante Arbeit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Entschieden vom Benutzer am 2026-09-08. Der Schalter heisst
autostartByManager und steht in InstanceSettings.json - bei der Instanz,
nicht beim Manager.
ZWEI DINGE IN EINEM SCHALTER, weil es dieselbe Zusage ist: Der Manager
startet diese Instanz, wenn er selbst hochkommt, und er startet sie wieder,
wenn sie abstuerzt. Ohne den Schalter ruehrt er nichts an - ein Manager,
der nach einem Neustart der Maschine alles hochfaehrt, was er findet,
startet auch das, was jemand mit Absicht angehalten hat. Ausgeschaltet
vorbelegt.
DER SICHERUNGSAUTOMAT ist der eigentliche Inhalt. Wieder hochzufahren ist
die einfache Haelfte; die schwierige ist zu erkennen, wann man es lassen
muss. Nach drei Neustarts in zehn Minuten (maxRestartsInWindow,
restartWindowMinutes) setzt der Manager aus und meldet es. Die Instanz
bleibt dann aus, bis jemand sie von Hand startet - und dieser Start raeumt
den Zaehler ab, denn wer von Hand startet, hat entweder etwas geaendert
oder weiss, was er tut. Das Zeitfenster wandert: Eine Instanz, die einmal
im Monat abstuerzt und wieder hochkommt, laeuft nie in die Grenze.
Nur bei einem Absturz, nicht wenn eine Instanz verstummt. Eine stumme
Instanz lebt noch; sie neu zu starten hiesse, sie erst abzuschiessen, und
ob der Manager das von sich aus darf, ist nicht entschieden. Als offene
Frage aufgeschrieben - genau dieser Zustand war der Anlass des Vorhabens.
Der Schalter steht bei der Instanz, weil er eine Eigenschaft dieser Instanz
ist und weil die Instanzdatei dem Instanzprozess gehoert: Sie vom Manager
schreiben zu lassen, waehrend die Instanz laeuft, waeren zwei Schreiber auf
einer Datei. Der Manager liest ihn nur; geaendert wird er auf der
Einstellungsseite der Instanz.
EIN DEFEKT, den erst diese Tests gezeigt haben: StartAsync gab "laeuft
schon" zurueck, wenn die Aufsicht die Instanz fuer laufend hielt - ohne
nachzusehen. Zwischen zwei Aufsichtsdurchgaengen liegen aber Sekunden, und
in denen kann sie wegbrechen. Wer in dieser Luecke "starten" verlangte,
bekam einen Erfolg, hinter dem nichts stand, und der naechste Durchgang
meldete einen Absturz, den niemand mehr erwartete. Jetzt wird gefragt,
bevor zugestimmt wird.
UND EIN TESTDOUBLE, das die Wirklichkeit nicht abbildete: Der falsche
Socket antwortete unabhaengig davon, ob ein Prozess lief. Damit war jeder
Testaufbau, der die Antwort vor dem Hochfahren hinterlegte, stillschweigend
ein anderer Test als beabsichtigt - eine Antwort sagt dem Manager "laeuft
bereits", er uebernimmt, und der Starter wird nie angefasst. Dreimal
passiert. Der falsche Socket haengt jetzt am falschen Starter.
Sicherungen im Manager sind als #530 zurueckgestellt, mit Ausloeser.
Vorab entschieden ist dort nur eines: Zurueckspielen ausschliesslich bei
inaktiver Instanz.
19 neue Tests. Build ohne Warnungen, 793 Tests gruen, 8 uebersprungen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Vorher hiess "Instanz wechseln": Der laufende Prozess faehrt sich herunter
und startet sich mit einer anderen Instanz neu. Wer wechselte, beendete
zwangslaeufig die Instanz, aus der heraus er es tat - und genau dabei hat
sich die Anwendung am 2026-09-08 aufgehaengt (#529). Jetzt laufen alle, und
es kommt eine nach vorn.
Neu: POST /api/instanz/fenster, wieder ausschliesslich ueber den Socket.
Die Instanz holt ihr Fenster SELBST nach vorn; der Manager kennt kein
Fenstersystem und soll keines kennen. Kopflos laeuft die Bitte ins Leere,
und das ist die richtige Antwort. Das letzte Wort hat der Fenstermanager -
Windows laesst einen Hintergrundprozess den Vordergrund nicht einfach an
sich reissen; der kurze Ausflug ueber Topmost half im Versuch, unter Linux
entscheidet der Fenstermanager. Mehr als bitten kann eine Anwendung nicht.
ShutdownSignal ist zu InstanceControl geworden: beenden und Fenster sind
zwei Bitten desselben Absenders ueber denselben Weg. Beenden gilt einmal,
das Fenster beliebig oft - jeder Wechsel auf diese Instanz ist einer.
--managed schaltet den Wechsel im Instanzfenster ab. Der Manager gibt es
jedem Instanzprozess mit; das Fenster graut seinen Instanz-Schalter aus und
erklaert auf Nachfrage, wo gewechselt wird. Zwei Schloesser an derselben
Tuer: Der Knopf ist aus, und der Weg dahinter prueft es noch einmal - denn
hinter ihm wartet ein Selbst-Neustart.
instanceWindows in manager.json, vorbelegt auf true: Jede Instanz behaelt
ihr Fenster. Auf einer Maschine ohne Bildschirmsitzung gehoert false hin.
ABNAHME an echten Fenstern: Instanz ueber den Manager gestartet, PID 18128,
Fenstertitel "ClawdDotNet", Befehlszeile mit --managed. Fenster von aussen
minimiert (IsIconic True), dann POST /instanzen/Instance-Test/fenster:
IsIconic False, im Vordergrund - und PID unveraendert 18128. Nichts neu
gestartet. Das ist die Abnahmebedingung dieser Stufe.
Build ohne Warnungen, 780 Tests gruen, 8 uebersprungen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Der Managerprozess. ClawdDotNet.Instanzmanager ist eine Konsolenanwendung:
Lizenz pruefen, uebernehmen was laeuft, Weboberflaeche aufhaengen, warten.
Beim Herunterfahren beendet er keine Instanz.
Zwei neue Projekte. ClawdDotNet.Manager.Web traegt die Weboberflaeche -
ohne jeden Verweis auf ClawdDotNet.Web, denn dort haengt App und daran
sechzehn Werkzeugprojekte. ClawdDotNet.ManagerApp ist der Einstiegspunkt.
wwwroot ist aus der Instanz in den Manager gezogen.
DER SCHNITT DER HTTP-FLAECHE: Unter /api/verwaltung steht, was den Manager
angeht - auflisten, anlegen, starten, anhalten. Alles andere unter /api
geht unveraendert an eine Instanz. Er leitet weiter, er implementiert
nicht. Welche Instanz gemeint ist, sagt die Kopfzeile X-Instanz; laeuft
genau eine, ist sie gemeint, und laufen mehrere, wird nachgefragt statt
geraten - eine Anfrage an die falsche Instanz ist schlimmer als eine
abgelehnte.
Der zusammengefuehrte Ereignisstrom haelt je laufender Instanz eine
Zuleitung und schreibt an jedes Ereignis, von wem es kommt. Ergaenzt statt
verpackt: Ein Umschlag waere einfacher gewesen, haette aber jede Ansicht
der Weboberflaeche zum Umschreiben gezwungen.
ABNAHME gegen laufende Prozesse: 401 ohne Token, Oberflaeche ohne Token
200, Instanz ueber den Manager gestartet und angehalten, /api/info und
/api/status unverfaelscht durchgereicht, /events/logs mit
"instanz":"Instance-Test" an jeder Zeile. Manager abgeschossen: Instanz
laeuft weiter. Manager neu gestartet: "1 Instanzen bekannt, 1 laufen
bereits" - uebernommen. E-M6 damit in beide Richtungen belegt.
DREI DEFEKTE, die erst der Lauf gezeigt hat:
1. Der Manager hing an einer Konsolenabfrage nach dem Lizenzschluessel. Ein
Test auf Console.IsInputRedirected reicht dafuer NICHT: Er beantwortet
"ist die Eingabe umgeleitet", nicht "kann jemand antworten" - ein
Prozess ganz ohne Konsole, der gefaehrlichste Fall, ist nicht
umgeleitet. Der Manager fragt jetzt gar nicht.
2. Eine unlesbare manager.json wurde stillschweigend durch Vorgaben
ersetzt: falsches Instanzverzeichnis, anderer Port, Lizenzfrage - und
nichts sagte, woran es lag. LoadProblem meldet den Grund jetzt.
3. Der Instanzprozess erbte CLAWD_CONFIG_DIR vom Manager und legte sich in
dessen Konfigurationsverzeichnis eine eigene Settings.json an. Eine
Umgebungsvariable vererbt sich, ein Argument nicht - der Manager nimmt
sein Verzeichnis jetzt ueber --config.
SharedLoggerProvider ist nach Core gezogen: Es gibt jetzt zwei Webhosts,
die dasselbe brauchen, und sie duerfen einander nicht kennen.
NOCH OFFEN in dieser Stufe: Die Weboberflaeche kennt noch keine Instanzen -
Instanzauswahl, X-Instanz und die Verwaltungsansicht sind Arbeit an
wwwroot. Und webServerPort steht noch in der Instanz.
Build ohne Warnungen, 775 Tests gruen, 8 uebersprungen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Neues Projekt ClawdDotNet.Licensing. LicenseGate, LicenseWatch, LicenseInfo
und ILicensePrompt sind aus ClawdDotNet.App dorthin gezogen, weil zwei
Prozesse dieselbe Lizenzpruefung brauchen und keiner von beiden den anderen
kennen darf. In Core konnte es nicht landen - dann zoege jedes der sechzehn
Werkzeugprojekte das Deploymentcenter-SDK mit.
Dabei ist die Kopplung an SettingsManager verschwunden. LicenseGate kennt
jetzt nur ILicenseStore: Serveradresse lesen, Schluessel lesen und
schreiben, speichern. Die Anwendung fuehrt ihn in Settings.json, der
Manager in manager.json. Der Torwaechter prueft Schluessel; Dateien
verwaltet er nicht. Auch die Anwendungsversion kommt als Parameter statt
aus einem globalen Zugriff - diese Schicht weiss nicht, welche Anwendung
sie benutzt.
ManagerCore ist die Klammer: eigene Einstellungen, Lizenz, Register,
Meldeweg. Drei Regeln:
- Ohne gueltige Lizenz startet er keine Instanz. Laufende werden trotzdem
in die Liste genommen - man soll sie sehen und anhalten koennen.
- Ein Widerruf haelt alle an. Der einzige Fall, in dem der Manager das von
sich aus tut. Ein Serverausfall gehoert ausdruecklich nicht dazu; das SDK
trennt Urteil und gescheiterten Versuch, und nur das Urteil kommt hier
an. Sonst naehme ein Netzproblem saemtliche Installationen mit.
- Ohne hinterlegte Lizenzpruefung sperrt er nichts, sonst gaebe es eine
Henne-Ei-Sperre, bevor jemand einen Schluessel eintragen kann.
Sub-Token je Instanz: Der Manager haelt das Master-Token und tauscht es
beim ANLEGEN einer Instanz gegen ein eigenes (watchdog:ping,
bugtracker:report, einzeln widerrufbar). Beim Anlegen und nicht beim ersten
Start, weil die Instanzdatei dann zweifelsfrei niemandem gehoert - sie
spaeter zu schreiben, waehrend der Instanzprozess laeuft, hiesse zwei
Schreiber auf einer Datei. Fuer Instanzen, die es vor dem Manager schon
gab, wird es vor dem Start nachgeholt. Danach fragt er ueber whoami nach,
ob das Token an ein Projekt gebunden ist (SDK 2.8.1). Ein
fehlgeschlagener Tokenbezug haelt die Instanz nicht auf.
NOCH NICHT VOLLSTAENDIG: Die Instanzen pruefen die Lizenz weiterhin selbst.
Das laesst sich erst abschalten, wenn eine Instanz feststellen kann, ob ein
Manager da ist - vorher entstuende eine Fassung ganz ohne Durchsetzung.
Und ein Testfehler, der zweimal derselbe war: Die Socket-Antwort war
hinterlegt, BEVOR der Manager hochfuhr. Damit sagt man "diese Instanz
laeuft bereits", der Manager uebernimmt sie, der Starter wird nie
angefasst - und der Test prueft etwas anderes, als er behauptet. Es gibt
jetzt eine Hilfsmethode, die das ausschliesst.
Build ohne Warnungen, 774 Tests gruen, 8 uebersprungen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Der zweite Teil von Stufe 3. Die Aufsicht ueber eine einzelne Instanz stand
schon; jetzt gibt es die Klammer darum und den Weg nach draussen.
InstanceRegistry haelt je Instanz eine Aufsicht. Zwei Zusagen, beide aus
E-M6: Beim Start wird UEBERNOMMEN, nicht gestartet - ein Manager, der beim
Hochkommen alles hochfaehrt, was er findet, startet nach einem Neustart der
Maschine auch das, was jemand mit Absicht angehalten hat. Und beim Beenden
wird nichts beendet: Wer den Manager schliesst, will den Manager
schliessen. Einzige Ausnahme ist StopAllAsync fuer einen Grund, der alle
betrifft - und der heisst Lizenzwiderruf.
SupervisionReporter macht aus einem Befund eine Bugtracker-Meldung,
stellvertretend: mit Prozesskennung, Abschiedscode und dem Ausschnitt aus
dem Instanzprotokoll, der noch auf der Platte liegt. Der Idempotenzschluessel
ist stabil je Instanz und Art - stuerzt dieselbe Instanz wiederholt ab,
zaehlt der Server hoch, statt den Bugtracker mit Zwillingen zu fuellen.
Ein leerer Protokollauszug ist dabei die aussagekraeftigste Zeile der
Meldung und wird ausdruecklich als solche geschrieben. Genau das war der
Zustand am 2026-09-08: Der Prozess wurde erschlagen, bevor sein
Schreibpuffer geleert war, und hinterliess nichts.
manager.json traegt die Felder aus Abschnitt 6 des Konzepts und sonst
nichts. Lizenzschluessel, Master-Token und Web-Token liegen darin
verschluesselt und zur Laufzeit im Klartext - dieselbe Bauart wie die
Anwendungseinstellungen, mit Absicht. Unsinnige Aufsichtswerte werden
eingefangen, weil die Datei von Hand bearbeitbar ist.
InstanceLayout ist nach Core gezogen (ResolveLogDirectory,
ResolveBackupDirectory). Der Manager braucht das Protokollverzeichnis einer
Instanz fuer den Auszug in der Meldung und darf ClawdDotNet.App nicht
kennen; dieselbe Rechnung an zwei Stellen zu fuehren waere die schlechtere
Antwort. AppHost leitet nur noch weiter.
EIN DEFEKT, den erst die eigenen Tests gezeigt haben: Eine angehaltene
Instanz erschien im Register als "Instance-Alpha" statt "Alpha". Die
Aufsicht kennt den Namen erst, wenn die Instanz einmal geantwortet hat, und
eine angehaltene tut das nie - waehrend genau diese Ansicht der Manager
anzeigt. Das Register fuehrt den Namen jetzt aus InstanceSettings.json mit.
Und ein Testdouble, das zu viel behauptet hat: Der falsche Socket
antwortete fuer jedes Verzeichnis dieselbe Instanz. Das laesst Tests gruen
werden, die im Betrieb zwei Instanzen verwechseln wuerden; er antwortet
jetzt je Verzeichnis.
29 neue Tests. Build ohne Warnungen, 766 Tests gruen, 8 uebersprungen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Der Anlass des ganzen Vorhabens: Am 2026-09-08 hat sich eine Instanz
aufgehaengt und wurde von Windows beendet. Zu diesem Vorgang steht keine
einzige Zeile in den Instanzprotokollen, kein Bugtracker-Eintrag, kein
Watchdog-Alarm - weil Meldeweg und Watchdog in genau dem Prozess lebten,
ueber den sie haetten berichten sollen. Ab jetzt sieht jemand anders hin.
Neu ist ClawdDotNet.Manager mit genau EINEM Projektverweis: Core. Das ist
keine Sparsamkeit, sondern die halbe Architektur - App schleppt sechzehn
Werkzeugprojekte hinter sich her, und "keine Werkzeuge im Manager" soll
eine Eigenschaft des Bauplans sein und keine Absichtserklaerung.
DIE ENTSCHEIDUNG, AN DER ALLES HAENGT: Die Aufsicht fragt den Socket, nicht
die Prozessliste. Die Prozessliste sagt, dass etwas da ist. Sie sagt nicht,
ob es noch arbeitet - und genau das war der Zustand, den niemand bemerkt
hat. Ein Durchgang kennt drei Antworten: Socket antwortet, sie laeuft.
Socket schweigt und der Prozess ist weg, Absturz mit Abschiedscode. Socket
schweigt und der Prozess lebt, verstummt - aber erst nach mehreren
Fehlversuchen in Folge, denn ein Alarm bei jedem Aussetzer ist nach einer
Woche der Alarm, den niemand mehr liest.
Ein Start gilt erst, wenn die Instanz antwortet. Zwischen "der Prozess
laeuft" und "die Instanz laeuft" liegen Datenbank, Agenten und Kestrel; wer
nur auf Process.Start wartet, haelt eine Instanz fuer gestartet, die gleich
an einer kaputten Konfiguration scheitert.
Angehalten wird durch Bitten. Neu auf der Instanzseite:
POST /api/instanz/beenden, ausschliesslich ueber den Socket - ueber TCP
gibt es den Endpunkt nicht, auch mit gueltigem Token nicht, und er
antwortet dort 404 statt 403. Die Lebensdauer einer Instanz gehoert dem
Manager; eine Browsersitzung soll den Prozess, der sie bedient, nicht
beenden koennen. Ausgeloest wird der Wunsch erst nach dem Absenden der
Antwort (Response.OnCompleted), sonst bekaeme der Manager statt einer
Zusage einen Verbindungsabbruch und hielte ihn fuer einen Fehlschlag.
Wiederfinden nach einem Managerausfall (E-M6): Die Zustandsdatei
instance-state.json ist der Hinweis, der Socket ist der Beweis. Erst wird
gefragt, wer da antwortet; nur bei gleicher Instanzkennung wird die
Prozesskennung aus der Datei angefasst. Andersherum fuehrt eine
wiederverwendete Nummer nach einem Neustart der Maschine geradewegs dazu,
ein fremdes Programm zu beaufsichtigen und beim Anhalten zu beenden.
Selbsttaetiger Neustart ist bewusst NICHT gebaut. Die Abnahmebedingung
lautet "merkt es und meldet es", und zum Neustarten trifft das Konzept
keine Entscheidung; eine Instanz in einer Schleife wieder hochzufahren,
die jedes Mal abstuerzt, waere die falsche Vorgabe fuer etwas, das niemand
entschieden hat. Als offene Frage aufgeschrieben.
ABNAHME, mit echten Prozessen gemessen: Manager startet Instanz Test in
0,7 s, identifiziert sie ueber die Named Pipe, schreibt die Zustandsdatei
(pid 54476, id d68af6fd). Prozess von aussen abgeschossen. Naechster
Durchgang: Crashed, Code -1, meldenswert, Zustandsdatei weggeraeumt. Dazu
20 Tests gegen gesteuerte Prozesse - ein Absturz zum gewuenschten Zeitpunkt
und eine wiederverwendete Prozesskennung sind mit einem echten Programm
nicht herzustellen.
Noch offen in dieser Stufe: Instanzen anlegen, Lizenz im Manager,
Sub-Token je Instanz, und der Managerprozess selbst.
Build ohne Warnungen, 737 Tests gruen, 8 uebersprungen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Eine Instanz ist jetzt ohne Port ansprechbar. InstanceEndpoint liefert die
Adresse: unter Linux <Instanz>/manager.sock, unter Windows eine Named Pipe,
deren Name aus einem SHA-256-Fingerabdruck des Instanzpfades entsteht. Zwei
Instanzen bekommen damit zwangslaeufig zwei Adressen, ohne dass jemand
etwas vergeben muss - genau der Unterschied zur Vorbelegung 7001, um die
sich zwei Instanzen stillschweigend streiten.
Der Socket ist immer da, auch ohne Weboberflaeche. Er gehoert nicht zu
#494, sondern ist die Steuerflaeche der Instanz: webUiEnabled schaltet den
TCP-Zugang, nicht den Socket. WebUiHost heisst deshalb jetzt
InstanceHttpHost - ein Kestrel, zwei Zugaenge.
Ueber TCP gilt Token-Pflicht, ueber den Socket nicht: Dort steht die Grenze
am Dateisystem (0600 unter Linux, CurrentUserOnly bei der Named Pipe,
explizit gesetzt statt auf die Vorgabe vertraut). Wer die Socketdatei
oeffnen darf, sieht ohnehin in das Verzeichnis, in dem alles liegt, was ein
Token schuetzen wuerde.
Woran die beiden Zugaenge auseinandergehalten werden, ist der Punkt, an dem
ein Irrtum teuer waere. Bei Socket-Verbindungen stehen in
HttpContext.Connection keine IP-Adressen - daraus zu schliessen "keine IP,
also Socket" waere eine Vermutung an der Stelle, an der ein Torwaechter
steht, und sie irrt in die falsche Richtung: Im Zweifel liesse sie eine
TCP-Anfrage ohne Token durch. Der Socket-Zuhoerer haengt deshalb jeder
Verbindung selbst eine Marke an (LocalTransport, Verbindungs-
Zwischenschicht ueber ListenOptions.Use); wo sie fehlt, gilt Token-Pflicht.
Ein belegter Port kostet nur noch die Weboberflaeche. Vorher gab TryStart
in dem Fall null zurueck und die ganze HTTP-Flaeche war weg. Seit dem
Socket ist das die falsche Rangfolge: Ihn zu verlieren, weil eine zweite
Instanz laeuft, hiesse die Instanz unerreichbar zu machen - in genau dem
Fall, fuer den es den Manager gibt.
Kopfloser Betrieb ueber --headless --instance <Pfad>. Die Verzweigung sitzt
in Program.Main vor BuildAvaloniaApp, damit auf einem Server ohne
Bildschirmsitzung kein Fenstersystem angefasst wird. Gefragt wird nichts:
Instanz aus dem Argument, Lizenz ueber das bereits vorhandene
NonInteractiveLicensePrompt, Telegram-Anmeldung aus.
Nachgemessen, nicht angenommen: Kopflose Instanz auf Instance-Test
gestartet, kein Fenster, und eine rohe HTTP/1.1-Anfrage aus einem fremden
Prozess (PowerShell, direkt auf die Pipe) bekam 200 OK auf /api/info, ohne
Token. Das ist die Abnahmebedingung fuer Stufe 2.
Korrektur zur eigenen Ankuendigung: webServerPort entfaellt nicht mit
Stufe 2, sondern mit Stufe 4. Solange kein Manager die Weboberflaeche
traegt, hiesse Wegnehmen, sie ersatzlos abzuschalten.
Zwei Luecken bleiben offen und gehoeren auf die Linux-Testmaschine: Die
Socketdatei-Faelle sind unter Windows gegenstandslos und werden dort mit
sichtbarer Begruendung uebersprungen - der Unix-Domain-Socket selbst ist
auf der Entwicklungsmaschine also ungeprueft, obwohl er die Zielplattform
ist. Und das geordnete Ende auf SIGTERM liess sich hier nicht ausloesen:
Windows kennt das Signal fuer einen fensterlosen Prozess nicht.
Build ohne Warnungen, 714 Tests gruen, 8 uebersprungen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Mehrere Instanzen sollen unabhaengig voneinander laufen. Heute tun sie das
nicht: Sie teilen sich Protokollverzeichnis, Sicherungsordner und
Sicherungszeitplan. In einer gemeinsamen Startup.log standen abwechselnd
Zeilen zweier Instanzen, ohne Kennzeichnung, welche gerade spricht -- im
Mehrinstanzbetrieb ist damit jede Fehlersuche Ratearbeit. Genau in dieser
Lage ist der Aufhaenger aus #529 entstanden.
Fuenf Schluessel wandern aus AppSettings nach InstanceSettings.json:
logDirectory, backupDirectory, backupKeepCount, autoBackupEnabled,
autoBackupTime. Leer heisst jetzt <Instanz>/Logs beziehungsweise
<Instanz>/Backups; ein relativer Wert zaehlt weiterhin gegen das
Instanzverzeichnis, nicht gegen das Arbeitsverzeichnis des Prozesses
(#375 bleibt gewahrt).
autoBackupEnabled und autoBackupTime standen in der Planung nicht, sind
aber mitgegangen: Ein Schalter, der die taegliche Sicherung fuer eine
Instanz einschaltet und sie damit fuer alle einschaltet, ist derselbe
Fehler wie ein Ordner fuer alle -- und zwei von vier Sicherungsfeldern zu
verschieben hinterliesse eine Einstellungsseite, auf der die Haelfte
anwendungsweit gilt.
Keine Uebernahme der Altwerte, aber eine Ansage: SettingsManager.
AbandonedKeys meldet die aufgegebenen Schluessel, solange sie noch in
Settings.json stehen, und der Start protokolliert einmal, was nicht mehr
gilt und wohin diese Instanz stattdessen schreibt. Ein anwendungsweiter
Pfad, in alle Instanzen kopiert, waere wieder ein Ordner fuer alle.
webServerPort bleibt vorerst stehen. Es entfaellt mit Stufe 2, sobald
Kestrel auf dem Socket hoert; vorher wegzunehmen hiesse, die
Weboberflaeche ohne Ersatz abzuschalten.
Korrektur an der eigenen Befundlage: "Instanz A wirft die Sicherungen von
Instanz B weg" war zu breit. Beide Rotationen filtern bereits nach dem
Praefix backup_<Instanzname>_. Der reale Defekt ist enger, und ein Praefix
ist keine Grenze: backup_Test_2_*.zip faengt mit backup_Test_ an, also
zaehlt Test im gemeinsamen Ordner die Archive von Test_2 mit. Belegt in
BackupSchedulerTests, das den alten Zustand eigens wiederherstellt.
Nachgeprueft an der laufenden Installation, nicht nur im Test: Nach dem
Umbau schreibt Instance-Test nach Instances/Instance-Test/Logs, das alte
gemeinsame Verzeichnis bekommt keine Zeile mehr, und die Warnung zu den
aufgegebenen Schluesseln erscheint genau einmal.
Enthaelt ausserdem, was seit der Weboberflaeche liegengeblieben war:
- #526: Instanzgeheimnisse wurden beim Speichern verschluesselt und beim
Laden nie entschluesselt. LoadInstanceConfig hatte kein
ConfigSecrets.Unprotect; ConfigLoader.LoadAsync macht es richtig, wird
zur Laufzeit aber gar nicht aufgerufen. Der OpenRouter-Schluessel ging
so verschluesselt an die API.
- Ein offener Ereignisstrom hielt das Beenden fuenf Sekunden auf. Die
Stroeme hingen nur an RequestAborted, das beim geordneten Herunterfahren
nicht feuert; jetzt zusaetzlich an ApplicationStopping. Der Fang in
WebUiHost gilt dazu ohne Bedingung auf RequestAborted -- mit ihr waere
jeder offene Strom beim Beenden als Fehler im Bugtracker gelandet.
- Nach der Anmeldung blieb die Weboberflaeche leer: #anmeldung
{ display:flex } schlaegt als ID-Selektor das hidden-Attribut.
- docs/Instanzmanager-Konzept.md: Befund, die Entscheidungen E-M1 bis
E-M6, der Schnitt zwischen Manager und Instanz und die sechs Stufen.
Build ohne Warnungen, 709 Tests gruen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- ClawdDotNet.Web: Kestrel im Prozess der Anwendung, Token-Absicherung (TokenGate mit FixedTimeEquals), Endpunkte unter /api, Ereignisstrom unter /events (Server-Sent Events) und fortlaufendes Log-Streaming.
- Weboberflaeche (wwwroot/): Vollstaendiges Single-Page-Frontend mit nativem HTML5, CSS3 und ES-Modulen ohne Buildschritt (strikt textContent, #-Routing, sofortiger Login-Sprung bei fehlendem Token, Light/Dark-Theme, lokale Barlow-Schriften).
- ClawdDotNet.App: Fachlogik aus den Avalonia-ViewModels in Dienste herausgeloest (AgentAdministration, JobAdministration, ServiceAdministration, RunCoordinator) und ueber InstanceChange synchronisiert.
- Tests: ClawdDotNet.Web.Tests und ClawdDotNet.App.Tests hinzugefuegt, alle 684 Tests erfolgreich.
Der Stand lag ueber eine Bestandsaufnahme, drei Konzeptpapiere, vier
Umsetzungsplaene und zwei Deploymentcenter-Dokumente verteilt - jedes mit
eigener Reihenfolge, teils widersprueglich. Alle offenen Punkte daraus sind
in docs/Roadmap.md zusammengefuehrt.
Aufbau der neuen Roadmap
- Statusvokabular: erledigt / beschlossen-offen / Entscheidung noetig /
zurueckgestellt / Idee. Damit steht das Geparkte sichtbar drin, statt in
einem Konzeptpapier zu verschwinden.
- Herkunft-Spalte traegt das alte Kuerzel (S4, K2, B9, T4, F-A1, C1, DC1),
damit die archivierten Papiere auffindbar bleiben, ohne sie zu lesen.
- Abschnitt 1 Reihenfolge, 2 offene Entscheidungen, 3 die Vorhaben nach
Bereich, 4 Ideenspeicher, 5 Chronik des Erledigten, 6 Modell-Einstufung,
7 Herkunftskarte.
Was dabei sichtbar wurde
- Neun Entscheidungen blockieren Arbeit, ohne dass sie Aufwand kosten -
allen voran Matrix oder Rocket.Chat. Sie stehen jetzt gesammelt in
Abschnitt 2 statt verstreut in den Diskussionsteilen der Konzepte.
- B8 (keine Tiefenbegrenzung bei AgentComm) ist unveraendert offen. Das ist
keine Theorie: A haelt sein Gate, waehrend es auf B wartet - ruft B nun A,
warten beide bis zum Timeout. Der Testfall A13 dafuer fehlt bis heute.
- Die vier Umsetzungsplaene vom 2026-08-05 sind alle unumgesetzt und waren
in keiner Roadmap verzeichnet.
Archiv
Sechs Dokumente ziehen nach docs/archiv/: Bestandsaufnahme, Konzepte
Backup/Finanz/Analyse, Linux-Portierung-Analyse, Lizenz-HardwareId-v2
(gegenstandslos - LicenseLabrador ist ersetzt), Deploymentcenter-Review und
der 2.4-Integrationsplan. Sie bleiben als Begruendung lesbar, werden aber
nicht mehr fortgeschrieben; das README ordnet jedes einzeln ein und warnt,
dass ihre Quelltext-Verweise ins Leere gehen koennen.
Bauplan bleibt Bauplan
Taskboard, Audit, Staging, Memory, Agentenkommunikation, RocketChat und
Deploymentcenter-Integration bleiben in docs/ - sie sind die Detailvorgabe
fuer die Umsetzung, nicht Vorhabenlisten. Jedes bekommt oben eine Zeile,
die seine Rolle und den Umsetzungsstand nennt und auf die Roadmap zeigt.
Dasselbe fuer die vier Umsetzungsplaene: die Reihenfolge gilt in der
Roadmap, nicht im Plan.
Nebenbei repariert: Taskboard-Konzept und Teststrategie verwiesen auf
AgentScheduler und ToolJobScheduler, die seit der Scanner-Konsolidierung
geloescht sind. Alle Dokument-Verweise in docs/ sind geprueft.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Die Avalonia-Portierung ist abgeschlossen, damit ist die in ClawdDotNet.slnx
angekuendigte Aufgabe "WinForms-Oberflaeche entfernen" faellig. Der Stand
davor liegt unter dem Tag vor-fruehjahrsputz-2026-08.
Entfernt (56 Dateien, seit dem Herausloesen der Anwendungsschicht nicht mehr
Teil des Builds): ClawdDotNet.csproj, Program.cs, sieben frm_*-Formulare,
UI/, Models/, EmbeddedUI/, Properties/, Resources/, Services/, das alte
Anwendungssymbol und Deploy-Build.ps1 (ersetzt durch deploy/publish.py).
Dazu configs/*.json - Beispielkonfigurationen aus der Zeit vor dem
Instanzverzeichnis, auf die nur noch die alten Prompts verwiesen.
Die vier Entwicklungs-Prompts der Anfangszeit ziehen nach docs/archiv/ um,
mit README, das ihren Stand einordnet. Eine Regel darin gilt weiter - die
Pflichtfelder fetchedAt/dataAsOf/source der Internet-Tools -, deshalb
Archiv statt Loeschen; der WebSearch-Plan verweist auf den neuen Pfad.
Toter Code
- PlaceholderPageViewModel samt Ansicht: Es gibt keinen Platzhalter-Bereich
mehr, seit alle neun Seiten portiert sind.
- Snappier als direkter Paketverweis: MongoDB.Driver loest es ohnehin auf
dieselbe Fassung auf, der Verweis hob nichts an.
Zwei Fehler, die dabei sichtbar wurden
- Die taegliche Sicherung lief ins Leere. Die Oberflaeche bot sie an und
schrieb Uhrzeit, Zielordner und Anzahl in die Einstellungen, aber der
BackupScheduler wurde nirgends erzeugt. Jetzt am AppHost verdrahtet und
in den geordneten Abbau aufgenommen.
- SettingsPageViewModel hielt die vier Sicherungs-Einstellungen doppelt.
Aus der Ansicht waren sie laengst verschwunden, gelesen und beim
Speichern zurueckgeschrieben wurden sie weiter: Wer die Uhrzeit auf der
Sicherungs-Seite aenderte und danach die Einstellungen speicherte, bekam
den alten Wert zurueck.
Pakete: keine bekannten Sicherheitsluecken mehr
- SQLitePCLRaw.bundle_e_sqlite3 auf 2.1.13 angehoben. Microsoft.Data.Sqlite
bringt 2.1.11 mit, darin steckt GHSA-2m69-gcr7-jv3q (NU1903, hoch).
- SharpCompress bleibt als direkter Verweis stehen. Beim Aufraeumen erst
als ungenutzt entfernt - dabei kam die von MongoDB.Driver gezogene
Fassung 0.30.1 mit GHSA-6c8g-7p36-r338 zurueck. Der Verweis ist eine
Anhebung, kein Ballast; das steht jetzt als Kommentar dabei.
Dokumentation
- Roadmap mit Statusblock: A1 und A3 erledigt, A2 nur zur Haelfte - Gate,
Policy und Dienst greifen, aber keine Ansicht ruft ApproveAsync auf, ein
gestagter Aufruf liegt unbeantwortet. Das ist jetzt Punkt 1 der Reihung.
Rocket.Chat steht und kollidiert mit A5 (Matrix) - Entscheidung faellig.
- Avalonia-Portierungsleitfaden -> Oberflaechen-Leitfaden: kein Auftrag mehr,
sondern Beschreibung des Stands.
- Bestandsaufnahme und Linux-Analyse als datierte Befunde gekennzeichnet;
der teure Teil der Linux-Analyse (8.900 Zeilen WinForms) ist hinfaellig.
- Verweise auf frm_*, WebView2 und ClawdDotNet.csproj in den lebenden
Dokumenten richtiggestellt.
Build fehlerfrei, 585 Tests gruen (6 uebersprungen).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>