1607c89459
Deterministic reasoning layer ON TOP of the Legal Knowledge Graph (obligation
registry) and the Compliance Execution Graph (control mapping/evidence). Answers
which regulations apply to a concrete product, which obligations follow, whether
the customer's implementation covers them, and whether a customer interpretation
is too narrow/broad/plausible.
- ProductProfile with tri-state facts (Optional[bool]=None => uncertain, never
false security); safe predicate evaluator (no eval).
- 6 regulation triggers (CRA/MaschinenVO/RED/EMV/DataAct/NIS2) with missing-fact
prompts; 24 obligation scope rules.
- CRA obligation_ids RE-USED verbatim from the registry (93 ids) — never re-minted
(control_uuid trap); Machine/Data-Act flagged proposed=True.
- required_evidence constrained to the framework-agnostic shared evidence catalog;
capabilities echo the planned Obligation->Capability layer.
- Overlap groups (CRA<->MaschinenVO cyber-safety) + evidence-for-multiple (USP).
- 4 endpoints POST /reasoning/{scope,obligations,implementation-assessment,
interpretation-assessment}; thin handlers, registered in api/__init__.py.
- 22 tests (5 machine-builder scenarios + 10 acceptance questions). No DB
migration, no RAG, no new controls.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
92 lines
3.6 KiB
Python
92 lines
3.6 KiB
Python
"""Obligation overlap groups (spec §4.5 / Modus 2).
|
|
|
|
Overlaps are emitted only for the members that are actually applicable to the
|
|
product. `canonical_obligation_id` points at the strongest / most specific
|
|
obligation in the group (preferring a registry-anchored CRA id).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from typing import List
|
|
|
|
from .enums import OverlapType
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class OverlapGroup:
|
|
overlap_group_id: str
|
|
members: List[str]
|
|
overlap_type: OverlapType
|
|
canonical_obligation_id: str
|
|
explanation: str
|
|
|
|
|
|
OVERLAP_GROUPS: List[OverlapGroup] = [
|
|
OverlapGroup(
|
|
overlap_group_id="VULNERABILITY_HANDLING",
|
|
members=[
|
|
"vuln_handling_process",
|
|
"coordinated_vulnerability_disclosure",
|
|
"machine_protection_against_corruption",
|
|
],
|
|
overlap_type=OverlapType.COMPLEMENTARY,
|
|
canonical_obligation_id="vuln_handling_process",
|
|
explanation=(
|
|
"CRA adressiert die Schwachstellenbehandlung des Produkts. Die MaschinenVO wird "
|
|
"komplementär relevant, sobald eine Cyber-Schwachstelle eine Sicherheitsfunktion "
|
|
"beeinflussen kann (Anhang III 1.1.9). Nicht identisch, aber gemeinsam zu erfüllen."
|
|
),
|
|
),
|
|
OverlapGroup(
|
|
overlap_group_id="SECURITY_UPDATES",
|
|
members=["provide_security_updates", "signed_update_integrity"],
|
|
overlap_type=OverlapType.COMPLEMENTARY,
|
|
canonical_obligation_id="provide_security_updates",
|
|
explanation=(
|
|
"Updates bereitstellen und ihre Integrität sichern sind zwei Seiten desselben "
|
|
"Update-Prozesses; ein Nachweis (Update-Policy, Release Notes) deckt teils beide ab."
|
|
),
|
|
),
|
|
OverlapGroup(
|
|
overlap_group_id="RISK_ASSESSMENT",
|
|
members=["cra_risk_assessment", "machine_risk_assessment"],
|
|
overlap_type=OverlapType.DIFFERENT_SCOPE,
|
|
canonical_obligation_id="cra_risk_assessment",
|
|
explanation=(
|
|
"Zwei getrennte Risikobetrachtungen: CRA = Cybersicherheits-Risiko, MaschinenVO = "
|
|
"Sicherheits-/Gefährdungsbeurteilung. Methodisch verwandt, inhaltlich unterschiedlich."
|
|
),
|
|
),
|
|
OverlapGroup(
|
|
overlap_group_id="TECHNICAL_DOCUMENTATION",
|
|
members=["cra_technical_documentation", "machine_risk_assessment"],
|
|
overlap_type=OverlapType.SIMILAR,
|
|
canonical_obligation_id="cra_technical_documentation",
|
|
explanation=(
|
|
"Beide Regime verlangen eine technische Dokumentation; Teile (Risikobetrachtung, "
|
|
"Konstruktionsunterlagen) lassen sich in einem konsolidierten technischen Dossier führen."
|
|
),
|
|
),
|
|
OverlapGroup(
|
|
overlap_group_id="CE_CONFORMITY",
|
|
members=["cra_ce_conformity_assessment", "machine_ce_conformity"],
|
|
overlap_type=OverlapType.COMPLEMENTARY,
|
|
canonical_obligation_id="machine_ce_conformity",
|
|
explanation=(
|
|
"Ein Produkt kann zwei CE-Regime gleichzeitig erfüllen müssen (MaschinenVO + CRA). "
|
|
"Eine gemeinsame CE-Kennzeichnung, aber getrennte Konformitätsbewertungen."
|
|
),
|
|
),
|
|
OverlapGroup(
|
|
overlap_group_id="INSTRUCTIONS_FOR_USE",
|
|
members=["cra_instructions_for_use", "machine_instructions_for_use"],
|
|
overlap_type=OverlapType.SIMILAR,
|
|
canonical_obligation_id="machine_instructions_for_use",
|
|
explanation=(
|
|
"Betriebsanleitung (MaschinenVO) und Sicherheitsinformationen (CRA) überschneiden sich; "
|
|
"ein integriertes Anleitungsdokument kann beide Pflichten bedienen."
|
|
),
|
|
),
|
|
]
|