# ruff: noqa # mypy: ignore-errors """Customer Mission #5 — a NON-security target: does evidence relevance really flip? The whole „Evidence-Relevance(Target)" claim is only convincing if it holds in BOTH directions. Missions #2–#4 showed security evidence (ISO 27001, PSIRT) ranking differently across security targets, and ISO 14001 being worthless against the CRA/TISAX. This mission closes the loop with a deliberately NON-security target — an environmental / material-evidence requirement set — and asks the one question: is `relevance(evidence, target)` genuinely a function of the TARGET, or an attribute of the evidence? Expected and shown: ISO 14001 is keine/niedrig against CRA and TISAX but HOCH against the environmental target — while the security certificates (ISO 27001, PSIRT) flip the other way (relevant for security, keine for the environmental target). The same evidence is worthless or decisive depending on the target. DELIBERATELY NOT here (per scope): no environmental corpus, no ISO-14001 norm model, no new runtime module, no deploy, no real names. The environmental target is a hand-authored Required set (injected like any TargetRequirement) purely to point the existing engine at a non-security goal. Run: cd backend-compliance && PYTHONPATH=. python3 reference_scenarios/mission_non_security_target.py """ from __future__ import annotations import os import yaml from compliance.company import ( CompanyContext, Certification, CapabilityMappingEntry, build_company_profile, ) from compliance.reasoning.enums import Confidence from compliance.transition_reasoning import ( TransitionContext, TransitionGoal, TargetRequirement, assess_transition, CoverageStatus, ) OUT = [] def w(s=""): OUT.append(s) _K = os.path.join(os.path.dirname(__file__), "..", "knowledge", "transition_patterns") def _caps(pattern_file): p = yaml.safe_load(open(os.path.join(_K, pattern_file), encoding="utf-8")) return [a["capability"] for a in p["likely_covered"]] + [d["capability"] for d in p["delta_requirements"]] # ── Three targets — two security, one NON-security (the new axis) ─────────────────────────── CRA = _caps("transition_pattern_iso27001_to_cra_maschinenvo_v1.yaml") # security regulation TISAX = _caps("transition_pattern_isms_to_tisax_v1.yaml") # security certification # NON-security target: an environmental / material-evidence requirement set. Hand-authored Required # capabilities (NOT a corpus, NOT an ISO-14001 norm model) — just a goal to point the engine at. ENVIRONMENTAL = [ "environmental_management_documentation", "energy_efficiency_documentation", "supply_chain_environmental_due_diligence", "material_declaration_scip_reach", "hazardous_substance_restriction_rohs", "carbon_footprint_accounting", "recycling_and_take_back", "battery_passport_material_data", ] TARGETS = [("CRA", "Security/Regulation", CRA), ("TISAX", "Security/Certification", TISAX), ("Umwelt-/Materialnachweis", "NICHT-Security", ENVIRONMENTAL)] # ── ONE company profile (the same multi-certified archetype; it HAS ISO 14001) ────────────── CERT_OBS = { "ISO27001": ["information_security_management", "incident_management", "access_control_and_authentication", "technical_vulnerability_management", "security_logging_and_monitoring", "secure_development_lifecycle"], "TISAX": ["information_security_management", "access_control_and_authentication", "incident_management", "supplier_security", "physical_security", "prototype_protection"], "PSIRT": ["coordinated_vulnerability_disclosure", "exploited_vuln_and_incident_reporting", "public_security_advisories"], # an EMS (ISO 14001) touches several environmental process areas — relevant ONLY to an env target: "ISO14001": ["environmental_management_documentation", "energy_efficiency_documentation", "supply_chain_environmental_due_diligence"], "ISO9001": ["ce_conformity_assessment_and_technical_documentation"], } cmap = {k: CapabilityMappingEntry(capability_ids=v, confidence=Confidence.MEDIUM) for k, v in CERT_OBS.items()} profile = build_company_profile( CompanyContext(company_id="mc5", certifications=[Certification(certification_id=k) for k in CERT_OBS]), cmap) def _delta(caps): reqs = [TargetRequirement(capability_id=c) for c in caps] a = assess_transition(TransitionContext(company_id="mc5", target=TransitionGoal(target_id="t")), reqs, profile) return sorted({c.capability_id for c in a.coverage if c.status == CoverageStatus.MISSING}) def _rel(cert_caps, target_caps): n = len(set(cert_caps) & set(target_caps)) return n, ("hoch" if n >= 3 else "niedrig" if n >= 1 else "keine") w('# Customer Mission #5 — ein Nicht-Security-Ziel: kippt die Evidence-Relevanz?') w("") w('_Enger Scope: KEIN Umweltrecht, KEINE ISO-14001-Normmodellierung, KEIN neues Modul, KEIN Deploy. Nur die EINE Frage: ist `relevance(evidence, target)` wirklich eine Funktion des Ziels — oder ein Attribut der Evidence? Das Umwelt-/Materialnachweis-Ziel ist ein hand-authored `Required`-Satz (synthetisch), nur um die bestehende Engine auf ein Nicht-Security-Ziel zu richten. Synthetischer Kunde, keine echten Namen._') w("") w("## Der Kunde (synthetisch) — EIN Profil (hat u. a. ISO 14001)") w("> **ISO 9001 · ISO 27001 · ISO 14001 · TISAX · PSIRT** · vernetzte Maschinen · Export EU") w("") # ── 1. Die Relevanz-Matrix (zwei Security-Ziele + ein Umwelt-Ziel) ───────── w("## 1. Evidence-Relevanz über drei Ziele — zwei Security, eines NICHT") w("| Zertifizierung (Evidence) | → CRA | → TISAX | → Umwelt-/Material |") w("|---|---|---|---|") for cert, caps in CERT_OBS.items(): cells = [_rel(caps, t)[1] + " (%d)" % _rel(caps, t)[0] for _, _, t in TARGETS] mark = " ⟵ kippt" if cert == "ISO14001" else "" w("| **%s** | %s | %s | %s |%s" % (cert, cells[0], cells[1], cells[2], mark)) w("") # ── 2. Der Beweis: dieselbe Evidence, gegensätzlicher Wert je Ziel ───────── iso14_env = _rel(CERT_OBS["ISO14001"], ENVIRONMENTAL) iso27_env = _rel(CERT_OBS["ISO27001"], ENVIRONMENTAL) psirt_env = _rel(CERT_OBS["PSIRT"], ENVIRONMENTAL) w("## 2. Beweis — Relevanz ist eine Funktion des ZIELS (in BEIDE Richtungen)") w("- **ISO 14001:** gegen CRA/TISAX **keine**, gegen das Umwelt-/Materialziel **%s (%d)**. Dieselbe Zertifizierung — von wertlos zu entscheidend, nur weil das Ziel wechselt." % (iso14_env[1], iso14_env[0])) w("- **Symmetrisch:** **ISO 27001** (hoch gegen CRA/TISAX) ist gegen das Umwelt-/Materialziel **%s (%d)**; **PSIRT** ebenso **%s (%d)**. Security-Evidence ist hier wertlos." % (iso27_env[1], iso27_env[0], psirt_env[1], psirt_env[0])) w("- Delta des Umwelt-/Materialziels: **%d** fehlende Fähigkeiten (das Profil deckt nur die ISO-14001-nahen ab) — über dieselbe `assess_transition`-Engine, kein Sonderpfad." % len(_delta(ENVIRONMENTAL))) w("") w('→ **Damit ist `relevance(evidence, target)` zweiseitig bewiesen:** keine Evidence ist „an sich" relevant; Relevanz entsteht erst gegen ein Ziel. Eine Capability/Zertifizierung ohne Ziel hat keinen Relevanzwert.') w("") # ── Befund ──────────────────────────────────────────────────────────────── w("## Befund") w("") w('> **Ein und dieselbe Evidence kann je Ziel wertlos oder hoch relevant sein** — hier erstmals an einem NICHT-Security-Ziel gezeigt, in beide Richtungen (ISO 14001 kippt von keine→hoch, Security-Certs von hoch→keine). Folgerung für das spätere Modell: Relevanz darf NICHT als Attribut der Evidence gespeichert werden, sondern nur als `relevance(evidence, target)` berechnet (computed-not-stored). **Damit ist die Ziel-Diversität für den späteren Selektor beisammen: Regulation · Certification · Contract/Tender · OEM-Spec · Umwelt-/Material-Ziel — fünf Zielarten durch dieselbe Engine. Erst jetzt wird ein Scope→Journey-Selektor sinnvoll** (er optimiert nicht mehr auf einer einzigen Zielart).') w("") print("\n".join(OUT))