Files
SuperClaude/superclaude/validators/context_contract.py
kazuki ca29e595fd feat: add comprehensive validation framework
Add validators package with 6 specialized validators:
- base.py: Abstract base validator with common patterns
- context_contract.py: PM mode context validation
- dep_sanity.py: Dependency consistency checks
- runtime_policy.py: Runtime policy enforcement
- security_roughcheck.py: Security vulnerability scanning
- test_runner.py: Automated test execution validation

Supports validation gates for quality assurance and risk mitigation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-20 03:52:40 +09:00

95 lines
3.6 KiB
Python

"""Context Contract Validator
Enforces project-specific rules from Context Contract:
- Kong/Traefik routing requirements
- Infisical usage requirements
- .env file prohibitions
- Security policies
"""
from typing import Dict, Any, List
import re
from pathlib import Path
from .base import Validator, ValidationResult
class ContextContractValidator(Validator):
"""Validates against Context Contract rules"""
def __init__(self):
super().__init__("Context Contract")
def validate(self, context: Dict[str, Any]) -> ValidationResult:
"""
Validate changes against Context Contract.
Context should contain:
- contract: Context Contract data
- changes: Dict of file changes (path -> content)
"""
contract = context.get("contract")
if not contract:
return self._skip("No Context Contract available")
changes = context.get("changes", {})
if not changes:
return self._pass("No changes to validate")
violations = []
suggestions = []
# Check principles
principles = contract.get("principles", {})
# Check 1: .env file creation prohibition
if principles.get("no_env_files"):
for file_path in changes.keys():
if ".env" in Path(file_path).name:
violations.append(f"❌ .env file creation prohibited: {file_path}")
suggestions.append("Use Infisical for secret management")
# Check 2: Hardcoded secrets
if principles.get("use_infisical_only"):
secret_patterns = [
r'INFISICAL_TOKEN\s*=\s*[\'"]st\.', # Infisical token
r'SUPABASE_SERVICE_ROLE_KEY\s*=\s*[\'"]eyJ', # Supabase JWT
r'OPENAI_API_KEY\s*=\s*[\'"]sk-', # OpenAI key
r'DATABASE_URL\s*=\s*[\'"]postgres.*password', # DB password
]
for file_path, content in changes.items():
for pattern in secret_patterns:
if re.search(pattern, content):
violations.append(f"❌ Hardcoded secret detected in {file_path}")
suggestions.append("Use Infisical or environment variables")
break
# Check 3: Outbound traffic routing
outbound_proxy = principles.get("outbound_through")
if outbound_proxy == "kong":
# Check if Kong routing is mentioned in docker-compose changes
for file_path, content in changes.items():
if "docker-compose" in file_path:
if "external" in content and "kong" not in content.lower():
violations.append(f"❌ External service without Kong routing in {file_path}")
suggestions.append("All external services must route through Kong")
elif outbound_proxy == "traefik":
# Check if Traefik labels are present
for file_path, content in changes.items():
if "docker-compose" in file_path:
if "external" in content and "traefik.enable" not in content:
violations.append(f"❌ External service without Traefik labels in {file_path}")
suggestions.append("All external services must use Traefik labels")
# Return result
if violations:
return self._fail(
f"Context Contract violations detected ({len(violations)} issues)",
details={"violations": violations},
suggestions=suggestions
)
return self._pass("All Context Contract rules satisfied")