"""Issue assignment validation logic. Validates that issue assignments follow coordinator rules, particularly the 50% rule to prevent context exhaustion. """ from dataclasses import dataclass from .models import IssueMetadata # Agent context limits (in tokens) # Based on COORD-004 agent profiles AGENT_CONTEXT_LIMITS = { "opus": 200_000, "sonnet": 200_000, "haiku": 200_000, "glm": 128_000, "minimax": 128_000, } @dataclass class ValidationResult: """Result of issue assignment validation. Attributes: valid: Whether the assignment is valid reason: Human-readable reason if invalid (empty string if valid) """ valid: bool reason: str = "" def validate_fifty_percent_rule(metadata: IssueMetadata) -> ValidationResult: """Validate that issue doesn't exceed 50% of target agent's context limit. The 50% rule prevents context exhaustion by ensuring no single issue consumes more than half of an agent's context window. This leaves room for conversation history, tool use, and prevents hitting hard limits. Args: metadata: Issue metadata including estimated context and assigned agent Returns: ValidationResult with valid=True if issue passes, or valid=False with reason Example: >>> metadata = IssueMetadata(estimated_context=120000, assigned_agent="sonnet") >>> result = validate_fifty_percent_rule(metadata) >>> print(result.valid) False """ agent = metadata.assigned_agent estimated = metadata.estimated_context # Get agent's context limit context_limit = AGENT_CONTEXT_LIMITS.get(agent, 200_000) # Calculate 50% threshold max_allowed = context_limit // 2 # Validate if estimated > max_allowed: return ValidationResult( valid=False, reason=( f"Issue context estimate ({estimated} tokens) exceeds 50% rule for " f"{agent} agent. Maximum allowed: {max_allowed} tokens " f"(50% of {context_limit} context limit)." ), ) return ValidationResult(valid=True, reason="")