# 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 | | NET | Network & Transport Security | TLS, Zertifikate, Netzwerk-Haertung | | SUP | Software Supply Chain | Signierung, SBOM, Dependency-Scanning | | LOG | Security Operations & Logging | Privacy-Aware Logging, SIEM | | WEB | Web Application Security | Admin-Flows, Account Recovery | | DATA | Data Governance & Classification | Datenklassifikation, Schutzmassnahmen | | CRYP | Cryptographic Operations | Key Management, Rotation, HSM | | REL | Release & Change Governance | Change Impact Assessment, Security Review | !!! 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 | | `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 (~183.000 Chunks aus Gesetzen, Verordnungen und Standards). Aktueller Stand: **~2.120 Controls** generiert. ### 8-Stufen-Pipeline ```mermaid flowchart TD A[1. RAG Scroll] -->|Alle 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 --> H[5. Harmonization - Embeddings] G --> H H -->|Duplikat| I[Als Duplikat speichern] H -->|Neu| J[6. Anchor Search] J --> K[7. Store Control] K --> L[8. 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: 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 6-8: 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: **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** (17 thematische Kategorien): encryption, authentication, network, data_protection, logging, incident, continuity, compliance, supply_chain, physical, personnel, application, system, risk, governance, hardware, identity ### 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:30b-a3b` | Lokales LLM fuer Vorfilter | | `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) | | `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_recht` | EU-Verordnungen (DSGVO, NIS2, AI Act etc.) | Rule 1 | | `bp_compliance_datenschutz` | Datenschutz-Leitlinien | 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 | --- ## 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 | ~183.000 | | Verarbeitete Chunks | ~183.000 (vollstaendig) | | Generierte Controls | **~2.120** | | Konversionsrate | ~1,2% (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