Add obligation discovery pipeline tooling

Sichert die validierte Obligation Discovery Pipeline aus /tmp als dauerhaftes,
committetes Tooling (scripts/obligation_discovery/) — der eigentliche Vermögenswert.

Stufen: precluster (Embedding-Cache + Mikro-Cluster) → meta_cluster (Review Units,
Skalierungs-Fix) → synthesize_obligations (Opus, Key aus ENV, Streaming, harte Tier-Regel,
Provenance) → validate_registry → merge_review_diff. Reine Helfer in _core.py, 16 Unit-Tests.

Doku docs-src/development/obligation_discovery_pipeline_v1.md mit Meilensteinen
(SBOM/Vuln reproduziert, Auth 4408→170 Review Units→54→kuriert 29) und der Architekturregel:
Runtime deterministisch, Discovery LLM-gestützt.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-06-25 07:41:45 +02:00
parent 48e39423e6
commit e1b270c36e
8 changed files with 595 additions and 0 deletions
@@ -0,0 +1,35 @@
"""Stufe 4 — Validierung: belastbare Registry-Checks (kein LLM/Key).
Prüft die User-Regeln: LEGAL_MINIMUM braucht legal_basis · member_controls vollständig ·
out_of_scope separat · >8-Obligations/Review-Unit-Warnung. Exit-Code 1 bei hartem Fehler.
python3 scripts/obligation_discovery/validate_registry.py obligations/cra_authentication.json
"""
from __future__ import annotations
import argparse
import json
import sys
from _core import validate_registry
def main() -> None:
ap = argparse.ArgumentParser()
ap.add_argument("registry")
a = ap.parse_args()
reg = json.load(open(a.registry, encoding="utf-8"))
v = validate_registry(reg)
print(f"=== validate {a.registry} ===")
print(f" obligations: {v['obligations']}")
print(f" LEGAL_MINIMUM: {v['legal_minimum']}")
print(f" LM ohne legal_basis: {v['lm_without_legal_basis'] or 'keine'}")
print(f" member_controls leer: {v['empty_member_controls'] or 'keine'}")
print(f" >8 Obligations/Review-Unit: {v['over8_per_review_unit'] or 'keine'}")
print(f" out_of_scope: {v['out_of_scope']}")
print(f" semantische Kanten: {v['semantic_edges']}")
print(f" PASSED: {v['passed']}")
sys.exit(0 if v["passed"] else 1)
if __name__ == "__main__":
main()