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 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>
Eine einmalige Aufgabe mit fill_by (spaetestens bis) statt Termin laeuft,
wenn der Tag Budget uebrig laesst: nach regulaerer und nachgeholter Arbeit,
nur wenn nichts vom Agenten wartet, bevorzugt ab 18 Uhr, und nur wenn ihre
eigene Schaetzung in den Spielraum aus #716 passt. Kurz vor der Frist wird
einmal ein Mensch gefragt; nach der Frist laeuft sie als regulaere Arbeit.
Ehrliche Schaetzung (TaskCostEstimator): eigene Laeufe, dann Geschwister
unter derselben Elternaufgabe, dann die Angabe des Autors (als Schaetzung
gekennzeichnet), zuletzt das Mittel des Agenten.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Cases/Decisions in der Instanz-DB; CaseDesk fuehrt die Regeln, der Brett-Task traegt
den Vorgang zum jeweiligen Halter
- Eskalation nur nach oben, eine Ebene je Schritt; die Leitung entscheidet (mit Begruendung,
bindet ihren Bereich), erledigt selbst oder reicht mit Einschaetzung weiter
- Erst nachsehen: bindende Beschluesse werden vor dem Eskalieren gezeigt; dieselbe Frage
aus derselben Einheit schliesst sich dem offenen Vorgang an
- Tagesdeckel je Einheit; nach der Frist wird ein Mensch gerufen (Anschluss fuer #644)
- Konflikt: zuerst die Gegenseite, dann Zustellung an die niedrigste gemeinsame Leitung;
Ebenen dazwischen vermerkt, nicht befragt
- Fremdinhalt-Stufe (#715): Eskalation ohne eigenen Text, kein Konflikt mit Position
- Jede Ebene haengt an (#697), beim Halter gerahmt als Daten
- Escalation ist ein implizites Werkzeug jedes Agenten; Briefing nennt den Weg
- Scanner behaelt einen im Lauf gesetzten Status blockiert/abgebrochen
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>
- TaskTreeWatch findet offene Aufgaben, deren ganzer Teilbaum zur Ruhe
gekommen ist: nichts laeuft, nichts wird gleich gestartet (eine todo an
einen Menschen bewegt sich nicht von selbst). Nur der oberste ruhende Baum
zaehlt. Rein und ohne Instanz pruefbar.
- Erkennen ist Code, Deuten ist Modell: Die Leitung der Einheit, zu der der
Baum gehoert (sonst die darueber, sonst ein Mensch), bekommt eine
Pruefaufgabe mit dem Baum und den typischen Fehlhalten. Sie darf Arbeit
zurueckgeben, nicht selbst nachbessern.
- Einmal je Ruhezustand: Ein Fingerabdruck des Baums im StateStore. Wer den
Stillstand hinnimmt, wird nicht erneut gefragt; erst wenn sich der Baum
bewegt hat und wieder ruht. Die Pruefaufgabe steht neben dem Baum, nicht
darin.
- Der Scanner ruft die Pruefung je Takt, sie schaut alle 30 Minuten.
Erster Baustein von #646 (Erkennen); die uebrigen Muster dort folgen.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- TaskItem.ParentId, in der Datei als parent, in der DB als ParentId. Die
Elternaufgabe ist der Zweck ("wofuer"), blocked_by die Voraussetzung
("wann").
- GoalChain: Eltern bis zu acht Stufen, Zyklen brechen den Gang ab und
werden beim Setzen abgelehnt. Oben steht das Ziel der Einheit - der
obersten Aufgabe, die zu einer Einheit gehoert (ein Ziel, das ein Mensch
auf der obersten Ebene setzt, gehoert keiner), sonst der naechsten Einheit
darueber mit Ziel.
- Der Lauf einer Aufgabe bekommt den Absatz "Why this task exists" und die
Bitte, zu melden, wenn die Aufgabe ihrem Zweck nicht mehr dient.
- Taskboard-Tool: parent bei task_create/task_update, geprueft auf Existenz,
Sichtbarkeit (#684) und Zyklen; task_list zeigt "Serves".
- WebUI: Feld im Aufgabendialog, Anzeige auf der Karte; die Verwaltung
prueft wie das Tool.
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>
- TaskSchedule.OccurrenceTimesBetween liefert die Zeitpunkte der restlichen
Laeufe; OccurrencesBetween zaehlt sie nur noch.
- BudgetHeadroom implementiert IBudgetOutlook: Die restlichen geplanten Laeufe
des Tages werden in zeitlicher Reihenfolge durchgegangen, je Agent mit
Grenze und fuer die Instanz, bis zum ersten Lauf, der das Budget verbraucht
vorfaende. Das spiegelt die Pruefung beim Start eines Laufs. Spaetwerk
zaehlt nicht mit, es laeuft ohnehin nur im Spielraum.
- Der Scanner schaut alle 30 Minuten voraus und nennt je Agent und Tag einmal,
wann das Budget ausgeht und wie viele der geplanten Laeufe dann ausfallen,
solange noch Zeit ist, nachzulegen oder zu entscheiden, was wartet.
Die Meldung steht vorerst im Protokoll (Warnung). Der Weg zum Menschen ueber
einen Kanal gehoert zu #646, die Anzeige ins Lagebild (#711).
Tests: 4 neu fuer die Vorschau. 1.261 gruen.
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>
Bisher teilte sich eine Budgetablehnung den Ausgang NichtGelaufen mit dem
Herunterfahren. Einmalige Aufgaben wurden den Rest des Tages alle 30 Minuten
erneut abgelehnt (jedes Mal ein Beleg) und liefen nach Mitternacht still zu
Lasten des neuen Tages. Wiederkehrende verfielen still.
- TaskLauf.KeinBudget als eigener Ausgang; der Dispatcher bildet
BudgetExceeded darauf ab.
- Vier Felder an der Aufgabe: BudgetMissCount, LastBudgetMissAt,
DeferredUntil, CatchUpPending (Spalten werden fuer bestehende Datenbanken
nachgeruestet).
- Einmalige Aufgaben werden mitgenommen: Der Termin bleibt erhalten, faellig
ist die Aufgabe wieder ab der naechsten lokalen Mitternacht, nicht vorher.
- Wiederkehrende Aufgaben folgen der Regel des Agenten
(budget.whenExhausted): expire vermerkt den Ausfall und laesst den Termin
verfallen; catchUpOnce fasst alle verpassten Termine zu einem Nachholauf am
naechsten Tag zusammen. Ein regulaer faelliger Termin deckt das Nachholen
mit ab, es bleibt bei einem Lauf.
- Der neue Tag hat Vorfahrt: Mitgenommenes und Nachholaeufe kommen nach allem
regulaer Faelligen, unabhaengig von der Prioritaet.
- Beim ersten Takt eines neuen Tages eine Zusammenfassung je Agent im Log.
- Sichtbar: Die Aufgabenkarte der WebUI zeigt Ausfaelle, Mitnahme und
Nachholen; die Regel ist im Desktop je Agent einstellbar. Nebenbei sind
"Next:"/"Last:" auf der Karte ins Sprachpaket gewandert.
Stufen 2 bis 4 (Reservierung, Spielraum statt pauschalem Anteil, Vorbeugen)
folgen.
Tests: BudgetMissTests (9 neu). 1.238 gruen.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Drei Fehler im Taktgeber des Taskboards, zwei gemeldet, einer beim Bau gefunden:
1. Unbegrenzte Parallelitaet. Jede faellige Aufgabe startete sofort. Bei
Cron-Terminen auf runden Zeiten hiess das: alle Agenten gleichzeitig, und
alle Laeufe passierten die Budgetpruefung gemeinsam, weil sie je Lauf vor
dem Start laeuft. Neu: maxParallelTaskRuns je Instanz (Vorgabe 4). Der Rest
wartet, sortiert nach Prioritaet und dann nach Faelligkeit.
2. Stille Kappung. Die Kandidaten kamen ueber ListAsync mit Limit 500; darueber
fielen Termine lautlos aus dem Takt. Neu: ListRunnableAsync liefert alle
Aufgaben auf todo, ungekappt. Muessen Aufgaben warten, steht das im Log,
allerdings nur, wenn sich die Zahl aendert.
3. Der Takt wartete auf jeden Lauf, den er startete. Ein zehnminuetiger Lauf
hielt damit jeden anderen Termin zehn Minuten an, und mit einem Deckel
haetten die freien Plaetze leer gestanden. Neu: Die Schleife startet und
wartet nicht; DisposeAsync wartet stattdessen auf die laufenden Laeufe.
Beansprucht wird nur, was sofort starten kann. Alles andere bleibt auf todo,
sonst liefe beim Warten der Lease ab und die Aufgabe wuerde ein zweites Mal
beansprucht. Ein Cron-Termin geht dadurch nicht verloren, weil DueOccurrence
bis zum letzten Lauf zuruecksucht. Ein von Hand gestarteter Lauf wartet auf
keinen Platz, belegt aber einen.
Bleibt offen: Bis zu maxParallelTaskRuns Laeufe koennen die Budgetpruefung
weiterhin gemeinsam passieren. Die Luecke ist damit begrenzt, aber nicht
geschlossen; dafuer braeuchte es eine Reservierung vor dem Lauf.
Tests: ScannerCapacityTests (9 neu). 1.229 gruen.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Umbau durch Gemini Flash, Durchsicht und Nacharbeit durch Claude.
Umfang:
- Desktop: LocalizationManager (JSON-Pakete, Rueckfall auf Englisch,
Umschalten zur Laufzeit), Localize-Markup-Erweiterung, Sprachwahl in den
Einstellungen (AppSettings.Language, Vorgabe "en"); 317 Schluessel je Sprache
- WebUI: alle Ansichten auf t()/data-i18n, 656 Schluessel je Sprache
- Agenten-Werkzeuge: Beschreibungen, Schemata und Meldungen auf Englisch
- Tests an die englischen Meldungen angepasst, keine Pruefung abgeschwaecht
Nacharbeit bei der Durchsicht:
- ~25 Kommentarbloecke mit Begruendungen waren ersatzlos entfallen, darunter
sicherheitsrelevante (NTFS-Datenstrom beim shared:-Praefix, Bremse gegen
Agentenschleifen, doppelter POST beim Anlegen einer Instanz). Wieder
eingesetzt: auf Englisch, wo die Datei umgestellt ist, sonst im Wortlaut.
- Drei WebUI-Schluessel fehlten (logs.paused, instances.instanceOfflineError,
instances.noInstanceActiveError). Weil t() bei fehlendem Schluessel den
Schluessel selbst liefert, griff der "|| err.message"-Rueckfall nie — die
Oberflaeche haette den Schluesselnamen angezeigt.
Geprueft: Schluesselgleichheit en/de, Platzhalter je Schluessel, jeder im
Code benutzte Schluessel vorhanden, node --check fuer alle Module,
1.220 Tests gruen.
Co-Authored-By: Claude Opus 5.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>
#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>
Der Nachrichten-Digest im Dauerbetrieb der Test-VM lief nie: CronExpression
verstand 'von-bis/schritt' nicht, TaskSchedule verschluckte den Fehler.
Version 0.1.5.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- #578: Abgebrochene Laeufe (Schrittgrenze, Zeitueberschreitung, Abbruch,
Ausnahme) tragen ihre bezahlten Token - vorher 0 in RunUsage, fuer das
Budget unsichtbar.
- #580: WebFetch prueft die aufgeloeste Zieladresse beim Verbinden; ein
erlaubter Name, der auf 127.0.0.1 aufloest, wird gesperrt.
- #575: Dateien entstehen unter Unix mit 0600 (AtomicFile, Protokolle,
FileRW-Anhaengen, state.db), Protokollverzeichnisse mit 0700.
- #576: SIGTERM/SIGINT beenden auch mit Fenster geordnet.
- #593: OpenRouter-Statusdienst wird gestartet.
- #589: Auftragsnachricht nennt aktuelle Zeit, Zeitzone und Termin.
- #581: Unvollstaendiges Argument-JSON erreicht das Werkzeug nicht mehr;
das Modell bekommt eine verstaendliche Rueckmeldung statt Parsertext.
- #591: Weboberflaeche liest die Felder, die API und Ereignisstrom liefern
(Freigaben, Protokoll, Taskboard mit Termin, Werkzeug-Einstellungen,
Tokennutzung); Ereignisstrom in camelCase.
- #592: Chat zeigt Nachrichten nicht mehr doppelt.
- #536 (teilweise): A2A-Antworten tragen Absender und Empfaenger, Parser
wirft nicht mehr; Datums- und Volltextfilter in Agenten-Chats.
- deploy/publish.py: Packager-Pfad net10.0, Schalter --agent-file.
- Version 0.1.4.
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>
Alle Behebungen auf der Linux-Test-VM gegengeprueft (Ubuntu, .NET 10.0.111):
Build 0 Warnungen / 0 Fehler, 637 Tests gruen, 1 uebersprungen (WindowsFact).
Sicherheit und Zielplattform
#373 PathBoundary.Canonicalize fiel offen aus. File.ResolveLinkTarget wirft
fuer einen fehlenden Abschnitt FileNotFoundException; der catch(IOException)
verliess daraufhin die GANZE Aufloesung mit dem unaufgeloesten Pfad - und
der besteht jede Praefixpruefung. Der Symlink-Schutz war damit bei jedem
Schreibvorgang wirkungslos. Jetzt ueber FileSystemInfo.LinkTarget, und
TryCanonicalize meldet "nicht bestimmbar", statt fail-open durchzureichen.
#374 WorkspacePath weist den Backslash rundheraus ab, wie den Doppelpunkt.
Eine Schreibweise statt einer Sonderregel je Windows-Form.
#375 Log-Verzeichnis: leer heisst "Anwendungseinstellung"; ein relativer Wert
zaehlt gegen das Instanzverzeichnis, nicht gegen das Arbeitsverzeichnis
des Prozesses. Ein systemd-Dienst landet nicht mehr auf /Logs.
Agentenkommunikation
#206 Delegationskette gegen A->B->A (Test A13). Zyklusfrei per Bauart, dazu
MaxDelegationDepth gegen die Staffel, die niemand beauftragt hat.
#461 Zwei unabhaengige Ketten ueber Kreuz - beim Beheben von #206 gefunden und
reproduziert. Ein delegierter Lauf wartet nur noch begrenzt auf ein fremdes
Gate; ein Chat vom Menschen reiht sich weiter unbegrenzt ein.
#234 Instanz-Id wird durchgereicht statt aus einem nur beilaeufig gesetzten Feld
gelesen.
Betrieb und Oberflaeche
#376 Log-Ansicht chronologisch statt gruppiert je Moduldatei, mit Stacktraces
an ihrer Meldung - auch ueber Taktgrenzen hinweg.
#377 Info-Tabelle: feste Spaltenbreiten, damit ein langer Aenderungstext den
anderen Spalten nicht den Platz nimmt.
#378 Sicherung: Mindestabstand zwischen Ueberschrift und Schaltflaechenleiste.
#379 Hellmodus: drei von vier gedaempften Textpinseln lagen unter 4,5:1. Die
helle Palette ist als Ganzes verschoben, damit die Staffelung sichtbar
bleibt statt auf einen Wert zusammenzufallen.
Hygiene
#233 stock_add: der Indexstand wird innerhalb der Sperre festgehalten.
#235 Zeitumstellung: eine nicht existierende Ortszeit wird auf den ersten
Zeitpunkt nach der Luecke verschoben statt uebersprungen (R4, R5).
#236 45 Nullable-Warnungen und eine CA1416 - nicht unterdrueckt, sondern die
Stellen so umgebaut, dass die Zusage nachvollziehbar wird. Mail meldet
jetzt, WELCHER Zugangsschluessel fehlt, statt an einer
KeyNotFoundException zu scheitern.
#203 Kompaktiert wird vor dem API-Aufruf statt danach; die gemessenen
Prompt-Groessen kalibrieren die Schaetzung je Modell.
Neu: tests/ClawdDotNet.App.Tests - fuer #375 und #376 gab es keinen Ort fuer
Tests. Dazu Regressionstests fuer jede Behebung; jeder wurde gegen den alten
Stand geprueft, damit belegt ist, dass er den Fehler faengt.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>