feat(assistant): add approval inbox and e2e hardening

This commit is contained in:
2026-03-29 10:10:59 +02:00
parent 4f48afe7b4
commit beae1a5d6e
12 changed files with 2482 additions and 331 deletions
+52 -74
View File
@@ -63,7 +63,12 @@ Es gibt aktuell vier Permission-/Scope-Ebenen:
### Teilweise abgedeckt
- Timeline: nur indirekt ueber Navigation und Allokations-Basisabfragen
- Timeline/Disposition read-only:
- `get_timeline_entries_view`
- `get_timeline_holiday_overlays`
- `get_project_timeline_context`
- `preview_project_shift`
- basiert bereits auf denselben Timeline-Readmodels/Shift-Preview-Helfern wie die UI
- Estimates: nur Suche, Detail und Anlegen, aber kein voller Lifecycle
- Reports: `run_report` ist flexibel, deckt aber nicht die spezialisierten Report-/Analyse-Readmodels ab
- Audit/History: nur einfache History-Abfragen, keine volle Audit-API
@@ -82,78 +87,48 @@ Es gibt aktuell vier Permission-/Scope-Ebenen:
- Import/Export-Flows
- User Self-Service und Preferences
- Country- und Metro-City-Administration
- Volle Timeline-Readmodels und Timeline-Mutationen
- Timeline-Mutationen und Dispo-spezifische Write-Flows
- Voller Estimate-Lifecycle
- Dispo-/Import-spezifische Flows
## Kritische Inkonsistenzen und Risiken
### P0: Human-in-the-Loop nur im Prompt, nicht serverseitig erzwungen
Stand 2026-03-28: Die frueheren P0s bei Notification-Scoping, `list_users`, Mutation-Audit und reinen Permission-Texten sind behoben. Die folgenden Punkte bleiben relevant.
Der System Prompt fordert bestaetigte Freigabe vor jeder schreibenden Aktion. Technisch wird das aber nicht serverseitig erzwungen. Wenn das Modell direkt ein Mutation-Tool aufruft, wird es ausgefuehrt.
### P0: Human-in-the-Loop ist serverseitig persistiert, aber noch nicht als vollwertiger Approval-Workspace ausgebaut
Betroffene Stellen:
Der Assistant blockiert Mutation-Tools serverseitig, legt dafuer persistente `assistantApproval`-Eintraege pro Nutzer und `conversationId` an und fuehrt die Aktion erst nach expliziter Bestaetigung in derselben Konversation aus.
- `packages/api/src/router/assistant.ts`
- `packages/api/src/router/assistant-tools.ts`
Die aktuelle Chat-UI persistiert die `conversationId` bereits im Browser-Session-Kontext und rendert Approval-Karten im Verlauf. Damit ist der grundlegende End-to-End-Fluss zwischen Frontend und Backend konsistent.
Aktuell noch offen:
- keine eigene Approval-Inbox / Uebersicht fuer mehrere offene Freigaben
- keine dedizierte Verwaltungs-UI ausserhalb des Chatverlaufs
- Timeout-/Ablauf-Handling ist funktional vorhanden, aber noch nicht als eigenstaendige Nutzerfuehrung sichtbar
Konsequenz:
- Die wichtigste Governance-Regel ist aktuell nur Prompt-Disziplin, keine technische Policy.
- Die zentrale Governance-Regel ist nicht mehr nur Prompt-Disziplin, sondern serverseitig gebunden.
- Fuer komplexe Mehrschritt-Workflows waere eine explizite Approval-Oberflaeche trotzdem robuster als reine Chat-Karten.
### P0: Notification-Scoping im Assistant ist fachlich/sicherheitsseitig falsch
### P1: Rechte-Paritaet zur Gesamt-App ist noch nicht vollstaendig
Die dedizierte `notificationRouter` scoped strikt auf den aktuellen Nutzer. Die Assistant-Tools tun das in `list_notifications` und `mark_notification_read` nicht.
Assistant-Verhalten:
- `list_notifications` listet Notifications ohne `userId`-Filter.
- `mark_notification_read` markiert per ID ohne Ownership-Check.
Die groben Tool-Guards sind deutlich konsistenter, aber der Assistant nutzt weiterhin in vielen Faellen eigene Queries statt die Readmodels der Fachrouter.
Konsequenz:
- Der Assistant kann Informationen sehen oder veraendern, die der Nutzer in der normalen Notification-UI nicht sehen duerfte.
- Objekt-Sichtbarkeit und Detailtiefe koennen in Randfaellen noch von der UI abweichen.
- Besonders Timeline-, Admin- und Spezial-Readmodels brauchen weiterhin dedizierte Assistant-Pendants.
### P0: `list_users` ist als admin-only beschrieben, aber nicht effektiv admin-only
### P1: Fehlende tiefe Fach-Readmodels und Write-Paritaet bleiben die groesste funktionale Luecke
Der Tool-Text sagt "Requires admin permission", aber es gibt weder einen Eintrag in `TOOL_PERMISSION_MAP` noch einen `assertPermission(...)` im Executor.
Der Assistant kann viele Kernfaelle, aber noch nicht denselben Arbeitsmodus wie spezialisierte Oberflaechen.
Konsequenz:
- Jeder Nutzer mit Assistant-Zugriff kann potenziell die User-Liste lesen, obwohl die normale App dies ueber `userRouter.list` nur Admins gibt.
### P1: Permission-Beschreibungen und technische Guards sind nicht konsistent
Beispiele:
- `create_estimate`
- Beschreibung: "Requires manageEstimates permission"
- Technik: `TOOL_PERMISSION_MAP` und Executor verlangen `manageProjects`
- `create_org_unit` / `update_org_unit`
- Beschreibung: "Requires admin permission"
- Technik: `manageResources`
- `send_broadcast`
- Beschreibung: "Requires manager permission"
- Technik: `manageProjects`
Konsequenz:
- Der Assistant ist fuer Nutzer und fuer uns selbst schwer vorhersehbar.
- Ein sauberer Rechteabgleich "User kann X in UI, also Assistant auch" ist dadurch nicht belastbar.
### P1: Nicht alle Assistant-Mutationen sind als Mutation-Typ sauber nachverfolgbar
`MUTATION_TOOLS` dient dem Logging von AI-Mutationen. Nicht jede schreibende Aktion ist dort gleich gut abgebildet.
Beispiel:
- `mark_notification_read` aendert Daten, ist aber nicht in `MUTATION_TOOLS`.
Konsequenz:
- Luecken im AI-spezifischen Audit-Trail.
- Timeline-Readmodel-Paritaet ist jetzt fuer die wichtigsten read-only Faelle vorhanden, aber komplexe Write-, Audit-, Admin- und Estimate-Workflows bleiben teilweise unvollstaendig
- tiefe Erklaerungen fuer Herleitungen und Governance sind noch nicht auf UI-Niveau
## Was der Assistant heute noch nicht "weiss"
@@ -179,15 +154,18 @@ Fehlend:
### Timeline und Disposition
- Vollstaendiges Timeline-Readmodel:
- `getEntriesView`
- Projekt-/Demand-/Assignment-Kontext in derselben Struktur wie die UI
- Holiday-Overlays der Timeline
- Projektkontext fuer Drag/Shift/Panel-Interaktionen
- Timeline-spezifische Vorschau-/Validierungsdaten:
- `previewShift`
- genaue Konflikte, Kosten-Delta, Auswirkungen vor Commit
- Batch- und Inline-Operationen der Timeline:
Bereits vorhanden:
- `get_timeline_entries_view`
- `get_timeline_holiday_overlays`
- `get_project_timeline_context`
- `preview_project_shift`
- Reuse derselben Timeline-Readmodels und Shift-Preview-Helfer wie in `timelineRouter`
Noch fehlend:
- vollstaendige Write-Paritaet fuer Timeline-/Dispo-Workflows
- Inline-/Batch-Operationen der Timeline:
- `updateAllocationInline`
- `quickAssign`
- `batchQuickAssign`
@@ -197,7 +175,7 @@ Fehlend:
Konsequenz:
- Der Assistant kann heute nicht denselben Timeline-Arbeitsmodus wie ein Nutzer in der UI abbilden.
- Der Assistant kann die wichtigsten Timeline-/Disposition-Readfaelle jetzt fachlich deutlich naeher an der UI abbilden, aber noch nicht denselben operativen Arbeitsmodus fuer Schreibaktionen und Imports.
### Transparenz, Herleitungen und Berechnungsgraphen
@@ -325,7 +303,7 @@ Fehlend:
### Deutlich unvollstaendige Router-Paritaet
- `timeline`
- `timeline` (read-only Kernfaelle vorhanden, Write-Paritaet fehlt)
- `vacation`
- `estimate`
- `notification`
@@ -353,22 +331,25 @@ Der Prompt suggeriert an mehreren Stellen mehr Paritaet, als technisch heute vor
### Problematische Aussagen
- "Urlaub, Feiertage" ist fuer Leseabfragen ok, aber nicht fuer Holiday-Calendar-Administration.
- "Notifications anzeigen" stimmt nur eingeschraenkt, weil das Assistant-Tooling aktuell nicht sauber auf den aktuellen Nutzer scoped.
- "Notifications anzeigen" ist fuer die Basisfaelle inzwischen sauberer gescoped, deckt aber weiterhin nicht die volle Notification-/Reminder-Paritaet der App ab.
- "Dashboard-Details abrufen" stimmt nur fuer einen Teil der Dashboard-/Analysewelt.
- "Den User zu relevanten Seiten navigieren" stimmt, ersetzt aber keine echte Daten-/Aktionsparitaet in Timeline, Holiday Editor oder Admin-Bereichen.
- "Ressourcenplanung und Projektmanagement" klingt umfassender, als die reale Tool-Abdeckung in spezialisierten Subsystemen ist.
### Wichtigste Prompt-Luecke
Die Human-in-the-Loop-Regel wird als harte Pflicht formuliert, ist technisch aber nicht hart erzwungen.
Die Human-in-the-Loop-Regel ist inzwischen serverseitig erzwungen. Der Prompt sollte trotzdem nicht so formulieren, als gaebe es bereits eine vollwertige Approval-Workbench oder vollstaendige Workflow-Paritaet.
## Was getan werden muss, damit der Assistant wirklich dieselben Nutzerfaehigkeiten hat
### P0: Sicherheits- und Governance-Hardening
1. Serverseitige Confirm-Policy fuer alle schreibenden Assistant-Tools einziehen.
- Schreibende Tool-Calls duerfen ohne bestaetigten Confirmation-Token nicht ausgefuehrt werden.
- Diese Policy darf nicht nur im Prompt stehen.
- Status: im Kern erledigt.
- Weiter offen:
- Approval-UX ausserhalb des Chatverlaufs
- bessere Sichtbarkeit mehrerer offener Freigaben
- explizitere Admin-/Audit-Auswertung offener/abgelaufener Freigaben
2. Assistant-Tools auf denselben Objekt-Scope wie die eigentlichen Router bringen.
- Besonders:
@@ -399,10 +380,7 @@ Die Human-in-the-Loop-Regel wird als harte Pflicht formuliert, ist technisch abe
2. Timeline-Assistant-Strang bauen
- Read:
- `get_timeline_entries_view`
- `get_timeline_holiday_overlays`
- `get_timeline_project_context`
- `preview_project_shift`
- Status: fuer die zentralen read-only Faelle umgesetzt
- Write:
- `update_allocation_inline`
- `apply_project_shift`
@@ -458,14 +436,14 @@ Die Human-in-the-Loop-Regel wird als harte Pflicht formuliert, ist technisch abe
### Stream A: Safety / Policy
- serverseitige Confirmation-Gates
- Approval-UX / Inbox / Lifecycle auf die persistente Server-Approval-Logik aufsetzen
- Ownership-/Permission-Fixes
- Mutation-Audit vervollstaendigen
### Stream B: Holiday + Timeline Parity
- Holiday-Calendar-Editor-Tools
- Timeline-Readmodels
- Timeline-Write-Aktionen
- Timeline-Shift-/Assign-Aktionen
### Stream C: Explainability / Analytics
@@ -487,6 +465,6 @@ Der Assistant ist bereits breit genug, um viele operative Fragen und Standardakt
Die drei groessten Blocker dafuer sind:
1. fehlende serverseitige Absicherung fuer schreibende AI-Aktionen,
1. fehlende vollwertige Approval-UX trotz bereits vorhandener serverseitiger Persistenz und Durchsetzung,
2. unvollstaendige fachliche Paritaet in Holiday/Timeline/Analytics/Admin-Bereichen,
3. inkonsistente oder zu schwache Permission- und Ownership-Pruefungen in einzelnen Tools.