388 lines
10 KiB
Markdown
388 lines
10 KiB
Markdown
|
|
# Composed Configurations Guide
|
||
|
|
|
||
|
|
**Status**: ✅ Complete
|
||
|
|
**Created**: January 12, 2026
|
||
|
|
**Total Config Files**: 4 (solo, multiuser, enterprise, main)
|
||
|
|
|
||
|
|
## Overview
|
||
|
|
|
||
|
|
Composed Nickel configurations that combine schema, constraints, defaults, and user customizations into production-ready configurations for all VAPORA deployment modes.
|
||
|
|
|
||
|
|
## Files Created
|
||
|
|
|
||
|
|
```plaintext
|
||
|
|
schemas/platform/configs/
|
||
|
|
├── vapora-solo.ncl ✅ Solo mode composition
|
||
|
|
├── vapora-multiuser.ncl ✅ Multiuser mode composition
|
||
|
|
├── vapora-enterprise.ncl ✅ Enterprise mode composition
|
||
|
|
├── main.ncl ✅ Entry point for all configs
|
||
|
|
├── README.md ✅ Comprehensive usage guide
|
||
|
|
```
|
||
|
|
|
||
|
|
## Composition Architecture
|
||
|
|
|
||
|
|
Each configuration file follows the **4-layer composition pattern**:
|
||
|
|
|
||
|
|
```
|
||
|
|
Layer 1: Schema Definition
|
||
|
|
↓ imports from ../../vapora/main.ncl
|
||
|
|
Defines all fields, types, contracts
|
||
|
|
|
||
|
|
Layer 2: Constraints & Validation
|
||
|
|
↓ checked by Platform Constraints
|
||
|
|
Validates values are in valid ranges
|
||
|
|
|
||
|
|
Layer 3: Defaults
|
||
|
|
↓ imports from ../defaults/common/ and ../defaults/deployment/
|
||
|
|
Provides sensible starting values
|
||
|
|
|
||
|
|
Layer 4: User Customizations
|
||
|
|
↓ composable via helpers.compose_config()
|
||
|
|
Allows final overrides for specific deployments
|
||
|
|
```
|
||
|
|
|
||
|
|
## Configuration Files Breakdown
|
||
|
|
|
||
|
|
### Solo Mode (`vapora-solo.ncl`)
|
||
|
|
|
||
|
|
**Purpose**: Development and testing
|
||
|
|
|
||
|
|
**Composition**:
|
||
|
|
```nickel
|
||
|
|
let schema = import "../../vapora/main.ncl" in
|
||
|
|
let defaults_mode = import "../defaults/deployment/solo.ncl" in
|
||
|
|
|
||
|
|
helpers.compose_config schema defaults_mode {
|
||
|
|
# User customizations (optional)
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Preset Values**:
|
||
|
|
- Host: `127.0.0.1` (localhost only)
|
||
|
|
- Backend: 2 workers
|
||
|
|
- Agents: 3 max instances
|
||
|
|
- Database: File-based
|
||
|
|
- NATS: Disabled
|
||
|
|
- Cost tracking: Disabled
|
||
|
|
- Security: JWT only
|
||
|
|
|
||
|
|
**Export**:
|
||
|
|
```bash
|
||
|
|
nickel export schemas/platform/configs/vapora-solo.ncl > vapora-solo.json
|
||
|
|
```
|
||
|
|
|
||
|
|
### Multiuser Mode (`vapora-multiuser.ncl`)
|
||
|
|
|
||
|
|
**Purpose**: Team collaboration and staging
|
||
|
|
|
||
|
|
**Composition**:
|
||
|
|
```nickel
|
||
|
|
let schema = import "../../vapora/main.ncl" in
|
||
|
|
let defaults_mode = import "../defaults/deployment/multiuser.ncl" in
|
||
|
|
|
||
|
|
helpers.compose_config schema defaults_mode {
|
||
|
|
# User customizations with examples
|
||
|
|
frontend.api_url = "https://api.vapora.internal:8001",
|
||
|
|
# ... more customizations commented
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Preset Values**:
|
||
|
|
- Host: `0.0.0.0` (network accessible)
|
||
|
|
- Backend: 4 workers
|
||
|
|
- Agents: 10 max instances
|
||
|
|
- Database: Remote SurrealDB
|
||
|
|
- NATS: Enabled
|
||
|
|
- Cost tracking: Enabled
|
||
|
|
- Security: TLS + MFA + audit
|
||
|
|
|
||
|
|
**Export**:
|
||
|
|
```bash
|
||
|
|
nickel export schemas/platform/configs/vapora-multiuser.ncl > vapora-multiuser.json
|
||
|
|
```
|
||
|
|
|
||
|
|
### Enterprise Mode (`vapora-enterprise.ncl`)
|
||
|
|
|
||
|
|
**Purpose**: Production high-availability
|
||
|
|
|
||
|
|
**Composition**:
|
||
|
|
```nickel
|
||
|
|
let schema = import "../../vapora/main.ncl" in
|
||
|
|
let defaults_mode = import "../defaults/deployment/enterprise.ncl" in
|
||
|
|
|
||
|
|
helpers.compose_config schema defaults_mode {
|
||
|
|
# User customizations with detailed examples
|
||
|
|
frontend.api_url = "https://api.vapora.production.com",
|
||
|
|
providers = { ... },
|
||
|
|
# ... more customizations commented
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Preset Values**:
|
||
|
|
- Host: `0.0.0.0` (clustered)
|
||
|
|
- Backend: 8 workers, 2000 connections
|
||
|
|
- Agents: 50 max instances
|
||
|
|
- Database: SurrealDB cluster, 100 pool size
|
||
|
|
- NATS: JetStream cluster
|
||
|
|
- Providers: All enabled (Claude, OpenAI, Gemini, Ollama)
|
||
|
|
- Security: TLS enforced, MFA required
|
||
|
|
- Observability: Prometheus, tracing, detailed logging
|
||
|
|
- Backup: Every 6 hours
|
||
|
|
|
||
|
|
**Export**:
|
||
|
|
```bash
|
||
|
|
nickel export schemas/platform/configs/vapora-enterprise.ncl > vapora-enterprise.json
|
||
|
|
```
|
||
|
|
|
||
|
|
### Main Entry Point (`main.ncl`)
|
||
|
|
|
||
|
|
**Purpose**: Load all configurations in one place
|
||
|
|
|
||
|
|
**Usage**:
|
||
|
|
```nickel
|
||
|
|
let configs = import "schemas/platform/configs/main.ncl" in
|
||
|
|
|
||
|
|
# Access each configuration
|
||
|
|
configs.solo
|
||
|
|
configs.multiuser
|
||
|
|
configs.enterprise
|
||
|
|
|
||
|
|
# Export all at once
|
||
|
|
configs.export.all
|
||
|
|
```
|
||
|
|
|
||
|
|
**Export All**:
|
||
|
|
```bash
|
||
|
|
nickel export schemas/platform/configs/main.ncl > all-vapora-configs.json
|
||
|
|
```
|
||
|
|
|
||
|
|
## Customization Patterns
|
||
|
|
|
||
|
|
### Pattern 1: Extend Solo for Testing
|
||
|
|
|
||
|
|
```nickel
|
||
|
|
# test-vapora.ncl
|
||
|
|
let helpers = import "schemas/platform/common/helpers.ncl" in
|
||
|
|
let schema = import "schemas/vapora/main.ncl" in
|
||
|
|
let solo = import "schemas/platform/defaults/deployment/solo.ncl" in
|
||
|
|
|
||
|
|
helpers.compose_config schema solo {
|
||
|
|
# Testing customizations
|
||
|
|
monitoring.log_level = "debug",
|
||
|
|
llm_router.providers.ollama_enabled = true,
|
||
|
|
backend.port = 9001,
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Pattern 2: Customize Multiuser for Specific Team
|
||
|
|
|
||
|
|
```nickel
|
||
|
|
# team-vapora.ncl
|
||
|
|
let helpers = import "schemas/platform/common/helpers.ncl" in
|
||
|
|
let schema = import "schemas/vapora/main.ncl" in
|
||
|
|
let multiuser = import "schemas/platform/defaults/deployment/multiuser.ncl" in
|
||
|
|
|
||
|
|
helpers.compose_config schema multiuser {
|
||
|
|
# Team-specific configuration
|
||
|
|
frontend.api_url = "https://api.my-team.internal",
|
||
|
|
|
||
|
|
llm_router.budget_enforcement.role_limits = {
|
||
|
|
architect_cents = 750000,
|
||
|
|
developer_cents = 500000,
|
||
|
|
reviewer_cents = 300000,
|
||
|
|
testing_cents = 150000,
|
||
|
|
},
|
||
|
|
|
||
|
|
agents.learning.recency_window_days = 14,
|
||
|
|
monitoring.log_level = "info",
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Pattern 3: Custom Enterprise with Regional Setup
|
||
|
|
|
||
|
|
```nickel
|
||
|
|
# us-west-vapora.ncl
|
||
|
|
let helpers = import "schemas/platform/common/helpers.ncl" in
|
||
|
|
let schema = import "schemas/vapora/main.ncl" in
|
||
|
|
let enterprise = import "schemas/platform/defaults/deployment/enterprise.ncl" in
|
||
|
|
|
||
|
|
helpers.compose_config schema enterprise {
|
||
|
|
# Regional customization
|
||
|
|
frontend.api_url = "https://api.us-west.vapora.production",
|
||
|
|
|
||
|
|
database.url = "ws://surrealdb-us-west.internal:8000",
|
||
|
|
|
||
|
|
providers.ollama_url = "http://ollama-us-west.internal:11434",
|
||
|
|
|
||
|
|
storage.base_path = "/mnt/production-us-west/vapora",
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Export Workflows
|
||
|
|
|
||
|
|
### Workflow 1: Generate JSON for Validation
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Export and validate JSON structure
|
||
|
|
nickel export schemas/platform/configs/vapora-multiuser.ncl | jq .
|
||
|
|
```
|
||
|
|
|
||
|
|
### Workflow 2: Generate TOML Configuration
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Export to JSON, then render TOML template
|
||
|
|
nickel export schemas/platform/configs/vapora-solo.ncl | \
|
||
|
|
jinja2 schemas/platform/templates/configs/toml.j2 > config.toml
|
||
|
|
|
||
|
|
# Use with backend
|
||
|
|
./vapora-backend --config config.toml
|
||
|
|
```
|
||
|
|
|
||
|
|
### Workflow 3: Generate Docker Compose Stack
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Render docker-compose.yml from multiuser config
|
||
|
|
nickel export schemas/platform/configs/vapora-multiuser.ncl | \
|
||
|
|
jinja2 schemas/platform/templates/docker-compose/docker-compose.yaml.j2 > docker-compose.yml
|
||
|
|
|
||
|
|
# Deploy
|
||
|
|
docker compose up -d
|
||
|
|
```
|
||
|
|
|
||
|
|
### Workflow 4: Generate Kubernetes ConfigMap
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Render Kubernetes ConfigMap from enterprise config
|
||
|
|
nickel export schemas/platform/configs/vapora-enterprise.ncl | \
|
||
|
|
jinja2 schemas/platform/templates/kubernetes/configmap.yaml.j2 > configmap.yaml
|
||
|
|
|
||
|
|
# Create ConfigMap in cluster
|
||
|
|
kubectl create -f configmap.yaml
|
||
|
|
|
||
|
|
# Or update existing
|
||
|
|
kubectl replace -f configmap.yaml
|
||
|
|
```
|
||
|
|
|
||
|
|
### Workflow 5: Multi-File Deployment
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Generate all configurations
|
||
|
|
for mode in solo multiuser enterprise; do
|
||
|
|
nickel export schemas/platform/configs/vapora-${mode}.ncl > vapora-${mode}.json
|
||
|
|
done
|
||
|
|
|
||
|
|
# Validate all
|
||
|
|
for f in vapora-*.json; do jq . "$f" > /dev/null && echo "✓ $f"; done
|
||
|
|
|
||
|
|
# Generate deployment artifacts
|
||
|
|
nickel export schemas/platform/configs/vapora-enterprise.ncl | \
|
||
|
|
jinja2 schemas/platform/templates/kubernetes/configmap.yaml.j2 > configmap.yaml
|
||
|
|
|
||
|
|
nickel export schemas/platform/configs/vapora-enterprise.ncl | \
|
||
|
|
jinja2 schemas/platform/templates/kubernetes/deployment.yaml.j2 > deployment.yaml
|
||
|
|
|
||
|
|
# Deploy to Kubernetes
|
||
|
|
kubectl apply -f configmap.yaml
|
||
|
|
kubectl apply -f deployment.yaml
|
||
|
|
```
|
||
|
|
|
||
|
|
## Integration with Deployment Pipeline
|
||
|
|
|
||
|
|
### CI/CD Integration
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# In CI/CD pipeline (e.g., .github/workflows/deploy.yml)
|
||
|
|
|
||
|
|
# 1. Validate all configurations
|
||
|
|
for config in schemas/platform/configs/vapora-*.ncl; do
|
||
|
|
nickel typecheck "$config" || exit 1
|
||
|
|
nickel export "$config" | jq . > /dev/null || exit 1
|
||
|
|
done
|
||
|
|
|
||
|
|
# 2. Generate all outputs
|
||
|
|
nickel export schemas/platform/configs/vapora-${DEPLOYMENT_MODE}.ncl > config.json
|
||
|
|
|
||
|
|
# 3. Render templates
|
||
|
|
jinja2 schemas/platform/templates/kubernetes/configmap.yaml.j2 < config.json > configmap.yaml
|
||
|
|
jinja2 schemas/platform/templates/kubernetes/deployment.yaml.j2 < config.json > deployment.yaml
|
||
|
|
|
||
|
|
# 4. Deploy
|
||
|
|
kubectl apply -f configmap.yaml
|
||
|
|
kubectl apply -f deployment.yaml
|
||
|
|
```
|
||
|
|
|
||
|
|
### Manual Deployment
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# 1. Choose deployment mode
|
||
|
|
DEPLOYMENT_MODE=multiuser
|
||
|
|
|
||
|
|
# 2. Export configuration
|
||
|
|
nickel export schemas/platform/configs/vapora-${DEPLOYMENT_MODE}.ncl > vapora.json
|
||
|
|
|
||
|
|
# 3. Validate
|
||
|
|
jq . vapora.json > /dev/null && echo "✓ Configuration valid"
|
||
|
|
|
||
|
|
# 4. Generate Docker Compose (for local testing)
|
||
|
|
jinja2 schemas/platform/templates/docker-compose/docker-compose.yaml.j2 < vapora.json > docker-compose.yml
|
||
|
|
|
||
|
|
# 5. Deploy
|
||
|
|
docker compose up -d
|
||
|
|
|
||
|
|
# 6. Verify
|
||
|
|
docker compose ps
|
||
|
|
```
|
||
|
|
|
||
|
|
## Key Benefits
|
||
|
|
|
||
|
|
✅ **Composable** - Mix and match schema, defaults, customizations
|
||
|
|
✅ **Type-Safe** - Schema defines all valid fields and types
|
||
|
|
✅ **Validated** - Constraints enforce valid value ranges
|
||
|
|
✅ **Defaulted** - Sensible defaults for each mode
|
||
|
|
✅ **Customizable** - Easy to override for specific needs
|
||
|
|
✅ **Reproducible** - Same config generates same output
|
||
|
|
✅ **Version-Controlled** - Configurations in Git
|
||
|
|
✅ **Multi-Format** - Generate JSON, TOML, YAML, K8s, Docker
|
||
|
|
|
||
|
|
## File Statistics
|
||
|
|
|
||
|
|
| Item | Count |
|
||
|
|
|------|-------|
|
||
|
|
| Composed config files | 3 |
|
||
|
|
| Entry point files | 1 |
|
||
|
|
| Documentation | 1 README + this guide |
|
||
|
|
| Lines of Nickel code | ~80 |
|
||
|
|
| Lines of documentation | ~400 |
|
||
|
|
|
||
|
|
## References
|
||
|
|
|
||
|
|
- **Platform Guide**: `schemas/platform/README.md`
|
||
|
|
- **Configs Details**: `schemas/platform/configs/README.md`
|
||
|
|
- **Defaults**: `schemas/platform/defaults/README.md`
|
||
|
|
- **Values**: `schemas/platform/values/README.md`
|
||
|
|
- **Templates**: `schemas/platform/templates/README.md`
|
||
|
|
- **Helpers**: `schemas/platform/common/helpers.ncl`
|
||
|
|
|
||
|
|
## Next Steps
|
||
|
|
|
||
|
|
1. **Create Jinja2 templates** for output formats:
|
||
|
|
- `templates/configs/{toml,yaml,json}.j2`
|
||
|
|
- `templates/kubernetes/{deployment,configmap,service}.yaml.j2`
|
||
|
|
- `templates/docker-compose/docker-compose.yaml.j2`
|
||
|
|
|
||
|
|
2. **Test composition** with real exports:
|
||
|
|
```bash
|
||
|
|
nickel export schemas/platform/configs/vapora-solo.ncl
|
||
|
|
```
|
||
|
|
|
||
|
|
3. **Integrate** with deployment pipeline:
|
||
|
|
- Add validation steps
|
||
|
|
- Generate outputs for each mode
|
||
|
|
- Deploy via docker-compose or Kubernetes
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
**Status**: ✅ Complete
|
||
|
|
**Ready for**: JSON export, template rendering, deployment
|
||
|
|
**Date**: January 12, 2026
|