Files
breakpilot-compliance/backend-compliance/reference_scenarios/automotive_convergence_stress_test.py
T
Benjamin Admin 90c3fe16b5 feat: Automotive convergence stress test — same capability from many sources (Phase Ω #2)
Not another domain to prove agnosticism (Environmental did that) but a DIFFERENT property: can the
SAME capability be fed by many overlapping Requirement Sources at once without the model becoming
unstable? Realistic setup — a supplier with ISO 9001 + IATF 16949 + TISAX + ASPICE + CSMS + SUMS
developing an ECU for OEM X. Seven sources (CRA, UNECE R155/CSMS, R156/SUMS, IATF, TISAX, ASPICE,
OEM X) with deliberate overlap, run through the SAME engine (0 runtime code, data only).

Three new measurements (user-requested):
  - Capability Convergence: technical_vulnerability_management = 4 sources across 3 source TYPES
    (regulation + certification + contract); secure_signed_update_distribution = 4 sources. The
    overlap is where the economic value lives ("one capability replaces five evidence worlds").
  - Existing-vs-New: 13/27 required caps reuse existing cyber/environmental MCAPs (48%) -> the
    registry is starting to converge; the automotive-specific rest (CSMS/SUMS/ASPICE/functional
    safety) is expectedly new (a maturity hint, not an architecture break).
  - Business Leverage: a convergent capability satisfies N regulations AND unlocks the OEM market —
    more convincing to a GF than "satisfies five laws". (Regulatory Leverage counts regulations;
    Business Leverage counts regulations + markets/customers.)

Ledger gains the automotive row (0/0, 14 new types, data_only); stability stays 7/7 = 100%. The
verdict recommends the user's next step: NOT a new domain but PAUSE and analyse the registry for the
cross-domain high-convergence core MCAPs. Non-runtime -> no deploy. 12 tests pass, check-loc 0.
2026-06-28 11:30:30 +02:00

128 lines
8.4 KiB
Python

# ruff: noqa
# mypy: ignore-errors
"""Automotive convergence stress test — does the SAME capability survive MANY sources? (Phase Ω, test #2)
Environmental proved domain-agnosticism. This tests a different property: can ONE capability be fed by
many overlapping Requirement Sources at once without the model becoming unstable? Realistic setup — a
supplier with ISO 9001 + IATF 16949 + TISAX + ASPICE + CSMS + SUMS developing an ECU for OEM X. Seven
sources (CRA, UNECE R155/CSMS, R156/SUMS, IATF, TISAX, ASPICE, OEM X) demand heavily OVERLAPPING caps.
Three new measurements the user asked for:
- Capability Convergence : per capability, how many sources / how many distinct source TYPES feed it.
- Existing-vs-New : how many required caps reuse the EXISTING registry vs are genuinely new
(a registry-convergence signal — high reuse => the core is forming).
- Business Leverage : the most convergent cap satisfies N regulations AND unlocks a market — more
convincing to a GF than "satisfies five laws".
Data only (a YAML + injected Required caps), zero runtime code. Synthetic, no real names. No deploy.
Run: cd backend-compliance && PYTHONPATH=. python3 reference_scenarios/automotive_convergence_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,
)
OUT = []
def w(s=""):
OUT.append(s)
_HERE = os.path.dirname(__file__)
A = yaml.safe_load(open(os.path.join(_HERE, "..", "knowledge", "domains", "automotive", "source_capabilities.yaml"), encoding="utf-8"))
SOURCES = A["sources"]
# ── known capability universe = caps already modelled in the cyber + environmental patterns ──
_K = os.path.join(_HERE, "..", "knowledge", "transition_patterns")
known = set()
for f in os.listdir(_K):
if f.endswith(".yaml"):
p = yaml.safe_load(open(os.path.join(_K, f), encoding="utf-8"))
known |= {a["capability"] for a in p.get("likely_covered", [])}
known |= {d["capability"] for d in p.get("delta_requirements", [])}
# ── one multi-certified company profile (many overlapping sources) ──────────────────────────
prof_caps = A["company_profile_capabilities"]
cmap = {k: CapabilityMappingEntry(capability_ids=v, confidence=Confidence.MEDIUM) for k, v in prof_caps.items()}
profile = build_company_profile(
CompanyContext(company_id="auto", certifications=[Certification(certification_id=k) for k in prof_caps]), cmap)
# ── required = union of all source caps for "ECU for OEM X"; delta via the SAME engine ───────
required = sorted({c for s in SOURCES for c in s["requires"]})
assess = assess_transition(TransitionContext(company_id="auto", target=TransitionGoal(target_id="ECU_for_OEM_X")),
[TargetRequirement(capability_id=c) for c in required], profile)
delta = sorted({c.capability_id for c in assess.coverage if c.status == CoverageStatus.MISSING})
# ── Capability Convergence: per cap -> sources + distinct source types ───────────────────────
conv = {}
for cap in required:
srcs = [s for s in SOURCES if cap in s["requires"]]
conv[cap] = (sorted(s["id"] for s in srcs), sorted({s["type"] for s in srcs}))
ranked = sorted(required, key=lambda c: (-len(conv[c][0]), -len(conv[c][1]), c))
# ── Existing-vs-New (registry convergence signal) ───────────────────────────────────────────
reuse = sorted(c for c in required if c in known)
fresh = sorted(c for c in required if c not in known)
reuse_pct = round(100 * len(reuse) / len(required)) if required else 0
w("# Automotive Convergence Stress Test — überlebt EINE Capability viele Quellen? (Phase Ω #2)")
w("")
w('_Nicht noch eine Domäne, sondern eine andere Eigenschaft: bleibt das Modell stabil, wenn dieselbe Capability gleichzeitig aus vielen überlappenden Quellen gespeist wird? Realistisch: ein Zulieferer (ISO 9001 + IATF 16949 + TISAX + ASPICE + CSMS + SUMS) entwickelt ein Steuergerät für OEM X. Sieben Quellen, bewusste Überlappung. Data-only, keine echten Namen._')
w("")
w("## 1. Sieben überlappende Quellen, eine Engine")
w("- Quellen: %s." % ", ".join("`%s`(%s)" % (s["id"], s["type"]) for s in SOURCES))
w('- **%d distinct geforderte Capabilities** für „Steuergerät → OEM X" — über dieselbe `assess_transition`-Engine, 0 neue Runtime-Klassen.' % len(required))
w("- Delta (fehlt dem Profil): **%d** Capabilities." % len(delta))
w("")
# ── 2. Capability Convergence ──────────────────────────────────────────────
w("## 2. Capability Convergence — dieselbe Capability aus vielen Quellen")
w("| Capability | Sources | Distinct Source Types | aus |")
w("|---|---:|---:|---|")
for cap in ranked[:8]:
srcs, types = conv[cap]
w("| `%s` | %d | %d | %s |" % (cap, len(srcs), len(types), ", ".join(srcs)))
w("")
top = ranked[0]
w('→ **`%s`** ist am konvergentesten: **%d Quellen** über **%d Quelltypen** — eine Maßnahme, viele Nachweiswelten. Genau hier entsteht der wirtschaftliche Nutzen (nicht „300 Gesetze", sondern „eine Capability ersetzt fünf Nachweiswelten").' % (top, len(conv[top][0]), len(conv[top][1])))
w("")
# ── 3. Existing-vs-New (registry convergence) ──────────────────────────────
w("## 3. Existing-vs-New — beginnt die Registry zu konvergieren?")
w("- **Bereits vorhandene MCAPs (Reuse aus Cyber/Umwelt): %d/%d = %d%%** — z. B. %s." % (
len(reuse), len(required), reuse_pct, ", ".join("`%s`" % c for c in reuse[:5]) + " …"))
w("- **Genuin neu (Automotive-spezifisch): %d** — z. B. %s." % (
len(fresh), ", ".join("`%s`" % c for c in fresh[:5]) + " …"))
w("- **Lesart:** %s" % (
"Hohe Wiederverwendung → die Registry konvergiert, ein Kern bildet sich." if reuse_pct >= 60 else
"Spürbare Wiederverwendung (%d%%) — der Kern beginnt sich zu bilden; der automotive-spezifische Rest (CSMS/SUMS/ASPICE/Funktionssicherheit) ist erwartbar neu. Kein Architekturbruch, sondern ein Hinweis auf den Reifegrad der Capability-Zerlegung." % reuse_pct))
w("")
# ── 4. Business Leverage ───────────────────────────────────────────────────
top_srcs, top_types = conv[top]
regs = [s for s in top_srcs if next(x["type"] for x in SOURCES if x["id"] == s) == "regulation"]
contracts = [s for s in top_srcs if next(x["type"] for x in SOURCES if x["id"] == s) == "contract"]
w('## 4. Business Leverage — Märkte + Regulierung, nicht nur „Gesetze"')
w("- `%s` erfüllt gleichzeitig **%d Regelwerke** (%s) **und** öffnet den **OEM-Markt** (%s)." % (
top, len(regs), ", ".join(regs), ", ".join(contracts) or "—"))
w('- Managementsatz: **„Diese eine Capability erfüllt %d regulatorische Anforderungen UND ist Eintrittskarte zum OEM-Geschäft"** — überzeugender als „erfüllt %d Gesetze". (Regulatory Leverage zählt Regelwerke; **Business Leverage** zählt Regelwerke + erschlossene Märkte/Kunden.)' % (len(regs), len(regs)))
w("")
# ── Befund ─────────────────────────────────────────────────────────────────
w("## Befund")
w("")
w('> **Eine Capability aus bis zu %d Quellen über %d Quelltypen — das Modell blieb stabil (0 neue Runtime-Klassen, 0 neue Pipeline; reine Daten).** Convergence ist messbar geworden, und %d%% der Automotive-Anforderungen bilden auf BESTEHENDE MCAPs ab — die Registry beginnt zu konvergieren. Nächster Schritt ist bewusst KEINE neue Domäne, sondern **innehalten und die Registry analysieren**: welche MCAPs tauchen domänenübergreifend (CRA·MaschinenVO·OEM·TISAX·ASPICE·Umwelt) am häufigsten auf? Diese hochkonvergenten Capabilities sind der dauerhaft wertvollste Plattformkern.' % (
len(conv[top][0]), len(conv[top][1]), reuse_pct))
w("")
print("\n".join(OUT))