Files
stack/apps/coordinator/src/validation.py
Jason Woltje a1b911d836 test(#143): Validate 50% rule prevents context exhaustion
Following TDD (Red-Green-Refactor):
- RED: Created comprehensive test suite with 12 test cases
- GREEN: Implemented validation logic that passes all tests
- All quality gates passed

Test Coverage:
- Oversized issue (120K) correctly rejected
- Properly sized issue (80K) correctly accepted
- Edge case at exactly 50% (100K) correctly accepted
- Sequential issues validated individually
- All agent types tested (opus, sonnet, haiku, glm, minimax)
- Edge cases covered (zero, very small, boundaries)

Implementation:
- src/validation.py: Pure validation function
- tests/test_fifty_percent_rule.py: 12 comprehensive tests
- docs/50-percent-rule-validation.md: Validation report
- 100% test coverage (14/14 statements)
- Type checking: PASS (mypy)
- Linting: PASS (ruff)

The 50% rule ensures no single issue exceeds 50% of target
agent's context limit, preventing context exhaustion while
allowing efficient capacity utilization.

Fixes #143

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-01 17:56:04 -06:00

75 lines
2.1 KiB
Python

"""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="")