feat: Environmental stress test — the architecture works OUTSIDE cyber (Phase Ω, data-only)
First NON-cyber stress test. Every prior journey was cyber (infosec/software/product security).
Environmental brings a completely different mental model (substance flows, emissions, water,
chemicals, energy, circularity). The claim under test: RS-005 carries it UNCHANGED — only new DATA,
zero runtime code.
ISO 14001 (an EMS) is modelled as a Company Profile and run through the SAME engines as ISO 27001 ->
CRA (new pattern transition_pattern_iso14001_to_environmental_v1.yaml, capabilities as VERBS):
- ISO 14001 yields 5 environmental MANAGEMENT capabilities (Welt-1, probably present)
- the concrete substance/emission/water/material EVIDENCE is the 11-capability delta
- rejected_assumptions state what ISO 14001 does NOT produce (substance lists, REACH, emissions,
battery passports, water analyses) — preserving the Welt-1/Welt-2 separation
- the Journey Matcher stays domain-agnostic: ISO14001->Environmental 100%, cyber journeys 0%
Result: a non-cyber domain ran through Reality -> ... -> Journey with 0 new runtime classes and 0
new pipeline — a stronger generality proof than ten more cyber regulations.
Also extends the Architecture Stability ledger with the third KPI column the user requested — "new
capability types" — as a granularity Frühindikator (a domain needing ~80 new types at 0 runtime would
flag a too-coarse/too-fine capability model). Environmental = 16 types (5 mgmt + 11 evidence), in
range. Ledger now flags cyber vs non_cyber family. Non-runtime -> no deploy. 19 tests pass, check-loc 0.
This commit is contained in:
@@ -2,19 +2,21 @@
|
||||
|
||||
_Der Fokus hat sich verschoben: nicht mehr „kann die Architektur das?", sondern „wo versagt sie bei echtem Fachwissen?". Diese zwei KPIs erhebt kaum jemand. Eine neue Domäne ist eine ZEILE im Ledger (Daten), nie eine Codeänderung — genau das macht den KPI auditierbar._
|
||||
|
||||
## Architecture Stability — pro integrierter Anforderungsquelle: neue Runtime-Klassen? neue Pipeline?
|
||||
## Architecture Stability — pro Quelle: neue Runtime-Klassen? neue Pipeline? neue Capability-Typen?
|
||||
|
||||
| Quelle | Zieltyp | als | neue Runtime-Klassen | neue Pipeline | Ergebnis |
|
||||
|---|---|---|---:|---:|---|
|
||||
| Cyber Resilience Act (CRA) | regulation | transition_pattern_data | 0 | 0 | ✅ |
|
||||
| Maschinenverordnung (MaschinenVO) | regulation | transition_pattern_data | 0 | 0 | ✅ |
|
||||
| TISAX | certification | transition_pattern_data | 0 | 0 | ✅ |
|
||||
| Public Tender (öffentliche Ausschreibung) | contract | injected_required_set | 0 | 0 | ✅ |
|
||||
| OEM Specification (Lastenheft) | contract | injected_required_set | 0 | 0 | ✅ |
|
||||
| Environmental / Material evidence target | environmental | injected_required_set | 0 | 0 | ✅ |
|
||||
| Quelle | Familie | neue Runtime-Klassen | neue Pipeline | neue Capability-Typen | Ergebnis |
|
||||
|---|---|---:|---:|---:|---|
|
||||
| Cyber Resilience Act (CRA) | cyber | 0 | 0 | 13 | ✅ |
|
||||
| Maschinenverordnung (MaschinenVO) | cyber | 0 | 0 | 4 | ✅ |
|
||||
| TISAX | cyber | 0 | 0 | 5 | ✅ |
|
||||
| Public Tender (öffentliche Ausschreibung) | cyber | 0 | 0 | 3 | ✅ |
|
||||
| OEM Specification (Lastenheft) | cyber | 0 | 0 | 4 | ✅ |
|
||||
| ISO 14001 -> Environmental/Material (REACH/RoHS/Batterie/Wasser/Energie/Abfall) | non_cyber | 0 | 0 | 16 | ✅ |
|
||||
|
||||
- **Architecture Stability: 6/6 = 100%** der Quellen ohne neue Runtime-Klasse und ohne neue Pipeline.
|
||||
- **Knowledge Velocity: 6/6 = 100%** der Quellen **data-only** integriert (kein Entwickler nötig).
|
||||
- **Generalität über Cyber hinaus: 1/6 Quellen NICHT-Cyber** (Umwelt) — trugen die Pipeline ebenfalls 0/0. Das ist der eigentliche Test (ein anderes Denkmodell, nicht noch ein Cyber-Regelwerk).
|
||||
- **Capability-Modell-Frühindikator: 45 neue Typen gesamt, Maximum 16** (Umwelt, erste Nicht-Cyber-Domäne) — in Range, KEIN Granularitätsalarm (Alarm ≈ eine Domäne braucht plötzlich ~80 neue Typen bei 0 Runtime-Change → Modell zu grob/fein).
|
||||
|
||||
## Ehrlichkeit: die Pipeline-Funktionen sind EINMALIG (jetzt eingefroren)
|
||||
- 6 domänen-AGNOSTISCHE Funktionen, einmal gebaut, nicht je Domäne: `transition_reasoning (RS-005)`, `optimization`, `journey_matcher (ADR-011)`, `playbook`, `completeness`, `company (2A)`.
|
||||
|
||||
@@ -38,20 +38,27 @@ w("# Architecture Stability + Knowledge Velocity — Phase Ω (Evidence of Gener
|
||||
w("")
|
||||
w('_Der Fokus hat sich verschoben: nicht mehr „kann die Architektur das?", sondern „wo versagt sie bei echtem Fachwissen?". Diese zwei KPIs erhebt kaum jemand. Eine neue Domäne ist eine ZEILE im Ledger (Daten), nie eine Codeänderung — genau das macht den KPI auditierbar._')
|
||||
w("")
|
||||
w("## Architecture Stability — pro integrierter Anforderungsquelle: neue Runtime-Klassen? neue Pipeline?")
|
||||
w("## Architecture Stability — pro Quelle: neue Runtime-Klassen? neue Pipeline? neue Capability-Typen?")
|
||||
w("")
|
||||
w("| Quelle | Zieltyp | als | neue Runtime-Klassen | neue Pipeline | Ergebnis |")
|
||||
w("|---|---|---|---:|---:|---|")
|
||||
w("| Quelle | Familie | neue Runtime-Klassen | neue Pipeline | neue Capability-Typen | Ergebnis |")
|
||||
w("|---|---|---:|---:|---:|---|")
|
||||
for s in sources:
|
||||
ok = "✅" if (s["new_runtime_classes"] == 0 and not s["new_pipeline"]) else "❌"
|
||||
w("| %s | %s | %s | %d | %s | %s |" % (
|
||||
s["source"], s["target_type"], s["integrated_as"], s["new_runtime_classes"],
|
||||
"ja" if s["new_pipeline"] else "0", ok))
|
||||
w("| %s | %s | %d | %s | %d | %s |" % (
|
||||
s["source"], s.get("family", "-"), s["new_runtime_classes"],
|
||||
"ja" if s["new_pipeline"] else "0", s.get("new_capability_types", 0), ok))
|
||||
w("")
|
||||
non_cyber = [s for s in sources if s.get("family") == "non_cyber"]
|
||||
total_types = sum(s.get("new_capability_types", 0) for s in sources)
|
||||
max_types = max((s.get("new_capability_types", 0) for s in sources), default=0)
|
||||
w("- **Architecture Stability: %d/%d = %d%%** der Quellen ohne neue Runtime-Klasse und ohne neue Pipeline." % (
|
||||
len(stable), n, round(arch_stability * 100)))
|
||||
w("- **Knowledge Velocity: %d/%d = %d%%** der Quellen **data-only** integriert (kein Entwickler nötig)." % (
|
||||
len(data_only), n, round(knowledge_velocity * 100)))
|
||||
w("- **Generalität über Cyber hinaus: %d/%d Quellen NICHT-Cyber** (Umwelt) — trugen die Pipeline ebenfalls 0/0. Das ist der eigentliche Test (ein anderes Denkmodell, nicht noch ein Cyber-Regelwerk)." % (
|
||||
len(non_cyber), n))
|
||||
w("- **Capability-Modell-Frühindikator: %d neue Typen gesamt, Maximum %d** (Umwelt, erste Nicht-Cyber-Domäne) — in Range, KEIN Granularitätsalarm (Alarm ≈ eine Domäne braucht plötzlich ~80 neue Typen bei 0 Runtime-Change → Modell zu grob/fein)." % (
|
||||
total_types, max_types))
|
||||
w("")
|
||||
|
||||
# pipeline functions = one-time, domain-agnostic infrastructure (honesty: not per-domain costs)
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
# Environmental Stress Test — funktioniert die Architektur AUSSERHALB von Cyber? (Phase Ω)
|
||||
|
||||
_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._
|
||||
|
||||
## 1. ISO 14001 als Company Profile — Management, nicht Evidence
|
||||
- ISO 14001 liefert **Umwelt-MANAGEMENT-Disziplin** (Welt-1, wahrscheinlich vorhanden): `identify_environmental_aspects`, `operate_environmental_compliance_process`, `conduct_internal_environmental_audits`, `run_continual_environmental_improvement`, `control_environmental_documents`.
|
||||
- Über **dieselbe** `assess_transition`-Engine wie im Cyber-Fall — **keine Zeile neuer Runtime-Code**, nur ein neues Pattern-YAML.
|
||||
|
||||
## 2. RS-005 stellt dieselbe Frage: welche Umwelt-Capabilities fehlen?
|
||||
> 16 zu klären, 0 bereits abgedeckt, 5 vermutlich vorhanden, 11 fehlt, 0 n/a, 0 nicht im Korpus.
|
||||
- **Vermutlich vorhanden (Management):** 5 — `conduct_internal_environmental_audits`, `control_environmental_documents`, `identify_environmental_aspects` …
|
||||
- **Delta (konkrete Evidence, fehlt): 11 Capabilities** — z. B. `account_energy_consumption`, `analyze_water_discharge`, `declare_material_composition`, `document_waste_streams` …
|
||||
- Capabilities sind **Verben** (capability-is-a-verb): `manage_chemical_substances`, `measure_air_emissions`, `issue_battery_passport` …
|
||||
|
||||
## 3. Neue Qualitätsfrage — was erzeugt ISO 14001 typischerweise NICHT? _(rejected_assumptions, Welt-1/Welt-2)_
|
||||
- ISO 14001 does NOT produce concrete substance lists or REACH registrations.
|
||||
- ISO 14001 does NOT produce concrete air-emission measurements.
|
||||
- ISO 14001 does NOT produce battery passports or material declarations.
|
||||
- ISO 14001 does NOT produce water or wastewater analyses.
|
||||
- An ISO 14001 certificate does NOT establish RoHS substance-restriction evidence.
|
||||
|
||||
→ 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.
|
||||
|
||||
## 4. Journey Matcher bleibt domänen-agnostisch
|
||||
> 1 Journeys erklaeren das Delta; beste: ISO14001 -> Environmental (100% des Deltas)
|
||||
| Journey | erklärt das Umwelt-Delta |
|
||||
|---|---|
|
||||
| ISO14001 -> Environmental | 100% |
|
||||
| ISMS -> TISAX | 0% |
|
||||
| ISO27001 -> CRA + MaschinenVO | 0% |
|
||||
|
||||
→ Die **Cyber-Journeys erklären 0 %** des Umwelt-Deltas — der Matcher rät nicht, er erklärt nur, was das Delta wirklich beschreibt.
|
||||
|
||||
## Befund
|
||||
|
||||
> **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. **16 neue Capability-Typen** (5 Management + 11 konkrete Evidence) — in der Größenordnung der Cyber-Domänen, kein Granularitäts-Frühindikator. Architecture Stability: **0 neue Runtime-Klassen, 0 neue Pipeline.**
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
# 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))
|
||||
Reference in New Issue
Block a user