Schemas

Nickel type contracts defining configuration structure and validation for all services.

Purpose

Schemas define:

  • Type safety - Required/optional fields, valid types (string, number, bool, record)
  • Value constraints - Enum values, numeric bounds (via contracts)
  • Documentation - Field descriptions and usage patterns
  • Composition - Inheritance and merging of schema types

File Organization

schemas/
├── README.md                           # This file
├── common/                             # Shared schemas (server, database, security, etc.)
│   ├── server.ncl                      # HTTP server configuration schema
│   ├── database.ncl                    # Database backend schema
│   ├── security.ncl                    # Authentication and security schema
│   ├── monitoring.ncl                  # Metrics and health checks schema
│   ├── logging.ncl                     # Log level and format schema
│   ├── network.ncl                     # Network binding and TLS schema
│   ├── storage.ncl                     # Storage backend schema
│   └── workspace.ncl                   # Workspace configuration schema
├── deployment/                         # Mode-specific schemas
│   ├── solo.ncl                        # Solo mode resource constraints
│   ├── multiuser.ncl                   # Multi-user mode schema
│   ├── cicd.ncl                        # CI/CD mode schema
│   └── enterprise.ncl                  # Enterprise HA schema
├── orchestrator.ncl                    # Orchestrator service schema
├── control-center.ncl                  # Control Center service schema
├── mcp-server.ncl                      # MCP Server service schema
└── installer.ncl                       # Installer service schema

Schema Patterns

1. Basic Schema Definition

# schemas/common/server.ncl
{
  Server = {
    host | String,                     # Required string field
    port | Number,                     # Required number field
    workers | Number | default = 4,    # Optional with default
    keep_alive | Number | optional,    # Optional field
    max_connections | Number | optional,
  },
}

2. Type with Contract Validation

# With constraint checking (via validators)
{
  WorkerCount =
    let valid_range = fun n =>
      if n < 1 then
        std.contract.blame "Workers must be >= 1" n
      else if n > 32 then
        std.contract.blame "Workers must be <= 32" n
      else
        n
    in
    Number | valid_range,
}

3. Record Merging (Composition)

# schemas/orchestrator.ncl
let server_schema = import "./common/server.ncl" in
let database_schema = import "./common/database.ncl" in

{
  OrchestratorConfig = {
    workspace | {
      name | String,
      path | String,
      enabled | Bool | default = true,
    },
    server | server_schema.Server,  # Reuse Server schema
    storage | database_schema.Database,  # Reuse Database schema
    queue | {
      max_concurrent_tasks | Number,
      retry_attempts | Number | default = 3,
    },
  },
}

Common Schemas

server.ncl

HTTP server configuration:

  • host - Bind address (string)
  • port - Listen port (number)
  • workers - Thread count (number, optional)
  • keep_alive - Keep-alive timeout (number, optional)
  • max_connections - Connection limit (number, optional)

database.ncl

Database backend selection:

  • backend - 'filesystem | 'rocksdb | 'surrealdb_embedded | 'surrealdb_server | 'postgres (enum)
  • path - Storage path (string, optional)
  • connection_string - DB URL (string, optional)
  • credentials - Auth object (optional)

security.ncl

Authentication and encryption:

  • jwt_issuer - JWT issuer (string, optional)
  • jwt_audience - JWT audience (string, optional)
  • jwt_expiration - Token expiration (number, optional)
  • encryption_key - Encryption key (string, optional)
  • kms_backend - KMS provider (string, optional)
  • mfa_required - Require MFA (bool, optional)

monitoring.ncl

Metrics and health:

  • enabled - Enable monitoring (bool, optional)
  • metrics_interval - Metrics collection interval (number, optional)
  • health_check_interval - Health check frequency (number, optional)
  • retention_days - Metrics retention (number, optional)

logging.ncl

Log configuration:

  • level - Log level (debug | info | warn | error)
  • format - Log format (json | text)
  • rotation - Log rotation policy (optional)
  • output - Log destination (stdout | file | syslog)

Service Schemas

orchestrator.ncl

Workflow orchestration:

OrchestratorConfig = {
  workspace | WorkspaceConfig,
  server | Server,
  storage | Database,
  queue | QueueConfig,
  batch | BatchConfig,
  monitoring | MonitoringConfig | optional,
  rollback | RollbackConfig | optional,
  extensions | ExtensionsConfig | optional,
}

control-center.ncl

Policy and RBAC:

ControlCenterConfig = {
  workspace | WorkspaceConfig,
  server | Server,
  database | Database,
  security | SecurityConfig,
  rbac | RBACConfig | optional,
  compliance | ComplianceConfig | optional,
}

mcp-server.ncl

MCP protocol server:

MCPServerConfig = {
  workspace | WorkspaceConfig,
  server | Server,
  capabilities | CapabilitiesConfig,
  tools | ToolsConfig | optional,
  resources | ResourcesConfig | optional,
}

Deployment Mode Schemas

Deployment schemas define resource constraints for each mode:

  • solo.ncl - 2 CPU, 4GB RAM, embedded DB
  • multiuser.ncl - 4 CPU, 8GB RAM, PostgreSQL
  • cicd.ncl - 8 CPU, 16GB RAM, ephemeral
  • enterprise.ncl - 16+ CPU, 32+ GB RAM, HA

Example:

# schemas/deployment/solo.ncl
{
  SoloMode = {
    resources = {
      cpu_cores | 2,
      memory_mb | 4096,
      disk_gb | 50,
    },
    database_backend | 'filesystem,
    security_level | 'basic,
  },
}

Validation with Schemas

Schemas are composed with validators in config files:

# configs/orchestrator.solo.ncl
let schemas = import "../schemas/orchestrator.ncl" in
let validators = import "../validators/orchestrator-validator.ncl" in
let defaults = import "../defaults/orchestrator-defaults.ncl" in

# Compose: defaults + validation + schema checking
{
  orchestrator = defaults.orchestrator & {
    queue = {
      max_concurrent_tasks = validators.ValidConcurrentTasks 5,
    },
  },
} | schemas.OrchestratorConfig

The final | schemas.OrchestratorConfig applies type checking.

Type System

Nickel Type Syntax

# Required field
field | Type,

# Optional field
field | Type | optional,

# Field with default
field | Type | default = value,

# Union type
field | [| 'option1, 'option2],

# Nested record
field | {
  subfield | Type,
},

Best Practices

  1. Reuse common schemas - Import and compose rather than duplicate
  2. Use enums for choices - 'filesystem | 'rocksdb instead of string validation
  3. Document fields - Add comments explaining purpose
  4. Keep schemas focused - Each file covers one logical component
  5. Test composition - Use nickel typecheck to verify schema merging

Modifying Schemas

When changing a schema:

  1. Update schema file (schemas/*.ncl)
  2. Update corresponding defaults (defaults/*.ncl) to match schema
  3. Update validators if constraints changed
  4. Run typecheck: nickel typecheck configs/orchestrator.*.ncl
  5. Verify all configs still type-check

Schema Testing

# Typecheck a schema
nickel typecheck provisioning/.typedialog/provisioning/platform/schemas/orchestrator.ncl

# Typecheck a config (which applies schema)
nickel typecheck provisioning/.typedialog/provisioning/platform/configs/orchestrator.solo.ncl

# Evaluate a schema
nickel eval provisioning/.typedialog/provisioning/platform/schemas/orchestrator.ncl

Version: 1.0.0 Last Updated: 2025-01-05