"""HTTP endpoints for the Regulatory Reasoning Engine (spec §7). Thin handlers — all reasoning lives in `compliance.reasoning.*`. No DB, no RAG; pure deterministic rule evaluation. POST /reasoning/scope -> which regulations apply + missing facts POST /reasoning/obligations -> obligations, overlaps, multi-evidence POST /reasoning/implementation-reasoning -> claim->obligation mapping (Welt 1, no verdict) POST /reasoning/interpretation-assessment -> verdict on a customer interpretation POST /reasoning/product-scope -> gate on facts, else run discover_scope once POST /reasoning/regulatory-map -> customer-readable read-model over the scope POST /reasoning/interpretation-in-map -> judge a customer interpretation within the map """ from __future__ import annotations from fastapi import APIRouter from compliance.interpretation_map import ( InterpretationInMapRequest, InterpretationInMapResult, interpret_in_map, ) from compliance.product_scope import ( ProductScopeRequest, ProductScopeResponse, resolve_product_scope, ) from compliance.regulatory_map import RegulatoryMap, RegulatoryMapRequest, render_regulatory_map from compliance.reasoning import ( assess_interpretation, derive_obligations, discover_scope, reason_implementation_claim, ) from compliance.reasoning.schemas import ( ImplementationReasoningRequest, ImplementationReasoningResponse, InterpretationRequest, InterpretationResponse, ObligationsRequest, ObligationsResponse, ScopeRequest, ScopeResponse, ) router = APIRouter(prefix="/reasoning", tags=["reasoning"]) @router.post("/scope", response_model=ScopeResponse) def scope_discovery(req: ScopeRequest) -> ScopeResponse: scope = discover_scope(req.product_profile) return ScopeResponse( regulatory_scope=scope, missing_facts=scope.missing_facts, confidence=scope.confidence, ) @router.post("/obligations", response_model=ObligationsResponse) def applicable_obligations(req: ObligationsRequest) -> ObligationsResponse: return derive_obligations(req.product_profile, req.regulatory_scope) @router.post("/implementation-reasoning", response_model=ImplementationReasoningResponse) def implementation_reasoning(req: ImplementationReasoningRequest) -> ImplementationReasoningResponse: return reason_implementation_claim(req.product_profile, req.customer_claim) @router.post("/product-scope", response_model=ProductScopeResponse) def product_scope(req: ProductScopeRequest) -> ProductScopeResponse: return resolve_product_scope(req.product_profile) @router.post("/regulatory-map", response_model=RegulatoryMap) def regulatory_map(req: RegulatoryMapRequest) -> RegulatoryMap: return render_regulatory_map(req.product_profile) @router.post("/interpretation-in-map", response_model=InterpretationInMapResult) def interpretation_in_map(req: InterpretationInMapRequest) -> InterpretationInMapResult: reg_map = render_regulatory_map(req.product_profile) return interpret_in_map(reg_map, req.customer_interpretation) @router.post("/interpretation-assessment", response_model=InterpretationResponse) def interpretation_assessment(req: InterpretationRequest) -> InterpretationResponse: result = assess_interpretation(req.customer_interpretation, req.product_profile) return InterpretationResponse( assessment=result.assessment, affected_regulations=result.affected_regulations, affected_obligations=result.affected_obligations, corrected_interpretation=result.corrected_interpretation, risks=result.risks, legal_basis_refs=result.legal_basis_refs, explanation=result.explanation, confidence=result.confidence, )