feat(pipeline): Scope-Audit als fester Review-Step (flag-only, non-blocking)

#3 (User): Scope-Audit in den Cut-Prozess aufnehmen — nicht-invasiv, nur flaggen,
Reklassifizierung bleibt menschlich/koordiniert (betrifft join_keys + Compliance Execution).

- validate_registry.py surfaced jetzt pro Cut authority-/institution-adressierte Obligations
  OHNE scope-Klassifikation als non-fatal Warnung (ändert Exit-Code NICHT, mutiert NICHT;
  importiert NON_MANUFACTURER_DOMAINS aus scope_audit.py, DRY). Verifiziert: clean-Fall
  (cra_machinery, 3 klassifiziert) still, Negativtest (sanctions ohne scope) feuert Warnung.
- obligation_registry_v1.md: neuer Abschnitt "Scope-Audit (Review-Step, PFLICHT je Cut)" mit
  scope-Achse (in_scope/out_of_scope/derived_obligation), Gate-Regel verbatim und
  Werkzeug-Trennung FLAG (scope_audit.py) ⊥ MUTATE (apply_scope_classification.py, nur Review-Go).

Gate: jeder neue Cut läuft durch Scope-Audit; Findings werden dokumentiert; automatische
Reclassification verboten ohne explizites Review-Go.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-07-01 13:54:44 +02:00
parent 6523286af6
commit 4027470855
2 changed files with 38 additions and 0 deletions
@@ -11,6 +11,7 @@ import json
import sys
from _core import validate_registry
from scope_audit import NON_MANUFACTURER_DOMAINS
def main() -> None:
@@ -28,6 +29,15 @@ def main() -> None:
print(f" out_of_scope: {v['out_of_scope']}")
print(f" semantische Kanten: {v['semantic_edges']}")
print(f" PASSED: {v['passed']}")
# Scope-Audit (Review-Step, FLAG-ONLY — mutiert nie, blockt nie, ändert Exit-Code nicht):
unclassified = [o.get("id") or o.get("obligation_id") for o in reg.get("obligations", [])
if (o.get("applicability") or "").strip() in NON_MANUFACTURER_DOMAINS and not o.get("scope")]
if unclassified:
print(f" ⚠ SCOPE-AUDIT: {len(unclassified)} authority-/institution-adressierte Obligation(s) OHNE scope:")
print(f" {', '.join(str(x) for x in unclassified)}")
print(" → Review-Pflicht: scope=out_of_scope|derived_obligation (apply_scope_classification.py, NUR mit Review-Go). Auto-Reclassification VERBOTEN.")
else:
print(" Scope-Audit: keine unklassifizierten authority-/institution-Obligations")
sys.exit(0 if v["passed"] else 1)