Commit Graph
5 Commits
Author SHA1 Message Date
RichardandClaude Opus 5 99f8a89fd0 Schluesselbund: ein Hauptschluessel, mehrfach verpackt (#190)
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>
2026-09-10 15:34:16 +02:00
RichardandClaude Opus 5 cffd6f4b77 Bugtracker-Durchgang: 13 Bugs behoben, Build ohne Warnungen
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>
2026-09-03 19:04:48 +02:00
RichardandClaude Opus 5 33d95a6c3f UI-Entwurf umgesetzt, Rocket.Chat-Tool, Deploymentcenter 2.4
Sicherungspunkt vor dem Aufraeumen. Buendelt die Arbeit, die seit dem
Abschluss der Avalonia-Portierung im Arbeitsverzeichnis lag.

Oberflaeche
- Entwurf aus Mockup/ umgesetzt: Theme.axaml (Farben je Thema, Barlow als
  mitgelieferte Schrift), Icons.axaml (Symbolgeometrien), Shell.axaml
  (eigene ControlThemes statt Fluent umzufaerben).
- Neue Steuerelemente StrokeIcon und BlueprintFrame, Seiten fuer
  Token-Verbrauch und Agenten-Chats, Werkzeug-Einstellungen als Seite
  statt eigenem Fenster, Texteditor-Fenster.
- ThemeManager mit hellem und dunklem Thema; die beiden Pinsel-Konverter
  entfallen, weil ein fester Farbwert den Themenwechsel nicht ueberlebt.

Rocket.Chat
- Neues Tool-Projekt (Client, Konfiguration, Workspace-Dateien) nach der
  Bauform des Telegram-Tools: rocketchat_poll als Tool-Job, geweckt wird
  nur, wenn wirklich etwas anliegt.
- send_file ist freigabepflichtig, send_message bewusst nicht: Der Raum
  ist Arbeitsraum, der Schutz sitzt an der Raum-Allowlist.
- Konzept-Doc um die Messung gegen die echte Instanz 8.7 ergaenzt; drei
  Annahmen waren falsch und sind korrigiert.

Deploymentcenter
- DC6 (Update anwenden) und DC7 (Erstinstallation ueber setup.json)
  erledigt, DC3 fuer win-x64/dev; deploy/publish.py als Release-Strecke.
- AppHost.DisposeAsync gegen doppeltes Herunterfahren gesperrt - sonst
  ueberschreibt eine zweite Abmeldung den Wartungszustand am Watchdog.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 12:16:05 +02:00
Richard b5bf97ae74 feat(ui): complete Avalonia UI port with 7 main pages, tool settings & top MenuBar 2026-08-10 10:48:34 +02:00
RichardandClaude Opus 4.8 8604fa30c7 S7: Zugangsdaten in Konfigurationsdateien verschluesseln
OpenRouter-Schluessel, Datenbank-Verbindungszeichenfolgen samt Passwort,
Mail-Zugangsdaten und das Telegram-2FA-Passwort lagen im Klartext in
AgentSettings.json und InstanceSettings.json. Wer die Dateien lesen konnte — ein
Backup, eine Dateifreigabe, ein versehentlicher Commit — hatte alle Zugaenge.

SecretProtector nutzt DPAPI im Benutzerkontext: Die Werte lassen sich nur vom
selben Windows-Benutzer auf demselben Rechner lesen. Das schuetzt gegen
Weitergabe der Datei, nicht gegen einen Angreifer, der bereits als dieser
Benutzer laeuft — fuer einen lokal laufenden Dienst die angemessene Stufe.

Verschluesselte Werte tragen ein Praefix. Dadurch bleibt Klartext aus bestehenden
Konfigurationen lesbar und wird beim naechsten Speichern automatisch uebernommen;
vorhandene Installationen laufen ohne Zutun weiter.

Ein Wert, der sich nicht entschluesseln laesst — etwa nach Benutzer- oder
Rechnerwechsel — wird gemeldet statt stillschweigend als Klartext
durchgereicht. Sonst ginge ein unbrauchbarer Schluessel an die API und der
Fehler waere schwer zuzuordnen.

ConfigSecrets entscheidet anhand der Feldnamen, welche Werte betroffen sind. Das
ist noetig, weil die Tool-Konfiguration ein freies Woerterbuch ist. Beim Speichern
werden die Werte nur fuer den Schreibvorgang verschluesselt und danach wieder
entschluesselt, damit die laufende Instanz weiterarbeiten kann.

309 Tests gruen (161 Core, 148 Tools).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-28 10:21:08 +02:00