|
|
""" |
|
|
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" |
|
|
VERIFIED = "verified" |
|
|
REJECTED = "rejected" |
|
|
WAIVED = "waived" |
|
|
OVERDUE = "overdue" |
|
|
|
|
|
|
|
|
class MilestoneType(str, Enum): |
|
|
"""Type of milestone.""" |
|
|
TECHNICAL = "technical" |
|
|
COMMERCIAL = "commercial" |
|
|
REGULATORY = "regulatory" |
|
|
FINANCIAL = "financial" |
|
|
REPORTING = "reporting" |
|
|
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 |
|
|
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 |
|
|
verification_notes: str |
|
|
evidence_review: List[Dict[str, Any]] |
|
|
critic_validation: Optional[Dict[str, Any]] = None |
|
|
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, |
|
|
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" |
|
|
|
|
|
|
|
|
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}") |
|
|
|
|
|
|
|
|
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}") |
|
|
|
|
|
|
|
|
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}") |
|
|
|
|
|
|
|
|
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") |
|
|
|
|
|
|
|
|
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 |
|
|
""" |
|
|
|
|
|
if confidence_score < self.human_review_threshold: |
|
|
return True |
|
|
|
|
|
|
|
|
if milestone.payment_trigger and milestone.payment_amount: |
|
|
if milestone.payment_amount > 50000: |
|
|
return True |
|
|
|
|
|
|
|
|
if milestone.milestone_type == MilestoneType.REGULATORY: |
|
|
return True |
|
|
|
|
|
return False |
|
|
|