Some checks failed
CI/CD / go-lint (push) Has been skipped
CI/CD / python-lint (push) Has been skipped
CI/CD / nodejs-lint (push) Has been skipped
CI/CD / test-go-ai-compliance (push) Failing after 47s
CI/CD / test-python-backend-compliance (push) Successful in 33s
CI/CD / test-python-document-crawler (push) Successful in 24s
CI/CD / test-python-dsms-gateway (push) Successful in 18s
CI/CD / validate-canonical-controls (push) Successful in 11s
CI/CD / Deploy (push) Has been skipped
Implements the full Multi-Layer Control Architecture for migrating ~25,000 Rich Controls into atomic, deduplicated Master Controls with full traceability. Architecture: Legal Source → Obligation → Control Pattern → Master Control → Customer Instance New services: - ObligationExtractor: 3-tier extraction (exact → embedding → LLM) - PatternMatcher: 2-tier matching (keyword + embedding + domain-bonus) - ControlComposer: Pattern + Obligation → Master Control - PipelineAdapter: Pipeline integration + Migration Passes 1-5 - DecompositionPass: Pass 0a/0b — Rich Control → atomic Controls - CrosswalkRoutes: 15 API endpoints under /v1/canonical/ New DB schema: - Migration 060: obligation_extractions, control_patterns, crosswalk_matrix - Migration 061: obligation_candidates, parent_control_uuid tracking Pattern Library: 50 YAML patterns (30 core + 20 IT-security) Go SDK: Pattern loader with YAML validation and indexing Documentation: MkDocs updated with full architecture overview 500 Python tests passing across all components. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
965 lines
37 KiB
Markdown
965 lines
37 KiB
Markdown
# Canonical Control Library (CP-CLIB)
|
|
|
|
Eigenstaendig formulierte Security Controls basierend auf offenem Wissen (OWASP, NIST, ENISA).
|
|
Unabhaengige Taxonomie — kein Bezug zu proprietaeren Frameworks.
|
|
|
|
**Prefix:** `CP-CLIB` · **Frontend:** `https://macmini:3007/sdk/control-library`
|
|
**Provenance Wiki:** `https://macmini:3007/sdk/control-provenance`
|
|
**Proxy:** `/api/sdk/v1/canonical` → `backend-compliance:8002/api/compliance/v1/canonical/...`
|
|
|
|
---
|
|
|
|
## Motivation
|
|
|
|
Wir benoetigen ein System, um aus verschiedenen Security-Guidelines **eigenstaendige, rechtlich defensible Controls** zu extrahieren, ohne proprietaere Texte im Produkt zu verwenden.
|
|
|
|
### Kernprinzipien
|
|
|
|
1. **Unabhaengige Taxonomie** — Eigene Domain-IDs (AUTH, NET, SUP, etc.), eigenes ID-Format (`DOMAIN-NNN`)
|
|
2. **Open-Source-Verankerung** — Jedes Control hat mindestens 1 Open Anchor (OWASP/NIST/ENISA)
|
|
3. **Strikte Quellentrennung** — Geschuetzte Quellen nur intern zur Analyse, nie im Produkt
|
|
4. **Automatisierte Pruefung** — Too-Close-Detektor + No-Leak-Scanner in CI/CD
|
|
|
|
---
|
|
|
|
## Rechtliche Basis
|
|
|
|
| Gesetz | Bezug |
|
|
|--------|-------|
|
|
| UrhG §44b | Text & Data Mining — Kopien loeschen |
|
|
| UrhG §23 | Hinreichender Abstand zum Originalwerk |
|
|
| BSI Nutzungsbedingungen | Kommerziell nur mit Zustimmung |
|
|
|
|
---
|
|
|
|
## Domains (Unabhaengige Taxonomie)
|
|
|
|
| Domain | Name | Beschreibung |
|
|
|--------|------|-------------|
|
|
| AUTH | Identity & Access Management | Authentisierung, MFA, Token-Management |
|
|
| CRYP | Cryptographic Operations | Key Management, Rotation, HSM |
|
|
| NET | Network & Transport Security | TLS, Zertifikate, Netzwerk-Haertung |
|
|
| DATA | Data Governance & Classification | Datenklassifikation, Schutzmassnahmen |
|
|
| LOG | Security Operations & Logging | Privacy-Aware Logging, SIEM |
|
|
| ACC | Access Control | Zugriffskontrolle, Berechtigungen |
|
|
| SEC | IT Security | Schwachstellen, Haertung, Konfiguration |
|
|
| INC | Incident Management | Vorfallmanagement, Wiederherstellung |
|
|
| AI | Artificial Intelligence | KI-Compliance, Bias, Transparenz |
|
|
| COMP | Compliance | Konformitaet, Audit, Zertifizierung |
|
|
| GOV | Government & Public Administration | Behoerden, Verwaltung, Aufsicht |
|
|
| LAB | Labor Law | Arbeitsrecht, Arbeitsschutz, Betriebsverfassung |
|
|
| FIN | Financial Regulation | Finanzregulierung, Rechnungslegung, BaFin |
|
|
| TRD | Trade Regulation | Gewerbe, Handelsrecht, Produktsicherheit |
|
|
| ENV | Environmental | Umweltschutz, Nachhaltigkeit, Emissionen |
|
|
| HLT | Health | Gesundheit, Medizinprodukte, Hygiene |
|
|
|
|
!!! warning "Keine BSI-Nomenklatur"
|
|
Die Domains verwenden bewusst KEINE BSI-Bezeichner (O.Auth_*, O.Netz_*).
|
|
Das ID-Format `DOMAIN-NNN` ist eine gaengige, nicht-proprietaere Konvention.
|
|
|
|
---
|
|
|
|
## Datenmodell (Migration 044)
|
|
|
|
```mermaid
|
|
erDiagram
|
|
canonical_control_licenses ||--o{ canonical_control_sources : "hat"
|
|
canonical_control_frameworks ||--o{ canonical_controls : "enthaelt"
|
|
canonical_controls ||--o{ canonical_control_mappings : "hat"
|
|
canonical_control_sources ||--o{ canonical_control_mappings : "referenziert"
|
|
|
|
canonical_control_licenses {
|
|
varchar license_id PK
|
|
varchar name
|
|
varchar commercial_use
|
|
boolean deletion_required
|
|
}
|
|
canonical_control_sources {
|
|
uuid id PK
|
|
varchar source_id UK
|
|
varchar title
|
|
boolean allowed_ship_in_product
|
|
}
|
|
canonical_control_frameworks {
|
|
uuid id PK
|
|
varchar framework_id UK
|
|
varchar name
|
|
varchar version
|
|
}
|
|
canonical_controls {
|
|
uuid id PK
|
|
uuid framework_id FK
|
|
varchar control_id
|
|
varchar severity
|
|
jsonb open_anchors
|
|
}
|
|
canonical_control_mappings {
|
|
uuid id PK
|
|
uuid control_id FK
|
|
uuid source_id FK
|
|
varchar mapping_type
|
|
varchar attribution_class
|
|
}
|
|
```
|
|
|
|
### Tabellen
|
|
|
|
| Tabelle | Zweck | Produktfaehig? |
|
|
|---------|-------|----------------|
|
|
| `canonical_control_licenses` | Lizenz-Metadaten | Ja (read-only) |
|
|
| `canonical_control_sources` | Quellen-Register | **Nein** (nur intern) |
|
|
| `canonical_control_frameworks` | Framework-Registry | Ja |
|
|
| `canonical_controls` | Die eigentlichen Controls | Ja |
|
|
| `canonical_control_mappings` | Provenance-Trail | **Nein** (nur Audit) |
|
|
|
|
---
|
|
|
|
## API Endpoints
|
|
|
|
| Methode | Pfad | Beschreibung |
|
|
|---------|------|--------------|
|
|
| `GET` | `/v1/canonical/frameworks` | Alle Frameworks |
|
|
| `GET` | `/v1/canonical/frameworks/{id}` | Framework-Details |
|
|
| `GET` | `/v1/canonical/frameworks/{id}/controls` | Controls eines Frameworks |
|
|
| `GET` | `/v1/canonical/controls` | Alle Controls (Filter: `severity`, `domain`, `release_state`) |
|
|
| `GET` | `/v1/canonical/controls/{control_id}` | Einzelnes Control (z.B. AUTH-001) |
|
|
| `GET` | `/v1/canonical/sources` | Quellenregister mit Berechtigungen |
|
|
| `GET` | `/v1/canonical/licenses` | Lizenz-Matrix |
|
|
| `POST` | `/v1/canonical/controls/{id}/similarity-check` | Too-Close-Pruefung |
|
|
| `POST` | `/v1/canonical/generate` | Generator-Job starten |
|
|
| `GET` | `/v1/canonical/generate/jobs` | Alle Generator-Jobs |
|
|
| `GET` | `/v1/canonical/generate/processed-stats` | Verarbeitungsstatistik pro Collection |
|
|
| `GET` | `/v1/canonical/generate/review-queue` | Controls zur Pruefung |
|
|
| `POST` | `/v1/canonical/generate/review/{control_id}` | Review abschliessen |
|
|
| `POST` | `/v1/canonical/generate/bulk-review` | Bulk-Review (approve/reject nach State) |
|
|
| `POST` | `/v1/canonical/generate/qa-reclassify` | QA-Reklassifizierung bestehender Controls |
|
|
| `GET` | `/v1/canonical/blocked-sources` | Gesperrte Quellen (Rule 3) |
|
|
| `POST` | `/v1/canonical/blocked-sources/cleanup` | Cleanup-Workflow starten |
|
|
|
|
### Beispiel: Control abrufen
|
|
|
|
```bash
|
|
curl -s https://macmini:8002/api/v1/canonical/controls/AUTH-001 | jq
|
|
```
|
|
|
|
### Beispiel: Similarity Check
|
|
|
|
```bash
|
|
curl -X POST https://macmini:8002/api/v1/canonical/controls/AUTH-001/similarity-check \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{
|
|
"source_text": "Die Anwendung muss MFA implementieren.",
|
|
"candidate_text": "Privileged accounts require multi-factor authentication."
|
|
}' | jq
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"max_exact_run": 0,
|
|
"token_overlap": 0.0714,
|
|
"ngram_jaccard": 0.0323,
|
|
"embedding_cosine": 0.0,
|
|
"lcs_ratio": 0.0714,
|
|
"status": "PASS",
|
|
"details": {
|
|
"max_exact_run": "PASS",
|
|
"token_overlap": "PASS",
|
|
"ngram_jaccard": "PASS",
|
|
"embedding_cosine": "PASS",
|
|
"lcs_ratio": "PASS"
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Too-Close-Detektor
|
|
|
|
5 Metriken mit Schwellwerten:
|
|
|
|
| Metrik | Warn | Fail | Beschreibung |
|
|
|--------|------|------|-------------|
|
|
| Exact Phrase | ≥8 Tokens | ≥12 Tokens | Laengste identische Token-Sequenz |
|
|
| Token Overlap | ≥0.20 | ≥0.30 | Jaccard der Token-Mengen |
|
|
| 3-Gram Jaccard | ≥0.10 | ≥0.18 | Zeichenketten-Aehnlichkeit |
|
|
| Embedding Cosine | ≥0.86 | ≥0.92 | Semantische Aehnlichkeit (bge-m3) |
|
|
| LCS Ratio | ≥0.35 | ≥0.50 | Longest Common Subsequence |
|
|
|
|
**Entscheidungslogik:**
|
|
|
|
- **PASS** — Kein Fail + max 1 Warn
|
|
- **WARN** — Max 2 Warn, kein Fail → Human Review
|
|
- **FAIL** — Irgendein Fail → Block, Umformulierung noetig
|
|
|
|
---
|
|
|
|
## License Gate
|
|
|
|
Jede Quelle hat definierte Berechtigungen:
|
|
|
|
| Nutzungsart | Spalte | Beispiel OWASP | Beispiel BSI |
|
|
|-------------|--------|---------------|-------------|
|
|
| Analyse | `allowed_analysis` | ✅ | ✅ |
|
|
| Excerpt speichern | `allowed_store_excerpt` | ✅ | ❌ |
|
|
| Embeddings shippen | `allowed_ship_embeddings` | ✅ | ❌ |
|
|
| Im Produkt shippen | `allowed_ship_in_product` | ✅ | ❌ |
|
|
|
|
---
|
|
|
|
## CI/CD Validation
|
|
|
|
Der Validator (`scripts/validate-controls.py`) prueft bei jedem Commit:
|
|
|
|
1. **Schema Validation** — Alle Pflichtfelder, ID-Format, Severity
|
|
2. **No-Leak Scanner** — Regex gegen BSI-Muster (`O.Auth_*`, `TR-03161`, etc.)
|
|
3. **Open Anchor Check** — Jedes Control hat ≥1 Open Anchor
|
|
4. **Taxonomy Check** — Keine BSI-style ID-Prefixe
|
|
5. **Evidence Structure** — Alle Evidence-Items haben `type` + `description`
|
|
|
|
---
|
|
|
|
## Frontend
|
|
|
|
### Control Library Browser (`/sdk/control-library`)
|
|
|
|
- Framework-Info mit Version und Beschreibung
|
|
- Filterable Control-Tabelle (Domain, Severity, Freitext)
|
|
- Detail-Ansicht mit: Ziel, Begruendung, Anforderungen, Pruefverfahren, Nachweise
|
|
- **Open-Source-Referenzen** prominent dargestellt (gruener Kasten)
|
|
- Tags und Scope-Informationen
|
|
|
|
### Control Provenance Wiki (`/sdk/control-provenance`)
|
|
|
|
- Dokumentation der Methodik
|
|
- Unabhaengige Taxonomie erklaert
|
|
- Offene Referenzquellen aufgelistet
|
|
- Geschuetzte Quellen und Trennungsprinzip
|
|
- **Live-Daten:** Lizenz-Matrix und Quellenregister aus der Datenbank
|
|
|
|
---
|
|
|
|
## Control Generator Pipeline
|
|
|
|
Automatische Generierung von Controls aus dem gesamten RAG-Korpus (~105.000 Chunks aus Gesetzen, Verordnungen und Standards).
|
|
Aktueller Stand: **~4.738 Controls** generiert.
|
|
|
|
### 9-Stufen-Pipeline
|
|
|
|
```mermaid
|
|
flowchart TD
|
|
A[1. RAG Scroll] -->|max_chunks| B[2. Prefilter - Lokales LLM]
|
|
B -->|Irrelevant| C[Als processed markieren]
|
|
B -->|Relevant| D[3. License Classify]
|
|
D -->|Batch sammeln| E[4. Batch Processing - 5 Chunks/API-Call]
|
|
E -->|Rule 1/2| F[4a. Structure Batch - Anthropic]
|
|
E -->|Rule 3| G[4b. Reform Batch - Anthropic]
|
|
F --> QA[5. QA Validation - Lokales LLM]
|
|
G --> QA
|
|
QA -->|Mismatch| QAF[Auto-Fix Category/Domain]
|
|
QA -->|OK| H[6. Harmonization - Embeddings]
|
|
QAF --> H
|
|
H -->|Duplikat| I[Als Duplikat speichern]
|
|
H -->|Neu| J[7. Anchor Search]
|
|
J --> K[8. Store Control]
|
|
K --> L[9. Mark Processed]
|
|
```
|
|
|
|
### Stufe 1: RAG Scroll (Vollstaendig)
|
|
|
|
Scrollt durch **ALLE** Chunks in allen RAG-Collections mittels Qdrant Scroll-API.
|
|
Kein Limit — jeder Chunk wird verarbeitet, um keine gesetzlichen Anforderungen zu uebersehen.
|
|
|
|
Bereits verarbeitete Chunks werden per SHA-256-Hash uebersprungen (`canonical_processed_chunks`).
|
|
|
|
### Stufe 2: Lokaler LLM-Vorfilter (Qwen 30B)
|
|
|
|
**Kostenoptimierung:** Bevor ein Chunk an die Anthropic API geht, prueft das lokale Qwen-Modell (`qwen3:30b-a3b` auf Mac Mini), ob der Chunk eine konkrete Anforderung enthaelt.
|
|
|
|
- **Relevant:** Pflichten ("muss", "soll"), technische Massnahmen, Datenschutz-Vorgaben
|
|
- **Irrelevant:** Definitionen, Inhaltsverzeichnisse, Begriffsbestimmungen, Uebergangsvorschriften
|
|
|
|
Irrelevante Chunks werden als `prefilter_skip` markiert und nie wieder verarbeitet.
|
|
Dies spart >50% der Anthropic-API-Kosten.
|
|
|
|
### Stufe 3: Lizenz-Klassifikation (3-Regel-System)
|
|
|
|
| Regel | Lizenz | Original erlaubt? | Beispiel |
|
|
|-------|--------|-------------------|----------|
|
|
| **Rule 1** (free_use) | EU-Gesetze, NIST, DE-Gesetze | Ja | DSGVO, BDSG, NIS2 |
|
|
| **Rule 2** (citation_required) | CC-BY, CC-BY-SA | Ja, mit Zitation | OWASP ASVS |
|
|
| **Rule 3** (restricted) | Proprietaer | Nein, volle Reformulierung | BSI TR-03161 |
|
|
|
|
### Stufe 4a/4b: Strukturierung / Reformulierung
|
|
|
|
- **Rule 1+2:** Anthropic strukturiert den Originaltext in Control-Format (Titel, Ziel, Anforderungen)
|
|
- **Rule 3:** Anthropic reformuliert vollstaendig — kein Originaltext, keine Quellennamen
|
|
|
|
### Batch Processing (Stufe 4 — Optimierung)
|
|
|
|
Die Pipeline verarbeitet Chunks **nicht einzeln**, sondern sammelt sie in Batches von **5 Chunks pro API-Call**.
|
|
Das reduziert die Anzahl der Anthropic-API-Aufrufe um ~80% und beschleunigt die Generierung erheblich.
|
|
|
|
#### Ablauf
|
|
|
|
1. **Chunks sammeln:** Nach dem Prefilter werden relevante Chunks mit ihrer Lizenz-Info in `pending_batch` gesammelt
|
|
2. **Batch voll?** Sobald `batch_size` (Default: 5) erreicht ist, wird `_flush_batch()` aufgerufen
|
|
3. **`_process_batch()`** trennt den Batch nach Lizenzregel:
|
|
- **Rule 1+2 Chunks** → `_structure_batch()` — ein einziger Anthropic-Call fuer alle
|
|
- **Rule 3 Chunks** → `_reformulate_batch()` — ein einziger Anthropic-Call fuer alle
|
|
4. **Ergebnis:** JSON-Array mit genau N Controls, zurueck-gemappt per `chunk_index`
|
|
|
|
#### `_structure_batch()` (Rule 1+2)
|
|
|
|
Sendet alle freien/CC-BY Chunks in einem einzigen Prompt an Anthropic. Der Originaltext darf verwendet werden.
|
|
Jeder Chunk wird als `--- CHUNK N ---` Block formatiert, das LLM gibt ein JSON-Array mit `chunk_index` zurueck.
|
|
|
|
```python
|
|
# Prompt-Auszug:
|
|
"Strukturiere die folgenden 5 Gesetzestexte jeweils als eigenstaendiges Control."
|
|
"Gib ein JSON-Array zurueck mit GENAU 5 Objekten."
|
|
```
|
|
|
|
**Processing Path:** `structured_batch` (in `generation_metadata`)
|
|
|
|
#### `_reformulate_batch()` (Rule 3)
|
|
|
|
Sendet alle eingeschraenkten Chunks in einem Prompt. Der Originaltext darf **nicht kopiert** werden.
|
|
Quellennamen und proprietaere Bezeichner werden im Prompt explizit verboten.
|
|
|
|
```python
|
|
# Prompt-Auszug:
|
|
"KOPIERE KEINE Saetze. Verwende eigene Begriffe und Struktur."
|
|
"NENNE NICHT die Quellen. Keine proprietaeren Bezeichner."
|
|
```
|
|
|
|
**Processing Path:** `llm_reform_batch` (in `generation_metadata`)
|
|
|
|
#### Fallback bei Batch-Fehler
|
|
|
|
Falls ein Batch-Call fehlschlaegt (z.B. Timeout, Parsing-Error), faellt die Pipeline automatisch auf **Einzelverarbeitung** zurueck:
|
|
|
|
```python
|
|
except Exception as e:
|
|
logger.error("Batch processing failed: %s — falling back to single-chunk mode", e)
|
|
for chunk, _lic in batch:
|
|
ctrl = await self._process_single_chunk(chunk, config, job_id)
|
|
```
|
|
|
|
!!! info "Batch-Konfiguration"
|
|
| Parameter | Wert | Beschreibung |
|
|
|-----------|------|-------------|
|
|
| `batch_size` | 5 (Default) | Chunks pro API-Call |
|
|
| `max_tokens` | 8192 | Maximale Token-Laenge der LLM-Antwort |
|
|
| `LLM_TIMEOUT` | 180s | Timeout pro Anthropic-Call |
|
|
|
|
Die `batch_size` ist ueber `GeneratorConfig` konfigurierbar.
|
|
Bei grosser Batch-Size steigt die Wahrscheinlichkeit fuer Parsing-Fehler.
|
|
|
|
### Stufe 5: QA Validation (Automatische Qualitaetspruefung)
|
|
|
|
Die QA-Stufe validiert die Klassifizierung jedes Controls automatisch. Sie vergleicht die LLM-Klassifizierung mit Keyword-basierter Erkennung und loest bei Abweichungen eine Arbitrierung durch das lokale Ollama-Modell aus.
|
|
|
|
#### Ablauf
|
|
|
|
1. **LLM-Category auswerten:** Der Anthropic-Prompt fragt jetzt explizit nach `category` und `domain`
|
|
2. **Keyword-Detection als Cross-Check:** `_detect_category(chunk.text)` liefert eine zweite Meinung
|
|
3. **Stimmen beide ueberein?** → Kein QA noetig (schneller Pfad)
|
|
4. **Bei Disagreement:** Lokales LLM (Ollama qwen3.5:35b-a3b) arbitriert
|
|
5. **Auto-Fix:** Bei hoher Konfidenz wird Category/Domain automatisch korrigiert
|
|
|
|
#### Beispiel
|
|
|
|
```
|
|
Control: "Offenlegung von Risikokonzentrationen bei Finanzinstrumenten"
|
|
LLM sagt: domain=AUTH, category=authentication
|
|
Keyword sagt: domain=FIN, category=finance
|
|
→ QA via Ollama: domain=FIN, category=finance (Grund: IFRS-Thema)
|
|
→ Auto-Fix: AUTH-315 → FIN-xxx
|
|
```
|
|
|
|
#### QA-Metriken in generation_metadata
|
|
|
|
```json
|
|
{
|
|
"qa_category_fix": {"from": "authentication", "to": "finance", "reason": "IFRS-Thema"},
|
|
"qa_domain_fix": {"from": "AUTH", "to": "FIN", "reason": "Finanzregulierung"}
|
|
}
|
|
```
|
|
|
|
#### QA-Reklassifizierung bestehender Controls
|
|
|
|
Fuer bereits generierte Controls gibt es den Backfill-Endpoint:
|
|
|
|
```bash
|
|
# Dry Run: Welche AUTH-Controls sind falsch klassifiziert?
|
|
curl -X POST https://macmini:8002/api/compliance/v1/canonical/generate/qa-reclassify \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"limit": 50, "dry_run": true, "filter_domain_prefix": "AUTH"}'
|
|
|
|
# Korrekturen anwenden:
|
|
curl -X POST https://macmini:8002/api/compliance/v1/canonical/generate/qa-reclassify \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"limit": 50, "dry_run": false, "filter_domain_prefix": "AUTH"}'
|
|
```
|
|
|
|
!!! info "Performance"
|
|
Die QA-Stufe nutzt das lokale Ollama-Modell (kostenlos, ~2s/Control).
|
|
Sie wird nur bei Disagreement zwischen LLM und Keyword getriggert (~10-15% der Controls),
|
|
sodass der Overhead minimal bleibt.
|
|
|
|
### Stufe 6: Harmonisierung (Embedding-basiert)
|
|
|
|
Prueft per bge-m3 Embeddings (Cosine Similarity > 0.85), ob ein aehnliches Control existiert.
|
|
Embeddings werden in Batches vorgeladen (32 Texte/Request) fuer maximale Performance.
|
|
|
|
### Stufe 7-9: Anchor Search, Store, Mark Processed
|
|
|
|
- **Anchor Search:** Findet Open-Source-Referenzen (OWASP, NIST, ENISA)
|
|
- **Store:** Persistiert Control mit `verification_method` und `category`
|
|
- **Mark Processed:** Markiert **JEDEN** Chunk als verarbeitet (auch bei Skip/Error/Duplikat)
|
|
|
|
### Automatische Klassifikation
|
|
|
|
Bei der Generierung werden automatisch zugewiesen:
|
|
|
|
**Category** wird seit 2026-03-16 **dreigleisig** bestimmt:
|
|
|
|
1. **LLM-Klassifikation (primaer):** Anthropic liefert `category` im JSON-Response
|
|
2. **Keyword-Detection (fallback):** Falls LLM keine Category liefert, greift `_detect_category()`
|
|
3. **QA-Arbitrierung (bei Mismatch):** Lokales LLM entscheidet bei Widerspruch
|
|
|
|
**Verification Method** (Nachweis-Methode):
|
|
|
|
| Methode | Beschreibung |
|
|
|---------|-------------|
|
|
| `code_review` | Im Source Code pruefbar |
|
|
| `document` | Dokument/Prozess-Nachweis |
|
|
| `tool` | Tool-basierte Pruefung |
|
|
| `hybrid` | Kombination mehrerer Methoden |
|
|
|
|
**Category** (22 thematische Kategorien):
|
|
|
|
| Kategorie | Beschreibung |
|
|
|-----------|-------------|
|
|
| `encryption` | Verschluesselung, Kryptographie |
|
|
| `authentication` | Authentifizierung, Login, MFA |
|
|
| `network` | Netzwerk, Firewall, VPN |
|
|
| `data_protection` | Datenschutz, DSGVO |
|
|
| `logging` | Protokollierung, Monitoring |
|
|
| `incident` | Vorfallmanagement |
|
|
| `continuity` | Business Continuity, Backup |
|
|
| `compliance` | Konformitaet, Audit, Zertifizierung |
|
|
| `supply_chain` | Lieferkette, Dienstleister |
|
|
| `physical` | Physische Sicherheit |
|
|
| `personnel` | Schulung, Mitarbeiter |
|
|
| `application` | Software, Code Review, API |
|
|
| `system` | Haertung, Patch, Konfiguration |
|
|
| `risk` | Risikobewertung, -management |
|
|
| `governance` | Sicherheitsorganisation, Richtlinien |
|
|
| `hardware` | Hardware, Firmware, TPM |
|
|
| `identity` | IAM, SSO, Verzeichnisdienste |
|
|
| `public_administration` | Behoerden, Verwaltung |
|
|
| `labor_law` | Arbeitsrecht, Arbeitsschutz |
|
|
| `finance` | Finanzregulierung, Rechnungslegung |
|
|
| `trade_regulation` | Gewerbe, Handelsrecht |
|
|
| `environmental` | Umweltschutz, Nachhaltigkeit |
|
|
| `health` | Gesundheit, Medizinprodukte |
|
|
|
|
### Konfiguration
|
|
|
|
| ENV-Variable | Default | Beschreibung |
|
|
|-------------|---------|-------------|
|
|
| `ANTHROPIC_API_KEY` | — | API-Key fuer Anthropic Claude |
|
|
| `CONTROL_GEN_ANTHROPIC_MODEL` | `claude-sonnet-4-6` | Anthropic-Modell fuer Formulierung |
|
|
| `OLLAMA_URL` | `http://host.docker.internal:11434` | Lokaler Ollama-Server (Vorfilter) |
|
|
| `CONTROL_GEN_OLLAMA_MODEL` | `qwen3.5:35b-a3b` | Lokales LLM fuer Vorfilter + QA |
|
|
| `CONTROL_GEN_LLM_TIMEOUT` | `180` | Timeout in Sekunden (erhoet fuer Batch-Calls) |
|
|
|
|
**Pipeline-Konfiguration (via `GeneratorConfig`):**
|
|
|
|
| Parameter | Default | Beschreibung |
|
|
|-----------|---------|-------------|
|
|
| `batch_size` | `5` | Chunks pro Anthropic-API-Call |
|
|
| `max_controls` | `0` | Limit (0 = alle Chunks verarbeiten) |
|
|
| `max_chunks` | `1000` | Max Chunks pro Job (respektiert Dokumentgrenzen) |
|
|
| `skip_processed` | `true` | Bereits verarbeitete Chunks ueberspringen |
|
|
| `dry_run` | `false` | Trockenlauf ohne DB-Schreibzugriffe |
|
|
| `skip_web_search` | `false` | Web-Suche fuer Anchor-Finder ueberspringen |
|
|
|
|
### Architektur-Entscheidung: Gesetzesverweise
|
|
|
|
Controls leiten sich aus zwei Quellen ab:
|
|
|
|
1. **Direkte gesetzliche Pflichten (Rule 1):** z.B. DSGVO Art. 32 erzwingt "technische und organisatorische Massnahmen". Diese Controls haben `source_citation` mit exakter Gesetzesreferenz und Originaltext.
|
|
|
|
2. **Implizite Umsetzung ueber Best Practices (Rule 2/3):** z.B. OWASP ASVS V2.7 fordert MFA — das ist keine gesetzliche Pflicht, aber eine Best Practice um NIS2 Art. 21 oder DSGVO Art. 32 zu erfuellen. Diese Controls haben Open-Source-Referenzen (Anchors).
|
|
|
|
**Im Frontend:**
|
|
- Rule 1/2 Controls zeigen eine blaue "Gesetzliche Grundlage" Box mit Gesetz, Artikel und Link
|
|
- Rule 3 Controls zeigen einen Hinweis dass sie implizit Gesetze umsetzen, mit Verweis auf die Referenzen
|
|
|
|
### API
|
|
|
|
```bash
|
|
# Job starten (laeuft im Hintergrund)
|
|
curl -X POST https://macmini:8002/api/compliance/v1/canonical/generate \
|
|
-H 'Content-Type: application/json' \
|
|
-H 'X-Tenant-ID: 550e8400-e29b-41d4-a716-446655440000' \
|
|
-d '{"collections": ["bp_compliance_gesetze"]}'
|
|
|
|
# Job-Status abfragen
|
|
curl https://macmini:8002/api/compliance/v1/canonical/generate/jobs \
|
|
-H 'X-Tenant-ID: 550e8400-e29b-41d4-a716-446655440000'
|
|
```
|
|
|
|
### 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 |
|
|
|
|
!!! warning "bp_compliance_recht entfernt (2026-03-16)"
|
|
Die Collection `bp_compliance_recht` wurde geloescht, da sie mit `bp_compliance_datenschutz`
|
|
ueberlappte (~20.000 Duplikat-Chunks). Alle relevanten EU-Verordnungen sind in den anderen
|
|
Collections enthalten.
|
|
|
|
---
|
|
|
|
## Processed Chunks Tracking
|
|
|
|
Die Tabelle `canonical_processed_chunks` trackt **JEDEN** verarbeiteten RAG-Chunk per SHA-256-Hash.
|
|
Dadurch werden Chunks bei erneutem Pipeline-Lauf automatisch uebersprungen (`skip_processed: true`).
|
|
|
|
### Tabelle: `canonical_processed_chunks` (Migration 046 + 048)
|
|
|
|
| Spalte | Typ | Beschreibung |
|
|
|--------|-----|-------------|
|
|
| `id` | UUID | Primary Key |
|
|
| `chunk_hash` | VARCHAR(64) | SHA-256 Hash des Chunk-Textes |
|
|
| `collection` | VARCHAR(100) | Qdrant-Collection (z.B. `bp_compliance_gesetze`) |
|
|
| `regulation_code` | VARCHAR(100) | Quell-Regulation (z.B. `bdsg`, `eu_2016_679`) |
|
|
| `document_version` | VARCHAR(50) | Versions-Tracking |
|
|
| `source_license` | VARCHAR(50) | Lizenz der Quelle |
|
|
| `license_rule` | INTEGER | 1, 2 oder 3 |
|
|
| `processing_path` | VARCHAR(20) | Verarbeitungspfad (siehe unten) |
|
|
| `generated_control_ids` | JSONB | UUIDs der generierten Controls |
|
|
| `job_id` | UUID | Referenz auf `canonical_generation_jobs` |
|
|
| `processed_at` | TIMESTAMPTZ | Zeitstempel |
|
|
|
|
**UNIQUE Constraint:** `(chunk_hash, collection, document_version)` — verhindert Doppelverarbeitung.
|
|
|
|
### Processing Paths
|
|
|
|
| Wert | Stufe | Bedeutung |
|
|
|------|-------|-----------|
|
|
| `prefilter_skip` | 2 | Lokaler LLM-Vorfilter: Chunk nicht sicherheitsrelevant |
|
|
| `structured` | 4a | Einzelner Chunk strukturiert (Rule 1/2) |
|
|
| `llm_reform` | 4b | Einzelner Chunk reformuliert (Rule 3) |
|
|
| `structured_batch` | 4a | Batch-Strukturierung (Rule 1/2, in `generation_metadata`) |
|
|
| `llm_reform_batch` | 4b | Batch-Reformulierung (Rule 3, in `generation_metadata`) |
|
|
| `no_control` | 4 | LLM konnte kein Control ableiten |
|
|
| `store_failed` | 7 | DB-Speichern fehlgeschlagen |
|
|
| `error` | — | Unerwarteter Fehler bei der Verarbeitung |
|
|
|
|
!!! note "Batch-Pfade in generation_metadata"
|
|
Die Werte `structured_batch` und `llm_reform_batch` werden im `processing_path` der Datenbank gespeichert
|
|
**und** im `generation_metadata` JSON-Feld des Controls. So ist nachvollziehbar, ob ein Control
|
|
einzeln oder im Batch generiert wurde.
|
|
|
|
### Beispiel-Query: Verarbeitungsstatistik
|
|
|
|
```sql
|
|
SELECT
|
|
processing_path,
|
|
COUNT(*) as count
|
|
FROM canonical_processed_chunks
|
|
GROUP BY processing_path
|
|
ORDER BY count DESC;
|
|
```
|
|
|
|
---
|
|
|
|
## Statistiken (processed-stats Endpoint)
|
|
|
|
Der Endpoint `GET /v1/canonical/generate/processed-stats` liefert Verarbeitungsstatistiken pro RAG-Collection.
|
|
|
|
```bash
|
|
curl -s https://macmini:8002/api/compliance/v1/canonical/generate/processed-stats | jq
|
|
```
|
|
|
|
**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
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### 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% (nur sicherheitsrelevante Chunks erzeugen Controls) |
|
|
|
|
!!! info "Warum so wenige Controls?"
|
|
Die meisten RAG-Chunks sind Definitionen, Begriffsbestimmungen, Inhaltsverzeichnisse oder
|
|
Uebergangsvorschriften. Der Prefilter (Stufe 2) sortiert >50% aus, die Harmonisierung (Stufe 5)
|
|
entfernt weitere Duplikate. Nur konkrete, einzigartige Anforderungen werden zu Controls.
|
|
|
|
---
|
|
|
|
## Migration von Controls (Lokal → Production)
|
|
|
|
Controls koennen ueber die REST-API von der lokalen Entwicklungsumgebung in die Production migriert werden.
|
|
Jedes Control wird einzeln per `POST` mit der Referenz auf das Framework erstellt.
|
|
|
|
```bash
|
|
# 1. Control aus lokaler Umgebung exportieren
|
|
curl -s https://macmini:8002/api/compliance/v1/canonical/controls/AUTH-001 | jq > control.json
|
|
|
|
# 2. In Production importieren (mit framework_id)
|
|
curl -X POST https://api-dev.breakpilot.ai/api/compliance/v1/canonical/controls \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{
|
|
"framework_id": "bp_security_v1",
|
|
"control_id": "AUTH-001",
|
|
"title": "Multi-Faktor-Authentifizierung",
|
|
"objective": "...",
|
|
"severity": "high",
|
|
"open_anchors": [...]
|
|
}'
|
|
```
|
|
|
|
!!! warning "Framework muss existieren"
|
|
Das Ziel-Framework (`bp_security_v1`) muss in der Production-DB bereits angelegt sein.
|
|
Falls nicht, zuerst das Framework erstellen:
|
|
```bash
|
|
curl -X POST https://api-dev.breakpilot.ai/api/compliance/v1/canonical/frameworks \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"framework_id": "bp_security_v1", "name": "BreakPilot Security", "version": "1.0"}'
|
|
```
|
|
|
|
---
|
|
|
|
## Dateien
|
|
|
|
| Datei | Typ | Beschreibung |
|
|
|-------|-----|-------------|
|
|
| `backend-compliance/migrations/044_canonical_control_library.sql` | SQL | 5 Tabellen + Seed-Daten |
|
|
| `backend-compliance/migrations/046_control_generator.sql` | SQL | Job-Tracking, Chunk-Tracking, Blocked Sources |
|
|
| `backend-compliance/migrations/047_verification_method_category.sql` | SQL | verification_method + category Felder |
|
|
| `backend-compliance/migrations/048_processing_path_expand.sql` | SQL | Erweiterte processing_path Werte |
|
|
| `backend-compliance/compliance/api/canonical_control_routes.py` | Python | REST API (8+ Endpoints) |
|
|
| `backend-compliance/compliance/api/control_generator_routes.py` | Python | Generator API (Start/Status/Jobs/Stats) |
|
|
| `backend-compliance/compliance/services/control_generator.py` | Python | 8-Stufen-Pipeline mit Batch Processing |
|
|
| `backend-compliance/compliance/services/license_gate.py` | Python | Lizenz-Gate-Logik |
|
|
| `backend-compliance/compliance/services/similarity_detector.py` | Python | Too-Close-Detektor (5 Metriken) |
|
|
| `backend-compliance/compliance/services/rag_client.py` | Python | RAG-Client (Search + Scroll) |
|
|
| `ai-compliance-sdk/internal/ucca/legal_rag.go` | Go | RAG Search + Scroll (Qdrant) |
|
|
| `ai-compliance-sdk/internal/api/handlers/rag_handlers.go` | Go | RAG HTTP-Handler |
|
|
| `ai-compliance-sdk/policies/canonical_controls_v1.json` | JSON | 10 Seed Controls, 39 Open Anchors |
|
|
| `ai-compliance-sdk/internal/ucca/canonical_control_loader.go` | Go | Control Loader mit Multi-Index |
|
|
| `admin-compliance/app/sdk/control-library/page.tsx` | TSX | Control Library Browser |
|
|
| `admin-compliance/app/sdk/control-provenance/page.tsx` | TSX | Provenance Wiki |
|
|
| `admin-compliance/app/api/sdk/v1/canonical/route.ts` | TS | Next.js API Proxy |
|
|
| `scripts/validate-controls.py` | Python | CI/CD Validator |
|
|
|
|
---
|
|
|
|
## Tests
|
|
|
|
| Datei | Sprache | Tests | Schwerpunkt |
|
|
|-------|---------|-------|-------------|
|
|
| `ai-compliance-sdk/internal/ucca/canonical_control_loader_test.go` | Go | 8 Tests | Control Loader, Multi-Index |
|
|
| `backend-compliance/compliance/tests/test_similarity_detector.py` | Python | 19 Tests | Too-Close-Detektor, 5 Metriken |
|
|
| `backend-compliance/tests/test_canonical_control_routes.py` | Python | 14 Tests | REST API Endpoints |
|
|
| `backend-compliance/tests/test_license_gate.py` | Python | 12 Tests | Lizenz-Klassifikation |
|
|
| `backend-compliance/tests/test_validate_controls.py` | Python | 14 Tests | CI/CD Validator |
|
|
| `backend-compliance/tests/test_control_generator.py` | Python | 15 Tests | Pipeline, Batch, Lizenzregeln |
|
|
| **Gesamt** | | **82 Tests** |
|
|
|
|
### Control Generator Tests (test_control_generator.py)
|
|
|
|
Die Generator-Tests decken folgende Bereiche ab:
|
|
|
|
- **`TestLicenseMapping`** (12 Tests) — Korrekte Zuordnung von `regulation_code` zu Lizenzregeln (Rule 1/2/3),
|
|
Case-Insensitivity, Rule 3 darf keine Quellennamen exponieren
|
|
- **`TestDomainDetection`** (5 Tests) — Erkennung von AUTH, CRYPT, NET, DATA Domains aus Chunk-Text
|
|
- **`TestJsonParsing`** (4 Tests) — Robustes Parsing von LLM-Antworten (plain JSON, Markdown-Fenced, mit Preamble)
|
|
- **`TestGeneratedControlRules`** (3 Tests) — Rule 1 hat Originaltext, Rule 2 hat Citation, Rule 3 hat **nichts**
|
|
- **`TestAnchorFinder`** (2 Tests) — RAG-Suche filtert Rule 3 Quellen aus, Web-Suche erkennt Frameworks
|
|
- **`TestPipelineMocked`** (5 Tests) — End-to-End mit Mocks: Lizenz-Klassifikation, Rule 3 Blocking,
|
|
Hash-Deduplizierung, Config-Defaults (`batch_size: 5`), Rule 1 Citation-Generierung
|
|
|
|
---
|
|
|
|
## Multi-Layer Control Architecture
|
|
|
|
Erweitert die bestehende Pipeline um ein 5-Schichten-Modell:
|
|
|
|
```
|
|
Legal Source → Obligation → Control Pattern → Master Control → Customer Instance
|
|
```
|
|
|
|
### Architektur-Uebersicht
|
|
|
|
| Layer | Asset | Beschreibung |
|
|
|-------|-------|-------------|
|
|
| 1: Legal Sources | Qdrant 5 Collections, 105K+ Chunks | RAG-Rohdaten |
|
|
| 2: Obligations | v2 Framework (325 Pflichten, 9 Verordnungen) | Rechtliche Pflichten |
|
|
| 3: Control Patterns | 50 YAML Patterns (30 Core + 20 IT-Security) | Umsetzungsmuster |
|
|
| 4: Master Controls | canonical_controls (atomare Controls nach Dedup) | Kanonische Controls |
|
|
| 5: Customer Instance | TOM Controls + Gap Mapping | Kundenspezifisch |
|
|
|
|
### Control-Ebenen
|
|
|
|
| Ebene | Beschreibung | Nutzen |
|
|
|-------|-------------|--------|
|
|
| **Rich Controls** | Narrativ, erklaerend, kontextreich (~25.000) | Schulung, Audit-Fragen, Massnahmenplaene |
|
|
| **Atomare Controls** | 1 Pflicht = 1 Control (nach Decomposition + Dedup) | Systemaudits, Code-Checks, Gap-Analyse, Traceability |
|
|
|
|
### Pipeline-Erweiterung (10-Stage)
|
|
|
|
```
|
|
Stage 1: RAG SCAN (unveraendert)
|
|
Stage 2: LICENSE CLASSIFY (unveraendert)
|
|
Stage 3: PREFILTER (unveraendert)
|
|
Stage 4: OBLIGATION EXTRACT (NEU — 3-Tier: exact → embedding → LLM)
|
|
Stage 5: PATTERN MATCH (NEU — Keyword + Embedding + Domain-Bonus)
|
|
Stage 6: CONTROL COMPOSE (NEU — Pattern + Obligation → Control)
|
|
Stage 7: HARMONIZE (unveraendert)
|
|
Stage 8: ANCHOR SEARCH (unveraendert)
|
|
Stage 9: STORE + CROSSWALK (erweitert — Crosswalk-Matrix)
|
|
Stage 10: MARK PROCESSED (unveraendert)
|
|
```
|
|
|
|
---
|
|
|
|
### Obligation Extractor (Stage 4)
|
|
|
|
3-Tier Extraktion (schnellste zuerst):
|
|
|
|
| Tier | Methode | Latenz | Trefferquote |
|
|
|------|---------|--------|--------------|
|
|
| 1 | Exact Match (regulation_code + article → obligation_id) | <1ms | ~40% |
|
|
| 2 | Embedding Match (Cosine > 0.80 gegen 325 Obligations) | ~50ms | ~30% |
|
|
| 3 | LLM Extraction (lokales Ollama, nur Fallback) | ~2s | ~25% |
|
|
|
|
**Datei:** `compliance/services/obligation_extractor.py`
|
|
|
|
### Pattern Library (Stage 5)
|
|
|
|
50 YAML-basierte Control Patterns in 16 Domains:
|
|
|
|
| Datei | Patterns | Domains |
|
|
|-------|----------|---------|
|
|
| `core_patterns.yaml` | 30 | AUTH, CRYP, NET, DATA, LOG, ACC, SEC, INC, COMP, GOV, RES |
|
|
| `domain_it_security.yaml` | 20 | SEC, NET, AUTH, LOG, CRYP |
|
|
|
|
**Pattern ID Format:** `CP-{DOMAIN}-{NNN}` (z.B. `CP-AUTH-001`)
|
|
|
|
**Matching:** 2-Tier (Keyword-Index + Embedding), Domain-Bonus (+0.10)
|
|
|
|
**Dateien:**
|
|
- `ai-compliance-sdk/policies/control_patterns/core_patterns.yaml`
|
|
- `ai-compliance-sdk/policies/control_patterns/domain_it_security.yaml`
|
|
- `compliance/services/pattern_matcher.py`
|
|
|
|
### Control Composer (Stage 6)
|
|
|
|
Drei Kompositions-Modi:
|
|
|
|
| Modus | Wann | Qualitaet |
|
|
|-------|------|-----------|
|
|
| Pattern-guided | Pattern gefunden, LLM antwortet | Hoch |
|
|
| Template-only | LLM-Fehler, aber Pattern vorhanden | Mittel |
|
|
| Fallback | Kein Pattern-Match | Basis |
|
|
|
|
**Datei:** `compliance/services/control_composer.py`
|
|
|
|
---
|
|
|
|
### Decomposition Pass (Pass 0)
|
|
|
|
Zerlegt Rich Controls in atomare Controls. Laeuft VOR den Migration Passes 1-5.
|
|
|
|
#### Pass 0a — Obligation Extraction
|
|
|
|
Extrahiert einzelne normative Pflichten aus einem Rich Control per LLM.
|
|
|
|
**6 Guardrails:**
|
|
|
|
1. Nur normative Aussagen (müssen, sicherzustellen, verpflichtet, ...)
|
|
2. Ein Hauptverb pro Pflicht
|
|
3. Testpflichten separat
|
|
4. Meldepflichten separat
|
|
5. Nicht auf Evidence-Ebene zerlegen
|
|
6. Parent-Link immer erhalten
|
|
|
|
**Quality Gate:** Jeder Kandidat wird gegen 6 Kriterien geprueft:
|
|
|
|
- `has_normative_signal` — Normatives Sprachsignal erkannt
|
|
- `single_action` — Nur eine Handlung
|
|
- `not_rationale` — Keine blosse Begruendung
|
|
- `not_evidence_only` — Kein reines Evidence-Fragment
|
|
- `min_length` — Mindestlaenge erreicht
|
|
- `has_parent_link` — Referenz zum Rich Control
|
|
|
|
Kritische Checks: `has_normative_signal`, `not_evidence_only`, `min_length`, `has_parent_link`
|
|
|
|
#### Pass 0b — Atomic Control Composition
|
|
|
|
Erstellt aus jedem validierten Obligation Candidate ein atomares Control
|
|
(LLM-gestuetzt mit Template-Fallback).
|
|
|
|
**Datei:** `compliance/services/decomposition_pass.py`
|
|
|
|
---
|
|
|
|
### Migration Passes (1-5)
|
|
|
|
Nicht-destruktive Passes fuer bestehende Controls:
|
|
|
|
| Pass | Beschreibung | Methode |
|
|
|------|-------------|---------|
|
|
| 1 | Obligation Linkage | source_citation → article → obligation_id (deterministisch) |
|
|
| 2 | Pattern Classification | Keyword-Matching gegen Pattern Library |
|
|
| 3 | Quality Triage | Kategorisierung: review / needs_obligation / needs_pattern / legacy_unlinked |
|
|
| 4 | Crosswalk Backfill | crosswalk_matrix Zeilen fuer verlinkte Controls |
|
|
| 5 | Deduplication | Gleiche obligation_id + pattern_id → Duplikat markieren |
|
|
|
|
**Datei:** `compliance/services/pipeline_adapter.py`
|
|
|
|
---
|
|
|
|
### Crosswalk Matrix
|
|
|
|
Der "goldene Faden" von Gesetz bis Umsetzung:
|
|
|
|
```
|
|
Regulation → Article → Obligation → Pattern → Master Control → TOM
|
|
```
|
|
|
|
Ein atomares Control kann von **mehreren Gesetzen** gleichzeitig gefordert sein.
|
|
Die Crosswalk-Matrix bildet diese N:M-Beziehung ab.
|
|
|
|
---
|
|
|
|
### DB-Schema (Migrations 060 + 061)
|
|
|
|
**Migration 060:** Multi-Layer Basistabellen
|
|
|
|
| Tabelle | Beschreibung |
|
|
|---------|-------------|
|
|
| `obligation_extractions` | Chunk→Obligation Verknuepfungen (3-Tier Tracking) |
|
|
| `control_patterns` | DB-Spiegel der YAML-Patterns fuer SQL-Queries |
|
|
| `crosswalk_matrix` | Goldener Faden: Regulation→Obligation→Pattern→Control |
|
|
| `canonical_controls.pattern_id` | Pattern-Zuordnung (neues Feld) |
|
|
| `canonical_controls.obligation_ids` | Obligation-IDs als JSONB-Array (neues Feld) |
|
|
|
|
**Migration 061:** Decomposition-Tabellen
|
|
|
|
| Tabelle | Beschreibung |
|
|
|---------|-------------|
|
|
| `obligation_candidates` | Extrahierte atomare Pflichten aus Rich Controls |
|
|
| `canonical_controls.parent_control_uuid` | Self-Referenz zum Rich Control (neues Feld) |
|
|
| `canonical_controls.decomposition_method` | Zerlegungsmethode (neues Feld) |
|
|
|
|
---
|
|
|
|
### API Endpoints (Crosswalk Routes)
|
|
|
|
Alle Endpoints unter `/api/compliance/v1/canonical/`:
|
|
|
|
#### Pattern Library
|
|
|
|
| Methode | Pfad | Beschreibung |
|
|
|---------|------|-------------|
|
|
| GET | `/patterns` | Alle Patterns (Filter: domain, category, tag) |
|
|
| GET | `/patterns/{pattern_id}` | Einzelnes Pattern mit Details |
|
|
| GET | `/patterns/{pattern_id}/controls` | Controls aus einem Pattern |
|
|
|
|
#### Obligation Extraction
|
|
|
|
| Methode | Pfad | Beschreibung |
|
|
|---------|------|-------------|
|
|
| POST | `/obligations/extract` | Obligation aus Text extrahieren + Pattern matchen |
|
|
|
|
#### Crosswalk Matrix
|
|
|
|
| Methode | Pfad | Beschreibung |
|
|
|---------|------|-------------|
|
|
| GET | `/crosswalk` | Query (Filter: regulation, article, obligation, pattern) |
|
|
| GET | `/crosswalk/stats` | Abdeckungs-Statistiken |
|
|
|
|
#### Migration + Decomposition
|
|
|
|
| Methode | Pfad | Beschreibung |
|
|
|---------|------|-------------|
|
|
| POST | `/migrate/decompose` | Pass 0a: Obligation Extraction aus Rich Controls |
|
|
| POST | `/migrate/compose-atomic` | Pass 0b: Atomare Control-Komposition |
|
|
| POST | `/migrate/link-obligations` | Pass 1: Obligation-Linkage |
|
|
| POST | `/migrate/classify-patterns` | Pass 2: Pattern-Klassifikation |
|
|
| POST | `/migrate/triage` | Pass 3: Quality Triage |
|
|
| POST | `/migrate/backfill-crosswalk` | Pass 4: Crosswalk-Backfill |
|
|
| POST | `/migrate/deduplicate` | Pass 5: Deduplizierung |
|
|
| GET | `/migrate/status` | Migrations-Fortschritt |
|
|
| GET | `/migrate/decomposition-status` | Decomposition-Fortschritt |
|
|
|
|
**Route-Datei:** `compliance/api/crosswalk_routes.py`
|
|
|
|
---
|
|
|
|
### Multi-Layer Tests
|
|
|
|
| Datei | Tests | Schwerpunkt |
|
|
|-------|-------|-------------|
|
|
| `tests/test_obligation_extractor.py` | 107 | 3-Tier Extraktion, Helpers, Regex |
|
|
| `tests/test_pattern_matcher.py` | 72 | Keyword-Index, Embedding, Domain-Affinity |
|
|
| `tests/test_control_composer.py` | 54 | Composition, Templates, License-Rules |
|
|
| `tests/test_pipeline_adapter.py` | 36 | Pipeline Integration, 5 Migration Passes |
|
|
| `tests/test_crosswalk_routes.py` | 57 | 15 API Endpoints, Pydantic Models |
|
|
| `tests/test_decomposition_pass.py` | 68 | Pass 0a/0b, Quality Gate, 6 Guardrails |
|
|
| `tests/test_migration_060.py` | 12 | Schema-Validierung |
|
|
| `tests/test_control_patterns.py` | 18 | YAML-Validierung, Pattern-Schema |
|
|
| **Gesamt Multi-Layer** | | **424 Tests** |
|
|
|
|
### Geplanter Migrationsflow
|
|
|
|
```
|
|
Rich Controls (~25.000, release_state=raw)
|
|
↓
|
|
Pass 0a: Obligation Extraction (LLM + Quality Gate)
|
|
↓
|
|
Pass 0b: Atomic Control Composition (LLM + Template Fallback)
|
|
↓
|
|
Pass 1: Obligation Linking (deterministisch)
|
|
↓
|
|
Pass 2: Pattern Classification (Keyword + Embedding)
|
|
↓
|
|
Pass 3: Quality Triage
|
|
↓
|
|
Pass 4: Crosswalk Backfill
|
|
↓
|
|
Pass 5: Dedup / Merge
|
|
↓
|
|
Master Controls (~15.000-20.000 mit voller Traceability)
|
|
```
|