""" Milestone Verifier for License Compliance Monitoring Tracks and verifies contractual milestones for license agreements. FEATURES (Planned): - Milestone definition and tracking - Evidence collection for verification - Deadline monitoring and alerts - Integration with CriticAgent for validation VISTA/HORIZON EU ALIGNMENT: - Supports milestone-based payment structures common in EU research - Integrates with project management workflows - Provides audit trail for milestone verification Author: SPARKNET Team Project: VISTA/Horizon EU Status: Placeholder - In Development """ from typing import Optional, Dict, Any, List from dataclasses import dataclass, field from datetime import datetime, date from enum import Enum from loguru import logger class MilestoneStatus(str, Enum): """Milestone tracking status.""" PENDING = "pending" IN_PROGRESS = "in_progress" SUBMITTED = "submitted" # Awaiting verification VERIFIED = "verified" REJECTED = "rejected" WAIVED = "waived" OVERDUE = "overdue" class MilestoneType(str, Enum): """Type of milestone.""" TECHNICAL = "technical" # Technical deliverable COMMERCIAL = "commercial" # Commercial target REGULATORY = "regulatory" # Regulatory approval FINANCIAL = "financial" # Financial target REPORTING = "reporting" # Report submission OTHER = "other" @dataclass class Milestone: """ License agreement milestone definition. Represents a contractual milestone that must be achieved for license compliance. """ milestone_id: str license_id: str title: str description: str milestone_type: MilestoneType due_date: date status: MilestoneStatus = MilestoneStatus.PENDING payment_trigger: bool = False # If true, triggers milestone payment payment_amount: Optional[float] = None currency: str = "EUR" evidence_required: List[str] = field(default_factory=list) evidence_submitted: List[Dict[str, Any]] = field(default_factory=list) verified_by: Optional[str] = None verified_at: Optional[datetime] = None notes: Optional[str] = None metadata: Dict[str, Any] = field(default_factory=dict) @dataclass class VerificationResult: """ Result of milestone verification. Includes CriticAgent validation scores when available. """ verification_id: str milestone_id: str verified: bool confidence_score: float # 0.0 to 1.0 verification_notes: str evidence_review: List[Dict[str, Any]] critic_validation: Optional[Dict[str, Any]] = None # CriticAgent output human_review_required: bool = False verified_at: datetime = field(default_factory=datetime.now) class MilestoneVerifier: """ Verifies milestone completion for license agreements. This component: - Tracks milestone deadlines - Collects and reviews evidence - Integrates with CriticAgent for AI validation - Implements human-in-the-loop for critical decisions HUMAN-IN-THE-LOOP CONSIDERATIONS: ---------------------------------- Milestone verification often requires human judgment. This component implements: 1. AUTOMATED VERIFICATION: - Document completeness checks - Format and structure validation - Cross-reference with requirements 2. AI-ASSISTED REVIEW: - CriticAgent evaluates evidence quality - Confidence scoring for verification - Anomaly detection in submissions 3. HUMAN DECISION POINTS: - Low-confidence verifications flagged for review - High-value milestones require approval - Rejection decisions need human confirmation 4. AUDIT TRAIL: - All decisions logged with reasoning - Evidence preserved for compliance - Verification history maintained """ def __init__( self, llm_client: Optional[Any] = None, critic_agent: Optional[Any] = None, # CriticAgent for validation database_url: Optional[str] = None, ): """ Initialize Milestone Verifier. Args: llm_client: LangChain LLM client for AI analysis critic_agent: CriticAgent for validation database_url: Database connection URL """ self.llm_client = llm_client self.critic_agent = critic_agent self.database_url = database_url self.name = "MilestoneVerifier" # Threshold for requiring human review self.human_review_threshold = 0.7 logger.info(f"Initialized {self.name} (placeholder)") async def create_milestone( self, license_id: str, title: str, description: str, milestone_type: MilestoneType, due_date: date, evidence_required: List[str], payment_trigger: bool = False, payment_amount: Optional[float] = None, ) -> Milestone: """ Create a new milestone for a license agreement. Args: license_id: License agreement identifier title: Milestone title description: Detailed description milestone_type: Type of milestone due_date: Deadline for completion evidence_required: List of required evidence types payment_trigger: Whether completion triggers payment payment_amount: Payment amount if payment_trigger is True Returns: Created milestone TODO: Implement actual milestone creation logic """ logger.info(f"Creating milestone '{title}' for license: {license_id}") return Milestone( milestone_id=f"ms_{datetime.now().strftime('%Y%m%d_%H%M%S')}", license_id=license_id, title=title, description=description, milestone_type=milestone_type, due_date=due_date, evidence_required=evidence_required, payment_trigger=payment_trigger, payment_amount=payment_amount, ) async def submit_evidence( self, milestone_id: str, evidence_type: str, evidence_data: Dict[str, Any], submitted_by: str, ) -> Dict[str, Any]: """ Submit evidence for milestone verification. Args: milestone_id: Milestone identifier evidence_type: Type of evidence being submitted evidence_data: Evidence data (documents, metrics, etc.) submitted_by: User/organization submitting Returns: Submission confirmation TODO: Implement actual evidence submission logic """ logger.info(f"Submitting {evidence_type} evidence for milestone: {milestone_id}") # Placeholder response return { "submission_id": f"sub_{datetime.now().strftime('%Y%m%d_%H%M%S')}", "milestone_id": milestone_id, "evidence_type": evidence_type, "submitted_at": datetime.now().isoformat(), "submitted_by": submitted_by, "status": "received", "message": "Evidence submission not yet fully implemented", } async def verify_milestone( self, milestone_id: str, auto_approve: bool = False, ) -> VerificationResult: """ Verify milestone completion using AI and human review. This method: 1. Checks all required evidence is submitted 2. Uses CriticAgent to validate evidence quality 3. Calculates confidence score 4. Determines if human review is needed Args: milestone_id: Milestone to verify auto_approve: Whether to auto-approve high-confidence verifications Returns: Verification result with confidence score TODO: Implement actual verification logic with CriticAgent """ logger.info(f"Verifying milestone: {milestone_id}") # Placeholder verification result result = VerificationResult( verification_id=f"ver_{datetime.now().strftime('%Y%m%d_%H%M%S')}", milestone_id=milestone_id, verified=False, confidence_score=0.0, verification_notes="Verification not yet implemented", evidence_review=[], human_review_required=True, ) return result async def get_overdue_milestones( self, as_of_date: Optional[date] = None, ) -> List[Milestone]: """ Get list of overdue milestones. Args: as_of_date: Reference date (defaults to today) Returns: List of overdue milestones TODO: Implement actual overdue milestone tracking """ as_of_date = as_of_date or date.today() logger.info(f"Checking overdue milestones as of {as_of_date}") # Placeholder response return [] async def get_upcoming_milestones( self, days_ahead: int = 30, ) -> List[Milestone]: """ Get milestones due in the near future. Args: days_ahead: Number of days to look ahead Returns: List of upcoming milestones TODO: Implement actual upcoming milestone tracking """ logger.info(f"Getting milestones due in next {days_ahead} days") # Placeholder response return [] def requires_human_review( self, confidence_score: float, milestone: Milestone, ) -> bool: """ Determine if milestone verification requires human review. Human review is required when: - Confidence score is below threshold - Milestone triggers large payment - Milestone type is regulatory - Evidence is incomplete or ambiguous Args: confidence_score: AI verification confidence milestone: Milestone being verified Returns: True if human review required """ # Low confidence requires review if confidence_score < self.human_review_threshold: return True # Large payments require review if milestone.payment_trigger and milestone.payment_amount: if milestone.payment_amount > 50000: # EUR threshold return True # Regulatory milestones always require review if milestone.milestone_type == MilestoneType.REGULATORY: return True return False