nickel

plurigrid's avatarfrom plurigrid

Nickel configuration language with gradual typing, contracts, and dynamic sufficiency verification. Use for type-safe configs, transformation contracts, and validation pipelines.

⭐1stars🔀2forks📁View on GitHub🕐Updated Jan 9, 2026

When & Why to Use This Skill

This Claude skill integrates the Nickel configuration language, a powerful tool designed for creating type-safe, modular, and programmatically verifiable configurations. By combining gradual typing with functional contracts and dynamic sufficiency verification, it enables developers to build complex configuration pipelines that are both flexible and robust, preventing common runtime errors in infrastructure and application settings.

Use Cases

  • Type-Safe Configuration Design: Define complex settings using gradual typing to ensure structural correctness and catch errors before deployment.
  • Automated Validation Pipelines: Implement functional contracts to enforce business logic and technical constraints across configuration files.
  • Safe Configuration Refactoring: Utilize transformation contracts and dynamic sufficiency checks to refactor large-scale configurations without breaking downstream dependencies.
  • Multi-Format Exporting: Manage a single source of truth in Nickel and export validated, error-free configurations to JSON or YAML for various environments.
namenickel
descriptionNickel configuration language with gradual typing, contracts, and dynamic sufficiency verification. Use for type-safe configs, transformation contracts, and validation pipelines.
version1.0.0

Nickel Configuration Language

Gradual typing + contracts for configuration that composes correctly.

Dynamic Sufficiency

A Nickel config is dynamically sufficient when:

  1. Structural: Contract coverage is complete (all fields typed)
  2. Computational: Same outputs for all valid inputs
  3. Semantic: Olog types preserved through transformations
# Sufficiency levels (from dynamic_sufficiency.jl)
let SufficiencyLevel = [|
  'NOT_SUFFICIENT,           # Different behavior
  'WEAKLY_SUFFICIENT,        # Same structure, different labels  
  'COMPUTATIONALLY_SUFFICIENT,  # Same outputs
  'SEMANTICALLY_SUFFICIENT      # Same olog meaning
|]

Core Contracts

Import from workspace:

let contracts = import ".topos/nickel/contracts/transformation-contracts.ncl"

Available contracts:

  • TransformationPattern - rename/refactor operations
  • TransformationStrategy - checkpoint + rollback + validation
  • BalancedTernarySelector - GF(3) strategy selection (seed 1069)
  • ValidationResult - gate pass/fail with exit codes

Gradual Typing Pattern

# Untyped (dynamic) - simple configs
{ name = "example", count = 42 }

# Typed block - contract enforcement
let typed_config : { name: String, count: Number } = 
  { name = "example", count = 42 }

# Contract annotation - runtime validation
let validated = config | TransformationStrategy

Idempotent Contracts

# Good: applying twice yields same result
let Positive = std.contract.from_predicate (fun x => x > 0)
5 | Positive | Positive  # ✓ idempotent

# Key property for dynamic sufficiency:
# ∀c: Contract, ∀x: (x | c) | c ≡ x | c

Workspace Integration

Path Purpose
.topos/nickel/contracts/ Reusable contract library
.topos/nickel/examples/ Transformation examples
environment-specs/environments.ncl Flox env specs
seth-rs/nickel/ Pipeline + telemetry modules

CLI Usage

# Evaluate config
nickel eval config.ncl

# Type-check without eval
nickel typecheck config.ncl

# Export to JSON
nickel export config.ncl --format json

# REPL
nickel repl

GF(3) Integration

Trit: 0 (ERGODIC - synthesis/validation)
Home: Prof
Poly Op: ⊗
Color: #FFFF00

Triadic pairing:

  • dune-analytics (+1) - expanding/querying
  • nickel (0) - contract validation
  • sicp (-1) - foundational evaluation

Dynamic Sufficiency Verification

# Verify sufficiency between two configs
let verify_sufficiency = fun cfg1 cfg2 =>
  let fields1 = std.record.fields cfg1 in
  let fields2 = std.record.fields cfg2 in
  if std.array.all (fun f => std.array.elem f fields2) fields1
  then 'COMPUTATIONALLY_SUFFICIENT
  else 'NOT_SUFFICIENT