"""Customer implementation claim normaliser (spec §4.6). Turns a free-text statement ("Wir haben einen Update-Prozess.") into structured capabilities + related topics + weakness qualifiers. Deterministic substring matching — the claim_id is a stable hash so the same statement always maps to the same id (no randomness, replay-safe). """ from __future__ import annotations import hashlib from typing import List, Optional from .schemas import CustomerImplementationClaim from .taxonomy_claims import match_capabilities, match_qualifiers, topics_for def _claim_id(raw_statement: str) -> str: digest = hashlib.sha1(raw_statement.strip().lower().encode("utf-8")).hexdigest() return "claim_%s" % digest[:10] def _normalized(capabilities: List[str], qualifiers: List[str]) -> str: if not capabilities: return "Keine bekannte Compliance-Fähigkeit aus der Aussage ableitbar." text = "Fähigkeiten: " + ", ".join(capabilities) if qualifiers: text += " | Einschränkungen: " + ", ".join(qualifiers) return text def normalize_claim( raw_statement: str, claim_id: Optional[str] = None, evidence_refs: Optional[List[str]] = None ) -> CustomerImplementationClaim: capabilities = match_capabilities(raw_statement) qualifiers = match_qualifiers(raw_statement) return CustomerImplementationClaim( claim_id=claim_id or _claim_id(raw_statement), raw_statement=raw_statement, normalized_claim=_normalized(capabilities, qualifiers), claimed_capability=capabilities, related_topics=topics_for(capabilities), qualifiers=qualifiers, evidence_refs=evidence_refs or [], )