# Constraints

Single source of truth for validation limits across all services.

## Purpose

The `constraints.toml` file defines:
- **Numeric ranges** (min/max values for ports, workers, timeouts, etc.)
- **Uniqueness rules** (field constraints, array bounds)
- **Validation bounds** (resource limits, timeout ranges)

These constraints are used by:
1. **Validators** (`validators/*.ncl`) - Check that configuration values are within bounds
2. **TypeDialog forms** (`forms/*.toml`) - Enable constraint interpolation for dynamic field validation
3. **Nickel schemas** (`schemas/*.ncl`) - Define type contracts with bounds

## File Structure

```javascript
constraints/
└── constraints.toml    # All validation constraints in TOML format
```

## Usage Pattern

### 1. Define Constraint

**constraints.toml**:

```toml
[orchestrator.queue.concurrent_tasks]
min = 1
max = 100
```

### 2. Reference in Validator

**validators/orchestrator-validator.ncl**:

```javascript
let constraints = import "../constraints/constraints.toml" in

{
  ValidConcurrentTasks = fun tasks =>
    if tasks < constraints.orchestrator.queue.concurrent_tasks.min then
      error "Tasks must be >= 1"
    else if tasks > constraints.orchestrator.queue.concurrent_tasks.max then
      error "Tasks must be <= 100"
    else
      tasks,
}
```

### 3. Reference in Form

**forms/fragments/orchestrator-queue-section.toml**:

```toml
[[elements]]
name = "max_concurrent_tasks"
type = "number"
min = "${constraint.orchestrator.queue.concurrent_tasks.min}"
max = "${constraint.orchestrator.queue.concurrent_tasks.max}"
help = "Max: ${constraint.orchestrator.queue.concurrent_tasks.max}"
nickel_path = ["orchestrator", "queue", "max_concurrent_tasks"]
```

## Constraint Categories

### Service-Specific Constraints

- **Orchestrator** (`[orchestrator.*]`)
  - Worker count bounds
  - Queue concurrency limits
  - Task timeout ranges
  - Batch parallelism limits

- **Control Center** (`[control_center.*]`)
  - JWT token expiration bounds
  - Rate limiting thresholds
  - RBAC policy limits

- **MCP Server** (`[mcp_server.*]`)
  - Tool concurrency limits
  - Resource size bounds
  - Prompt template limits

### Common Constraints

- **Server** (`[common.server.*]`)
  - Port range (1024-65535)
  - Worker count
  - Connection limits

- **Deployment** (`[deployment.{solo,multiuser,cicd,enterprise}.*]`)
  - CPU core bounds
  - Memory allocation bounds
  - Disk space requirements

## Modifying Constraints

When changing constraint bounds:

1. **Update constraints.toml**
2. **Update validators** that use the constraint
3. **Update forms** that interpolate the constraint
4. **Test validation** in forms and Nickel typecheck
5. **Update documentation** of affected services

### Example: Increase Max Queue Tasks

**Before**:

```toml
[orchestrator.queue.concurrent_tasks]
min = 1
max = 100
```

**After**:

```toml
[orchestrator.queue.concurrent_tasks]
min = 1
max = 200  # Increased from 100
```

**Then**:
1. Verify `validators/orchestrator-validator.ncl` still type-checks
2. Form will automatically show new max (via constraint interpolation)
3. Test with: `nu scripts/validate-config.nu values/orchestrator.*.ncl`

## Constraint Interpolation in Forms

TypeDialog supports dynamic constraint references via `${constraint.path.to.value}`:

```bash
# Static min/max
min = 1
max = 100

# Dynamic from constraints.toml
min = "${constraint.orchestrator.queue.concurrent_tasks.min}"
max = "${constraint.orchestrator.queue.concurrent_tasks.max}"

# Help text with dynamic reference
help = "Value must be between ${constraint.orchestrator.queue.concurrent_tasks.min} and ${constraint.orchestrator.queue.concurrent_tasks.max}"
```

## Best Practices

1. **Single source of truth** - Define constraint once in constraints.toml
2. **Meaningful names** - Use clear path hierarchy (service.subsystem.property)
3. **Document ranges** - Add comments explaining why min/max values exist
4. **Validate propagation** - Ensure forms and validators reference the same constraint
5. **Test edge cases** - Verify min/max values work in validators and forms

## Files to Update When Modifying Constraints

When you change `constraints/constraints.toml`:

1. `validators/*.ncl` - Update validator bounds
2. `forms/fragments/*.toml` - Update form field constraints
3. `schemas/*.ncl` - Update type contracts if needed
4. Documentation - Update service-specific constraint documentation

---

**Version**: 1.0.0
**Last Updated**: 2025-01-05
