# Defaults

Default configuration values for all services and deployment modes.

## Purpose

Defaults provide:
- **Base values** for all configuration fields
- **Mode-specific overrides** (solo, multiuser, cicd, enterprise)
- **Composition with validators** for constraint checking
- **Documentation** of recommended values

## File Organization

```bash
defaults/
├── README.md                           # This file
├── common/                             # Shared defaults
│   ├── server-defaults.ncl             # HTTP server defaults
│   ├── database-defaults.ncl           # Database defaults
│   ├── security-defaults.ncl           # Security defaults
│   ├── monitoring-defaults.ncl         # Monitoring defaults
│   └── logging-defaults.ncl            # Logging defaults
├── deployment/                         # Mode-specific defaults
│   ├── solo-defaults.ncl               # Solo mode (2 CPU, 4GB)
│   ├── multiuser-defaults.ncl          # Multi-user mode (4 CPU, 8GB)
│   ├── cicd-defaults.ncl               # CI/CD mode (8 CPU, 16GB)
│   └── enterprise-defaults.ncl         # Enterprise mode (16+ CPU, 32+ GB)
├── orchestrator-defaults.ncl           # Orchestrator base defaults
├── control-center-defaults.ncl         # Control Center base defaults
├── mcp-server-defaults.ncl             # MCP Server base defaults
└── installer-defaults.ncl              # Installer base defaults
```

## Composition Pattern

Configuration is built from layers:

```toml
Base Defaults (service-defaults.ncl)
    ↓
+ Mode Overlay (deployment/{mode}-defaults.ncl)
    ↓
+ User Customization (values/{service}.{mode}.ncl)
    ↓
+ Schema Validation (schemas/*.ncl)
    ↓
= Final Configuration (configs/{service}.{mode}.ncl)
```

Example:

```bash
# configs/orchestrator.solo.ncl
let defaults = import "../defaults/orchestrator-defaults.ncl" in
let solo_defaults = import "../defaults/deployment/solo-defaults.ncl" in

{
  orchestrator = defaults.orchestrator & {
    # Mode-specific overrides
    server.workers = 2,          # Solo mode: fewer workers
    queue.max_concurrent_tasks = 3,  # Solo: limited concurrency
  },
}
```

## Default Value Hierarchy

### 1. Service Base Defaults

**orchestrator-defaults.ncl**:

```json
{
  orchestrator = {
    workspace = {
      name = "default",
      path = "/var/lib/provisioning/orchestrator",
      enabled = true,
      multi_workspace = false,
    },
    server = {
      host = "127.0.0.1",
      port = 9090,
      workers = 4,        # General default
    },
    storage = {
      backend = 'filesystem,
      path = "/var/lib/provisioning/orchestrator/data",
    },
    queue = {
      max_concurrent_tasks = 5,
      retry_attempts = 3,
    },
  },
}
```

### 2. Mode-Specific Overrides

**deployment/solo-defaults.ncl**:

```json
{
  resources = {
    cpu_cores = 2,
    memory_mb = 4096,
  },
  services = {
    orchestrator = {
      workers = 2,                    # Override: fewer workers for solo
      queue_max_concurrent_tasks = 3,  # Override: limited concurrency
      storage_backend = 'filesystem,
    },
  },
}
```

**deployment/enterprise-defaults.ncl**:

```json
{
  resources = {
    cpu_cores = 16,
    memory_mb = 32768,
  },
  services = {
    orchestrator = {
      workers = 16,                   # Override: more workers for enterprise
      queue_max_concurrent_tasks = 50,  # Override: high concurrency
      storage_backend = 'surrealdb_server,
      surrealdb_url = "surrealdb://cluster:8000",
    },
  },
}
```

## Common Defaults

### server-defaults.ncl

```json
{
  server = {
    host = "0.0.0.0",        # Accept all interfaces
    port = 8080,             # Standard HTTP port (service-specific override)
    workers = 4,             # CPU-aware default
    keep_alive = 75,         # seconds
    max_connections = 100,
  },
}
```

### database-defaults.ncl

```json
{
  database = {
    backend = 'rocksdb,      # Fast embedded default
    path = "/var/lib/provisioning/data",
    pool_size = 10,          # Connection pool
    timeout = 30000,         # milliseconds
  },
}
```

### security-defaults.ncl

```json
{
  security = {
    jwt_issuer = "provisioning-system",
    jwt_expiration = 3600,   # 1 hour
    encryption_key = "",     # User must set
    kms_backend = "age",     # Local encryption
    mfa_required = false,    # Solo: disabled by default
  },
}
```

### monitoring-defaults.ncl

```json
{
  monitoring = {
    enabled = false,         # Optional feature
    metrics_interval = 60,   # seconds
    health_check_interval = 30,
    retention_days = 30,
  },
}
```

## Mode Configurations

### Solo Mode
- **Use case**: Single developer, testing
- **Resources**: 2 CPU, 4GB RAM, 50GB disk
- **Database**: Filesystem or embedded (RocksDB)
- **Security**: Simplified (no MFA, local encryption)
- **Services**: Core services only (orchestrator, control-center)

### MultiUser Mode
- **Use case**: Team collaboration, staging
- **Resources**: 4 CPU, 8GB RAM, 100GB disk
- **Database**: PostgreSQL or SurrealDB server
- **Security**: RBAC enabled, shared authentication
- **Services**: Full platform (orchestrator, control-center, MCP, Gitea)

### CI/CD Mode
- **Use case**: Automated pipelines, testing
- **Resources**: 8 CPU, 16GB RAM, 200GB disk
- **Database**: Ephemeral, fast cleanup
- **Security**: API tokens, no UI
- **Services**: Minimal (orchestrator in API mode)

### Enterprise Mode
- **Use case**: Production, high availability
- **Resources**: 16+ CPU, 32+ GB RAM, 500GB+ disk
- **Database**: SurrealDB cluster with replication
- **Security**: MFA required, KMS integration, compliance
- **Services**: Full platform with redundancy, monitoring, logging

## Modifying Defaults

### Changing a Base Default

**orchestrator-defaults.ncl**:

```nickel
# Before
queue = {
  max_concurrent_tasks = 5,
},

# After
queue = {
  max_concurrent_tasks = 10,  # Increased default
},
```

**Then**:
1. Test with: `nickel eval configs/orchestrator.solo.ncl`
2. Verify forms still work
3. Update documentation if default meaning changes

### Changing Mode Override

**deployment/solo-defaults.ncl**:

```nickel
# Before
orchestrator = {
  workers = 2,
}

# After
orchestrator = {
  workers = 1,  # Reduce to 1 for solo
}
```

## Best Practices

1. **Keep it conservative** - Default to safe, minimal values
2. **Document overrides** - Explain why mode-specific values differ
3. **Use composition** - Import and merge rather than duplicate
4. **Test composition** - Verify defaults merge correctly with modes
5. **Provide examples** - Use `examples/` directory to show realistic setups

## Testing Defaults

```bash
# Evaluate defaults
nickel eval provisioning/.typedialog/provisioning/platform/defaults/orchestrator-defaults.ncl

# Test merged defaults (base + mode)
nickel eval provisioning/.typedialog/provisioning/platform/configs/orchestrator.solo.ncl | head -50

# Typecheck with schemas
nickel typecheck provisioning/.typedialog/provisioning/platform/configs/orchestrator.solo.ncl
```

## Default Value Guidelines

### Ports
- Solo mode: Local (127.0.0.1) only
- Multi-user/Enterprise: Bind all interfaces (0.0.0.0)
- Never conflict with system services

### Workers/Concurrency
- Solo: 1-2 workers, limited concurrency
- Multi-user: 4-8 workers, moderate concurrency
- Enterprise: 8+ workers, high concurrency

### Resources
- Solo: 2 CPU, 4GB RAM (laptop testing)
- Multi-user: 4 CPU, 8GB RAM (team servers)
- Enterprise: 16+ CPU, 32+ GB RAM (production)

### Security
- Solo: Disabled/minimal (local development)
- Multi-user: RBAC enabled (shared team)
- Enterprise: MFA required, KMS backend (production)

### Storage
- Solo: Filesystem or RocksDB (no infrastructure needed)
- Multi-user: PostgreSQL or SurrealDB (team data)
- Enterprise: SurrealDB cluster with replication (HA)

---

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