autogenerate-constraints
Autogenerate constraint checking code from constraints (C-*) that specify system limits, timeouts, dependencies, or environmental requirements. Use when C-* includes technical constraints like timeouts, API limits, or compliance requirements.
Installation
Follow the repository instructions for this skill and your agent. Review the files and dependencies before adding it to your workflow.
View source ↗GuidesSkill instructions
autogenerate-constraints
Skill Type: Actuator (Code Generation) Purpose: Generate constraint checking code from C-* specifications Prerequisites:
- Constraints (C-*) with technical specifications
Agent Instructions
You are autogenerating constraint checks from constraint specifications.
Your goal is to transform structured C- constraints* into constraint checking functions and configuration.
Generation Patterns
Pattern 1: Timeout Constraints
Input:
C-001: Stripe API timeout
Timeout: 10 seconds
Behavior: Raise TimeoutError if exceeded
Fallback: Return error to user
Generated:
# Generated from: C-001
STRIPE_API_TIMEOUT = 10 # seconds
def call_stripe_api(operation, **kwargs):
"""
Call Stripe API with timeout constraint.
Generated from: C-001 (Stripe API timeout)
Args:
operation: Stripe API operation to call
**kwargs: Operation parameters
Returns:
API response
Raises:
TimeoutError: If operation exceeds 10 seconds
"""
# Implements: C-001
try:
return operation(timeout=STRIPE_API_TIMEOUT, **kwargs)
except TimeoutError as e:
# Fallback: Return error to user
raise PaymentError("Payment service temporarily unavailable") from e
# Generated test
def test_stripe_timeout_respected(mock_stripe):
# C-001: Verify timeout is set
mock_stripe.Charge.create = Mock()
call_stripe_api(mock_stripe.Charge.create, amount=100)
mock_stripe.Charge.create.assert_called_with(timeout=10, amount=100)
def test_stripe_timeout_handles_error(mock_stripe_timeout):
# C-001: Verify timeout error handling
with pytest.raises(PaymentError):
call_stripe_api(mock_stripe_timeout.Charge.create, amount=100)
Pattern 2: Rate Limit Constraints
Input:
C-010: API rate limit
Limit: 100 requests per minute
Behavior: Return 429 status if exceeded
Retry: After 60 seconds
Generated:
# Generated from: C-010
API_RATE_LIMIT = 100 # requests per minute
RATE_LIMIT_WINDOW = 60 # seconds
class RateLimiter:
"""
Enforce API rate limits.
Generated from: C-010 (API rate limit)
"""
def __init__(self):
self.requests = []
def check_rate_limit(self) -> Optional[int]:
"""
Check if rate limit would be exceeded.
Generated from: C-010
Returns:
None if OK, seconds to wait if rate limited
"""
# Implements: C-010
now = datetime.now()
cutoff = now - timedelta(seconds=RATE_LIMIT_WINDOW)
# Remove old requests
self.requests = [r for r in self.requests if r > cutoff]
# Check limit
if len(self.requests) >= API_RATE_LIMIT:
# Calculate retry time
oldest = min(self.requests)
retry_after = RATE_LIMIT_WINDOW - (now - oldest).seconds
return retry_after
return None
def record_request(self) -> None:
"""Record a request for rate limiting"""
self.requests.append(datetime.now())
# Generated tests
def test_rate_limit_under_limit():
limiter = RateLimiter()
for _ in range(99):
limiter.record_request()
assert limiter.check_rate_limit() is None
def test_rate_limit_at_limit():
limiter = RateLimiter()
for _ in range(100):
limiter.record_request()
retry_after = limiter.check_rate_limit()
assert retry_after is not None
assert 0 < retry_after <= 60
Pattern 3: Resource Limit Constraints
Input:
C-020: File upload size
Max size: 10 MB
Behavior: Reject files larger than limit
Error: "File too large. Maximum size is 10 MB"
Generated:
# Generated from: C-020
MAX_UPLOAD_SIZE_BYTES = 10 * 1024 * 1024 # 10 MB
def validate_file_size(file_size: int) -> Optional[str]:
"""
Validate file size is within limit.
Generated from: C-020 (File upload size limit)
Args:
file_size: File size in bytes
Returns:
None if valid, error message if too large
"""
# Implements: C-020
if file_size > MAX_UPLOAD_SIZE_BYTES:
return "File too large. Maximum size is 10 MB"
return None
# Generated tests
def test_file_size_valid():
assert validate_file_size(5 * 1024 * 1024) is None # 5 MB
def test_file_size_at_limit():
assert validate_file_size(10 * 1024 * 1024) is None # Exactly 10 MB
def test_file_size_too_large():
assert validate_file_size(11 * 1024 * 1024) == "File too large. Maximum size is 10 MB"
Pattern 4: Dependency Constraints
Input:
C-030: Python version
Minimum: 3.8
Behavior: Raise error if version < 3.8
Error: "Python 3.8 or higher required"
Generated:
# Generated from: C-030
import sys
PYTHON_MIN_VERSION = (3, 8)
def check_python_version() -> None:
"""
Check Python version meets minimum requirement.
Generated from: C-030 (Python version constraint)
Raises:
RuntimeError: If Python version < 3.8
"""
# Implements: C-030
if sys.version_info < PYTHON_MIN_VERSION:
current = f"{sys.version_info.major}.{sys.version_info.minor}"
required = f"{PYTHON_MIN_VERSION[0]}.{PYTHON_MIN_VERSION[1]}"
raise RuntimeError(
f"Python {required} or higher required. Current version: {current}"
)
# Generated test
def test_python_version_check():
# This test always passes (we're running on valid Python)
check_python_version() # Should not raise
Pattern 5: Compliance Constraints
Input:
C-040: PCI-DSS compliance
Constraint: Never store full credit card numbers
Behavior: Tokenize cards via Stripe API
Validation: No card numbers in logs or database
Generated:
# Generated from: C-040
def validate_no_card_numbers(text: str) -> Optional[str]:
"""
Validate text does not contain credit card numbers.
Generated from: C-040 (PCI-DSS compliance)
Args:
text: Text to validate (log message, database field, etc.)
Returns:
None if valid, error message if card number detected
"""
# Implements: C-040 (PCI-DSS: no storing card numbers)
# Simple Luhn algorithm check for card-like patterns
import re
# Pattern: 13-19 digit sequences
potential_cards = re.findall(r'\b\d{13,19}\b', text)
for number in potential_cards:
if _is_valid_luhn(number):
return "PCI-DSS violation: Potential card number detected"
return None
def _is_valid_luhn(card_number: str) -> bool:
"""Check if number passes Luhn algorithm (credit card check)"""
# Luhn algorithm implementation
digits = [int(d) for d in card_number]
checksum = 0
for i, d in enumerate(reversed(digits)):
if i % 2 == 1:
d = d * 2
if d > 9:
d = d - 9
checksum += d
return checksum % 10 == 0
# Generated tests
def test_validate_no_card_numbers_safe_text():
assert validate_no_card_numbers("User logged in") is None
def test_validate_no_card_numbers_detects_visa():
# Valid Visa test number
assert validate_no_card_numbers("Card: 4532015112830366") == "PCI-DSS violation: Potential card number detected"
Pattern 6: Idempotency Constraints
Input:
C-050: Payment idempotency
Constraint: Same idempotency key = same charge
Key format: SHA256(user_id + timestamp + amount)
Behavior: Return existing charge if key matches
Generated:
# Generated from: C-050
import hashlib
from typing import Optional
def generate_idempotency_key(user_id: str, amount: float, timestamp: int) -> str:
"""
Generate idempotency key for payment.
Generated from: C-050 (Payment idempotency)
Args:
user_id: User identifier
amount: Payment amount
timestamp: Unix timestamp
Returns:
SHA256 hash as idempotency key
"""
# Implements: C-050
data = f"{user_id}{timestamp}{amount}"
return hashlib.sha256(data.encode()).hexdigest()
def check_idempotency(idempotency_key: str) -> Optional[str]:
"""
Check if idempotency key already used.
Generated from: C-050
Returns:
Existing charge_id if key used, None if new
"""
# Implements: C-050
from .models import Payment
existing = Payment.get_by_idempotency_key(idempotency_key)
if existing:
return existing.charge_id
return None
# Generated tests
def test_generate_idempotency_key_deterministic():
key1 = generate_idempotency_key("user123", 100.00, 1637000000)
key2 = generate_idempotency_key("user123", 100.00, 1637000000)
assert key1 == key2 # Same inputs → same key
def test_check_idempotency_new_key():
key = generate_idempotency_key("user123", 100.00, 1637000000)
assert check_idempotency(key) is None
Prerequisites Check
Before invoking this skill, ensure:
- Constraints (C-*) exist with detailed specifications
- Specifications include: values, behaviors, error messages
If C-* too vague:
- Ask user: "C-001 says 'API timeout' - what timeout value should I use?"
Next Steps
After constraint generation:
- Run generated tests (verify all pass)
- Commit generated code
- Integrate into feature implementation
Notes
Why autogenerate constraints?
- Compliance: Ensures constraints are enforced in code
- Consistency: All constraints follow same pattern
- Documentation: Generated code includes constraint rationale
- Testability: Constraints are verified via tests
Homeostasis Goal:
desired_state:
all_constraints_have_code: true
all_constraint_code_has_tests: true
all_tests_passing: true
"Excellence or nothing" 🔥
Examples
Read the usage examples in the source repository.
View source ↗Source history
- Indexed on
- 2026-01-20
- Index updated
- 2026-01-26
- Branch
- main
Index and sync dates describe this directory. View the source repository for code history.
GitHub ↗chat Comments (0)
Sign in to join the discussion and leave a comment.
No comments yet. Be the first to share your thoughts!