""" Canonical Control Library schemas. Phase 1 Step 4: extracted from ``compliance.api.canonical_control_routes``. """ from typing import Any, Optional from pydantic import BaseModel class FrameworkResponse(BaseModel): id: str framework_id: str name: str version: str description: Optional[str] = None owner: Optional[str] = None policy_version: Optional[str] = None release_state: str created_at: str updated_at: str class ControlResponse(BaseModel): id: str framework_id: str control_id: str title: str objective: str rationale: str scope: dict[str, Any] requirements: list[Any] test_procedure: list[Any] evidence: list[Any] severity: str risk_score: Optional[float] = None implementation_effort: Optional[str] = None evidence_confidence: Optional[float] = None open_anchors: list[Any] release_state: str tags: list[Any] created_at: str updated_at: str class ControlCreateRequest(BaseModel): framework_id: str # e.g. 'bp_security_v1' control_id: str # e.g. 'AUTH-003' title: str objective: str rationale: str scope: dict[str, Any] = {} requirements: list[Any] = [] test_procedure: list[Any] = [] evidence: list[Any] = [] severity: str = "medium" risk_score: Optional[float] = None implementation_effort: Optional[str] = None evidence_confidence: Optional[float] = None open_anchors: list[Any] = [] release_state: str = "draft" tags: list[Any] = [] class ControlUpdateRequest(BaseModel): title: Optional[str] = None objective: Optional[str] = None rationale: Optional[str] = None scope: Optional[dict[str, Any]] = None requirements: Optional[list[Any]] = None test_procedure: Optional[list[Any]] = None evidence: Optional[list[Any]] = None severity: Optional[str] = None risk_score: Optional[float] = None implementation_effort: Optional[str] = None evidence_confidence: Optional[float] = None open_anchors: Optional[list[Any]] = None release_state: Optional[str] = None tags: Optional[list[Any]] = None class SimilarityCheckRequest(BaseModel): source_text: str candidate_text: str class SimilarityCheckResponse(BaseModel): max_exact_run: int token_overlap: float ngram_jaccard: float embedding_cosine: float lcs_ratio: float status: str details: dict[str, Any] __all__ = [ "FrameworkResponse", "ControlResponse", "ControlCreateRequest", "ControlUpdateRequest", "SimilarityCheckRequest", "SimilarityCheckResponse", ]