Configuration Patterns Skill
Hard Guardrails for configuration management in this repository. Reference:
docs/adr/adr-003-version-management.md
Architecture Overview
code
┌──────────────────────────────────────────────────────────────────┐ │ USER ENVIRONMENT │ ├──────────────────────────────────────────────────────────────────┤ │ direnv (.envrc) │ │ └── `use flake` → Automatic environment activation │ ├──────────────────────────────────────────────────────────────────┤ │ Nix Flake (flake.nix) Pixi (pixi.toml) │ │ ├── System packages (git, helix) ├── ROS2 Humble │ │ ├── Development tools (cargo, gcc) ├── Python packages │ │ ├── LSP servers (pyright, nil) ├── Node.js │ │ └── Home-manager modules └── Conda ecosystem │ ├──────────────────────────────────────────────────────────────────┤ │ Home-manager Modules (modules/) │ │ ├── common/ Cross-platform (shells, editor, direnv) │ │ ├── linux/ Linux-specific (systemd, docker, udev) │ │ └── macos/ macOS-specific (homebrew, system.nix) │ ├──────────────────────────────────────────────────────────────────┤ │ DevPod (.devcontainer/devcontainer.json) │ │ └── Remote development with Nix + volume caching │ └──────────────────────────────────────────────────────────────────┘
Hard Guardrails
MUST USE
| Tool | File | Purpose |
|---|---|---|
| Nix flakes | flake.nix | System packages, dev shells |
| Pixi | pixi.toml | ROS2, Python, conda packages |
| direnv | .envrc | Auto-activate use flake |
| Home-manager | modules/ | User configuration |
| Lock files | *.lock | Reproducibility |
MUST NOT USE
| Tool | File | Violation |
|---|---|---|
| mise/rtx | .mise.toml, .tool-versions | Redundant with Nix + Pixi |
| asdf | .asdfrc | Superseded by mise, which is superseded by Nix |
| 0install | *.0install.xml | Conflicts with Nix store |
| pyenv | .python-version | Use pixi.toml Python version |
| nvm | .nvmrc | Use pixi.toml or flake.nix Node.js |
| Symlinks | * (type=symlink) | Causes Git/Windows/tooling issues |
Symlink Warning
Nix and Home-manager use symlinks by design:
- •
~/.config/*→/nix/store/...-home-manager-files/... - •
~/.nix-profile→/nix/var/nix/profiles/...
If symlinks are unacceptable:
- •For project configs: Use actual files, not symlinks
- •For user dotfiles: Consider chezmoi instead of Home-manager
- •For Nix itself: No alternative - Nix fundamentally uses symlinks
Responsibility Matrix
| Category | Primary Tool | File Location |
|---|---|---|
| System CLI tools | Nix | flake.nix |
| Development shells | Nix devshell | flake.nix |
| ROS2 packages | Pixi + RoboStack | pixi.toml |
| Python packages | Pixi + conda-forge | pixi.toml |
| Node.js runtime | Pixi or Nix | pixi.toml or flake.nix |
| Rust toolchain | Nix | flake.nix |
| Shell configuration | Home-manager | modules/common/shell/ |
| Editor configuration | Home-manager | modules/common/editor/ |
| Docker images | DevContainer | .devcontainer/ |
Validation Commands
bash
# Validate configuration policies
conftest test . --policy .claude/policies/configuration.rego
# Check for forbidden files
ls .tool-versions .mise.toml .asdfrc 2>/dev/null && echo "VIOLATION!" || echo "OK"
# Verify direnv integration
grep -q "use flake" .envrc && echo "OK" || echo "VIOLATION: .envrc missing 'use flake'"
# Verify lock files exist
[[ -f flake.lock && -f pixi.lock ]] && echo "OK" || echo "VIOLATION: Missing lock files"
# Verify Home-manager module structure
find modules/ -name "*.nix" -exec grep -L "lib\|mkDefault\|mkOption" {} \;
When to Consider Alternatives
chezmoi (Dotfile Management)
Consider When:
- •Users need portable dotfiles across non-Nix systems
- •Template-heavy per-user configuration is needed
- •1Password/pass secret integration required
Do NOT Use For:
- •Project configuration (use
flake.nix) - •Development shells (use devshell)
- •Package management (use Nix/Pixi)
mise (Runtime Version Manager)
Consider When:
- •Non-Nix users need quick onboarding
- •Runtime version switching during active development
- •CI environments without Nix available
Do NOT Use For:
- •ROS2 packages (no RoboStack equivalent)
- •Reproducible builds (less rigorous than Nix)
- •Primary development workflow
Decision Tree
code
Need to manage configuration? ├── Project-level packages → Nix (flake.nix) or Pixi (pixi.toml) ├── Project-level shells → Nix devshell ├── User-level dotfiles? │ ├── Nix system available → Home-manager │ └── Portable/non-Nix → chezmoi ├── Runtime version switching? │ ├── Reproducibility critical → Nix + pixi environments │ └── Quick switching needed → mise (fallback only) └── Remote development → DevPod with .devcontainer/
Module Patterns
Home-manager Module Template
nix
# modules/common/example.nix
{ config, lib, pkgs, ... }:
let
inherit (lib) mkDefault mkOption types;
in
{
options.example = {
enable = mkOption {
type = types.bool;
default = true;
description = "Enable example configuration";
};
};
config = lib.mkIf config.example.enable {
# Configuration here
};
}
direnv stdlib Extensions
bash
# In modules/common/direnv.nix → programs.direnv.stdlib
# Enhanced use_flake with pixi integration
use_flake_pixi() {
use flake
if [[ -f pixi.toml ]]; then
eval "$(pixi shell-hook)"
fi
}
# ROS2 workspace layout
layout_ros2() {
export ROS_DOMAIN_ID=${ROS_DOMAIN_ID:-0}
if [[ -f install/local_setup.bash ]]; then
source install/local_setup.bash
fi
}
DevContainer Requirements
json
{
"name": "project-name",
"features": {
"ghcr.io/devcontainers/features/nix:1": {
"extraNixConfig": "experimental-features = nix-command flakes"
}
},
"mounts": [
"source=nix-store,target=/nix,type=volume"
],
"postCreateCommand": "direnv allow && nix develop"
}
Enforcement Integration
Pre-commit Hook
yaml
# .pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: config-policy-check
name: Configuration Policy Check
entry: conftest test --policy .claude/policies/configuration.rego
language: system
files: '(flake\.nix|pixi\.toml|\.envrc|modules/.*\.nix)$'
CI Workflow
yaml
# .github/workflows/config-check.yml
name: Configuration Policy Check
on:
push:
paths:
- 'flake.nix'
- 'pixi.toml'
- '.envrc'
- 'modules/**'
- '.devcontainer/**'
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check forbidden files
run: |
! ls .tool-versions .mise.toml .asdfrc 2>/dev/null
- name: Validate with conftest
run: |
conftest test . --policy .claude/policies/configuration.rego
Routing Command
code
@config - Route to Configuration Patterns validation
References
- •ADR-003:
docs/adr/adr-003-version-management.md - •Tooling Analysis:
docs/TOOLING-ANALYSIS.md - •OPA Policies:
.claude/policies/configuration.rego - •direnv config:
modules/common/direnv.nix