# Constraints\n\nSingle source of truth for validation limits across all services.\n\n## Purpose\n\nThe `constraints.toml` file defines:\n- **Numeric ranges** (min/max values for ports, workers, timeouts, etc.)\n- **Uniqueness rules** (field constraints, array bounds)\n- **Validation bounds** (resource limits, timeout ranges)\n\nThese constraints are used by:\n1. **Validators** (`validators/*.ncl`) - Check that configuration values are within bounds\n2. **TypeDialog forms** (`forms/*.toml`) - Enable constraint interpolation for dynamic field validation\n3. **Nickel schemas** (`schemas/*.ncl`) - Define type contracts with bounds\n\n## File Structure\n\n```\nconstraints/\n└── constraints.toml    # All validation constraints in TOML format\n```\n\n## Usage Pattern\n\n### 1. Define Constraint\n\n**constraints.toml**:\n\n```\n[orchestrator.queue.concurrent_tasks]\nmin = 1\nmax = 100\n```\n\n### 2. Reference in Validator\n\n**validators/orchestrator-validator.ncl**:\n\n```\nlet constraints = import "../constraints/constraints.toml" in\n\n{\n  ValidConcurrentTasks = fun tasks =>\n    if tasks < constraints.orchestrator.queue.concurrent_tasks.min then\n      error "Tasks must be >= 1"\n    else if tasks > constraints.orchestrator.queue.concurrent_tasks.max then\n      error "Tasks must be <= 100"\n    else\n      tasks,\n}\n```\n\n### 3. Reference in Form\n\n**forms/fragments/orchestrator-queue-section.toml**:\n\n```\n[[elements]]\nname = "max_concurrent_tasks"\ntype = "number"\nmin = "${constraint.orchestrator.queue.concurrent_tasks.min}"\nmax = "${constraint.orchestrator.queue.concurrent_tasks.max}"\nhelp = "Max: ${constraint.orchestrator.queue.concurrent_tasks.max}"\nnickel_path = ["orchestrator", "queue", "max_concurrent_tasks"]\n```\n\n## Constraint Categories\n\n### Service-Specific Constraints\n\n- **Orchestrator** (`[orchestrator.*]`)\n  - Worker count bounds\n  - Queue concurrency limits\n  - Task timeout ranges\n  - Batch parallelism limits\n\n- **Control Center** (`[control_center.*]`)\n  - JWT token expiration bounds\n  - Rate limiting thresholds\n  - RBAC policy limits\n\n- **MCP Server** (`[mcp_server.*]`)\n  - Tool concurrency limits\n  - Resource size bounds\n  - Prompt template limits\n\n### Common Constraints\n\n- **Server** (`[common.server.*]`)\n  - Port range (1024-65535)\n  - Worker count\n  - Connection limits\n\n- **Deployment** (`[deployment.{solo,multiuser,cicd,enterprise}.*]`)\n  - CPU core bounds\n  - Memory allocation bounds\n  - Disk space requirements\n\n## Modifying Constraints\n\nWhen changing constraint bounds:\n\n1. **Update constraints.toml**\n2. **Update validators** that use the constraint\n3. **Update forms** that interpolate the constraint\n4. **Test validation** in forms and Nickel typecheck\n5. **Update documentation** of affected services\n\n### Example: Increase Max Queue Tasks\n\n**Before**:\n\n```\n[orchestrator.queue.concurrent_tasks]\nmin = 1\nmax = 100\n```\n\n**After**:\n\n```\n[orchestrator.queue.concurrent_tasks]\nmin = 1\nmax = 200  # Increased from 100\n```\n\n**Then**:\n1. Verify `validators/orchestrator-validator.ncl` still type-checks\n2. Form will automatically show new max (via constraint interpolation)\n3. Test with: `nu scripts/validate-config.nu values/orchestrator.*.ncl`\n\n## Constraint Interpolation in Forms\n\nTypeDialog supports dynamic constraint references via `${constraint.path.to.value}`:\n\n```\n# Static min/max\nmin = 1\nmax = 100\n\n# Dynamic from constraints.toml\nmin = "${constraint.orchestrator.queue.concurrent_tasks.min}"\nmax = "${constraint.orchestrator.queue.concurrent_tasks.max}"\n\n# Help text with dynamic reference\nhelp = "Value must be between ${constraint.orchestrator.queue.concurrent_tasks.min} and ${constraint.orchestrator.queue.concurrent_tasks.max}"\n```\n\n## Best Practices\n\n1. **Single source of truth** - Define constraint once in constraints.toml\n2. **Meaningful names** - Use clear path hierarchy (service.subsystem.property)\n3. **Document ranges** - Add comments explaining why min/max values exist\n4. **Validate propagation** - Ensure forms and validators reference the same constraint\n5. **Test edge cases** - Verify min/max values work in validators and forms\n\n## Files to Update When Modifying Constraints\n\nWhen you change `constraints/constraints.toml`:\n\n1. `validators/*.ncl` - Update validator bounds\n2. `forms/fragments/*.toml` - Update form field constraints\n3. `schemas/*.ncl` - Update type contracts if needed\n4. Documentation - Update service-specific constraint documentation\n\n---\n\n**Version**: 1.0.0\n**Last Updated**: 2025-01-05
