diff --git a/docs-src/services/sdk-modules/control-generator-pipeline.md b/docs-src/services/sdk-modules/control-generator-pipeline.md index 4ac03cc..ce3235c 100644 --- a/docs-src/services/sdk-modules/control-generator-pipeline.md +++ b/docs-src/services/sdk-modules/control-generator-pipeline.md @@ -1,16 +1,68 @@ # Control Generator Pipeline -Automatische Generierung von Canonical Controls aus dem gesamten RAG-Korpus (~105.000 Chunks aus Gesetzen, Verordnungen und Standards). +Automatische Generierung, Zerlegung und Bewertung von Compliance Controls aus dem RAG-Korpus (~105.000 Chunks aus EU/DE-Gesetzen, Verordnungen und Standards). -**Backend:** `backend-compliance/compliance/services/control_generator.py` -**Routes:** `backend-compliance/compliance/api/control_generator_routes.py` -**API-Prefix:** `/api/compliance/v1/canonical/generate` +!!! info "Pipeline-Standort (seit April 2026)" + Die gesamte Pipeline liegt im **breakpilot-core** Repository unter `control-pipeline/`. + **Port:** 8098 · **Container:** `bp-core-control-pipeline` --- -## Pipeline-Uebersicht +## Gesamtueberblick -Die Pipeline durchlaeuft 7 Stufen, um aus RAG-Chunks eigenstaendige Security/Compliance Controls zu erzeugen: +Die Pipeline verwandelt Rohtexte aus Regulierungen in pruefbare, atomare Compliance Controls mit Abhaengigkeitslogik. Sie besteht aus 6 Hauptphasen: + +```mermaid +flowchart TD + A["Phase 1: RAG Ingestion"] -->|105k Chunks| B["Phase 2: Control Generation (7 Stufen)"] + B -->|~33k Rich Controls| C["Phase 3: Obligation Extraction (Pass 0a)"] + C -->|~181k Obligations| D["Phase 4: Atomic Composition (Pass 0b)"] + D -->|~15-25k Atomic Controls| E["Phase 5: Deduplizierung"] + E -->|~15-25k Unique| F["Phase 6: Dependency Engine + Evaluation"] +``` + +| Phase | Name | Input | Output | Methode | +|-------|------|-------|--------|---------| +| 1 | RAG Ingestion | PDF/HTML Dokumente | 105k Chunks in Qdrant | Embedding + Chunking | +| 2 | Control Generation | RAG Chunks | ~33k Rich Controls | Claude Sonnet + Lizenz-Gate | +| 3 | Pass 0a | Rich Controls | ~181k Obligations | Claude Haiku (Batch API) | +| 4 | Pass 0b | Obligations | Atomic Controls | Claude Sonnet (Batch API) + Pre-LLM Filter | +| 5 | Deduplizierung | Atomic Controls | Unique Master Controls | Embedding + LLM Dedup | +| 6 | Dependencies | Master Controls | Evaluierte Controls | Ontology + Pattern + Domain Packs | + +--- + +## Phase 1: RAG Document Ingestion + +Dokumente werden in den RAG-Service (Qdrant) ingestiert und in Chunks zerlegt. + +### Qdrant Collections + +| Collection | Inhalte | Lizenzregel | Chunks | +|-----------|---------|-------------|--------| +| `bp_compliance_gesetze` | Deutsche Gesetze (BDSG, TTDSG, TKG) | Rule 1 | ~45k | +| `bp_compliance_datenschutz` | Datenschutz-Leitlinien, EU-Verordnungen | Rule 1/2 | ~25k | +| `bp_compliance_ce` | CE/Sicherheitsstandards, Maschinenverordnung | Rule 1/2/3 | ~20k | +| `bp_dsfa_corpus` | DSFA-spezifische Dokumente | Rule 1/2 | ~10k | +| `bp_legal_templates` | Rechtsvorlagen | Rule 1 | ~5k | + +### Chunk-Metadaten + +Jeder Chunk in Qdrant hat: + +- `regulation_id` — Eindeutige Regulations-ID +- `regulation_name_de` — Deutscher Name +- `article`, `paragraph` — Strukturreferenz +- `chunk_text` — Der eigentliche Text +- `download_url` — Quelldokument-Link + +--- + +## Phase 2: Control Generation (7-Stufen-Pipeline) + +**Datei:** `control-pipeline/services/control_generator.py` + +Aus RAG-Chunks werden eigenstaendige "Rich Controls" erzeugt. Dies ist die aelteste Pipeline-Stufe. ```mermaid flowchart TD @@ -25,573 +77,77 @@ flowchart TD H --> I[7. Mark Processed] ``` -| Stufe | Name | Beschreibung | -|-------|------|-------------| -| 1 | **RAG Scan** | Laedt unverarbeitete Chunks aus Qdrant (Scroll-API), filtert per SHA-256-Hash | -| 2 | **License Classify** | Bestimmt die Lizenzregel (Rule 1/2/3) anhand `regulation_code` | -| 3a | **Structure (Batch)** | Rule 1+2: Strukturiert Originaltext als Control (Anthropic API) | -| 3b | **Reform (Batch)** | Rule 3: Vollstaendige Reformulierung ohne Originaltext (Anthropic API) | -| 4 | **Harmonize** | Embedding-basierte Duplikaterkennung (bge-m3, Cosine > 0.85) | -| 5 | **Anchor Search** | Findet Open-Source-Referenzen (OWASP, NIST, ENISA) | -| 6 | **Store** | Persistiert Control in `canonical_controls` mit Metadaten | -| 7 | **Mark Processed** | Markiert jeden Chunk als verarbeitet (auch bei Skip/Error/Duplikat) | +### Stufe 1: RAG Scan ---- +Laedt unverarbeitete Chunks aus Qdrant via Scroll-API. Filtert per SHA-256-Hash gegen `canonical_processed_chunks` (keine Doppelverarbeitung). -## Pipeline-Versionen - -Die Pipeline hat zwei Versionen. Die Version wird als `pipeline_version` auf `canonical_controls` und `canonical_processed_chunks` gespeichert. - -### v1 (Original) - -| Eigenschaft | Wert | -|-------------|------| -| **Vorfilter** | Lokales LLM (llama3.2 3B) entscheidet ob Chunk relevant | -| **Anthropic-Prompt** | Alter Prompt ohne null-Skip | -| **Annexe/Anhaenge** | Kein Schutz — wurden haeufig faelschlich als irrelevant uebersprungen | -| **`pipeline_version`** | `1` | - -### v2 (Aktuell) - -| Eigenschaft | Wert | -|-------------|------| -| **Vorfilter** | Optional (`skip_prefilter`). Wenn aktiviert, entscheidet Anthropic API selbst | -| **Anthropic-Prompt** | Neuer Prompt mit **null-Skip**: API gibt `null` fuer Chunks ohne Anforderung zurueck | -| **Annexe/Anhaenge** | Explizit geschuetzt — Prompt-Anweisung: "Anhaenge/Annexe enthalten oft KONKRETE technische Anforderungen — diese MUESSEN als Control erfasst werden!" | -| **`pipeline_version`** | `2` | - -#### Wesentliche Aenderungen v1 → v2 - -1. **Relevanz-Entscheidung an Anthropic delegiert** — Das lokale LLM (Vorfilter) ist optional. Die Anthropic API entscheidet selbst, welche Chunks Controls enthalten, indem sie `null` fuer irrelevante Chunks zurueckgibt. -2. **null-Skip im JSON-Array** — Das Ergebnis-Array enthaelt `null`-Eintraege fuer Chunks ohne umsetzbare Anforderung. Kein separater Vorfilter-Schritt noetig. -3. **Annexe/Anhaenge geschuetzt** — Explizite Prompt-Anweisung verhindert, dass technische Anforderungen in Anhaengen uebersprungen werden. - -#### Datenbank-Feld - -```sql --- Migration 062 -ALTER TABLE canonical_controls - ADD COLUMN pipeline_version smallint NOT NULL DEFAULT 1; - -ALTER TABLE canonical_processed_chunks - ADD COLUMN pipeline_version smallint NOT NULL DEFAULT 1; -``` - -Neue Controls erhalten automatisch `pipeline_version = 2`. Bestehende (v1) behalten `1`, damit sie spaeter identifiziert und ggf. reprocessiert werden koennen. - ---- - -## Konfiguration - -### Request-Parameter (`GenerateRequest`) - -| Parameter | Typ | Default | Beschreibung | -|-----------|-----|---------|-------------| -| `collections` | `List[str]` | Alle 5 Collections | Qdrant-Collections zum Durchsuchen | -| `domain` | `str` | — | Filter auf eine Domain (z.B. `AUTH`, `NET`) | -| `regulation_filter` | `List[str]` | — | Prefix-Matching auf `regulation_code` (z.B. `["eu_2023_1230", "owasp_"]`) | -| `skip_prefilter` | `bool` | `false` | Ueberspringt lokalen LLM-Vorfilter, sendet alle Chunks an die Anthropic API | -| `batch_size` | `int` | `5` | Chunks pro Anthropic-API-Call | -| `max_controls` | `int` | `50` | Maximale Anzahl Controls pro Job (0 = unbegrenzt) | -| `max_chunks` | `int` | `1000` | Maximale Chunks pro Job (0 = unbegrenzt, respektiert Dokumentgrenzen) | -| `skip_web_search` | `bool` | `false` | Ueberspringt Web-Suche in der Anchor-Findung (Stufe 5) | -| `dry_run` | `bool` | `false` | Trockenlauf ohne DB-Schreibzugriffe (synchron, mit Controls im Response) | - -!!! info "`regulation_filter` — Prefix-Matching" - Der Filter vergleicht den `regulation_code` jedes Chunks per Prefix. - Beispiel: `["eu_2023_1230"]` erfasst nur Chunks aus der Maschinenverordnung. - `["owasp_"]` erfasst alle OWASP-Dokumente (OWASP ASVS, OWASP SAMM, etc.). - Gross-/Kleinschreibung wird ignoriert. - -### Umgebungsvariablen - -| Variable | Default | Beschreibung | -|----------|---------|-------------| -| `ANTHROPIC_API_KEY` | — | API-Key fuer Anthropic Claude (Pflicht) | -| `CONTROL_GEN_ANTHROPIC_MODEL` | `claude-sonnet-4-6` | Anthropic-Modell fuer Strukturierung/Reformulierung | -| `OLLAMA_URL` | `http://host.docker.internal:11434` | Lokaler Ollama-Server (Vorfilter + QA) | -| `CONTROL_GEN_OLLAMA_MODEL` | `qwen3.5:35b-a3b` | Lokales LLM-Modell fuer Vorfilter und QA-Arbitrierung | -| `CONTROL_GEN_LLM_TIMEOUT` | `180` | Timeout in Sekunden pro Anthropic-API-Call | - -### Pipeline-interne Konstanten - -| Konstante | Wert | Beschreibung | -|-----------|------|-------------| -| `PIPELINE_VERSION` | `2` | Aktuelle Pipeline-Version | -| `HARMONIZATION_THRESHOLD` | `0.85` | Cosine-Similarity-Schwelle fuer Duplikaterkennung | -| `max_tokens` | `8192` | Maximale Token-Laenge der LLM-Antwort | - ---- - -## API Endpoints - -Alle Endpoints unter `/api/compliance/v1/canonical/`. - -### Uebersicht - -| Methode | Pfad | Beschreibung | -|---------|------|-------------| -| `POST` | `/generate` | Generierungs-Job starten (laeuft im Hintergrund) | -| `GET` | `/generate/status/{job_id}` | Status eines laufenden Jobs abfragen | -| `GET` | `/generate/jobs` | Alle Jobs auflisten (paginiert) | -| `GET` | `/generate/processed-stats` | Verarbeitungsstatistik pro Collection | -| `GET` | `/generate/review-queue` | Controls zur manuellen Pruefung | -| `POST` | `/generate/review/{control_id}` | Review eines einzelnen Controls abschliessen | -| `POST` | `/generate/bulk-review` | Bulk-Review nach `release_state` | -| `POST` | `/generate/qa-reclassify` | QA-Reklassifizierung bestehender Controls | -| `GET` | `/blocked-sources` | Gesperrte Quellen (Rule 3) auflisten | -| `POST` | `/blocked-sources/cleanup` | Cleanup-Workflow fuer gesperrte Quellen starten | - ---- - -### POST `/v1/canonical/generate` — Job starten - -Startet einen Generierungs-Job im Hintergrund. Gibt sofort eine `job_id` zurueck. - -**Request:** - -```json -{ - "collections": ["bp_compliance_gesetze"], - "regulation_filter": ["eu_2023_1230"], - "skip_prefilter": false, - "batch_size": 5, - "max_chunks": 500, - "max_controls": 0, - "skip_web_search": false, - "dry_run": false -} -``` - -**Response (200):** - -```json -{ - "job_id": "a1b2c3d4-...", - "status": "running", - "message": "Generation started in background. Poll /generate/status/{job_id} for progress." -} -``` - -**Beispiel:** - -```bash -# Alle Chunks der Maschinenverordnung verarbeiten -curl -X POST https://api-dev.breakpilot.ai/api/compliance/v1/canonical/generate \ - -H 'Content-Type: application/json' \ - -H 'X-Tenant-ID: 550e8400-e29b-41d4-a716-446655440000' \ - -d '{ - "collections": ["bp_compliance_ce"], - "regulation_filter": ["eu_2023_1230"], - "max_chunks": 200, - "batch_size": 5 - }' -``` - -```bash -# Dry Run: Keine DB-Aenderungen, Controls im Response -curl -X POST https://api-dev.breakpilot.ai/api/compliance/v1/canonical/generate \ - -H 'Content-Type: application/json' \ - -H 'X-Tenant-ID: 550e8400-e29b-41d4-a716-446655440000' \ - -d '{ - "collections": ["bp_compliance_gesetze"], - "max_chunks": 10, - "dry_run": true - }' -``` - -```bash -# Ohne Vorfilter: Alle Chunks direkt an Anthropic API -curl -X POST https://api-dev.breakpilot.ai/api/compliance/v1/canonical/generate \ - -H 'Content-Type: application/json' \ - -H 'X-Tenant-ID: 550e8400-e29b-41d4-a716-446655440000' \ - -d '{ - "collections": ["bp_compliance_gesetze"], - "regulation_filter": ["bdsg"], - "skip_prefilter": true, - "max_chunks": 100 - }' -``` - -!!! warning "Kosten beachten" - Ohne `regulation_filter` und mit `max_chunks: 0` werden **alle** ~105.000 Chunks verarbeitet. - Das verursacht erhebliche Anthropic-API-Kosten (~$700). - ---- - -### GET `/v1/canonical/generate/status/{job_id}` — Job-Status - -Gibt den vollstaendigen Status eines Jobs zurueck inkl. Metriken und Fehler. - -**Beispiel:** - -```bash -curl https://api-dev.breakpilot.ai/api/compliance/v1/canonical/generate/status/a1b2c3d4-... \ - -H 'X-Tenant-ID: 550e8400-e29b-41d4-a716-446655440000' -``` - -**Response:** - -```json -{ - "id": "a1b2c3d4-...", - "status": "completed", - "total_chunks_scanned": 500, - "controls_generated": 48, - "controls_verified": 45, - "controls_needs_review": 3, - "controls_too_close": 0, - "controls_duplicates_found": 12, - "controls_qa_fixed": 5, - "config": { "..." }, - "started_at": "2026-03-17T10:00:00+00:00", - "completed_at": "2026-03-17T10:15:32+00:00" -} -``` - ---- - -### GET `/v1/canonical/generate/jobs` — Alle Jobs - -Paginierte Liste aller Generierungs-Jobs. - -**Query-Parameter:** - -| Parameter | Default | Beschreibung | -|-----------|---------|-------------| -| `limit` | `20` | Anzahl Jobs (1-100) | -| `offset` | `0` | Offset fuer Paginierung | - -**Beispiel:** - -```bash -curl "https://api-dev.breakpilot.ai/api/compliance/v1/canonical/generate/jobs?limit=5" \ - -H 'X-Tenant-ID: 550e8400-e29b-41d4-a716-446655440000' -``` - ---- - -### GET `/v1/canonical/generate/review-queue` — Review-Queue - -Listet Controls auf, die eine manuelle Pruefung benoetigen. - -**Query-Parameter:** - -| Parameter | Default | Beschreibung | -|-----------|---------|-------------| -| `release_state` | `needs_review` | Filter: `needs_review`, `too_close`, `duplicate` | -| `limit` | `50` | Anzahl (1-200) | - -**Beispiel:** - -```bash -curl "https://api-dev.breakpilot.ai/api/compliance/v1/canonical/generate/review-queue?release_state=needs_review&limit=10" \ - -H 'X-Tenant-ID: 550e8400-e29b-41d4-a716-446655440000' -``` - ---- - -### POST `/v1/canonical/generate/review/{control_id}` — Review abschliessen - -Schliesst die manuelle Pruefung eines Controls ab. - -**Request:** - -```json -{ - "action": "approve", - "release_state": "draft", - "notes": "Inhaltlich korrekt, Severity passt." -} -``` - -**Moegliche `action`-Werte:** - -| Action | Neuer State | Beschreibung | -|--------|-------------|-------------| -| `approve` | `draft` (oder per `release_state` ueberschreiben) | Control freigeben | -| `reject` | `deprecated` | Control verwerfen | -| `needs_rework` | `needs_review` | Zurueck in die Queue | - -**Beispiel:** - -```bash -curl -X POST https://api-dev.breakpilot.ai/api/compliance/v1/canonical/generate/review/AUTH-042 \ - -H 'Content-Type: application/json' \ - -H 'X-Tenant-ID: 550e8400-e29b-41d4-a716-446655440000' \ - -d '{"action": "approve", "release_state": "draft"}' -``` - ---- - -### POST `/v1/canonical/generate/bulk-review` — Bulk-Review - -Aendert den `release_state` aller Controls, die einen bestimmten State haben. - -**Request:** - -```json -{ - "release_state": "needs_review", - "action": "approve", - "new_state": "draft" -} -``` - -**Beispiel:** - -```bash -# Alle needs_review Controls auf draft setzen -curl -X POST https://api-dev.breakpilot.ai/api/compliance/v1/canonical/generate/bulk-review \ - -H 'Content-Type: application/json' \ - -H 'X-Tenant-ID: 550e8400-e29b-41d4-a716-446655440000' \ - -d '{"release_state": "needs_review", "action": "approve", "new_state": "draft"}' -``` - ---- - -### GET `/v1/canonical/generate/processed-stats` — Verarbeitungsstatistik - -Liefert Statistiken pro RAG-Collection. - -**Beispiel:** - -```bash -curl https://api-dev.breakpilot.ai/api/compliance/v1/canonical/generate/processed-stats \ - -H 'X-Tenant-ID: 550e8400-e29b-41d4-a716-446655440000' -``` - -**Response:** - -```json -{ - "stats": [ - { - "collection": "bp_compliance_gesetze", - "processed_chunks": 45200, - "direct_adopted": 1850, - "llm_reformed": 120, - "skipped": 43230, - "total_chunks_estimated": 0, - "pending_chunks": 0 - } - ] -} -``` - ---- - -## Kosten und Performance - -### Kostenabschaetzung - -| Metrik | Wert | -|--------|------| -| **Kosten pro Chunk** | ~$0.0067 (Anthropic API, Batch-Modus) | -| **Yield (Controls/Chunks)** | ~4.5-10% (nur Chunks mit konkreten Anforderungen erzeugen Controls) | -| **Vorfilter-Ersparnis** | ~55% der API-Kosten wenn aktiviert (irrelevante Chunks werden lokal aussortiert) | - -### Performance-Kennzahlen - -| Metrik | Wert | -|--------|------| -| **Batch-Groesse** | 5 Chunks pro API-Call (Default) | -| **API-Aufrufe Reduktion** | ~80% weniger Aufrufe durch Batching | -| **LLM-Timeout** | 180 Sekunden pro Call | -| **QA-Overhead** | ~2s pro Control (nur bei Disagreement, ~10-15% der Controls) | - -### RAG Collections - -| Collection | Inhalte | Erwartete Regel | -|-----------|---------|----------------| -| `bp_compliance_gesetze` | Deutsche Gesetze (BDSG, TTDSG, TKG etc.) | Rule 1 | -| `bp_compliance_datenschutz` | Datenschutz-Leitlinien + EU-Verordnungen | Rule 1/2 | -| `bp_compliance_ce` | CE/Sicherheitsstandards | Rule 1/2/3 | -| `bp_dsfa_corpus` | DSFA-Korpus | Rule 1/2 | -| `bp_legal_templates` | Rechtsvorlagen | Rule 1 | - -### Aktuelle Groessenordnung - -| Metrik | Wert | -|--------|------| -| RAG-Chunks gesamt | ~105.000 (nach Dedup 2026-03-16) | -| Verarbeitete Chunks | ~105.000 | -| Generierte Controls | **~4.738** | -| Konversionsrate | ~4,5% | - ---- - -## Lizenz-Klassifikation (3-Regel-System) - -Jeder Chunk wird basierend auf `regulation_code` einer Lizenzregel zugeordnet: +### Stufe 2: License Classify (3-Regel-System) | Regel | Typ | Original erlaubt? | Beispiele | |-------|-----|-------------------|----------| -| **Rule 1** (free_use) | EU-Gesetze, NIST, DE-Gesetze, Public Domain | Ja | DSGVO, BDSG, NIS2, AI Act | +| **Rule 1** (free_use) | EU-Gesetze, NIST, DE-Gesetze | Ja | DSGVO, BDSG, NIS2, AI Act | | **Rule 2** (citation_required) | CC-BY, CC-BY-SA | Ja, mit Zitation | OWASP ASVS, OWASP SAMM | | **Rule 3** (restricted) | Proprietaer | Nein, volle Reformulierung | BSI TR-03161, ISO 27001 | -### Verarbeitung nach Regel +!!! warning "Keine Normtexte reproduzieren" + Rule 3 Quellen werden VOLLSTAENDIG reformuliert. Keine Originaltexte, keine Quellennamen im Output. -- **Rule 1+2 → `_structure_batch()`**: Anthropic strukturiert den Originaltext als Control. Ein API-Call fuer den gesamten Batch. -- **Rule 3 → `_reformulate_batch()`**: Anthropic reformuliert vollstaendig — kein Originaltext, keine Quellennamen. Ein API-Call fuer den gesamten Batch. +### Stufe 3a/3b: Strukturierung / Reformulierung -### Batch Processing +- **Rule 1+2 → `_structure_batch()`**: Originaltext als Control strukturieren +- **Rule 3 → `_reformulate_batch()`**: Vollstaendig reformulieren -Die Pipeline sammelt Chunks in Batches (Default: 5 Chunks) und sendet sie in einem einzigen Anthropic-API-Call. +Batch Processing: 5 Chunks pro Claude API-Call. Ergebnis: JSON-Array mit `null` fuer irrelevante Chunks. -1. Relevante Chunks werden mit Lizenz-Info in `pending_batch` gesammelt -2. Bei `batch_size` erreicht → `_flush_batch()` -3. Batch wird nach Lizenzregel getrennt: Rule 1+2 → `_structure_batch()`, Rule 3 → `_reformulate_batch()` -4. Ergebnis: JSON-Array mit genau N Elementen (`null` fuer irrelevante Chunks) +### Stufe 4: Harmonize (Embedding-Dedup) -**Fallback:** Bei Batch-Fehler (Timeout, Parsing-Error) wird automatisch auf Einzelverarbeitung zurueckgefallen. +Cosine Similarity > 0.85 via Qdrant → Duplikat. Zwei-Tier: + +- **Score >= 0.92**: Automatisch als Duplikat markiert +- **Score 0.85-0.92**: Lokales LLM (qwen3.5) verifiziert + +### Stufe 5: Anchor Search + +Findet Open-Source-Referenzen (OWASP, NIST, ENISA) via Qdrant-Vektorsuche gegen offene Collections. + +### Stufe 6+7: Store + Mark Processed + +Persistiert Controls in `canonical_controls` mit allen Metadaten. Markiert jeden Chunk als verarbeitet. + +### Aktueller Stand + +| Metrik | Wert | +|--------|------| +| RAG-Chunks gesamt | ~105.000 | +| Generierte Rich Controls | ~32.793 (draft) | +| Pipeline-Version | 3 (mit Scoped Applicability) | --- -## Chunk-Tracking (Processed Chunks) +## Phase 3: Pass 0a — Obligation Extraction -### Tabelle `canonical_processed_chunks` +**Datei:** `control-pipeline/services/decomposition_pass.py` +**Funktion:** `DecompositionPass.submit_batch_pass0a()` -| Spalte | Typ | Beschreibung | -|--------|-----|-------------| -| `chunk_hash` | VARCHAR(64) | SHA-256 Hash des Chunk-Textes | -| `collection` | VARCHAR(100) | Qdrant-Collection | -| `regulation_code` | VARCHAR(100) | Quell-Regulation (z.B. `bdsg`, `eu_2016_679`) | -| `license_rule` | INTEGER | 1, 2 oder 3 | -| `processing_path` | VARCHAR(20) | Wie der Chunk verarbeitet wurde | -| `generated_control_ids` | JSONB | UUIDs der generierten Controls | -| `pipeline_version` | SMALLINT | Pipeline-Version (1 oder 2) | -| `job_id` | UUID | Referenz auf den Generierungs-Job | - -**UNIQUE Constraint:** `(chunk_hash, collection, document_version)` — verhindert Doppelverarbeitung. - -### Processing Paths - -| Wert | Stufe | Bedeutung | -|------|-------|-----------| -| `prefilter_skip` | 2 | Lokaler LLM-Vorfilter: Chunk nicht relevant | -| `structured` | 3a | Einzelner Chunk strukturiert (Rule 1/2) | -| `structured_batch` | 3a | Batch-Strukturierung (Rule 1/2) | -| `llm_reform` | 3b | Einzelner Chunk reformuliert (Rule 3) | -| `llm_reform_batch` | 3b | Batch-Reformulierung (Rule 3) | -| `no_control` | 3 | LLM konnte kein Control ableiten (null im Array) | -| `store_failed` | 6 | DB-Speichern fehlgeschlagen | -| `error` | — | Unerwarteter Fehler | - ---- - -## QA Validation (Automatische Qualitaetspruefung) - -Die QA-Stufe validiert die Klassifizierung jedes generierten Controls: - -1. **LLM-Category:** Anthropic liefert `category` und `domain` im JSON-Response -2. **Keyword-Detection:** `_detect_category(chunk.text)` liefert eine zweite Meinung -3. **Stimmen beide ueberein?** → Schneller Pfad (kein QA noetig) -4. **Bei Disagreement:** Lokales LLM (Ollama) arbitriert -5. **Auto-Fix:** Category/Domain werden automatisch korrigiert - -Die QA-Metriken werden in `generation_metadata` gespeichert: - -```json -{ - "qa_category_fix": {"from": "authentication", "to": "finance", "reason": "IFRS-Thema"}, - "qa_domain_fix": {"from": "AUTH", "to": "FIN", "reason": "Finanzregulierung"} -} -``` - -### Recital-Erkennung (Erwägungsgrund-Detektion) - -Die QA-Stufe prueft zusaetzlich, ob der `source_original_text` eines Controls tatsaechlich aus einem Gesetzesartikel stammt — oder aus einem Erwaegungsgrund (Recital). Erwaegungsgruende enthalten keine normativen Pflichten und fuehren zu falsch zugeordneten Controls. - -**Erkennungsmethoden:** - -| Methode | Pattern | Beispiel | -|---------|---------|----------| -| **Regex** | `\((\d{1,3})\)\s*\n` — Erwaegungsgrund-Nummern | `(126)\nUm den Verwaltungsaufwand...` | -| **Phrasen** | Typische Recital-Formulierungen (≥2 Treffer) | "daher sollte", "in Erwägung nachstehender Gründe" | - -**Ergebnis bei Verdacht:** - -- `release_state` wird auf `needs_review` gesetzt -- `generation_metadata.recital_suspect = true` -- `generation_metadata.recital_detection` enthaelt Details: - -```json -{ - "recital_suspect": true, - "recital_detection": { - "recital_suspect": true, - "recital_numbers": ["126", "127"], - "recital_phrases": ["daher sollte"], - "detection_method": "regex+phrases" - } -} -``` - -**Funktion:** `_detect_recital(text)` in `control_generator.py` - -**Hintergrund:** Bei der Analyse von ~5.500 Controls mit Quelltext wurden 1.555 (28%) als Erwaegungsgrund-Verdacht identifiziert. Der Document Crawler unterschied nicht zwischen Artikeltext und Erwaegungsgruenden, was zu falschen `article`/`paragraph`-Zuordnungen fuehrte. - -### QA-Reklassifizierung bestehender Controls - -```bash -# Dry Run: Welche AUTH-Controls sind falsch klassifiziert? -curl -X POST https://api-dev.breakpilot.ai/api/compliance/v1/canonical/generate/qa-reclassify \ - -H 'Content-Type: application/json' \ - -H 'X-Tenant-ID: 550e8400-e29b-41d4-a716-446655440000' \ - -d '{"limit": 50, "dry_run": true, "filter_domain_prefix": "AUTH"}' - -# Korrekturen anwenden: -curl -X POST https://api-dev.breakpilot.ai/api/compliance/v1/canonical/generate/qa-reclassify \ - -H 'Content-Type: application/json' \ - -H 'X-Tenant-ID: 550e8400-e29b-41d4-a716-446655440000' \ - -d '{"limit": 50, "dry_run": false, "filter_domain_prefix": "AUTH"}' -``` - ---- - -## Quelldateien - -| Datei | Beschreibung | -|-------|-------------| -| `backend-compliance/compliance/services/control_generator.py` | 7-Stufen-Pipeline mit Batch Processing | -| `backend-compliance/compliance/api/control_generator_routes.py` | REST API Endpoints | -| `backend-compliance/compliance/services/license_gate.py` | Lizenz-Gate-Logik | -| `backend-compliance/compliance/services/similarity_detector.py` | Too-Close-Detektor (5 Metriken) | -| `backend-compliance/compliance/services/rag_client.py` | RAG-Client (Qdrant Search + Scroll) | -| `backend-compliance/migrations/046_control_generator.sql` | Job-Tracking, Chunk-Tracking Tabellen | -| `backend-compliance/migrations/048_processing_path_expand.sql` | Erweiterte Processing-Path-Werte | -| `backend-compliance/migrations/062_pipeline_version.sql` | `pipeline_version` Spalte | -| `backend-compliance/tests/test_control_generator.py` | 98+ Tests (Lizenz, Domain, Batch, Pipeline, Recital, Source-Type) | - ---- - -## Pass 0a/0b: Atomare Control-Zerlegung - -Die Pipeline v3 erweitert die 7-Stufen-Pipeline um einen Vor-Pass, der Rich Controls in atomare Controls zerlegt. - -### Pass 0a: Obligation Extraction - -Extrahiert individuelle normative Pflichten aus Rich Controls via LLM. +Extrahiert individuelle normative Pflichten aus Rich Controls via Claude Haiku (Anthropic Batch API, 50% Kostenreduktion). ```mermaid flowchart LR - A[Rich Control] -->|LLM| B[Obligations] + A[Rich Control] -->|Claude Haiku| B[Obligations] B --> C{Quality Gate} C -->|Pass| D[validated] C -->|Fail| E[rejected] ``` -**3-Tier Klassifikation:** +### 3-Tier Klassifikation -| Typ | Erkennungsmuster | Beispiel | -|-----|-----------------|---------| +| Typ | Signal | Beispiel | +|-----|--------|---------| | **Pflicht** | muss, ist verpflichtet, hat sicherzustellen | "Der Verantwortliche MUSS ein Verzeichnis fuehren" | | **Empfehlung** | soll, sollte, wird empfohlen | "Es SOLLTE eine Risikobewertung durchgefuehrt werden" | | **Kann** | kann, darf, ist berechtigt | "Die Aufsichtsbehoerde KANN Geldbussen verhaengen" | -**Quality Gate (6 Regeln):** +### Quality Gate (6 Regeln) 1. Nur normative Aussagen (muss, sicherzustellen, verpflichtet) 2. Ein Hauptverb pro Obligation @@ -600,53 +156,380 @@ flowchart LR 5. Nicht auf Evidence-Ebene splitten 6. Parent-Link immer erhalten -### Pass 0b: Atomic Control Composition +### Obligation-Felder -Verwandelt jede validierte Obligation in ein eigenstaendiges atomares Control. +| Feld | Beschreibung | +|------|-------------| +| `obligation_text` | Vollstaendiger Pflichttext | +| `action` | Hauptverb (z.B. "implementieren") | +| `object` | Gegenstand (z.B. "Rate-Limiting") | +| `condition` | Bedingung (optional) | +| `normative_strength` | must / should / may | +| `is_test_obligation` | Testpflicht? | +| `is_reporting_obligation` | Meldepflicht? | +| `trigger_type` | event / periodic / continuous | -```mermaid -flowchart LR - A[Obligation] -->|LLM| B[Atomic Control] - B -->|Dedup Check| C{4-Stage Dedup} - C -->|NEW| D[Insert + Index] - C -->|LINK| E[Parent-Link] - C -->|REVIEW| F[Review-Queue] -``` - -**Konfiguration:** - -| Variable | Default | Beschreibung | -|----------|---------|-------------| -| `DECOMPOSITION_LLM_MODEL` | `claude-sonnet-4-6` | LLM fuer Pass 0a/0b | -| `DECOMPOSITION_BATCH_SIZE` | `5` | Obligations pro LLM-Call | -| `DECOMPOSITION_LLM_TIMEOUT` | `120` | Timeout in Sekunden | - -**Ergebnisse (Stand 2026-03-21):** +### Aktueller Stand | Metrik | Wert | |--------|------| -| Rich Controls (technisch) | ~6.800 | -| Atomare Controls (bisher) | 30 (PoC: 10x CRYP, AUTH, SEC) | -| Ziel nach Full Run | ~18.000 unique Master Controls | -| Obligations pro Rich Control | ~10 | -| Dedup-Reduktion erwartet | ~70% | +| Validierte Obligations | ~180.827 | +| Obligations pro Rich Control | ~5-10 | -### Quelldateien (Pass 0a/0b) +--- -| Datei | Beschreibung | -|-------|-------------| -| `compliance/services/decomposition_pass.py` | Pass 0a + 0b Logik | -| `compliance/services/control_dedup.py` | 4-Stufen Dedup-Engine | -| `migrations/061_obligation_candidates.sql` | Obligation-Tabelle | -| `migrations/074_control_dedup.sql` | Dedup-Tabellen (Parent-Links, Review-Queue) | -| `tests/test_decomposition_pass.py` | 90 Tests | -| `tests/test_control_dedup.py` | 56 Tests | +## Phase 4: Pass 0b — Atomic Control Composition + +**Datei:** `control-pipeline/services/decomposition_pass.py` +**Funktion:** `DecompositionPass.submit_batch_pass0b()` + +Verwandelt jede validierte Obligation in ein eigenstaendiges atomares Control via Claude Sonnet (Batch API). + +### Pre-LLM Filter (Ontology) + +**Datei:** `control-pipeline/services/control_ontology.py` + +Vor dem LLM-Call werden Obligations klassifiziert um Kosten zu sparen: + +| Routing | Beschreibung | Aktion | +|---------|-------------|--------| +| `atomic` | Echte atomare Pflicht | An LLM senden | +| `composite` | Container-Obligation (z.B. "Sichere Sitzungsverwaltung umsetzen") | Ueberspringen | +| `evidence` | Nachweis-Pflicht (z.B. "Screenshot der MFA-Konfiguration") | Ueberspringen | +| `framework_container` | Framework-Referenz (z.B. "OWASP ASVS V3 umsetzen") | Ueberspringen | + +### Control Ontology (26 Action Types) + +| Action Type | Phase | Deutsche Aliases | +|---|---|---| +| define | definition | definieren, festlegen, bestimmen | +| implement | implementation | implementieren, umsetzen, einfuehren | +| configure | configuration | konfigurieren, einstellen | +| enforce | implementation | durchsetzen, erzwingen | +| monitor | monitoring | ueberwachen, beobachten | +| test | testing | testen, Test durchfuehren | +| review | review | ueberpruefen, pruefen | +| assess | assessment | bewerten, beurteilen | +| train | training | schulen, unterweisen | +| report | reporting | melden, berichten | +| prevent | implementation | verhindern, unterbinden | +| exclude | implementation | ausschliessen, verbieten | +| ... | ... | (26 Typen gesamt, siehe `control_ontology.py`) | + +### MCP-taugliche Output-Felder + +Jedes atomare Control hat Felder die MCP-Scanner verwenden koennen: + +| Feld | Beschreibung | Beispiel | +|------|-------------|---------| +| `assertion` | Pruefbare Aussage | "Alle API-Endpunkte haben Rate-Limiting konfiguriert" | +| `pass_criteria` | Wann erfuellt? | ["Rate-Limit < 100 req/min", "429 Response bei Ueberschreitung"] | +| `fail_criteria` | Wann nicht erfuellt? | ["Kein Rate-Limiting konfiguriert", "Unbegrenzter Durchsatz"] | +| `check_type` | Pruefmethode | technical_config_check / document_clause_check / code_pattern_check | +| `merge_key` | Dedup-Key | "implement:api_rate_limiting:implementation" | +| `dependency_hints` | Abhaengigkeits-Hinweise | ["prerequisite:define:api_security_policy"] | +| `lifecycle_phase_order` | Lebenszyklusphase 1-13 | 4 (implementation) | + +### Canonical Key Format + +``` +action_type:normalized_object:control_phase[:asset_scope] +``` + +Beispiel: `implement:api_rate_limiting:implementation:api_endpoints` + +### Aktueller Stand + +| Metrik | Wert | +|--------|------| +| Verarbeitete Obligations (Test) | ~1.000 | +| Erzeugte atomare Controls | 562 | +| Merge-Key Coverage | 99.8% | +| MCP-Feld Coverage | 100% (neue Batches) | + +--- + +## Phase 5: Deduplizierung + +**Datei:** `control-pipeline/services/control_generator.py` (Harmonization) + +### 3-Stufen Entscheidungsbaum + +```mermaid +flowchart TD + A[Atomic Control] --> B{Merge-Key gleich?} + B -->|Ja| C{Embedding Similarity} + B -->|Nein| D[NEW CONTROL] + C -->|>= 0.92| E[AUTO-LINK] + C -->|0.85 - 0.92| F{LLM Verify} + C -->|< 0.85| D + F -->|Duplikat| E + F -->|Verschieden| D +``` + +1. **Merge-Key Grouping**: Controls mit gleichem `action_type:normalized_object` werden verglichen +2. **Embedding Similarity**: bge-m3 Embeddings, Cosine Distance +3. **LLM Verification**: Lokales qwen3.5 (think:false) fuer Grenzfaelle (0.85-0.92) + +### Multi-Parent-Linking + +Ein atomares Control kann aus mehreren Regulierungen stammen: + +```json +{ + "control_id": "AUTH-1072", + "title": "MFA fuer privilegierte Accounts aktiviert", + "parent_links": [ + {"source": "NIST IA-02(01)", "regulation": "nist_sp_800_53"}, + {"source": "NIS2 Art. 21", "regulation": "eu_2022_2555"}, + {"source": "DSGVO Art. 32", "regulation": "eu_2016_679"} + ] +} +``` + +--- + +## Phase 6: Dependency Engine + Evaluation + +**Datei:** `control-pipeline/services/dependency_engine.py` +**Generator:** `control-pipeline/services/dependency_generator.py` +**Domain Packs:** `control-pipeline/data/domain_packs/*.yaml` + +Controls sind nicht unabhaengig — sie haben logische Abhaengigkeiten. Die Dependency Engine modelliert diese generisch. + +### 5 Dependency-Typen + +| Typ | Prioritaet | Beschreibung | Beispiel | +|-----|-----------|-------------|---------| +| `supersedes` | 10 (staerkste) | A ersetzt B vollstaendig | GHV-Klausel im Vertrag → Schulung nicht noetig | +| `scope_exclusion` | 20 | A schliesst B aus dem Scope aus | "Kein KI-Einsatz" → KI-Controls not_applicable | +| `prerequisite` | 50 | A muss vor B existieren | Policy definieren → Policy implementieren | +| `conditional_requirement` | 70 | B nur unter Bedingung X | Enhanced Logging nur fuer grosse Unternehmen | +| `compensating_control` | 80 (schwaechste) | A mildert B-Failure | ISO-Zertifizierung kompensiert Einzelcontrols | + +### Evaluation-Status + +| Status | Bedeutung | +|--------|-----------| +| `pass` | Control erfuellt | +| `fail` | Control nicht erfuellt | +| `not_applicable` | Nicht anwendbar (durch Dependency oder Scope) | +| `partially_satisfied` | Teilweise erfuellt | +| `compensated_fail` | Nicht erfuellt, aber kompensiert | +| `review_required` | Manuelle Pruefung noetig (z.B. bei Zyklen) | + +### Generische Condition Language + +Dependencies verwenden eine regelbasierte Sprache: + +```json +{ + "operator": "AND", + "clauses": [ + {"field": "source.status", "op": "==", "value": "pass"}, + {"field": "context.company_size", "op": "in", "value": ["large", "enterprise"]} + ] +} +``` + +**Felder:** `source.status`, `target.status`, `context.industry`, `context.company_size`, `context.scope_signals` +**Operatoren:** `==`, `!=`, `in`, `not_in`, `>`, `<`, `>=`, `<=`, `AND`, `OR`, `NOT` + +### Evaluation-Algorithmus + +1. Adjacency-List bauen (target → Dependencies) +2. Zyklen erkennen (DFS) → betroffene Controls = `review_required` +3. Topologisch sortieren (Kahn's Algorithmus) +4. Fuer jedes Control: Conditions pruefen, Effects sammeln, Priority-Konflikt loesen +5. Dependency-Trace fuer MCP-Output aufzeichnen + +### Automatische Dependency-Generierung + +3 Strategien: + +1. **Ontology-basiert**: Controls mit gleichem `normalized_object` und aufeinanderfolgenden Phasen → `prerequisite` +2. **Pattern-basiert**: Regeln wie "define → implement", "implement → monitor" +3. **Domain Packs** (YAML): DSGVO, AI Act, CRA, Security, Arbeitsrecht + +### Beispiel: GHV-Szenario + +```yaml +MC-001: GHV-Klausel im Arbeitsvertrag vorhanden +MC-002: Vertraulichkeitsschulung durchgefuehrt +MC-003: Jaehrliche Nachschulung durchgefuehrt + +Dependencies: + MC-001 supersedes MC-002 (wenn MC-001 = pass) + MC-002 prerequisite MC-003 +``` + +**Fall 1:** Vertrag hat GHV → MC-002 + MC-003 = `not_applicable` (kein unnoeiger Aufwand) +**Fall 2:** Vertrag fehlt, Schulung vorhanden → MC-002 = `pass`, MC-003 erforderlich + +### MCP-Output mit Dependency-Trace + +```json +{ + "control_id": "MC-002", + "raw_status": "fail", + "resolved_status": "not_applicable", + "dependency_resolution": [ + { + "dependency_type": "supersedes", + "source_control_id": "MC-001", + "source_status": "pass", + "condition_met": true, + "effect_applied": {"set_status": "not_applicable"}, + "priority": 10 + } + ] +} +``` + +--- + +## Phase C2: Applicability Engine + +**Datei:** `control-pipeline/services/applicability_engine.py` + +Filtert Controls basierend auf dem Unternehmensprofil (Branche, Groesse, Scope-Signale). + +### Zwei-Schicht-Filterung + +1. **Deterministischer Filter** (schnell): SQL + Python Pre-Filter auf `applicable_industries`, `applicable_company_size`, `scope_conditions` +2. **Assessment Layer**: Confidence-Scoring, Eskalationserkennung, Reasoning + +### Scope-Signale + +Controls koennen `scope_conditions` haben, die bestimmte Unternehmenssignale erfordern: + +```json +{ + "scope_conditions": { + "requires_any": ["has_ai_system", "uses_third_party_ai"] + } +} +``` + +Wenn das Unternehmen keines dieser Signale hat → Control nicht anwendbar. + +--- + +## Document Compliance Engine + +**Datei:** `control-pipeline/services/document_scope_resolver.py` + +Bestimmt welche rechtlichen Dokumente ein Unternehmen braucht, basierend auf Business-Flags: + +| Flag | Erforderliches Dokument | +|------|----------------------| +| `has_website` | Impressum, Datenschutzerklaerung | +| `uses_cookies` | Cookie-Banner, Cookie-Richtlinie | +| `sells_online` | AGB, Widerrufsbelehrung, Preisangabenverordnung | +| `processes_personal_data` | DSGVO Verarbeitungsverzeichnis | +| `uses_ai_system` | KI-Transparenzhinweis | +| `sells_electronics` | WEEE-Entsorgungshinweis | + +--- + +## Qualitaetsmetriken + +**Endpoint:** `GET /v1/canonical/generate/quality-metrics` + +| Metrik | Zielwert | Aktuell | +|--------|---------|---------| +| Controls pro Obligation | 0.2-0.4 | 0.56 (vor Dedup) | +| Duplikat-Merge-Key-Rate | < 5% | 0.2% | +| Evidence-Leak-Rate | < 2% | 0.0% | +| Truncated-Title-Rate | 0% | 0.0% | +| Merge-Key Coverage | 100% | 99.8% | +| MCP-Feld Coverage | 100% | 100% (neue Batches) | + +--- + +## API Endpoints + +Alle Endpoints unter dem Control Pipeline Service (Port 8098). + +### Control Generation + +| Methode | Pfad | Beschreibung | +|---------|------|-------------| +| `POST` | `/v1/canonical/generate` | Generierungs-Job starten | +| `GET` | `/v1/canonical/generate/status/{job_id}` | Job-Status abfragen | +| `GET` | `/v1/canonical/generate/quality-metrics` | Qualitaetsmetriken | +| `POST` | `/v1/canonical/generate/submit-pass0b` | Pass 0b Batch einreichen | +| `POST` | `/v1/canonical/generate/process-batch` | Batch-Ergebnisse verarbeiten | +| `GET` | `/v1/canonical/generate/batch-api-status/{id}` | Anthropic Batch Status | + +### Controls CRUD + +| Methode | Pfad | Beschreibung | +|---------|------|-------------| +| `GET` | `/v1/canonical/controls` | Alle Controls (filterbar) | +| `GET` | `/v1/canonical/controls/{id}` | Einzelnes Control | +| `POST` | `/v1/canonical/controls/applicable` | Applicability-Filter | +| `GET` | `/v1/canonical/controls/{id}/traceability` | Traceability-Chain | + +### Dependencies + +| Methode | Pfad | Beschreibung | +|---------|------|-------------| +| `GET` | `/v1/dependencies` | Dependencies auflisten | +| `POST` | `/v1/dependencies` | Dependency erstellen | +| `POST` | `/v1/dependencies/generate` | Auto-Generierung | +| `POST` | `/v1/dependencies/evaluate` | Controls evaluieren | +| `POST` | `/v1/dependencies/validate` | Zyklen pruefen | +| `GET` | `/v1/dependencies/graph` | Graph fuer Visualisierung | + +### Document Compliance + +| Methode | Pfad | Beschreibung | +|---------|------|-------------| +| `POST` | `/v1/document-compliance/required` | Erforderliche Dokumente | + +--- + +## Datenbanktabellen + +| Tabelle | Schema | Beschreibung | +|---------|--------|-------------| +| `canonical_controls` | compliance | Alle Controls (rich + atomic) | +| `obligation_candidates` | compliance | Extrahierte Obligations (Pass 0a) | +| `control_parent_links` | compliance | M:N Parent-Child-Beziehungen | +| `control_dependencies` | compliance | Abhaengigkeiten zwischen Controls | +| `control_evaluation_results` | compliance | Evaluierungsergebnisse mit Traces | +| `canonical_processed_chunks` | compliance | Verarbeitete RAG-Chunks | +| `canonical_generation_jobs` | compliance | Generierungs-Jobs | + +--- + +## Quelldateien + +| Datei | Repo | Beschreibung | +|-------|------|-------------| +| `services/control_generator.py` | core | 7-Stufen Control Generation Pipeline | +| `services/decomposition_pass.py` | core | Pass 0a + 0b (Obligation → Atomic Control) | +| `services/control_ontology.py` | core | 26 Action Types, Phase Ordering, Pre-LLM Filter | +| `services/dependency_engine.py` | core | Dependency Evaluation (5 Typen, Cycle Detection) | +| `services/dependency_generator.py` | core | Auto-Generierung (Ontology + Pattern + Domain Packs) | +| `services/applicability_engine.py` | core | Scope-basierte Applicability-Filterung | +| `services/document_scope_resolver.py` | core | 28 Document Compliance Rules | +| `services/anchor_finder.py` | core | Open-Source Anchor Search (Qdrant) | +| `data/domain_packs/*.yaml` | core | 5 Domain Packs (GDPR, AI Act, CRA, Security, Arbeitsrecht) | +| `tests/test_dependency_engine.py` | core | 39 Tests (Dependency Engine) | +| `tests/test_dependency_generator.py` | core | 14 Tests (Auto-Generierung) | +| `tests/test_golden_controls.py` | core | 37 Tests (Golden Test Suite, alle 8 Kategorien) | +| `tests/test_control_ontology.py` | core | 36 Tests (Ontology-Klassifikation) | + +**Tests gesamt:** 126+ (alle bestanden) --- ## Verwandte Dokumentation -- [Canonical Control Library (CP-CLIB)](canonical-control-library.md) — Domains, Datenmodell, Too-Close-Detektor, CI/CD Validation -- [Deduplizierungs-Engine](dedup-engine.md) — 4-Stufen Dedup, Multi-Parent-Linking, Review-Queue -- [RAG Pipeline Benchmark](../../development/rag-pipeline-benchmark.md) — State-of-the-Art Vergleich, Optimierungsempfehlungen -- [Multi-Layer Control Architecture](canonical-control-library.md#multi-layer-control-architecture) — 10-Stage Pipeline-Erweiterung mit Obligations, Patterns, Crosswalk +- [Canonical Control Library (CP-CLIB)](canonical-control-library.md) — Domains, Datenmodell, Lizenz-Gate +- [Deduplizierungs-Engine](dedup-engine.md) — Multi-Parent-Linking, Review-Queue +- [Obligations v2 (CP-OBL)](obligations.md) — Obligation-Datenmodell +- [Normative Verbindlichkeit](normative-verbindlichkeit.md) — Dreistufenmodell (Pflicht/Empfehlung/Kann) +- [Evidence Type](evidence-type.md) — Code vs. Prozess Evidence diff --git a/docs-src/services/sdk-modules/dependency-engine.md b/docs-src/services/sdk-modules/dependency-engine.md new file mode 100644 index 0000000..8bf51b1 --- /dev/null +++ b/docs-src/services/sdk-modules/dependency-engine.md @@ -0,0 +1,228 @@ +# Control Dependency Engine + +Generische Engine zur Modellierung und Auswertung von Abhaengigkeiten zwischen Compliance Controls. Stellt sicher, dass Controls nicht isoliert bewertet werden, sondern im Kontext ihrer logischen Beziehungen. + +**Datei:** `control-pipeline/services/dependency_engine.py` +**Generator:** `control-pipeline/services/dependency_generator.py` +**Domain Packs:** `control-pipeline/data/domain_packs/` +**API:** `/v1/dependencies/` + +--- + +## Motivation + +Ohne Dependency-Logik: + +- System fordert Schulung obwohl Vertrag vorhanden +- Kunde verliert Vertrauen +- Falsche Findings, unnoetige Massnahmen + +Mit Dependency-Logik: + +- "Control B wurde nicht geprueft, weil Control A bestanden hat" +- "Control C ist fehlgeschlagen, aber durch Control E kompensiert" +- Korrekte Audit-Ergebnisse, weniger False Positives + +--- + +## 5 Dependency-Typen (v1) + +```mermaid +flowchart LR + subgraph Stark + A[supersedes Prio=10] + B[scope_exclusion Prio=20] + end + subgraph Mittel + C[prerequisite Prio=50] + D[conditional_requirement Prio=70] + end + subgraph Schwach + E[compensating_control Prio=80] + end +``` + +| Typ | Prioritaet | Bedeutung | Beispiel | +|-----|-----------|-----------|---------| +| `supersedes` | 10 | A macht B ueberfluessig | GHV-Klausel → Schulung | +| `scope_exclusion` | 20 | A schliesst B aus | Kein KI → KI-Controls | +| `prerequisite` | 50 | A muss vor B existieren | Policy definieren → implementieren | +| `conditional_requirement` | 70 | B nur unter Bedingung | Enhanced Logging nur fuer Grosse | +| `compensating_control` | 80 | A kompensiert B-Failure | ISO-Cert → Einzelcontrols | + +--- + +## Condition Language + +Jede Dependency hat eine `condition` (JSONB) die gegen einen Kontext ausgewertet wird: + +### Einfache Bedingung + +```json +{"field": "source.status", "op": "==", "value": "pass"} +``` + +### Zusammengesetzte Bedingung + +```json +{ + "operator": "AND", + "clauses": [ + {"field": "source.status", "op": "==", "value": "pass"}, + {"field": "context.company_size", "op": "in", "value": ["large", "enterprise"]} + ] +} +``` + +### Negation + +```json +{ + "operator": "NOT", + "clause": {"field": "context.scope_signals", "op": "contains", "value": "uses_ai"} +} +``` + +### Verfuegbare Felder + +| Feld | Beschreibung | +|------|-------------| +| `source.status` | Status des Quell-Controls | +| `target.status` | Status des Ziel-Controls | +| `context.industry` | Branche des Unternehmens | +| `context.company_size` | Unternehmensgroesse | +| `context.scope_signals` | Scope-Signale (Liste) | + +### Operatoren + +`==`, `!=`, `in`, `not_in`, `>`, `<`, `>=`, `<=`, `contains`, `AND`, `OR`, `NOT` + +--- + +## Evaluation-Algorithmus + +```mermaid +flowchart TD + A[Alle Dependencies laden] --> B[Zyklen erkennen DFS] + B --> C{Zyklen?} + C -->|Ja| D[Betroffene Controls = review_required] + C -->|Nein| E[Topologisch sortieren] + E --> F[Fuer jedes Control:] + F --> G[Conditions pruefen] + G --> H[Matching Effects sammeln] + H --> I[Hoechste Prioritaet gewinnt] + I --> J[Status setzen + Trace schreiben] +``` + +### Priority-basierte Konfliktloesung + +Wenn mehrere Dependencies auf dasselbe Control wirken, gewinnt die mit der **niedrigsten** Prioritaetsnummer: + +- `scope_exclusion` (Prio 20) schlaegt `compensating_control` (Prio 80) +- `supersedes` (Prio 10) schlaegt alles + +### Cycle Detection + +Zyklen (A → B → A) werden via DFS erkannt. Betroffene Controls erhalten `review_required` mit Confidence 0.5. + +--- + +## Automatische Generierung + +### 1. Ontology-basiert + +Controls mit gleichem `normalized_object` und verschiedenen Lifecycle-Phasen: + +``` +define:access_policy (Phase 2) + → prerequisite fuer → +implement:access_policy (Phase 4) + → prerequisite fuer → +test:access_policy (Phase 8) +``` + +### 2. Pattern-basiert + +| Regel | Source | Target | Dependency | +|-------|--------|--------|-----------| +| define_before_implement | define | implement | prerequisite | +| implement_before_monitor | implement/configure | monitor/test | prerequisite | +| define_before_enforce | define | enforce | prerequisite | +| train_before_review | train | review/assess | prerequisite | + +### 3. Domain Packs (YAML) + +Regulierungsspezifische Regeln in YAML-Dateien: + +**DSGVO (`gdpr.yaml`):** +- Verarbeitungsverzeichnis → DSFA (prerequisite) +- Rechtsgrundlage → Datenverarbeitung (prerequisite) + +**Security (`security.yaml`):** +- MFA → Passwortkomplexitaet (compensating_control) +- ISO-Cert → Einzelcontrols (compensating_control) + +**AI Act (`ai_act.yaml`):** +- Risikoklassifizierung → High-Risk-Anforderungen (prerequisite) +- FRIA → KI-Einsatz (prerequisite) + +**CRA (`cra.yaml`):** +- SBOM → Vulnerability Monitoring (prerequisite) +- CE-Zertifizierung → Einzelnachweise (compensating_control) + +**Arbeitsrecht (`labor_contracts.yaml`):** +- GHV-Klausel → Schulung (supersedes) +- Erstschulung → Nachschulung (prerequisite) + +--- + +## API Endpoints + +| Methode | Pfad | Beschreibung | +|---------|------|-------------| +| `GET` | `/v1/dependencies/` | Dependencies auflisten (filterbar) | +| `POST` | `/v1/dependencies/` | Dependency manuell erstellen | +| `DELETE` | `/v1/dependencies/{id}` | Dependency deaktivieren | +| `POST` | `/v1/dependencies/generate` | Auto-Generierung (dry_run default) | +| `POST` | `/v1/dependencies/evaluate` | Controls evaluieren | +| `GET` | `/v1/dependencies/evaluate/{run_id}` | Ergebnisse abrufen | +| `POST` | `/v1/dependencies/validate` | Zyklen pruefen | +| `GET` | `/v1/dependencies/graph` | Graph (Nodes + Edges) | + +--- + +## DB-Schema + +### `control_dependencies` + +| Spalte | Typ | Beschreibung | +|--------|-----|-------------| +| `id` | UUID | Primaerschluessel | +| `source_control_id` | UUID FK | Quell-Control | +| `target_control_id` | UUID FK | Ziel-Control (wird beeinflusst) | +| `dependency_type` | VARCHAR(30) | Typ (5 Werte) | +| `condition` | JSONB | Generische Bedingung | +| `effect` | JSONB | Effekt bei Bedingung=true | +| `priority` | INT | Niedrig = hohe Prioritaet | +| `generation_method` | VARCHAR(30) | manual / ontology / pattern / domain_pack | +| `is_active` | BOOLEAN | Soft-Delete | + +### `control_evaluation_results` + +| Spalte | Typ | Beschreibung | +|--------|-----|-------------| +| `control_id` | UUID FK | Ausgewertetes Control | +| `evaluation_run_id` | UUID | Gruppiert einen Lauf | +| `raw_status` | VARCHAR(30) | Status vor Dependencies | +| `resolved_status` | VARCHAR(30) | Status nach Dependencies | +| `dependency_resolution` | JSONB | Vollstaendiger Trace | +| `confidence` | FLOAT | 0.0-1.0 | + +--- + +## Tests + +| Testdatei | Tests | Beschreibung | +|-----------|-------|-------------| +| `test_dependency_engine.py` | 39 | Condition Evaluator, Effect Applier, Cycle Detection, Topological Sort, GHV-Szenario | +| `test_dependency_generator.py` | 14 | Ontology, Pattern, Domain Pack Generation | diff --git a/mkdocs.yml b/mkdocs.yml index 8a3af81..4cc4e9c 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -107,6 +107,7 @@ nav: - Policy-Bibliothek (29 Richtlinien): services/sdk-modules/policy-bibliothek.md - Canonical Control Library (CP-CLIB): services/sdk-modules/canonical-control-library.md - Control Generator Pipeline: services/sdk-modules/control-generator-pipeline.md + - Dependency Engine: services/sdk-modules/dependency-engine.md - Deduplizierungs-Engine: services/sdk-modules/dedup-engine.md - Control Provenance Wiki: services/sdk-modules/control-provenance.md - Normative Verbindlichkeit (Dreistufenmodell): services/sdk-modules/normative-verbindlichkeit.md