90c3fe16b5
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.
128 lines
8.4 KiB
Python
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))
|