AgentSkillsCN

configuration-patterns

强制Nix + Pixi + direnv + Home-manager配置模式

SKILL.md
--- frontmatter
name: configuration-patterns
description: Enforce Nix + Pixi + direnv + Home-manager configuration patterns
icon: "shield"
category: infrastructure
tools:
  - conftest
  - nix
  - pixi
  - direnv

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

ToolFilePurpose
Nix flakesflake.nixSystem packages, dev shells
Pixipixi.tomlROS2, Python, conda packages
direnv.envrcAuto-activate use flake
Home-managermodules/User configuration
Lock files*.lockReproducibility

MUST NOT USE

ToolFileViolation
mise/rtx.mise.toml, .tool-versionsRedundant with Nix + Pixi
asdf.asdfrcSuperseded by mise, which is superseded by Nix
0install*.0install.xmlConflicts with Nix store
pyenv.python-versionUse pixi.toml Python version
nvm.nvmrcUse 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

CategoryPrimary ToolFile Location
System CLI toolsNixflake.nix
Development shellsNix devshellflake.nix
ROS2 packagesPixi + RoboStackpixi.toml
Python packagesPixi + conda-forgepixi.toml
Node.js runtimePixi or Nixpixi.toml or flake.nix
Rust toolchainNixflake.nix
Shell configurationHome-managermodules/common/shell/
Editor configurationHome-managermodules/common/editor/
Docker imagesDevContainer.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