fbbd0957bd
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.
80 lines
2.9 KiB
Python
80 lines
2.9 KiB
Python
"""Architecture Stability + Knowledge Velocity KPI — Phase Ω guardrail.
|
|
|
|
This is not a feature test; it is a LIVING GUARDRAIL. The day someone integrates a Requirement Source
|
|
that needs a new runtime class or a new pipeline (i.e. NOT data-only), `test_every_source_is_data_only`
|
|
fails — surfacing the exact moment the architecture stopped being general. That is the whole point of
|
|
Phase Ω: measure where it breaks under real domain knowledge.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
|
|
import yaml
|
|
|
|
|
|
def _ledger():
|
|
p = os.path.join(os.path.dirname(__file__), "..", "knowledge", "architecture_stability", "integration_ledger.yaml")
|
|
return yaml.safe_load(open(p, encoding="utf-8"))
|
|
|
|
|
|
def _run():
|
|
root = os.path.join(os.path.dirname(__file__), "..")
|
|
r = subprocess.run(
|
|
[sys.executable, "reference_scenarios/architecture_stability_kpi.py"],
|
|
cwd=root, env={**os.environ, "PYTHONPATH": "."}, capture_output=True, text=True,
|
|
)
|
|
assert r.returncode == 0, r.stderr
|
|
return r.stdout
|
|
|
|
|
|
def test_every_source_is_data_only_and_zero_runtime():
|
|
# GUARDRAIL: every integrated source must cost 0 runtime classes, no new pipeline, data-only.
|
|
# If a future domain breaks this, fix the architecture or record the break honestly — do not
|
|
# weaken this assertion to make it pass.
|
|
for s in _ledger()["sources"]:
|
|
assert s["new_runtime_classes"] == 0, s["source"]
|
|
assert s["new_pipeline"] is False, s["source"]
|
|
assert s["integration_kind"] == "data_only", s["source"]
|
|
|
|
|
|
def test_kpis_reported_at_full_stability():
|
|
out = _run()
|
|
n = len(_ledger()["sources"])
|
|
assert "Architecture Stability: %d/%d = 100%%" % (n, n) in out
|
|
assert "Knowledge Velocity: %d/%d = 100%%" % (n, n) in out
|
|
|
|
|
|
def test_capability_types_column_and_non_cyber_generality():
|
|
out = _run()
|
|
# the third KPI column (capability-model granularity Frühindikator) is present and populated
|
|
assert "neue Capability-Typen" in out
|
|
assert "Capability-Modell-Frühindikator" in out
|
|
# the first non-cyber domain is recorded and carried the pipeline 0/0
|
|
assert "non_cyber" in out
|
|
assert "Generalität über Cyber hinaus" in out
|
|
# every ledger source carries a capability-type count
|
|
for s in _ledger()["sources"]:
|
|
assert s["new_capability_types"] >= 1, s["source"]
|
|
|
|
|
|
def test_pipeline_functions_are_one_time_infrastructure():
|
|
out = _run()
|
|
assert "EINMALIG (jetzt eingefroren)" in out
|
|
assert "journey_matcher" in out and "letzte architektonische Baustein" in out
|
|
|
|
|
|
def test_three_knowledge_layers_present():
|
|
out = _run()
|
|
for layer in ["Beschreibend", "Transformation", "Produktion"]:
|
|
assert layer in out
|
|
|
|
|
|
def test_three_success_questions_present():
|
|
out = _run()
|
|
assert "Musste für eine neue Domäne Runtime-Code geändert werden?" in out
|
|
assert "Knowledge Velocity" in out
|
|
assert "Architecture Stability" in out
|