feat(ui): complete Avalonia UI port with 7 main pages, tool settings & top MenuBar
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
# Audit-Log & Receipts — Nachvollziehbarkeit
|
||||
|
||||
Setzt A3 aus der [Roadmap](Roadmap.md) um (F-A2). Zwei zusammengehörige Dinge:
|
||||
|
||||
- **Audit-Log** — ein Eintrag je Tool-Aufruf: wer, wann, welches Tool, mit welchem
|
||||
Ausgang.
|
||||
- **Receipts** — ein Abschluss-Beleg je Lauf: Ergebnis, Schritte, Tokens, Kosten,
|
||||
verknüpft mit dem Task.
|
||||
|
||||
A3 ist das Fundament für A2 (jede Staging-Entscheidung wird als Datensatz verankert)
|
||||
und für C7 („Kosten pro Ergebnis", fällt aus den Receipts ab). Die Tool-Fehlerquote aus
|
||||
der Leistungsanalyse liest sich direkt aus dem Log.
|
||||
|
||||
## Warum eigene Tabellen, nicht der State-Store
|
||||
|
||||
Dieselbe Überlegung wie bei Gedächtnis und Taskboard: `IStateStore` ist Schlüssel-Wert.
|
||||
Ein Log, das man nach Lauf, Task oder Tool filtern und dessen Fehlerquote man auswerten
|
||||
will, braucht typisierte Spalten. Zwei Tabellen auf dem vorhandenen
|
||||
[`SqliteStorage`](../src/ClawdDotNet.Core/Storage/SqliteStorage.cs): `AuditLog` und
|
||||
`RunReceipts`.
|
||||
|
||||
## Provenienz — von der Engine gestempelt, nie vom Agenten behauptet
|
||||
|
||||
Die entscheidende Regel (aus dem OpenAlice-Provenance-Konzept):
|
||||
|
||||
- **Herkunft stempelt die Engine.** `AgentId`, `Model` und `Source` kommen aus dem
|
||||
Wissen der Engine über den Lauf, nicht aus dem Tool-Ergebnis. Ein Tool kann seine
|
||||
Herkunft nicht fälschen, weil es sie gar nicht schreibt.
|
||||
- **Einträge sind unveränderlich.** Das Repository hat kein Update und kein Delete —
|
||||
eine Korrektur ist ein neuer Eintrag. Das ist die eigentliche Zusage, keine fehlende
|
||||
Funktion.
|
||||
- **Unbekanntes wird als unbekannt markiert, nicht geraten.** Fehlt die Quelle, steht
|
||||
`unknown`, nicht ein plausibel geratener Kanal.
|
||||
- **Worker-Typ und Session sind getrennt.** `Model` (das ausführende Modell) und
|
||||
`Source` (die verantwortliche Session: `webview`, `telegram`, `task`, `agentcomm`,
|
||||
`job`, `direct`) sind verschiedene Begriffe und stehen in eigenen Spalten.
|
||||
|
||||
## Audit-Log
|
||||
|
||||
Gestempelt an genau einer Stelle: `AgentEngine.ExecuteToolCallAsync` — dort, wo jeder
|
||||
Tool-Aufruf durchläuft. Je Aufruf ein Eintrag mit Ausgang:
|
||||
|
||||
| Status | Wann |
|
||||
|---|---|
|
||||
| `Ok` | Tool lief und lieferte ein Ergebnis |
|
||||
| `Error` | Tool meldete einen Fehler oder warf |
|
||||
| `Denied` | das `PermissionGate` hat abgelehnt |
|
||||
| `NotFound` | Tool dem Agenten nicht zugewiesen/unbekannt |
|
||||
|
||||
Ein Abbruch (Cancellation) wird **nicht** protokolliert — der Aufruf kam nicht zum
|
||||
Abschluss. Die Argumente werden roh, aber gekappt abgelegt (4 000 Zeichen); die
|
||||
Ausgangsnotiz kurz (500).
|
||||
|
||||
**Best effort:** Ein Fehler beim Schreiben des Audits darf den Lauf nie scheitern
|
||||
lassen — dieselbe Linie wie bei der Verbrauchserfassung. Der Eintrag wird geschrieben,
|
||||
nachdem die eigentliche Arbeit getan ist.
|
||||
|
||||
## Receipts
|
||||
|
||||
Je Lauf ein Beleg, geschrieben beim Abschluss von `RunAsync`/`ChatAsync` (neben der
|
||||
vorhandenen `RunUsage`-Erfassung). Er trägt Status, Schritte, Prompt-/Completion-/
|
||||
Cached-Tokens, geschätzte Kosten (aus dem `ModelPricingCatalog`, mit
|
||||
`CostIsKnown`-Flag) und einen kurzen Ergebnis-Verweis.
|
||||
|
||||
**Verknüpfung `RunUsage` ↔ Task:** Der Receipt trägt die `TaskId`, wenn der Lauf aus dem
|
||||
Taskboard kam — der `EngineTaskDispatcher` reicht sie (samt `source: task`) durch. Damit
|
||||
ist „Kosten pro Ergebnis" (C7) ein Abfallprodukt: `ListReceiptsForTaskAsync` liefert
|
||||
alle Belege zu einem Task.
|
||||
|
||||
## RunId — die Klammer
|
||||
|
||||
Jeder Lauf bekommt zu Beginn eine `RunId` (GUID). Alle Audit-Einträge **und** der
|
||||
Receipt eines Laufs tragen sie. So lässt sich ein Lauf lückenlos rekonstruieren:
|
||||
`ListForRunAsync(runId)` gibt die Aufrufe in Reihenfolge, `GetReceiptForRunAsync(runId)`
|
||||
den Abschluss.
|
||||
|
||||
## Verdrahtung
|
||||
|
||||
`IAuditRepository` ist optional (wie Gedächtnis und Taskboard): ohne Repo läuft die
|
||||
Engine unverändert. In `Program.cs` wird ein `SqliteAuditRepository` auf der Instanz-DB
|
||||
erzeugt und der Engine übergeben.
|
||||
|
||||
## Offen
|
||||
|
||||
- **Output-Scrubbing** — die `Arguments` können Secrets enthalten. Das zentrale
|
||||
Maskieren bekannter Secret-Werte (eigener beschlossener Roadmap-Punkt) greift, sobald
|
||||
es steht; der Andockpunkt (`ExecuteToolCallAsync`) ist derselbe.
|
||||
- **Review-Oberfläche** — die Anzeige/Durchsicht des Logs und der Receipts gehört zu A2
|
||||
(Staging-Review im Hauptfenster); die Abfragemethoden dafür stehen bereit.
|
||||
- **Export** — ein JSONL-Export des Logs wäre für externe Auswertung nützlich (später,
|
||||
passt zum A6-Spiegel).
|
||||
Reference in New Issue
Block a user