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:
@@ -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
|
||||||
Reference in New Issue
Block a user