diff --git a/CHANGELOG.md b/CHANGELOG.md index 2eb77de..120e244 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,10 +8,15 @@ Alle nennenswerten Aenderungen an diesem Projekt werden in dieser Datei festgeha - GHCR-Publish-Workflow fuer das API-Container-Image bei Release-Tags und manuellen Tag-Backfills. - Build-Argument fuer `BEYOND_AI_VERSION`, damit Container und Health-Endpoint dieselbe Release-Version tragen. +- Neues Architekturmodul `observability/` fuer den Qualitaets-Layer aus Detection Integrity, Data Trust, Service Health und Business Impact. +- Neues Architekturmodul `federation/` fuer das foederative Drei-Schichtenmodell aus Public, Federated und Internal Layer. +- Shared-Modelle fuer Confidence Levels, Surrogat-Korrelation, Quality Signals und federative Sichtbarkeitsklassen. +- Tests fuer die neuen Shared-Modelle und ihre Routing-/Impact-Logik. ### Changed - GitHub-Actions-Workflows auf Node-24-faehige Major-Versionen von `actions/checkout` und `actions/setup-python` angehoben. +- Root-README um Observability-, Federation- und Strangler-Prinzipien aus der Watchdog-Serie erweitert. ## [0.1.0-alpha.1] - 2026-03-29 diff --git a/README.md b/README.md index 6096277..55eb5e7 100644 --- a/README.md +++ b/README.md @@ -21,40 +21,103 @@ Dieses Repository ist der Beweis, dass die Technologie reif ist β€” und dass der | [`sanctions/`](sanctions) | 🟒 Live | Sanctions & PEP Screening auf Basis von OpenSanctions + yente β€” deployed auf [sanction.endvater.de](https://sanction.endvater.de) | Dow Jones R&C, World-Check, Sanction Scanner | | [`horizon/`](horizon) | βšͺ Geplant | Regulatory Horizon Scanner β€” EUR-Lex, BaFin, EBA/ESMA automatisch gescrapt und LLM-klassifiziert | VΓ–B RADAR, CUBE, msg LCM | | [`osint/`](osint) | βšͺ Geplant | Adverse Media & OSINT β€” RSS-Aggregation, LLM-Klassifikation, Entity Resolution | LexisNexis, Quantexa, Chainalysis | -| [`shared/`](shared) | 🟑 Basis | Gemeinsame Infrastruktur: Neo4j-Connector, LLM-Gateway, Confidence Framework, Config | β€” | +| [`observability/`](observability) | 🟑 Blueprint | Qualitaets-Layer fuer Detection Integrity, Data Trust, Service Health und Business Impact | isolierte Monitoring-Kacheln, fachlich blinde DQ-Programme | +| [`federation/`](federation) | 🟑 Blueprint | Foederatives Schichtenmodell: oeffentlicher, foederativer und bankinterner Layer | Single-Bank-Silos, Vendor-Blackboxes | +| [`shared/`](shared) | 🟑 Basis | Gemeinsame Infrastruktur: Neo4j-Connector, LLM-Gateway, Confidence, Observability- und Federation-Modelle | β€” | ## Architektur ``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Beyond AI β”‚ -β”‚ β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ sanctions/ β”‚ β”‚ horizon/ β”‚ β”‚ osint/ β”‚ β”‚ -β”‚ β”‚ Screening β”‚ β”‚ Scanner β”‚ β”‚ Adverse Media β”‚ β”‚ -β”‚ β”‚ PEP/Lists β”‚ β”‚ Norms β”‚ β”‚ Entity Resolution β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ β”‚ β”‚ β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ shared/ β”‚ β”‚ -β”‚ β”‚ Neo4j Β· LiteLLM Gateway (Ollama/Claude) Β· Confidence β”‚ β”‚ -β”‚ β”‚ Config Β· FastAPI Boilerplate Β· Prefect Scheduler β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ Datenquellen & Matching-Layer β”‚ β”‚ -β”‚ β”‚ OpenSanctions Β· yente Β· nomenklatura Β· FollowTheMoney (FtM) β”‚ β”‚ -β”‚ β”‚ ICIJ Offshore Leaks Β· EUR-Lex Β· BaFin Β· EBA Β· OFAC Β· UN β”‚ β”‚ -β”‚ β”‚ Splink (Entity Resolution) Β· Aleph (OCCRP) Β· watchman β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β–Ό - FinRegAgents (upstream) - github.com/endvater/finreg-agents - Confidence-aware Validation Framework +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Beyond AI β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ sanctions/ β”‚ β”‚ horizon/ β”‚ β”‚ osint/ β”‚ β”‚ +β”‚ β”‚ Screening β”‚ β”‚ Scanner β”‚ β”‚ Adverse Media β”‚ β”‚ +β”‚ β”‚ PEP/Lists β”‚ β”‚ Norms β”‚ β”‚ Entity Resolution β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ observability/ β”‚ β”‚ +β”‚ β”‚ Detection Integrity Β· Data Trust Β· Service Health Β· Impact Map β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ federation/ β”‚ β”‚ +β”‚ β”‚ Public Layer Β· Federated Layer Β· Internal Layer β”‚ β”‚ +β”‚ β”‚ Confidence-aware Sidecars Β· Privacy-preserving Signals β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ shared/ β”‚ β”‚ +β”‚ β”‚ Neo4j Β· LLM Gateway Β· Confidence Β· Observability Models β”‚ β”‚ +β”‚ β”‚ Federation Models Β· Config Β· FastAPI Boilerplate β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ Datenquellen und Signale β”‚ β”‚ +β”‚ β”‚ Public Data Β· Federated Signals Β· Internal Telemetry β”‚ β”‚ +β”‚ β”‚ OpenSanctions Β· EUR-Lex Β· BaFin Β· EBA Β· ICIJ Β· OpenCorporates β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό + FinRegAgents (upstream) + github.com/endvater/finreg-agents + Confidence-aware Validation Framework ``` +## Neue Architekturprinzipien + +### 1. Observability als Qualitaets-Layer + +Beyond AI erweitert die klassische Produktarchitektur um einen expliziten +Qualitaets-Layer ueber alle FinCrime-Module hinweg: + +- `Business-Qualitaet`: erkennt das System noch das Richtige? +- `Daten-Qualitaet`: kann das Institut der Entscheidungsbasis trauen? +- `IT-Service-Qualitaet`: laeuft die Erkennungskette noch technisch integer? + +Die entscheidende Regel lautet: Nicht jedes Data- oder IT-Signal gehoert ins +Compliance-Cockpit. Sichtbar werden nur Signale mit nachweisbarer +`Business Impact`-Wirkung auf Regeln, Modelle, Populationen, Faelle oder +Kontrollhandlungen. + +### 2. Foederatives Schichtenmodell + +Die Beyond-AI-Architektur folgt einem dreistufigen Sichtbarkeitsmodell: + +- `Public Layer`: alles, was aus Regulatorik, oeffentlichen Typologien und + offenen Datenquellen ohnehin sichtbar ist +- `Federated Layer`: institutionsuebergreifende Signale, Regeln und Muster ohne + pauschalen Rohdatenaustausch +- `Internal Layer`: bankspezifische Modelle, Graphen, Entscheidungs- und + Priorisierungslogik + +Technologie ist kopierbar. Netzwerke, Governance und geteilte +Qualitaetssicherung sind es nicht. + +### 3. Legacy-Modernisierung nach dem Strangler-Prinzip + +Beyond AI geht davon aus, dass reale AML-Landschaften nicht cloud-nativ +beginnen. Deshalb ist `Mirror First` Teil der Architektur: + +- Event Mirrors und Shadow Pipelines vor produktiver Kernablaesung +- Surrogat-IDs mit `Confidence Levels`, wenn keine echte End-to-End-Trace-ID + existiert +- Strangeln von Faehigkeiten statt romantischer Komplett-Ablage von Systemen +- Vendor-Lock-in bedeutet oft: zuerst Umgebung stranglen, nicht den Kern + +## Architekturtexte + +Die Repo-Architektur wird nicht nur im Code, sondern auch in den Watchdog- +Texten entfaltet: + +- [Beyond AI/FinCrime OS β€” Weil Technologie kopierbar ist. Netzwerke nicht.](https://watchdog.endvater.de/2026/03/beyond-ai-weil-technologie-kopierbar-ist-netzwerke-nicht/) +- [Beyond AI/FinCrime OS: Die drei Schichten der Unsichtbarkeit](https://watchdog.endvater.de/2026/03/beyond-ai-fincrime-os-die-drei-schichten-der-unsichtbarkeit/) +- Observability-Serie Teil II: Business-, Daten- und IT-Service-Qualitaet als gemeinsamer Qualitaets-Layer +- Observability-Serie Teil III: Strangler-Fig-Modernisierung fuer die Legacy-Bank + ## Quickstart ```bash @@ -198,6 +261,11 @@ DSGV, BVR oder ein vergleichbarer Verband institutionalisiert das System. Die Ba Wir suchen Institute β€” Sparkassen, Volksbanken, Landesbanken β€” die den genossenschaftlichen Gedanken in Code ΓΌbersetzen wollen. +Das technische Modell dazu ist jetzt explizit in [`federation/`](federation) +dokumentiert: nicht nur als Betriebsform, sondern als mehrschichtige +Detection-Architektur aus sichtbaren, foederierten und vollstaendig internen +Erkennungsebenen. + > *Was noch fehlt, ist kein Tool. Es ist der erste Telefonanruf.* > β€” FinCrime OS 2026 diff --git a/federation/README.md b/federation/README.md new file mode 100644 index 0000000..2f00a41 --- /dev/null +++ b/federation/README.md @@ -0,0 +1,69 @@ +# Beyond AI β€” Federation Layer + +**Status: 🟑 Blueprint / Architekturmodul** + +`federation/` ist die explizite Repo-Verankerung der These: + +**Technologie ist kopierbar. Netzwerke nicht.** + +Beyond AI versteht Foederation deshalb nicht nur als Betriebsform, sondern als +Detection-Architektur mit unterschiedlichen Sichtbarkeits- und +Kooperationsschichten. + +## Das Drei-Schichten-Modell + +| Layer | Sichtbarkeit fuer Externe | Typische Inhalte | Sharing-Modus | +|------|----------------------------|------------------|---------------| +| `public` | hoch | oeffentliche Typologien, Sanktionslisten, regulatorische Schwellen, Standard-KYC | public source | +| `federated` | niedrig | anonymisierte Muster, gemeinsame Heuristiken, privacy-preserving Signale, Cross-Bank-Learning | anonymized / privacy-preserving | +| `internal` | null | bankspezifische Modelle, Priorisierung, interne Graph-Analytik, proprietaere Entscheidungslogik | institution only | + +## Warum das relevant ist + +Ein professioneller Geldwaescher kennt heute viele Elemente des oeffentlichen +Layers: Typologien, Schwellenwerte, Standardkontrollen, offene Watchlists. +Er kann gegen diese sichtbare Logik optimieren. + +Ein Beyond-AI-System soll deshalb nicht nur "besser erkennen", sondern auch +die Sichtbarkeit seiner eigentlichen Erkennungstiefe steuern: + +- `public`: regulatorisch nachvollziehbar und erwartbar +- `federated`: zwischen Instituten lernfaehig, aber fuer Angreifer opak +- `internal`: vollstaendig bankspezifisch und nicht testbar von aussen + +## Foederation heisst nicht Rohdatenaustausch + +Das Repo geht bewusst nicht von pauschalem Teilen sensibler Rohdaten aus. +Foederation meint hier in erster Linie: + +- geteilte Regeln und Kuratierung +- anonymisierte oder aggregierte Muster +- privacy-preserving Signale +- gemeinsame Qualitaetssicherung +- gemeinsames Betriebs- und Governance-Modell + +## Beziehung zur Legacy-Modernisierung + +In realen Banken laesst sich nicht jede Vendor-Blackbox direkt stranglen. +Foederation hilft auch dort: + +- gemeinsame Kuratierung rund um Blackboxes +- gemeinsame Referenzdaten- und Trust-Layer +- geteilte Priorisierungs- und Kontextlogik +- Verlagerung von Wissen aus Vendor-Silos in einen gemeinsamen Layer + +## Kernartefakte + +- `VisibilityLayer` +- `SharingMode` +- `DetectionLayer` +- `FederatedCapability` + +Diese Modelle liegen in `shared/federation/`. + +## Roadmap + +- [ ] Default Detection Layers fuer Beyond AI festziehen +- [ ] Sharing-Regeln fuer Signale aus `sanctions/` definieren +- [ ] Public/Federated/Internal-Klassifikation fuer kΓΌnftige Module einfuehren +- [ ] Governance-Playbook fuer foederativen Betrieb dokumentieren diff --git a/federation/__init__.py b/federation/__init__.py new file mode 100644 index 0000000..f6e1ba3 --- /dev/null +++ b/federation/__init__.py @@ -0,0 +1 @@ +"""Beyond AI federation module placeholder.""" diff --git a/observability/README.md b/observability/README.md new file mode 100644 index 0000000..8754925 --- /dev/null +++ b/observability/README.md @@ -0,0 +1,78 @@ +# Beyond AI β€” Observability Layer + +**Status: 🟑 Blueprint / Architekturmodul** + +Der `observability/`-Layer erweitert Beyond AI um eine explizite +Qualitaetsschicht fuer FinCrime-Systeme. Nicht mehr nur: "Funktioniert das +Modul?" Sondern: "Erkennt das Institut noch verlaesslich, worauf diese Sicht +beruht - und wo sie gerade bruechig wird?" + +## Die drei Qualitaetsdimensionen + +Beyond AI behandelt Observability nicht als reines IT-Monitoring, sondern als +Layer ueber drei Ebenen: + +- `Business-Qualitaet` + Erkennen Regeln, Modelle und Workflows noch die richtigen Risiken? +- `Daten-Qualitaet` + Kann das Institut der Entscheidungsbasis trauen? +- `IT-Service-Qualitaet` + Laeuft die Erkennungskette technisch noch integer? + +## Designregeln + +1. Nicht jedes Datenproblem ist ein Compliance-Problem. +2. Nicht jede technische Degradation gehoert ins Compliance-Cockpit. +3. Sichtbar werden nur Signale mit `Business Impact`. +4. Korrelationen ohne native Trace-ID brauchen `Surrogat-IDs` mit + `Confidence Levels`. +5. Die Navigationslogik ist wichtiger als die Kachelzahl: + `fachliches Symptom -> Datenursache -> IT-Ursache -> Massnahme`. + +## Architektur + +``` + Beyond AI Product Modules + sanctions/ horizon/ osint/ + β”‚ β”‚ β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + observability/ + β”‚ + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ β”‚ β”‚ +Detection Integrity Data Trust Service Health + β”‚ β”‚ β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + Business Impact Map + β”‚ + Compliance Cockpit +``` + +## Kernartefakte + +- `QualitySignal` +- `CorrelationHandle` +- `IncidentSeverity` +- `SurfaceTarget` + +Diese Modelle liegen in `shared/observability/` und sind bewusst +moduluebergreifend formuliert: Der Sanctions Screener, der Horizon Scanner und +spaetere Graph- oder Workflow-Komponenten sollen dieselbe Sprache fuer +Qualitaet und Impact sprechen. + +## Was dieser Layer bewusst nicht ist + +- kein allgemeines NOC-Dashboard +- kein ungefilterter Data-Quality-Alarmstrom +- kein Ersatz fuer Modellvalidierung oder interne Revision +- kein Versuch, jede lokale technische Stoerung in die Compliance zu werfen + +## Roadmap + +- [ ] Impact-aware Signals aus `sanctions/` einspeisen +- [ ] Read-only Detection Integrity fuer Vendor-TM-Exports vorbereiten +- [ ] Data-Trust-Indikatoren fuer Referenzdatenfeeds definieren +- [ ] Service-Health-Signale mit Business Impact verknuepfen +- [ ] Compliance-Cockpit-Projektion als eigene API/Oberflaeche ableiten diff --git a/observability/__init__.py b/observability/__init__.py new file mode 100644 index 0000000..71b408d --- /dev/null +++ b/observability/__init__.py @@ -0,0 +1 @@ +"""Beyond AI observability module placeholder.""" diff --git a/pyproject.toml b/pyproject.toml index 67ebde1..b3d7241 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,4 +11,4 @@ ignore = [ [tool.pytest.ini_options] asyncio_mode = "auto" -testpaths = ["sanctions/tests"] +testpaths = ["sanctions/tests", "tests"] diff --git a/shared/confidence/__init__.py b/shared/confidence/__init__.py index e69de29..9761904 100644 --- a/shared/confidence/__init__.py +++ b/shared/confidence/__init__.py @@ -0,0 +1,35 @@ +"""Shared confidence primitives for Beyond AI.""" + +from enum import StrEnum + + +class ConfidenceLevel(StrEnum): + """Small shared confidence scale for model, retrieval and correlation signals.""" + + LOW = "low" + MEDIUM = "medium" + HIGH = "high" + + @property + def rank(self) -> int: + return { + ConfidenceLevel.LOW: 0, + ConfidenceLevel.MEDIUM: 1, + ConfidenceLevel.HIGH: 2, + }[self] + + def at_least(self, minimum: "ConfidenceLevel") -> bool: + return self.rank >= minimum.rank + + @classmethod + def from_score(cls, score: float) -> "ConfidenceLevel": + if not 0.0 <= score <= 1.0: + raise ValueError("score must be between 0.0 and 1.0") + if score >= 0.85: + return cls.HIGH + if score >= 0.60: + return cls.MEDIUM + return cls.LOW + + +__all__ = ["ConfidenceLevel"] diff --git a/shared/federation/__init__.py b/shared/federation/__init__.py new file mode 100644 index 0000000..6efed61 --- /dev/null +++ b/shared/federation/__init__.py @@ -0,0 +1,17 @@ +"""Shared federation models for Beyond AI.""" + +from .models import ( + DetectionLayer, + FederatedCapability, + SharingMode, + VisibilityLayer, + default_detection_layers, +) + +__all__ = [ + "DetectionLayer", + "FederatedCapability", + "SharingMode", + "VisibilityLayer", + "default_detection_layers", +] diff --git a/shared/federation/models.py b/shared/federation/models.py new file mode 100644 index 0000000..ab77bd2 --- /dev/null +++ b/shared/federation/models.py @@ -0,0 +1,95 @@ +"""Federated visibility and sharing models for Beyond AI.""" + +from __future__ import annotations + +from dataclasses import dataclass +from enum import StrEnum + + +class VisibilityLayer(StrEnum): + """Visibility classes for the Beyond-AI detection architecture.""" + + PUBLIC = "public" + FEDERATED = "federated" + INTERNAL = "internal" + + +class SharingMode(StrEnum): + """How knowledge is allowed to travel across institutional boundaries.""" + + PUBLIC_SOURCE = "public_source" + ANONYMIZED_SIGNAL = "anonymized_signal" + PRIVACY_PRESERVING = "privacy_preserving" + INSTITUTION_ONLY = "institution_only" + + +@dataclass(frozen=True) +class DetectionLayer: + """One architectural visibility layer in the federated model.""" + + layer: VisibilityLayer + title: str + description: str + externally_visible: bool + sharing_mode: SharingMode + raw_data_shared: bool = False + + def hidden_from_adversary(self) -> bool: + """True when external actors should not see the logic of this layer.""" + return not self.externally_visible + + +@dataclass(frozen=True) +class FederatedCapability: + """Capability that can operate in one of the three federation layers.""" + + name: str + layer: VisibilityLayer + sharing_mode: SharingMode + description: str + raw_data_shared: bool = False + + def allows_cross_institution_learning(self) -> bool: + return self.layer == VisibilityLayer.FEDERATED + + def requires_internal_only_operation(self) -> bool: + return self.layer == VisibilityLayer.INTERNAL + + +def default_detection_layers() -> tuple[DetectionLayer, ...]: + """Reference implementation of the three visibility layers from the manifesto.""" + return ( + DetectionLayer( + layer=VisibilityLayer.PUBLIC, + title="Public Layer", + description=( + "Visible controls built from public typologies, open watchlists " + "and regulatorily expected baseline checks." + ), + externally_visible=True, + sharing_mode=SharingMode.PUBLIC_SOURCE, + raw_data_shared=False, + ), + DetectionLayer( + layer=VisibilityLayer.FEDERATED, + title="Federated Layer", + description=( + "Cross-institution signals, shared curation and privacy-preserving " + "patterns that remain opaque for external actors." + ), + externally_visible=False, + sharing_mode=SharingMode.PRIVACY_PRESERVING, + raw_data_shared=False, + ), + DetectionLayer( + layer=VisibilityLayer.INTERNAL, + title="Internal Layer", + description=( + "Institution-specific graph logic, prioritization, hidden thresholds " + "and internal models that are not externally testable." + ), + externally_visible=False, + sharing_mode=SharingMode.INSTITUTION_ONLY, + raw_data_shared=False, + ), + ) diff --git a/shared/observability/__init__.py b/shared/observability/__init__.py new file mode 100644 index 0000000..724f89f --- /dev/null +++ b/shared/observability/__init__.py @@ -0,0 +1,19 @@ +"""Shared observability models for Beyond AI.""" + +from .models import ( + CorrelationHandle, + CorrelationMethod, + IncidentSeverity, + QualityDomain, + QualitySignal, + SurfaceTarget, +) + +__all__ = [ + "CorrelationHandle", + "CorrelationMethod", + "IncidentSeverity", + "QualityDomain", + "QualitySignal", + "SurfaceTarget", +] diff --git a/shared/observability/models.py b/shared/observability/models.py new file mode 100644 index 0000000..e721405 --- /dev/null +++ b/shared/observability/models.py @@ -0,0 +1,107 @@ +"""Impact-aware observability primitives for Beyond AI.""" + +from __future__ import annotations + +from dataclasses import dataclass +from enum import StrEnum + +from shared.confidence import ConfidenceLevel + + +class QualityDomain(StrEnum): + """Which quality plane emitted a signal.""" + + BUSINESS = "business" + DATA = "data" + SERVICE = "service" + + +class IncidentSeverity(StrEnum): + """Common severity scale for quality-layer incidents.""" + + INFO = "info" + DEGRADED = "degraded" + MATERIAL = "material" + CRITICAL = "critical" + + +class SurfaceTarget(StrEnum): + """Where a signal should appear operationally.""" + + PLATFORM_TEAM = "platform_team" + DATA_TEAM = "data_team" + COMPLIANCE_COCKPIT = "compliance_cockpit" + EXECUTIVE_ESCALATION = "executive_escalation" + + +class CorrelationMethod(StrEnum): + """How a signal was correlated across system boundaries.""" + + NATIVE = "native" + SURROGATE = "surrogate" + + +@dataclass(frozen=True) +class CorrelationHandle: + """Reference used to tie a quality signal to a process or entity.""" + + name: str + value: str + method: CorrelationMethod = CorrelationMethod.NATIVE + confidence: ConfidenceLevel = ConfidenceLevel.HIGH + + def requires_review(self) -> bool: + """Surrogate correlations below high confidence need operator review.""" + return self.method == CorrelationMethod.SURROGATE and self.confidence != ConfidenceLevel.HIGH + + +@dataclass(frozen=True) +class QualitySignal: + """Cross-layer signal for Detection Integrity, Data Trust and Service Health.""" + + name: str + domain: QualityDomain + severity: IncidentSeverity + summary: str + correlation_handles: tuple[CorrelationHandle, ...] = () + affected_capabilities: tuple[str, ...] = () + business_impact: bool = False + manual_control_required: bool = False + affected_population: int | None = None + + def should_surface_to_compliance(self) -> bool: + """ + Only surface issues to the compliance cockpit when they change the + institution's effective field of view. + """ + return ( + self.business_impact + or self.manual_control_required + or bool(self.affected_capabilities) + ) + + def surface_targets(self) -> tuple[SurfaceTarget, ...]: + """Determine the minimum set of target audiences for a signal.""" + targets: list[SurfaceTarget] = [] + if self.domain == QualityDomain.DATA: + targets.append(SurfaceTarget.DATA_TEAM) + else: + targets.append(SurfaceTarget.PLATFORM_TEAM) + + if self.should_surface_to_compliance(): + targets.append(SurfaceTarget.COMPLIANCE_COCKPIT) + + if self.severity == IncidentSeverity.CRITICAL and self.should_surface_to_compliance(): + targets.append(SurfaceTarget.EXECUTIVE_ESCALATION) + + return tuple(targets) + + def lowest_correlation_confidence(self) -> ConfidenceLevel | None: + """Return the weakest confidence rating across all attached handles.""" + if not self.correlation_handles: + return None + + return min( + (handle.confidence for handle in self.correlation_handles), + key=lambda level: level.rank, + ) diff --git a/tests/test_architecture_models.py b/tests/test_architecture_models.py new file mode 100644 index 0000000..e8ddd7c --- /dev/null +++ b/tests/test_architecture_models.py @@ -0,0 +1,104 @@ +"""Tests for shared observability and federation architecture models.""" + +from shared.confidence import ConfidenceLevel +from shared.federation import SharingMode, VisibilityLayer, default_detection_layers +from shared.observability import ( + CorrelationHandle, + CorrelationMethod, + IncidentSeverity, + QualityDomain, + QualitySignal, + SurfaceTarget, +) + + +def test_confidence_level_from_score(): + assert ConfidenceLevel.from_score(0.2) == ConfidenceLevel.LOW + assert ConfidenceLevel.from_score(0.75) == ConfidenceLevel.MEDIUM + assert ConfidenceLevel.from_score(0.95) == ConfidenceLevel.HIGH + + +def test_surrogate_correlation_requires_review_below_high_confidence(): + surrogate = CorrelationHandle( + name="batch_cycle_id", + value="2026-04-04T09:00", + method=CorrelationMethod.SURROGATE, + confidence=ConfidenceLevel.MEDIUM, + ) + native = CorrelationHandle( + name="trace_id", + value="abc-123", + method=CorrelationMethod.NATIVE, + confidence=ConfidenceLevel.HIGH, + ) + + assert surrogate.requires_review() is True + assert native.requires_review() is False + + +def test_quality_signal_only_surfaces_to_compliance_with_business_impact(): + signal = QualitySignal( + name="schema drift", + domain=QualityDomain.DATA, + severity=IncidentSeverity.DEGRADED, + summary="Local schema drift without proven downstream impact.", + ) + + assert signal.should_surface_to_compliance() is False + assert signal.surface_targets() == (SurfaceTarget.DATA_TEAM,) + + +def test_quality_signal_with_business_impact_reaches_compliance_and_exec(): + signal = QualitySignal( + name="sanctions source delayed", + domain=QualityDomain.DATA, + severity=IncidentSeverity.CRITICAL, + summary="Reference data delay affects sanctions hit quality.", + affected_capabilities=("sanctions screening",), + business_impact=True, + ) + + assert signal.should_surface_to_compliance() is True + assert signal.surface_targets() == ( + SurfaceTarget.DATA_TEAM, + SurfaceTarget.COMPLIANCE_COCKPIT, + SurfaceTarget.EXECUTIVE_ESCALATION, + ) + + +def test_quality_signal_reports_lowest_correlation_confidence(): + signal = QualitySignal( + name="legacy batch mismatch", + domain=QualityDomain.SERVICE, + severity=IncidentSeverity.MATERIAL, + summary="Batch and case flow disagree.", + correlation_handles=( + CorrelationHandle( + name="job_run_id", + value="run-1", + method=CorrelationMethod.NATIVE, + confidence=ConfidenceLevel.HIGH, + ), + CorrelationHandle( + name="file_delivery_id", + value="delivery-42", + method=CorrelationMethod.SURROGATE, + confidence=ConfidenceLevel.LOW, + ), + ), + ) + + assert signal.lowest_correlation_confidence() == ConfidenceLevel.LOW + + +def test_default_detection_layers_model_public_federated_internal(): + layers = default_detection_layers() + + assert [layer.layer for layer in layers] == [ + VisibilityLayer.PUBLIC, + VisibilityLayer.FEDERATED, + VisibilityLayer.INTERNAL, + ] + assert layers[0].externally_visible is True + assert layers[1].sharing_mode == SharingMode.PRIVACY_PRESERVING + assert layers[2].hidden_from_adversary() is True