Merge pull request 'Customer Mission #3 — one profile, three target types' (#31) from feat/customer-mission-3-target-types into main

This commit is contained in:
pilotadmin
2026-06-28 09:54:21 +02:00
3 changed files with 257 additions and 0 deletions
@@ -0,0 +1,40 @@
# Customer Mission #3 — EIN Profil, DREI Zieltypen (der Requirements-Verification-Beweis)
_Mission #2 bewies: der Start ist ein Company Capability Profile, kein Zertifikat. Mission #3 beweist das Nächste: dieselbe Pipeline ist ZIELTYP-AGNOSTISCH. Ein Gesetz, eine Zertifizierung und ein Vertrag reduzieren sich alle auf geforderte Fähigkeiten. Synthetischer Kunde + synthetische Ausschreibung, keine echten Namen._
## Der Kunde (synthetisch) — EIN Profil
> **ISO 9001 · ISO 27001 · ISO 14001 · TISAX · CE-Prozess · PSIRT** · vernetzte Maschinen · Export EU
## 1. Drei Zieltypen — dieselbe Engine `Profil Required = Delta`
| Ziel | Zieltyp | geforderte Fähigkeiten | Delta (fehlt) |
|---|---|---|---|
| **CRA** | Regulation | 17 | **8** |
| **TISAX** | Certification | 13 | **3** |
| **Öffentliche Ausschreibung** | Contract | 11 | **4** |
→ Drei **völlig unterschiedliche Zielarten** (Gesetz · Zertifizierung · Vertrag) liefen durch **eine** Engine ohne Sonderfall. Der Vertrag (Ausschreibung) ist nur ein weiterer `Required`-Satz — genau das ist die **Requirements Verification Platform** ([[strategy-requirements-intelligence]]): die Anforderungs-QUELLE ist austauschbar, die Pipeline bleibt.
## 2. Konvergenz über Zieltypen hinweg
- **8 Fähigkeiten erfüllen ≥2 der drei Zielarten gleichzeitig** — eine Maßnahme zahlt auf Gesetz UND Zertifizierung UND/ODER Vertrag ein.
- Beispiele (Fähigkeit → Ziele): `incident_management`→{CRA,TISAX,Öffentliche Ausschreibung}; `technical_vulnerability_management`→{CRA,Öffentliche Ausschreibung}; `access_control_and_authentication`→{CRA,TISAX,Öffentliche Ausschreibung}; `sbom_creation`→{CRA,Öffentliche Ausschreibung}
- Das ist der Hebel *eine Ebene höher* als Mission #1: dort konvergierten **Gesetze** (CRA+MaschinenVO), hier konvergieren **ZielTYPEN**.
## 3. Evidence-Relevanz(Ziel) — dieselbe Zertifizierung, anderer Wert je Ziel
> Nicht „Evidence vorhanden", sondern **Evidence-Relevanz(Ziel)**: jede Zertifizierung wird **relativ zum Ziel** bewertet. Das erklärt, warum dieselbe Capability in zwei Beratungen unterschiedlich priorisiert wird.
| Zertifizierung (Evidence) | → CRA | → TISAX | → Ausschreibung |
|---|---|---|---|
| **ISO27001** | hoch (5) | hoch (5) | hoch (4) |
| **TISAX** | mittel (2) | hoch (8) | hoch (5) |
| **PSIRT** | hoch (3) | keine (0) | mittel (1) |
| **ISO9001** | mittel (1) | keine (0) | keine (0) |
| **ISO14001** | keine (0) | keine (0) | keine (0) |
| **CE** | mittel (1) | keine (0) | keine (0) |
**PSIRT** ist gegen die **CRA hoch**, gegen **TISAX keine**, gegen die **Ausschreibung mittel** — dieselbe Evidence, drei verschiedene Werte. **ISO 14001** ist gegen alle drei (Security/Qualität) **keine***aber* gegen ein **Umwelt-Ziel** (Batterieverordnung/Umweltauflagen) wäre sie **hoch**. Genau deshalb gilt: **Relevanz ist eine Funktion des Ziels, kein Attribut der Evidence.**
## Befund
> **Dieselbe Pipeline trägt Gesetz, Zertifizierung UND Vertrag.** Damit ist bewiesen, dass die Architektur nicht „Compliance" macht, sondern **Anforderungen verifiziert** — die Quelle (Regulation/Certification/Contract) ist nur ein `Required`-Satz, der Rest ist `Profil Required = Delta`. Zwei durable Folgerungen: (1) **Evidence-Relevanz ist zielrelativ** (gehört künftig als `relevance(evidence, target)` modelliert, nicht als „vorhanden/fehlt"); (2) Konvergenz existiert nicht nur zwischen Gesetzen, sondern zwischen **Zielarten** — der höchste Hebel überhaupt.
@@ -0,0 +1,159 @@
# ruff: noqa
# mypy: ignore-errors
"""Customer Mission #3 — ONE company profile, THREE target TYPES (the Requirements Verification proof).
Mission #2 proved the start is a Company Capability Profile, not a certificate. This mission proves the
NEXT thing: the same pipeline does not care what KIND of target it is pointed at. We run ONE profile
against three deliberately different target types —
1. a REGULATION (CRA) — law
2. a CERTIFICATION (TISAX) — scheme
3. a CONTRACT (public tender) — buyer requirement (synthetic, hand-authored)
— through the identical engine (assess_transition). If all three run, the architecture is not a
„compliance" system but a Requirements Verification platform: a regulation, a certification and a
contract all reduce to required capabilities, and `Profile Required = Delta` is target-type-agnostic.
It also makes the user's „Evidence-Relevance(Target)" concrete: the SAME evidence (a certification)
is worth a different amount against a different target — ISO 14001 is irrelevant to all three security
targets here, yet would be decisive against an environmental target.
Synthetic company + synthetic tender (NO real names). Runs the REAL engines. Non-runtime -> no deploy.
Run: cd backend-compliance && PYTHONPATH=. python3 reference_scenarios/mission_three_target_types.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)
_K = os.path.join(os.path.dirname(__file__), "..", "knowledge", "transition_patterns")
def _caps(pattern_file):
p = yaml.safe_load(open(os.path.join(_K, pattern_file), encoding="utf-8"))
return [a["capability"] for a in p["likely_covered"]] + [d["capability"] for d in p["delta_requirements"]]
# ── The three targets, each a different TYPE, each just a set of required capabilities ──────
CRA = _caps("transition_pattern_iso27001_to_cra_maschinenvo_v1.yaml") # REGULATION
TISAX = _caps("transition_pattern_isms_to_tisax_v1.yaml") # CERTIFICATION
# CONTRACT: a synthetic public tender for a networked industrial machine. Hand-authored required
# capabilities (a tender has no parser yet — injected exactly like Execution-placeholder requirements).
TENDER = [
"information_security_management", "access_control_and_authentication", "incident_management",
"technical_vulnerability_management", "coordinated_vulnerability_disclosure", "sbom_creation",
"supplier_security", "data_protection_processing_on_behalf",
"penetration_test_evidence", "reference_project_evidence", "security_sla_and_support_commitment",
]
TARGETS = [
("CRA", "Regulation", "regulatorisch", CRA),
("TISAX", "Certification", "Zertifizierung", TISAX),
("Öffentliche Ausschreibung", "Contract", "vertraglich (synthetisch)", TENDER),
]
# ── ONE Company Capability Profile (the same multi-certified company as Mission #2) ─────────
# Each certification is an OBSERVATION contributing probable capabilities; ISO 14001 is in the
# profile but contributes nothing any of the three security/quality targets needs (target-relative).
CERT_OBS = {
"ISO27001": ["information_security_management", "incident_management", "access_control_and_authentication",
"technical_vulnerability_management", "security_logging_and_monitoring",
"secure_development_lifecycle", "asset_and_configuration_management", "cryptography"],
"TISAX": ["information_security_management", "access_control_and_authentication", "incident_management",
"supplier_security", "physical_security", "security_awareness_training",
"prototype_protection", "data_protection_processing_on_behalf"],
"PSIRT": ["coordinated_vulnerability_disclosure", "exploited_vuln_and_incident_reporting",
"public_security_advisories"],
"ISO9001": ["ce_conformity_assessment_and_technical_documentation"],
"ISO14001": ["environmental_management_documentation"],
"CE": ["ce_conformity_assessment_and_technical_documentation"],
}
cmap = {k: CapabilityMappingEntry(capability_ids=v, confidence=Confidence.MEDIUM) for k, v in CERT_OBS.items()}
profile = build_company_profile(
CompanyContext(company_id="mc3", certifications=[Certification(certification_id=k) for k in CERT_OBS]), cmap)
def _delta(target_caps):
reqs = [TargetRequirement(capability_id=c) for c in target_caps]
a = assess_transition(TransitionContext(company_id="mc3", target=TransitionGoal(target_id="t")), reqs, profile)
missing = sorted({c.capability_id for c in a.coverage if c.status == CoverageStatus.MISSING})
return len(target_caps), missing
def _relevance(cert_caps, target_caps):
n = len(set(cert_caps) & set(target_caps))
return n, ("hoch" if n >= 3 else "mittel" if n >= 1 else "keine")
w('# Customer Mission #3 — EIN Profil, DREI Zieltypen (der Requirements-Verification-Beweis)')
w("")
w('_Mission #2 bewies: der Start ist ein Company Capability Profile, kein Zertifikat. Mission #3 beweist das Nächste: dieselbe Pipeline ist ZIELTYP-AGNOSTISCH. Ein Gesetz, eine Zertifizierung und ein Vertrag reduzieren sich alle auf geforderte Fähigkeiten. Synthetischer Kunde + synthetische Ausschreibung, keine echten Namen._')
w("")
w("## Der Kunde (synthetisch) — EIN Profil")
w("> **ISO 9001 · ISO 27001 · ISO 14001 · TISAX · CE-Prozess · PSIRT** · vernetzte Maschinen · Export EU")
w("")
# ── 1. Drei Zieltypen durch DIESELBE Engine ───────────────────────────────
w("## 1. Drei Zieltypen — dieselbe Engine `Profil Required = Delta`")
w("")
w("| Ziel | Zieltyp | geforderte Fähigkeiten | Delta (fehlt) |")
w("|---|---|---|---|")
deltas = {}
for name, kind, _, caps in TARGETS:
total, missing = _delta(caps)
deltas[name] = (total, missing)
w("| **%s** | %s | %d | **%d** |" % (name, kind, total, len(missing)))
w("")
w("→ Drei **völlig unterschiedliche Zielarten** (Gesetz · Zertifizierung · Vertrag) liefen durch **eine** Engine ohne Sonderfall. Der Vertrag (Ausschreibung) ist nur ein weiterer `Required`-Satz — genau das ist die **Requirements Verification Platform** ([[strategy-requirements-intelligence]]): die Anforderungs-QUELLE ist austauschbar, die Pipeline bleibt.")
w("")
# ── 2. Cross-Target-Typ-Konvergenz ────────────────────────────────────────
all_caps = {}
for name, _, _, caps in TARGETS:
for c in caps:
all_caps.setdefault(c, []).append(name)
multi = {c: ts for c, ts in all_caps.items() if len(ts) >= 2}
w("## 2. Konvergenz über Zieltypen hinweg")
w("- **%d Fähigkeiten erfüllen ≥2 der drei Zielarten gleichzeitig** — eine Maßnahme zahlt auf Gesetz UND Zertifizierung UND/ODER Vertrag ein." % len(multi))
w("- Beispiele (Fähigkeit → Ziele): %s" % "; ".join(
"`%s`→{%s}" % (c, ",".join(ts)) for c, ts in list(multi.items())[:4]))
w("- Das ist der Hebel *eine Ebene höher* als Mission #1: dort konvergierten **Gesetze** (CRA+MaschinenVO), hier konvergieren **ZielTYPEN**.")
w("")
# ── 3. Evidence-Relevance(Target) — dieselbe Evidence, anderer Wert je Ziel ─
w("## 3. Evidence-Relevanz(Ziel) — dieselbe Zertifizierung, anderer Wert je Ziel")
w('> Nicht „Evidence vorhanden", sondern **Evidence-Relevanz(Ziel)**: jede Zertifizierung wird **relativ zum Ziel** bewertet. Das erklärt, warum dieselbe Capability in zwei Beratungen unterschiedlich priorisiert wird.')
w("")
w("| Zertifizierung (Evidence) | → CRA | → TISAX | → Ausschreibung |")
w("|---|---|---|---|")
for cert, caps in CERT_OBS.items():
cells = []
for _, _, _, tcaps in TARGETS:
n, lvl = _relevance(caps, tcaps)
cells.append("%s (%d)" % (lvl, n))
w("| **%s** | %s | %s | %s |" % (cert, cells[0], cells[1], cells[2]))
w("")
w("→ **PSIRT** ist gegen die **CRA hoch**, gegen **TISAX keine**, gegen die **Ausschreibung mittel** — dieselbe Evidence, drei verschiedene Werte. **ISO 14001** ist gegen alle drei (Security/Qualität) **keine** — *aber* gegen ein **Umwelt-Ziel** (Batterieverordnung/Umweltauflagen) wäre sie **hoch**. Genau deshalb gilt: **Relevanz ist eine Funktion des Ziels, kein Attribut der Evidence.**")
w("")
# ── Befund ────────────────────────────────────────────────────────────────
w("## Befund")
w("")
w('> **Dieselbe Pipeline trägt Gesetz, Zertifizierung UND Vertrag.** Damit ist bewiesen, dass die Architektur nicht „Compliance" macht, sondern **Anforderungen verifiziert** — die Quelle (Regulation/Certification/Contract) ist nur ein `Required`-Satz, der Rest ist `Profil Required = Delta`. Zwei durable Folgerungen: (1) **Evidence-Relevanz ist zielrelativ** (gehört künftig als `relevance(evidence, target)` modelliert, nicht als „vorhanden/fehlt"); (2) Konvergenz existiert nicht nur zwischen Gesetzen, sondern zwischen **Zielarten** — der höchste Hebel überhaupt.')
w("")
print("\n".join(OUT))
@@ -0,0 +1,58 @@
"""Customer Mission #3 — one profile, three target TYPES (Requirements Verification proof).
Pins what Mission #3 proves with the real engines: the pipeline is target-type-agnostic (a regulation,
a certification and a contract all reduce to required capabilities and run through assess_transition),
and Evidence-Relevance is target-relative (the same certification is worth a different amount against a
different target — PSIRT is hoch against the CRA, keine against TISAX, mittel against the tender).
"""
from __future__ import annotations
import os
import subprocess
import sys
def _run():
root = os.path.join(os.path.dirname(__file__), "..")
r = subprocess.run(
[sys.executable, "reference_scenarios/mission_three_target_types.py"],
cwd=root, env={**os.environ, "PYTHONPATH": "."}, capture_output=True, text=True,
)
assert r.returncode == 0, r.stderr
return r.stdout
def test_runs_end_to_end():
out = _run()
assert "Customer Mission #3" in out
assert "ZIELTYP-AGNOSTISCH" in out
def test_three_target_types_one_engine():
out = _run()
# a regulation, a certification and a contract all rendered through the same engine
for kind in ["Regulation", "Certification", "Contract"]:
assert kind in out
assert "Öffentliche Ausschreibung" in out
def test_evidence_relevance_is_target_relative():
out = _run()
# the headline demonstration: PSIRT ranks differently per target
assert "**PSIRT** | hoch (3) | keine (0) | mittel (1) |" in out
# ISO 14001 is irrelevant to all three security/quality targets (but noted hoch for environmental)
assert "**ISO14001** | keine (0) | keine (0) | keine (0) |" in out
assert "Relevanz ist eine Funktion des Ziels" in out
def test_cross_target_type_convergence():
out = _run()
assert "über Zieltypen hinweg" in out
assert "Zielarten gleichzeitig" in out
def test_no_real_company_names():
out = _run().lower()
for name in ["eto", "owis", "winterhalter"]:
assert name not in out