# Constraint Interpolation Guide

## Overview

TypeDialog form fields can reference constraints from `constraints.toml` using Jinja2-style template syntax. This provides a **single source of truth** for validation limits across forms, Nickel schemas, and validators.

## Pattern

All numeric form fields should use constraint interpolation for `min` and `max` values:

```toml
[[elements]]
name = "field_name"
type = "number"
default = 5
help = "Field description (range: ${constraint.path.to.constraint.min}-${constraint.path.to.constraint.max})"
min = "${constraint.path.to.constraint.min}"
max = "${constraint.path.to.constraint.max}"
nickel_path = ["path", "to", "field"]
prompt = "Field Label"
```

## Benefits

1. **Single Source of Truth**: Constraints defined once in `constraints.toml`, used everywhere
2. **Dynamic Validation**: If constraint changes, all forms automatically get updated ranges
3. **User-Friendly**: Forms show actual valid ranges in help text
4. **Type Safety**: Constraints match Nickel schema contract ranges

## Complete Constraint Mapping

### Orchestrator Fragments

| Fragment | Field | Constraint Path | Min | Max |
| ---------- | ------- | ----------------- | ----- | ----- |
| `queue-section.toml` | `queue_max_concurrent_tasks` | `orchestrator.queue.concurrent_tasks` | 1 | 100 |
| `queue-section.toml` | `queue_retry_attempts` | `orchestrator.queue.retry_attempts` | 0 | 10 |
| `queue-section.toml` | `queue_retry_delay` | `orchestrator.queue.retry_delay` | 1000 | 60000 |
| `queue-section.toml` | `queue_task_timeout` | `orchestrator.queue.task_timeout` | 60000 | 86400000 |
| `batch-section.toml` | `batch_parallel_limit` | `orchestrator.batch.parallel_limit` | 1 | 50 |
| `batch-section.toml` | `batch_operation_timeout` | `orchestrator.batch.operation_timeout` | 60000 | 3600000 |
| `extensions-section.toml` | `extensions_max_concurrent` | `orchestrator.extensions.max_concurrent` | 1 | 20 |
| `extensions-section.toml` | `extensions_discovery_interval` | Not in constraints (use reasonable bounds) | 300 | 86400 |
| `extensions-section.toml` | `extensions_init_timeout` | Not in constraints (use reasonable bounds) | 1000 | 300000 |
| `extensions-section.toml` | `extensions_sandbox_max_memory_mb` | Not in constraints (use reasonable bounds) | 64 | 4096 |
| `performance-section.toml` | `memory_max_heap_mb` | Not in constraints (use mode-based bounds) | 256 | 131072 |
| `performance-section.toml` | `profiling_sample_rate` | Not in constraints (use reasonable bounds) | 10 | 1000 |
| `storage-section.toml` | `storage_cache_ttl` | Not in constraints (use 60-3600) | 60 | 3600 |
| `storage-section.toml` | `storage_cache_max_entries` | Not in constraints (use 10-100000) | 10 | 100000 |
| `storage-section.toml` | `storage_compression_level` | Not in constraints (zstd: 1-19) | 1 | 19 |
| `storage-section.toml` | `storage_gc_retention` | Not in constraints (use 3600-31536000) | 3600 | 31536000 |
| `storage-section.toml` | `storage_gc_interval` | Not in constraints (use 300-86400) | 300 | 86400 |

### Control Center Fragments

| Fragment | Field | Constraint Path | Min | Max |
| ---------- | ------- | ----------------- | ----- | ----- |
| `security-section.toml` | `jwt_token_expiration` | `control_center.jwt.token_expiration` | 300 | 604800 |
| `security-section.toml` | `jwt_refresh_expiration` | `control_center.jwt.refresh_expiration` | 3600 | 2592000 |
| `security-section.toml` | `rate_limiting_max_requests` | `control_center.rate_limiting.max_requests` | 10 | 10000 |
| `security-section.toml` | `rate_limiting_window` | `control_center.rate_limiting.window_seconds` | 1 | 3600 |
| `security-section.toml` | `users_sessions_max_active` | Not in constraints (use 1-100) | 1 | 100 |
| `security-section.toml` | `users_sessions_idle_timeout` | Not in constraints (use 300-86400) | 300 | 86400 |
| `security-section.toml` | `users_sessions_absolute_timeout` | Not in constraints (use 3600-2592000) | 3600 | 2592000 |
| `policy-section.toml` | `policy_cache_ttl` | Not in constraints (use 60-86400) | 60 | 86400 |
| `policy-section.toml` | `policy_cache_max_policies` | Not in constraints (use 100-10000) | 100 | 10000 |
| `policy-section.toml` | `policy_versioning_max_versions` | Not in constraints (use 1-100) | 1 | 100 |
| `users-section.toml` | `users_registration_auto_role` | Not in constraints (select field, not numeric) | - | - |
| `users-section.toml` | `users_sessions_max_active` | Not in constraints (use 1-100) | 1 | 100 |
| `users-section.toml` | `users_sessions_idle_timeout` | Not in constraints (use 300-86400) | 300 | 86400 |
| `users-section.toml` | `users_sessions_absolute_timeout` | Not in constraints (use 3600-2592000) | 3600 | 2592000 |
| `compliance-section.toml` | `audit_retention_days` | `control_center.audit.retention_days` | 1 | 3650 |
| `compliance-section.toml` | `compliance_validation_interval` | Not in constraints (use 1-168 hours) | 1 | 168 |
| `compliance-section.toml` | `compliance_data_retention_years` | Not in constraints (use 1-30) | 1 | 30 |
| `compliance-section.toml` | `compliance_audit_log_days` | Not in constraints (use 90-10950) | 90 | 10950 |

### MCP Server Fragments

| Fragment | Field | Constraint Path | Min | Max |
| ---------- | ------- | ----------------- | ----- | ----- |
| `tools-section.toml` | `tools_max_concurrent` | `mcp_server.tools.max_concurrent` | 1 | 20 |
| `tools-section.toml` | `tools_timeout` | `mcp_server.tools.timeout` | 5000 | 600000 |
| `prompts-section.toml` | `prompts_max_templates` | `mcp_server.prompts.max_templates` | 1 | 100 |
| `prompts-section.toml` | `prompts_cache_ttl` | Not in constraints (use 60-86400) | 60 | 86400 |
| `prompts-section.toml` | `prompts_versioning_max_versions` | Not in constraints (use 1-100) | 1 | 100 |
| `resources-section.toml` | `resources_max_size` | `mcp_server.resources.max_size` | 1048576 | 1073741824 |
| `resources-section.toml` | `resources_cache_max_size_mb` | Not in constraints (use 10-10240) | 10 | 10240 |
| `resources-section.toml` | `resources_cache_ttl` | `mcp_server.resources.cache_ttl` | 60 | 3600 |
| `resources-section.toml` | `resources_validation_max_depth` | Not in constraints (use 1-100) | 1 | 100 |
| `sampling-section.toml` | `sampling_max_tokens` | `mcp_server.sampling.max_tokens` | 100 | 100000 |
| `sampling-section.toml` | `sampling_temperature` | Not in constraints (use 0.0-2.0) | 0.0 | 2.0 |
| `sampling-section.toml` | `sampling_cache_ttl` | Not in constraints (use 60-3600) | 60 | 3600 |

### Common/Shared Fragments

| Fragment | Field | Constraint Path | Min | Max |
| ---------- | ------- | ----------------- | ----- | ----- |
| `server-section.toml` | `server_port` | `common.server.port` | 1024 | 65535 |
| `server-section.toml` | `server_workers` | `common.server.workers` | 1 | 32 |
| `server-section.toml` | `server_max_connections` | `common.server.max_connections` | 10 | 10000 |
| `server-section.toml` | `server_keep_alive` | `common.server.keep_alive` | 0 | 600 |
| `monitoring-section.toml` | `monitoring_metrics_interval` | `common.monitoring.metrics_interval` | 10 | 300 |
| `monitoring-section.toml` | `monitoring_health_check_interval` | `common.monitoring.health_check_interval` | 5 | 300 |
| `logging-section.toml` | `logging_max_file_size` | `common.logging.max_file_size` | 1048576 | 1073741824 |
| `logging-section.toml` | `logging_max_backups` | `common.logging.max_backups` | 1 | 100 |
| `database-rocksdb-section.toml` | `database_pool_size` | Not in constraints (use 1-100) | 1 | 100 |
| `database-rocksdb-section.toml` | `database_timeout` | Not in constraints (use 10-3600) | 10 | 3600 |
| `database-rocksdb-section.toml` | `database_retry_attempts` | Not in constraints (use 0-10) | 0 | 10 |
| `database-rocksdb-section.toml` | `database_retry_delay` | Not in constraints (use 1000-60000) | 1000 | 60000 |
| `database-surrealdb-section.toml` | `pool_size` | Not in constraints (use 1-200) | 1 | 200 |
| `database-surrealdb-section.toml` | `timeout` | Not in constraints (use 10-3600) | 10 | 3600 |
| `database-postgres-section.toml` | `postgres_port` | Not in constraints (use 1024-65535) | 1024 | 65535 |
| `database-postgres-section.toml` | `postgres_pool_size` | Not in constraints (use 5-200) | 5 | 200 |

### Installer Fragments

| Fragment | Field | Constraint Path | Min | Max |
| ---------- | ------- | ----------------- | ----- | ----- |
| `target-section.toml` | `remote_ssh_port` | `common.server.port` | 1024 | 65535 |
| `preflight-section.toml` | `min_disk_gb` | `deployment.solo.disk_gb.min` (mode-dependent) | Variable | Variable |
| `preflight-section.toml` | `min_memory_gb` | `deployment.solo.memory_mb.min` (mode-dependent) | Variable | Variable |
| `preflight-section.toml` | `min_cpu_cores` | `deployment.solo.cpu.min` (mode-dependent) | Variable | Variable |
| `installation-section.toml` | `parallel_services` | Not in constraints (use 1-10) | 1 | 10 |
| `installation-section.toml` | `installation_timeout_seconds` | Not in constraints (use 0-14400) | 0 | 14400 |
| `installation-section.toml` | `log_level` | Not in constraints (select field, not numeric) | - | - |
| `installation-section.toml` | `validation_timeout` | Not in constraints (use 5000-300000) | 5000 | 300000 |
| `services-section.toml` | `orchestrator_port` | `common.server.port` | 1024 | 65535 |
| `services-section.toml` | `control_center_port` | `common.server.port` | 1024 | 65535 |
| `services-section.toml` | `mcp_server_port` | `common.server.port` | 1024 | 65535 |
| `services-section.toml` | `api_gateway_port` | `common.server.port` | 1024 | 65535 |
| `database-section.toml` | `connection_pool_size` | Not in constraints (use 1-100) | 1 | 100 |
| `database-section.toml` | `connection_pool_timeout` | Not in constraints (use 10-3600) | 10 | 3600 |
| `database-section.toml` | `connection_idle_timeout` | Not in constraints (use 60-14400) | 60 | 14400 |
| `storage-section.toml` | `storage_size_gb` | Not in constraints (use 10-100000) | 10 | 100000 |
| `storage-section.toml` | `storage_replication_factor` | Not in constraints (use 2-10) | 2 | 10 |
| `networking-section.toml` | `load_balancer_http_port` | `common.server.port` | 1024 | 65535 |
| `networking-section.toml` | `load_balancer_https_port` | `common.server.port` | 1024 | 65535 |
| `ha-section.toml` | `ha_cluster_size` | Not in constraints (use 3-256) | 3 | 256 |
| `ha-section.toml` | `ha_db_quorum_size` | Not in constraints (use 1-max_cluster_size) | 1 | 256 |
| `ha-section.toml` | `ha_health_check_interval` | Not in constraints (use 1-120) | 1 | 120 |
| `ha-section.toml` | `ha_health_check_failure_threshold` | Not in constraints (use 1-10) | 1 | 10 |
| `ha-section.toml` | `ha_failover_delay` | Not in constraints (use 0-600) | 0 | 600 |
| `upgrades-section.toml` | `rolling_upgrade_parallel` | Not in constraints (use 1-10) | 1 | 10 |
| `upgrades-section.toml` | `canary_percentage` | Not in constraints (use 1-50) | 1 | 50 |
| `upgrades-section.toml` | `canary_duration_seconds` | Not in constraints (use 30-3600) | 30 | 3600 |

## Fragments Status

### ✅ Completed (Constraints Interpolated)
- `server-section.toml` - All numeric fields updated
- `monitoring-section.toml` - Core metrics interval updated
- `orchestrator/queue-section.toml` - All queue fields updated
- `orchestrator/batch-section.toml` - Parallel limit and operation timeout updated
- `mcp-server/tools-section.toml` - Tools concurrency and timeout updated

### ⏳ Remaining (Need Updates)
- All other orchestrator fragments (extensions, performance, storage)
- All control-center fragments (security, policy, users, compliance)
- Remaining MCP fragments (prompts, resources, sampling)
- All installer fragments (target, preflight, installation, services, database, storage, networking, ha, upgrades)
- All database fragments (rocksdb, surrealdb, postgres)
- logging-section.toml

## How to Add Constraints to a Fragment

1. **Identify numeric fields** with `type = "number"` that have `min` and/or `max` values
2. **Find the constraint path** in the mapping table above
3. **Update the field** with constraint references:

```toml
# Before
[[elements]]
default = 5
min = 1
max = 100
name = "my_field"
type = "number"

# After
[[elements]]
default = 5
help = "Field description (range: ${constraint.path.to.field.min}-${constraint.path.to.field.max})"
min = "${constraint.path.to.field.min}"
max = "${constraint.path.to.field.max}"
name = "my_field"
type = "number"
```

4. **For fields without existing constraints**, add reasonable bounds based on the domain:
   - Timeouts: typically 1 second to 1 hour (1000-3600000 ms)
   - Counters: typically 1-100 or 1-1000
   - Memory: use deployment mode constraints (64MB-256GB)
   - Ports: use `common.server.port` (1024-65535)

5. **Test** that the constraint is accessible in `constraints.toml`

## Example: Adding Constraint to a New Field

```toml
[[elements]]
default = 3600
help = "Cache timeout in seconds (range: ${constraint.common.monitoring.health_check_interval.min}-${constraint.common.monitoring.health_check_interval.max})"
min = "${constraint.common.monitoring.health_check_interval.min}"
max = "${constraint.common.monitoring.health_check_interval.max}"
name = "cache_timeout_seconds"
nickel_path = ["cache", "timeout_seconds"]
prompt = "Cache Timeout (seconds)"
type = "number"
```

## Integration with TypeDialog

When TypeDialog processes forms:

1. **Load time**: Constraint references are resolved from `constraints.toml`
2. **Validation**: User input is validated against resolved min/max values
3. **Help text**: Ranges are shown to user in help messages
4. **Nickel generation**: Jinja2 templates receive validated values

## See Also

- `provisioning/.typedialog/provisioning/platform/constraints/constraints.toml` - Constraint definitions
- `constraint_update_status.md` - Progress tracking for constraint interpolation updates
- `provisioning/.typedialog/provisioning/platform/templates/*.j2` - Jinja2 templates for code generation
- `provisioning/schemas/` - Nickel schemas (use same ranges as constraints)
