Alfred besteht aus vier Diensten: Redis (Caching & Session-Replay),
Cortex (Backend auf Port 3000), Monitor (Hintergrund-Preprocessing)
und Face (Angular Frontend auf Port 4200).
Alle Steuerscripts liegen in scripts/.
./scripts/start-redis.sh
# Cortex starten
./scripts/start-cortex.sh # Vordergrund
./scripts/start-cortex.sh -d # Hintergrund (log: data/logs/cortex.log)
./scripts/start-cortex.sh -t # Hintergrund + tail (Ctrl+C beendet nur tail)
# Monitor starten (Mail-Analyse im Hintergrund)
./scripts/start-monitor.sh # Vordergrund
./scripts/start-monitor.sh -d # Hintergrund (log: data/logs/monitor.log)
./scripts/start-monitor.sh -t # Hintergrund + tail
# Face starten
./scripts/start-face.sh # Vordergrund
./scripts/start-face.sh -d # Hintergrund (log: data/logs/face.log)
# Alles zusammen (Cortex + Face, Vordergrund)
./scripts/start-dev.sh # Ctrl+C beendet beides
./scripts/status.sh
# Einzeln prüfen
./scripts/cortex-up-check.sh # → cortex running (PID 12345)
./scripts/face-up-check.sh # → face running (PID 12346)
# Stoppen
./scripts/stop-cortex.sh # Kill by process title alfred:cortex
./scripts/stop-monitor.sh # Kill by process title alfred:monitor
./scripts/stop-face.sh # Kill by ng serve on port 4200
process.title = 'alfred:cortex',
Monitor setzt process.title = 'alfred:monitor' beim Start.
Die Stop- und Check-Scripts nutzen pgrep -f, um den Prozess zuverlässig zu finden —
kein PID-Merken nötig.
Der Monitor ist ein eigenständiger Hintergrundprozess, der eingehende E-Mails automatisch analysiert, bevor der Nutzer sie sieht. Er läuft parallel zum Cortex und schreibt Ergebnisse nach Redis.
./scripts/test/test-redis.sh monitor
# Monitor zurücksetzen (alle Ergebnisse löschen, Neuanalyse erzwingen)
./scripts/test/reset-monitor.sh
# Danach Monitor neustarten (in-memory analyzedUids bleibt sonst bestehen)
./scripts/test/reset-monitor.sh und starte den Monitor neu.
Alfred schreibt auf drei Ebenen mit — jede Ebene hat einen anderen Zweck und eine andere Lebensdauer.
| Ebene | Speicherort | Format | Lebensdauer | Zweck |
|---|---|---|---|---|
| Run Records | data/runs/{ts}-{workflow}.json |
JSON | Dauerhaft | Kompletter Lauf inkl. aller Events — für Operations-Dashboard, KPIs, Nachvollziehbarkeit |
| Audit Log | data/audit/audit-{YYYY-MM-DD}.jsonl |
JSONL (1 Event pro Zeile) | Dauerhaft | Chronologisches Protokoll aller Aktionen — für Compliance, Audit-Dashboard |
| Redis Streams | session:{id}, audit:* |
Redis Stream | 1 Stunde TTL | Session-Replay bei F5, Live-Dashboard, schnelle Abfragen |
| Process Logs | data/logs/cortex.log, face.log |
Stdout/Stderr | Bis überschrieben | Debugging, Startprobleme, Request-Logs |
Pro abgeschlossenem Workflow-Lauf entsteht eine JSON-Datei. Sie enthält den kompletten Lauf mit allen Events und Ergebnissen.
stadtwerke-stromanmeldungdurationMscompleted | failed | cancelledZusätzlich wird der Run als Redis Hash unter run:{runId} gespeichert,
was schnelle Lookups ohne Dateisystem-Zugriff ermöglicht.
Das Audit-Log ist ein append-only JSONL-File, das täglich rotiert.
Jede Zeile ist ein eigenständiger JSON-Eintrag — ideal für grep,
jq und Streaming-Verarbeitung.
| Event-Typ | Beschreibung | Details-Felder |
|---|---|---|
| run-started | Workflow-Lauf gestartet | workflow, params |
| step-completed | Ein Schritt im Workflow abgeschlossen | step, duration |
| confirm-requested | Bestätigung vom Nutzer angefordert | fields, confidence |
| confirm-accepted | Nutzer hat bestätigt | accepted fields |
| confirm-cancelled | Nutzer hat abgebrochen | — |
| field-edited | Nutzer hat ein Feld korrigiert | field, before, after |
| correction-submitted | Korrektur nach Fehler eingereicht | field, value |
| answer-given | Nutzer hat eine Frage beantwortet | question, answer |
| timeout-continue | Nutzer hat nach Timeout fortgesetzt | — |
| timeout-abort | Timeout-Abbruch | — |
| run-completed | Workflow erfolgreich abgeschlossen | durationMs, result |
| run-failed | Workflow mit Fehler beendet | error |
| run-cancelled | Workflow abgebrochen | — |
| mail-trigger | E-Mail hat Workflow ausgelöst | subject, from, workflow |
Redis dient als schneller Puffer für Live-Sessions. Wenn der Nutzer während eines Laufs F5 drückt, fragt die Face den Cortex nach den bisherigen Events — diese kommen aus dem Redis Stream.
Während eines Workflow-Laufs erstellt der Web-Actor Playwright-Screenshots. Diese werden nicht als base64 in den SSE-Stream geschrieben, sondern auf Disk externalisiert.
data/temp/{sessionId}/screenshot-{n}.jpgGET /api/screenshot/{sessionId}/{fileName}Die Angular-Face bietet vier Dashboards, die sich aus den verschiedenen Datenquellen speisen.
| Dashboard | Route | Datenquelle | Inhalt |
|---|---|---|---|
| Operations | /operations |
data/runs/ |
KPI-Karten (Anzahl Runs, Erfolgsrate, Durchschnittsdauer), Workflow-Breakdown, Runs-Tabelle |
| Live | /active |
SSE-Stream | Laufende Workflows in Echtzeit, verschwindet nach Abschluss |
| Szenarien | /scenarios |
data/scenarios/ |
Katalog aller Szenarien, Health-Badges (grün/rot/unbekannt), Prüfen-Button |
| Audit | /audit |
data/audit/ |
Chronologisches Event-Log, filterbar |
Jedes Szenario kann automatisch geprüft werden, wenn alle Pflichtfelder ein
verificationValue im YAML haben. Der Health-Check startet einen headless Playwright-Lauf
und prüft auf Validierungsfehler und Submit-Button-Status.
green oder red, Zeitstempel, Fehlerdetailsred wird die Ausführung blockiert.
./scripts/test/test-redis.sh health
# Health-Status löschen
./scripts/test/test-redis.sh flush-health
# Health-Gate testen
./scripts/test/test-health-gate.sh
Zwei Scripts zum Zurücksetzen von Laufzeitdaten. Beide löschen niemals Quellcode oder Konfiguration.
./scripts/flush-redis.sh
# Komplett-Reset: Redis + Dateisystem (runs/, audit/, logs/, temp/)
./scripts/flush-all.sh
Alle Test-Scripts liegen in scripts/test/ und sind ohne interaktive Eingabe ausführbar.
| Script | Zweck | Benötigt |
|---|---|---|
test-redis.sh |
Redis-Keys inspizieren: Übersicht, Health-Status, Suche nach Pattern | Redis |
trace-run.sh |
Alle Daten eines Runs finden — Files, Audit, Logs, Redis | Redis |
test-recognition.sh |
Szenario-Erkennung testen: Phrase eingeben, Match prüfen | Cortex |
test-preprocessing.sh |
Monitor-Preprocessing-Pipeline prüfen: Flags und Ergebnisse in Redis | Cortex, Redis |
test-health-gate.sh |
Health-Gate testen: Szenario auf red setzen, Blockierung prüfen | Cortex, Redis |
test-forms.sh |
Extraction-Tests für ausgefüllte Formular-Fixtures | Node.js |
prompt-alfred.sh |
E2E: Prompt an Face senden (Playwright), Antwort erfassen | Cortex, Face, Playwright |
reset-monitor.sh |
Monitor-Ergebnisse in Redis löschen (Neuanalyse erzwingen) | Redis |
send-test-mail.py |
Test-Mail mit Anhängen an Maildev senden | Maildev (SMTP :1025) |
./scripts/test/test-recognition.sh "Verarbeite die Stromanmeldung"
# Beispiel: Einen Run nachverfolgen
./scripts/test/trace-run.sh stromanmeldung
Bei mail-getriggerten Workflows verhindert ein Redis NX Lock, dass dasselbe Szenario für dieselbe Mail doppelt ausgeführt wird.
Die Browser-Extension sammelt Interaktionsdaten (Klicks, Feldeingaben, Idle-Zeiten, Netzwerk-Calls, Submit-Ergebnisse)
und sendet sie an POST /api/learning/events. Pro Session entsteht eine JSONL-Datei
in data/logs/learning/.
extension/content/learning-logger.js → ALLOWED_DOMAINS.
Aktuell:
localhost.
Für Kunden-Deployments die jeweilige Domain ergänzen (z.B.
app.customer.de).
Subdomains werden automatisch erkannt.
session_start, session_end, page_context,
field_focus, field_blur, field_paste,
click, submit,
navigation, visibility,
idle_start, idle_end,
network_call,
step_advance, deviation
network-interceptor.js läuft im MAIN-World-Kontext und
wrapped fetch + XMLHttpRequest. Loggt nur URL-Pattern, Methode, Status, Dauer —
keine Request/Response-Bodies. Nur aktiv wenn Learning Mode eingeschaltet ist.
Eigene Calls (/api/learning/) und bekannte Tracker werden gefiltert.
ls data/logs/learning/ — eine Datei pro Session.
Schnellcheck:
jq -r '.type' data/logs/learning/DATEI.jsonl | sort | uniq -c | sort -rn
Validierung:
./scripts/test/test-learning-logger.sh
FLUSH_INTERVAL_MS).
Bei Cortex-Ausfall werden Events im Speicher gehalten und beim nächsten erfolgreichen Flush nachgeliefert.
docker start alfred-redis verbindet Cortex sich automatisch neu.
./scripts/cortex-up-check.sh — falls alter Prozess läuft: ./scripts/stop-cortex.sh./scripts/face-up-check.sh — falls alter Prozess läuft: ./scripts/stop-face.sh./scripts/test/reset-monitor.sh + Monitor neustarten.
Redis-Keys prüfen: ./scripts/test/test-redis.sh monitorred. Prüfen: ./scripts/test/test-redis.sh health.
Zum Löschen: ./scripts/test/test-redis.sh flush-healthdata/runs/ und data/audit/?
Wenn nicht, wurde noch kein Workflow ausgeführt.
tail -f data/logs/cortex.log, data/logs/monitor.log
bzw. data/logs/face.log (nur bei detached-Start)
./scripts/flush-all.sh — Redis + alle Laufzeitdaten. Frischer Start.