docs(knowledge): TP-ISO27001->CRA gold standard + reference scenario (RS-005 regression)

(1) Harden the first Transition Pattern to the gold-standard template per quality checklist:
versioned transition_goal (ISO27001:2022 -> CRA, applies 2027-12-11), source_state_variants
(certified/isms_introduced/expired/limited_scope), each likely_covered assumption with a typed
relationship (supports|partially_supports, never equivalent) + verification + rationale (the Warum)
+ an auditor-checkable reviewable_claim, delta as missing-capability + needed-info, an explicit
rejected_assumptions section, and a determinism_goal. README schema updated to match.

(2) New Reference-Suite scenario 4 (Transition): the generator READS the pattern YAML and runs it
through the RS-005 Planning Engine + Company 2A -> coverage + question requests. Proves the
architecture fully carries the pattern (17 caps -> 17 coverage + 17 requests; 9 HIGH delta = the
real CRA gaps, 8 probably-covered from the ISMS). Now a living regression test: every future pattern
runs through the same engine.

Non-runtime knowledge + reference harness -> no deploy (ADR-001). Next: ISMS->TISAX once approved.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-06-27 08:11:42 +02:00
parent cb18eac7ec
commit 4bfd552da7
4 changed files with 244 additions and 121 deletions
@@ -34,6 +34,11 @@ from compliance.capability import (
EvidenceKind, mint_capability, evaluate_relation,
)
from compliance.reasoning.enums import Confidence
from compliance.transition_reasoning import (
TransitionContext, TransitionGoal, TargetType, TargetRequirement, assess_transition,
)
import os
import yaml
Row = Tuple[str, str, str]
OUT: List[str] = []
@@ -235,6 +240,55 @@ coverage_table([
("cap ↔ MCAP Linking", "TODO", "zwei Vokabulare unverbunden → RS-003"),
])
# ── Scenario 4 — Transition (RS-005 Planning Engine + Knowledge Pattern) ───
w("## Szenario 4 — Transition ISO27001 → CRA (RS-005 + Pattern TP-ISO27001-CRA-v1)")
w("")
w('_Frage: „Ich bin ISO27001-zertifiziert — was fehlt mir für den CRA?"_')
w("")
_pat_path = os.path.join(os.path.dirname(__file__), "..", "knowledge", "transition_patterns",
"transition_pattern_iso27001_to_cra_v1.yaml")
with open(_pat_path, encoding="utf-8") as _f:
PAT = yaml.safe_load(_f)
# „habe": ISO27001 -> the pattern's likely_covered capabilities become INFERRED via Company 2A
_iso_caps = [a["capability"] for a in PAT["likely_covered"]]
_iso_map = {"ISO27001": CapabilityMappingEntry(capability_ids=_iso_caps, confidence=Confidence.MEDIUM)}
_profile = build_company_profile(
CompanyContext(company_id="iso-kunde", certifications=[Certification(certification_id="ISO27001")]), _iso_map)
# „required": likely_covered + delta -> TargetRequirements (here read from the pattern)
_reqs = [TargetRequirement(capability_id=a["capability"], question_intent="verify_existence",
expected_evidence=a.get("expected_evidence", [])) for a in PAT["likely_covered"]]
_reqs += [TargetRequirement(capability_id=d["capability"], question_intent=d.get("needed_information", "verify_existence"),
expected_evidence=d.get("expected_evidence", [])) for d in PAT["delta_requirements"]]
_tc = TransitionContext(company_id="iso-kunde", known_certifications=["ISO27001"],
target=TransitionGoal(target_id="CRA", target_type=TargetType.REGULATION,
label=PAT["transition_goal"]["to"]["regulation"]))
_a = assess_transition(_tc, _reqs, _profile)
w("**Input:** ISO27001-zertifiziert (Pattern TP-ISO27001-CRA-v1) → %d ISMS-Capabilities inferred; Ziel CRA." % len(_iso_caps))
w("")
w("**Expected Transition Assessment (RS-005 v0 gegen den Pattern):**")
w("> Ziel %s · %s" % (_a.target_id, _a.summary.headline))
w("")
w("**Delta zuerst (HIGH — fehlt einem ISO-27001-only-Hersteller):**")
for _r in _a.question_requests:
if _r.priority.value == "high":
w("- `%s` — intent=%s, Nachweis=%s" % (_r.capability_id, _r.question_intent, _r.expected_evidence))
w("")
w("**Aus ISO27001 vermutlich abgedeckt (Produkt-Nachweis bestätigen):** %s" % ", ".join(_a.summary.probably_covered))
w("")
_carried = len(_a.coverage) == len(_reqs) and len(_a.question_requests) > 0
_n_high = sum(1 for _r in _a.question_requests if _r.priority.value == "high")
w("**Architektur-Test — trägt RS-005 den Pattern vollständig?** %d Pattern-Capabilities → %d Coverage + %d Question-Requests → **%s**."
% (len(_reqs), len(_a.coverage), len(_a.question_requests), "ja, vollständig getragen" if _carried else "NICHT vollständig"))
w("")
coverage_table([
("Pattern-Load (YAML)", "PASS", "TP-ISO27001-CRA-v1 (draft, gold-standard)"),
("Company 2A (habe)", "PASS", "ISO27001 → %d inferred caps" % len(_a.summary.probably_covered)),
("RS-005 Planning Engine", "PASS" if _carried else "PARTIAL", "Pattern → TransitionQuestionRequests"),
("Transition ISO27001→CRA", "PASS" if _carried else "PARTIAL",
"%d Delta-Fragen (HIGH) + %d zu bestätigen" % (_n_high, len(_a.summary.probably_covered))),
("RS-005.1 Renderer (Fragetext)", "TODO", "verschoben — Engine liefert nur Requests"),
])
# ── Epics + roll-up ───────────────────────────────────────────────────────
w("## Gaps → Epics (Backlog — nur erfasst, NICHT implementiert)")
w("")
@@ -145,6 +145,40 @@ _ILLUSTRATIVES Mapping: ISO27001 -> incident_response, supplier_management, asse
| Master Capability Registry | **PASS** | computed confidence, policy-versioniert |
| cap ↔ MCAP Linking | **TODO** | zwei Vokabulare unverbunden → RS-003 |
## Szenario 4 — Transition ISO27001 → CRA (RS-005 + Pattern TP-ISO27001-CRA-v1)
_Frage: „Ich bin ISO27001-zertifiziert — was fehlt mir für den CRA?"_
**Input:** ISO27001-zertifiziert (Pattern TP-ISO27001-CRA-v1) → 8 ISMS-Capabilities inferred; Ziel CRA.
**Expected Transition Assessment (RS-005 v0 gegen den Pattern):**
> Ziel CRA · 17 zu klären, 0 bereits abgedeckt, 8 vermutlich vorhanden, 9 fehlt, 0 n/a, 0 nicht im Korpus.
**Delta zuerst (HIGH — fehlt einem ISO-27001-only-Hersteller):**
- `ce_conformity_assessment_and_technical_documentation` — intent=request_evidence, Nachweis=['technical_documentation', 'declaration_of_conformity']
- `coordinated_vulnerability_disclosure` — intent=verify_existence, Nachweis=['cvd_policy']
- `exploited_vuln_and_incident_reporting` — intent=verify_existence, Nachweis=['reporting_procedure']
- `product_cyber_risk_assessment` — intent=verify_existence, Nachweis=['product_risk_assessment']
- `public_security_advisories` — intent=verify_existence, Nachweis=['advisory_process']
- `sbom_creation` — intent=determine_sbom_maturity, Nachweis=['sbom']
- `secure_by_default_no_default_credentials` — intent=verify_existence, Nachweis=['config_export', 'test_report']
- `secure_signed_update_distribution` — intent=verify_existence, Nachweis=['config_export', 'test_report']
- `security_update_support_period` — intent=determine_duration, Nachweis=['support_policy', 'product_lifecycle_policy']
**Aus ISO27001 vermutlich abgedeckt (Produkt-Nachweis bestätigen):** incident_management, technical_vulnerability_management, supplier_security, access_control_and_authentication, cryptography, security_logging_and_monitoring, secure_development_lifecycle, asset_and_configuration_management
**Architektur-Test — trägt RS-005 den Pattern vollständig?** 17 Pattern-Capabilities → 17 Coverage + 17 Question-Requests → **ja, vollständig getragen**.
**Architecture Coverage**
| Layer | Status | Hinweis |
|---|---|---|
| Pattern-Load (YAML) | **PASS** | TP-ISO27001-CRA-v1 (draft, gold-standard) |
| Company 2A (habe) | **PASS** | ISO27001 → 8 inferred caps |
| RS-005 Planning Engine | **PASS** | Pattern → TransitionQuestionRequests |
| Transition ISO27001→CRA | **PASS** | 9 Delta-Fragen (HIGH) + 8 zu bestätigen |
| RS-005.1 Renderer (Fragetext) | **TODO** | verschoben — Engine liefert nur Requests |
## Gaps → Epics (Backlog — nur erfasst, NICHT implementiert)
| Epic | Titel | schliesst Coverage-Luecke |
@@ -156,6 +190,6 @@ _ILLUSTRATIVES Mapping: ISO27001 -> incident_response, supplier_management, asse
## Suite-Status (Roll-up)
- Coverage-Zellen gesamt: **20**
- PASS: **13** · PARTIAL: 3 · UNSUPPORTED: 1 · TODO: 2 · N/A: 1 · NEEDS_FACTS: 0
- Coverage-Zellen gesamt: **25**
- PASS: **17** · PARTIAL: 3 · UNSUPPORTED: 1 · TODO: 3 · N/A: 1 · NEEDS_FACTS: 0
- Fortschritt = PASS-Anteil steigt, wenn Epics RS-001…004 landen (objektiver Maßstab, kein LOC).