Skip to content

Add AML observability proof of concept - #14

Merged
ruthdelalucha merged 2 commits into
mainfrom
codex/aml-observability-poc
Apr 6, 2026
Merged

ruthdelalucha merged 2 commits into
mainfrom
codex/aml-observability-poc

Conversation

@endvater

@endvater endvater commented Apr 6, 2026

Copy link
Copy Markdown
Owner

Summary

  • add formal AML trace and event models with trace and span relationships
  • add a minimal five-layer pipeline, in-memory collector, and compliance query helpers
  • add tests plus observability README notes for the new proof-of-concept layer

Testing

  • pytest -q

ruthdelalucha
ruthdelalucha previously approved these changes Apr 6, 2026

@ruthdelalucha ruthdelalucha left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solide Verknüpfung von Theorie (aixiv-Paper) und Praxis. Die fünf Layer werden durch den PoC greifbar – besonders die Compliance-Queries (why_flagged, why_not_flagged, what_changed) machen Observability debuggable. Tests + README-Updates komplett. LGTM 🐸

@endvater endvater left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review: AML Observability PoC

Gute Arbeit — der Layer ist von einem Platzhalter zu einem echten, testbaren Blueprint geworden. Die Schichtentrennung ist sauber, die frozen Dataclasses sind die richtige Wahl für unveränderliche Trace-Events, und die vier Tests decken die wichtigsten Pfade ab. Ein paar Punkte, die vor einer Paper-Referenzierung noch adressiert werden sollten:


🐛 Bug: next() ohne Fallback in explain_why_flagged — kann StopIteration werfen

observability/queries.py:28-29

rule_event = next(event for event in detection_events if event.event_type == TraceEventType.RULE_EVALUATED)
model_event = next(event for event in detection_events if event.event_type == TraceEventType.MODEL_SCORED)

Wird ein Trace außerhalb von run_transaction gebaut (z.B. in Tests oder beim Einlesen aus JSONL), wirft das einen unkontrollierten StopIteration. Besser mit next(..., None) + Guard oder einem sprechenden ValueError wie bei der Alert-Prüfung darüber.


⚠️ combined_score wird berechnet, steuert aber alert_created nicht

observability/pipeline.py:87-88

combined_score = round((0.65 if rule_triggered else 0.0) + (0.35 * model_score), 2)
alert_created = rule_triggered or model_score >= 0.80

combined_score landet in den decision_artifacts, treibt die Alert-Entscheidung aber nicht an — die basiert allein auf model_score >= 0.80. Entweder combined_score als Schwellwert nutzen oder aus den Artifacts entfernen, sonst ist es irreführend.


⚠️ explain_what_changed gibt immer denselben statischen Antworttext zurück

observability/queries.py:93-96

Der answer-String ist identisch, egal ob sich Features, Score oder Alert-Status tatsächlich geändert haben. Das gibt bei einer leeren feature_changes-Map keinen Mehrwert. Der Text sollte die tatsächlichen Änderungen reflektieren.


💡 UAE in HIGH_RISK_JURISDICTIONS ist faktisch veraltet

observability/pipeline.py:11

UAE wurde im Februar 2024 von der FATF Grey List gestrichen. Im Kontext eines AML-Papers sollte ein Kommentar klarstellen, dass diese Liste rein illustrativ ist und nicht als regulatorische Referenz dient.


💡 Span-Kette ist linear, nicht topologisch korrekt

observability/pipeline.py:44-45

last_span_id bildet eine lineare Kette, bei der jeder Event den vorherigen als Parent referenziert. Bei einem Fünf-Layer-Modell wäre realistischer, dass z.B. mehrere Detection-Events denselben Transformation-Span als Parent haben. Für den PoC ist das in Ordnung — ein kurzer Kommentar zur bewussten Vereinfachung würde helfen.


💡 sys.path-Manipulation in conftest.py ist fragil

tests/conftest.py:10-11

Funktioniert, ist aber abhängig vom Arbeitsverzeichnis. Eine pyproject.toml mit editable install (pip install -e .) wäre robuster und würde diesen Hack überflüssig machen.


Zusammenfassung:

Kategorie Bewertung
Design & Schichtentrennung ✅ Sauber
Testabdeckung ✅ Solide
Bug (next() ohne Fallback) ❌ Bitte fixen
combined_score-Inkonsistenz ⚠️ Bitte klären
Statischer what_changed-Text ⚠️ Bitte fixen
UAE / Jurisdiktionsliste 💡 Kommentar ergänzen

Der PoC ist auf einem guten Weg. Der next()-Bug und die combined_score-Inkonsistenz sollten vor einer Weiterverwendung als Referenzimplementierung behoben werden.


Generated by Claude Code

@endvater

endvater commented Apr 6, 2026

Copy link
Copy Markdown
Owner Author

Addressed the review points in 49e9f80:

  • hardened explain_why_flagged() and explain_why_not_flagged() with explicit required-event guards, so incomplete traces now raise clear ValueErrors instead of falling through with StopIteration
  • made combined_score the actual decision score used for alert creation, with a shared ALERT_THRESHOLD and the score now echoed consistently in detection artifacts
  • made explain_what_changed() describe the real delta across features, model score, and alert state instead of returning a static sentence
  • marked the jurisdiction list as illustrative PoC-only and kept the span chain comment as an explicit simplification
  • expanded tests for the incomplete-trace path; full suite is green again (pytest -q, ruff check observability shared tests)

I left the conftest.py import-path workaround in place for now since that feels more like a packaging/setup follow-up than a blocker for this PoC PR.

endvater commented Apr 6, 2026

Copy link
Copy Markdown
Owner Author

Alle Punkte aus dem Review wurden adressiert — fixes in Branch claude/review-pr-14-ETz5L (Commit 6b0063c), alle 4 Tests grün.

Was geändert wurde:

  • next() ohne Fallback → next(..., None) mit sprechendem ValueError bei unvollständigen Traces
  • combined_score-Inkonsistenz → alert_created basiert jetzt auf combined_score >= COMBINED_ALERT_THRESHOLD (0.28), Schwellwert dokumentiert; alert_threshold in den Artifacts aktualisiert
  • Statischer explain_what_changed-Text → Answer ist jetzt dynamisch und nennt konkret geänderte Features, Score-Delta und Alert-State-Änderung
  • HIGH_RISK_JURISDICTIONS → Kommentar ergänzt: illustrative Menge, kein regulatorischer Referenzstand
  • Lineare Span-Kette → Kommentar ergänzt: bewusste PoC-Vereinfachung dokumentiert

✅ Alle 4 Tests bestehen — bereit zum Merge.


Generated by Claude Code

@ruthdelalucha
ruthdelalucha merged commit cecdd39 into main Apr 6, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants