kogral/templates/examples/decision-example.md
Jesús Pérez 9ea04852a8
Some checks failed
Rust CI / Security Audit (push) Has been cancelled
Rust CI / Check + Test + Lint (nightly) (push) Has been cancelled
Rust CI / Check + Test + Lint (stable) (push) Has been cancelled
Nickel Type Check / Nickel Type Checking (push) Has been cancelled
chore: add schemas and just recipes
2026-01-23 16:12:50 +00:00

118 lines
3.1 KiB
Markdown

---
id: 660e8400-e29b-41d4-a716-446655440001
type: decision
title: Use Nickel for Configuration
created: 2026-01-15T09:00:00Z
modified: 2026-01-15T09:30:00Z
tags: ["architecture", "configuration", "nickel"]
status: accepted
relates_to:
- pattern-config-driven-design
supersedes:
- decision-use-toml-only
project: knowledge-base
context: |
We need a configuration system for the knowledge base that is:
- Type-safe at definition time
- Composable and reusable
- Validated before reaching Rust code
- Easy to understand and maintain
decision: |
Use Nickel (.ncl) as the primary configuration format, with TOML and JSON as fallbacks.
Pattern: Nickel → JSON → serde → Rust structs
This provides double validation: Nickel type checker + Rust serde.
consequences:
- Adds Nickel CLI as a dependency for config export
- Provides compile-time type safety for configurations
- Enables schema composition and inheritance
- Clear error messages with line numbers
- Users can still use TOML/JSON if Nickel not available
---
# Use Nickel for Configuration
## Status
Accepted
Supersedes: [[decision-use-toml-only]]
## Context
We need a configuration system for the knowledge base that is:
- Type-safe at definition time
- Composable and reusable
- Validated before reaching Rust code
- Easy to understand and maintain
Previous approach used TOML-only, which lacked compile-time validation and composition features.
## Decision
Use Nickel (.ncl) as the primary configuration format, with TOML and JSON as fallbacks.
**Pattern:** Nickel → JSON → serde → Rust structs
This provides double validation: Nickel type checker validates .ncl files, then Rust serde validates JSON.
**Implementation:**
- Define schemas in `schemas/*.ncl`
- Export via `nickel export --format json`
- Load JSON in Rust via serde
- Fall back to TOML/JSON if Nickel CLI unavailable
## Consequences
**Positive:**
- Type safety at configuration definition time
- Compile errors show exact line numbers in config files
- Schema composition enables inheritance and overrides
- Documentation built into schema (via `| doc "..."`)
- IDE support via Nickel LSP
- Still supports TOML/JSON for users without Nickel
**Negative:**
- Adds Nickel CLI as a build-time dependency
- Users need to learn Nickel syntax (though TOML/JSON still work)
- Extra build step (ncl → json) for Nickel users
**Neutral:**
- Config loading code needs to handle multiple formats
- Schemas must be maintained in Nickel (but provide documentation)
## Alternatives Considered
### Alternative 1: TOML Only
**Pros:**
- Simple, widely known format
- No additional dependencies
- Direct serde deserialization
**Cons:**
- No compile-time type checking
- No schema composition
- Errors only at runtime
- Limited validation
### Alternative 2: JSON Schema
**Pros:**
- Widely supported
- Validation before Rust code
- JSON Schema ecosystem
**Cons:**
- JSON Schema is verbose and complex
- Lacks composition features of Nickel
- Error messages not as clear
- Requires separate validation step
## References
- [[pattern-config-driven-design]]
- [Nickel Language](https://nickel-lang.org/)
- Implementation: `crates/kogral-core/src/config/`