# ruff: noqa # mypy: ignore-errors """Environmental stress test — does the architecture work OUTSIDE cyber? (Phase Ω) Every prior journey lived in the cyber family (CRA / MaschinenVO / TISAX / ISO 27001 / OEM / Tender — all infosec, software, product cybersecurity). This is the first NON-cyber stress test: substance flows, emissions, water, chemicals, energy, circularity. The claim under test is NOT "we built an environmental cluster" but "RS-005 carries an entirely different mental model UNCHANGED — only new DATA, zero runtime". It runs ISO 14001 (an EMS, as a Company Profile, Welt-1) -> an Environmental target through the SAME engines used for ISO 27001 -> CRA, and asks the SAME question: which environmental capabilities are still missing? Plus the new quality question (rejected_assumptions): which capabilities does ISO 14001 typically NOT produce? And it runs the Journey Matcher to confirm it stays domain-agnostic. Synthetic, no real names. Non-runtime -> no deploy. Run: cd backend-compliance && PYTHONPATH=. python3 reference_scenarios/environmental_stress_test.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, ) from compliance.journey_matcher import JourneySignature, match_journeys OUT = [] def w(s=""): OUT.append(s) _K = os.path.join(os.path.dirname(__file__), "..", "knowledge", "transition_patterns") def _load(name): return yaml.safe_load(open(os.path.join(_K, name), encoding="utf-8")) ENV = _load("transition_pattern_iso14001_to_environmental_v1.yaml") mgmt = [a["capability"] for a in ENV["likely_covered"]] # what ISO 14001 DOES give (Welt-1) concrete = [d["capability"] for d in ENV["delta_requirements"]] # what it does NOT give (the delta) # ── Company Profile: ISO 14001 -> the management capabilities only (NO concrete evidence) ──── profile = build_company_profile( CompanyContext(company_id="env", certifications=[Certification(certification_id="ISO14001")]), {"ISO14001": CapabilityMappingEntry(capability_ids=mgmt, confidence=Confidence.MEDIUM)}) # ── SAME engine as ISO 27001 -> CRA: required = management + concrete; delta = what's missing ─ reqs = [TargetRequirement(capability_id=c) for c in mgmt + concrete] assess = assess_transition(TransitionContext(company_id="env", target=TransitionGoal(target_id="Environmental")), reqs, profile) covered = sorted({c.capability_id for c in assess.coverage if c.status != CoverageStatus.MISSING}) delta = sorted({c.capability_id for c in assess.coverage if c.status == CoverageStatus.MISSING}) # ── Journey Matcher: stays domain-agnostic? cyber journeys must score ~0 on an env delta ───── def _sig(name, label): p = _load(name) return JourneySignature(journey_id=p.get("id", name), label=label, capability_pattern=[d["capability"] for d in p["delta_requirements"]]) journeys = [ _sig("transition_pattern_iso14001_to_environmental_v1.yaml", "ISO14001 -> Environmental"), _sig("transition_pattern_iso27001_to_cra_maschinenvo_v1.yaml", "ISO27001 -> CRA + MaschinenVO"), _sig("transition_pattern_isms_to_tisax_v1.yaml", "ISMS -> TISAX"), ] match = match_journeys(delta, journeys) w("# Environmental Stress Test — funktioniert die Architektur AUSSERHALB von Cyber? (Phase Ω)") w("") w('_Erster Nicht-Cyber-Test. Nicht „wir bauen einen Umwelt-Cluster", sondern: trägt RS-005 ein völlig anderes Denkmodell (Stoffe/Emissionen/Wasser/Energie/Kreislauf) UNVERÄNDERT — nur neue DATEN, null Runtime-Code? ISO 14001 als Company Profile (Welt-1), dieselbe Engine wie ISO 27001 → CRA. Synthetisch, keine echten Namen._') w("") w("## 1. ISO 14001 als Company Profile — Management, nicht Evidence") w("- ISO 14001 liefert **Umwelt-MANAGEMENT-Disziplin** (Welt-1, wahrscheinlich vorhanden): %s." % ", ".join("`%s`" % c for c in mgmt)) w("- Über **dieselbe** `assess_transition`-Engine wie im Cyber-Fall — **keine Zeile neuer Runtime-Code**, nur ein neues Pattern-YAML.") w("") w("## 2. RS-005 stellt dieselbe Frage: welche Umwelt-Capabilities fehlen?") w("> %s" % assess.summary.headline) w("- **Vermutlich vorhanden (Management):** %d — %s" % (len(covered), ", ".join("`%s`" % c for c in covered[:3]) + " …")) w("- **Delta (konkrete Evidence, fehlt): %d Capabilities** — z. B. %s …" % (len(delta), ", ".join("`%s`" % c for c in delta[:4]))) w("- Capabilities sind **Verben** (capability-is-a-verb): `manage_chemical_substances`, `measure_air_emissions`, `issue_battery_passport` …") w("") w("## 3. Neue Qualitätsfrage — was erzeugt ISO 14001 typischerweise NICHT? _(rejected_assumptions, Welt-1/Welt-2)_") for r in ENV["rejected_assumptions"]: w("- %s" % r) w("") w("→ Genau wie ISO 9001 → CRA: ein **Managementsystem** gibt die Disziplin, aber **nicht die konkrete substanz-/produktspezifische Evidence**. Die Welt-1/Welt-2-Trennung bleibt erhalten.") w("") w("## 4. Journey Matcher bleibt domänen-agnostisch") w("> %s" % match.headline) w("| Journey | erklärt das Umwelt-Delta |") w("|---|---|") for m in match.matches: w("| %s | %d%% |" % (m.label, round(m.score * 100))) w("") w("→ Die **Cyber-Journeys erklären 0 %** des Umwelt-Deltas — der Matcher rät nicht, er erklärt nur, was das Delta wirklich beschreibt.") w("") w("## Befund") w("") w('> **Ein völlig anderes Denkmodell (Umwelt) lief durch `Reality → Evidence → Capability → Required → Delta → Journey` ohne eine Zeile neuen Runtime-Code — nur ein neues Pattern-YAML + injizierte Required-Caps.** Das ist ein stärkerer Generalitätsbeweis als zehn weitere Cyber-Regelwerke: die Architektur ist nicht „Compliance/Cyber", sondern ein allgemeines Trägersystem. **%d neue Capability-Typen** (5 Management + %d konkrete Evidence) — in der Größenordnung der Cyber-Domänen, kein Granularitäts-Frühindikator. Architecture Stability: **0 neue Runtime-Klassen, 0 neue Pipeline.**' % (len(mgmt) + len(concrete), len(concrete))) w("") print("\n".join(OUT))