9 Commits
Author SHA1 Message Date
RichardandClaude Opus 5.5 77062facc9 Stufe 4c (#764): Bezeichner auf Englisch - Typen, Methoden, Felder, Parameter, Locals, Testnamen
Mit Roslyn umbenannt (Verweise folgen, Zeichenketten bleiben unberuehrt).
Nicht umbenannt, weil gespeichert oder ueber die API gebunden (Stufe 4e):
Properties, Record-Parameter, Enum-Member sowie die Parameter der
Endpunkt-Handler (Routen-/Query-Bindung ueber den Namen). Die JSON-Felder
anonymer Objekte bleiben ausdruecklich benannt (JsonFilter: pfad).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 13:18:43 +02:00
RichardandClaude Opus 5.5 837a634a22 Stufe 4c (#764): Kommentare in C#, WebUI-Skripten, CSS und HTML auf Englisch
Rund 2.600 Kommentarblöcke in 310 C#-Dateien übersetzt, Begründungen vollständig
erhalten: blockweise gleiche Anzahl wie vorher, kein Block unter 60 % seiner
Länge, der Code außerhalb der Kommentare per Tokenizer byte-identisch geprüft.
Zitate deutscher Oberflächentexte und Testdaten bleiben deutsch.

WebUI: Kommentare in JS/CSS/HTML übersetzt, JSDoc-@param an die in 4b
umbenannten Parameter angeglichen.

Dabei behoben:
- 4b hatte "tag" (HTML-Tag) als deutsches "Tag" gelesen und zu "dayValue"
  gemacht (makeElement, svg, Tagesübersicht) - zurück auf tag/day.
- Aufgaben "InProgress" bekamen die Plakettenart "laufend", für die es nie eine
  CSS-Klasse gab - jetzt "success" wie laufende Instanzen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 12:45:03 +02:00
RichardandClaude Opus 5.5 6d81693041 Stufe 3 (#764): Avalonia-Fenster entfernt
- Views, ViewModels, Controls, Converters, Styles, Services, Desktop-i18n,
  Schriften und App.axaml raus; Avalonia- und Mvvm-Pakete raus
- ClawdDotNet ohne Schalter: Manager starten (unter systemd ueber den Dienst,
  nie doppelt) und WebUI oeffnen (LauncherRun) - bis die Huelle kommt
- Instanzen laufen immer kopflos; instanceWindows wird gelesen, nicht mehr
  ausgewertet; die Kette 'Fenster nach vorn holen' ist entfernt
- Telegram-Anmeldung nur noch ueber die WebUI (tote Dialog-Rueckrufe raus)
- systemd-Vorlagen im Linux-Paket; Oberflaechen-Leitfaden ins Archiv

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 20:23:12 +02:00
RichardandClaude Opus 5.5 753d633cf3 Linux-Wackeltests: Instanz endet erst auf die Stopp-Bitte, Lesetest schreibt bis genug gelesen ist (#722)
Drei Manager-Tests liessen den Prozess vor der Stopp-Bitte enden; unter Last
sah der Aufsichtstakt das zuerst und meldete Crashed statt Stopped. Die
FakeChannel bekommt OnStopRequest, die Tests beenden darin. Der Drain-Test
bekommt 20 s statt 2 s Luft. AtomicFile schreibt, bis der Leser 20 Blicke
hatte, statt fest 40 Mal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 11:50:51 +02:00
RichardandClaude Opus 5 dcffcdcff5 Instanzmanager: Weboberflaeche kennt Instanzen, geordnetes Ende, Puls (#528, #531)
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>
2026-09-10 11:15:59 +02:00
RichardandClaude Opus 5 7d4e8b3096 Autostart durch Manager, mit Sicherungsautomat (#528)
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>
2026-09-09 00:01:52 +02:00
RichardandClaude Opus 5 db7abf699f Instanzmanager Stufe 5: Wechseln heisst nach vorn holen (#528, E-M2)
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>
2026-09-08 23:39:50 +02:00
RichardandClaude Opus 5 72b0764d1a Instanzmanager: Register, Einstellungen und stellvertretende Meldung (#528)
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>
2026-09-08 22:45:22 +02:00
RichardandClaude Opus 5 4ef6d714a8 Instanzmanager Stufe 3: Prozessaufsicht, Start und Stopp (#528)
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>
2026-09-08 22:32:28 +02:00