Commit f16497f5f43c

Vincent Demeester <vincent@sbr.pm>
2025-12-04 16:54:38
feat: Add comprehensive workflows to Nix skill
- Provide detailed guidance for 8 core Nix operations - Enable quick reference for building, debugging, and deploying - Support development shells with direnv integration - Include package creation, flakes management, and secrets handling - Add comprehensive troubleshooting guide for common errors - Improve workflow routing with trigger-based dispatch table Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Vincent Demeester <vincent@sbr.pm>
1 parent 6036833
dots/.config/claude/skills/Nix/workflows/Build.md
@@ -0,0 +1,527 @@
+# Build Workflow
+
+Build Nix packages, NixOS configurations, and understand the build process.
+
+## When to Use
+
+- "build nix package"
+- "build nixos configuration"
+- "nix build"
+- "compile nix expression"
+
+## Quick Commands
+
+### Building Packages
+```bash
+# Build package from flake
+nix build .#package-name
+
+# Build and create result symlink
+nix build .#package-name -o result
+
+# Build specific output
+nix build .#package-name.out
+
+# Build without creating result symlink
+nix build .#package-name --no-link
+
+# Show build logs
+nix build .#package-name -L
+nix build .#package-name --print-build-logs
+```
+
+### Building NixOS Configurations
+```bash
+# Build NixOS configuration
+nixos-rebuild build --flake .#hostname
+
+# Build without switching
+nix build .#nixosConfigurations.hostname.config.system.build.toplevel
+
+# Dry build (show what would change)
+nixos-rebuild dry-build --flake .#hostname
+
+# Build with verbose output
+nixos-rebuild build --flake .#hostname --show-trace
+```
+
+### Building for Different Systems
+```bash
+# Build for different architecture
+nix build .#package-name --system x86_64-linux
+nix build .#package-name --system aarch64-linux
+
+# Cross-compile
+nix build .#package-name.pkgsCross.aarch64-multiplatform
+```
+
+## Understanding Build Process
+
+### Build Phases
+```
+Nix build phases (for stdenv.mkDerivation):
+1. unpackPhase    - Extract source
+2. patchPhase     - Apply patches
+3. configurePhase - Run ./configure
+4. buildPhase     - Run make
+5. checkPhase     - Run tests
+6. installPhase   - Install to output
+7. fixupPhase     - Fix up outputs
+```
+
+### Viewing Build Steps
+```bash
+# Show derivation
+nix show-derivation .#package-name
+
+# Show build script
+nix develop .#package-name --command cat $(type -p genericBuild)
+
+# Build with debug output
+nix build .#package-name --debug
+```
+
+## Building Packages
+
+### From Flake
+```bash
+# Build package
+nix build .#mypackage
+
+# Build and run
+nix run .#mypackage
+
+# Build all packages
+nix build .#packages.x86_64-linux.mypackage
+```
+
+### From nixpkgs
+```bash
+# Build package from nixpkgs
+nix build nixpkgs#firefox
+
+# Build specific version
+nix build github:nixos/nixpkgs/nixos-23.11#firefox
+```
+
+### Build Local Package
+```bash
+# Build package in current directory
+nix build
+
+# Build with specific expression
+nix build -f default.nix
+
+# Build attribute
+nix build -f . mypackage
+```
+
+## Building NixOS Systems
+
+### Local System
+```bash
+# Build current system configuration
+sudo nixos-rebuild build --flake .
+
+# Build specific host
+nixos-rebuild build --flake .#hostname
+
+# Build and show what will change
+nixos-rebuild dry-build --flake .#hostname
+```
+
+### Remote System
+```bash
+# Build for remote host
+nixos-rebuild build --flake .#remote-host \
+  --target-host user@remote-host \
+  --use-remote-sudo
+
+# Build locally for remote deployment
+nix build .#nixosConfigurations.remote-host.config.system.build.toplevel
+```
+
+### Build VM
+```bash
+# Build VM from configuration
+nixos-rebuild build-vm --flake .#hostname
+
+# Run the VM
+./result/bin/run-*-vm
+```
+
+## Build Options
+
+### Parallel Builds
+```bash
+# Build with more cores
+nix build .#package --cores 8
+
+# Limit parallel jobs
+nix build .#package --max-jobs 4
+```
+
+### Offline Mode
+```bash
+# Build without network access
+nix build .#package --offline
+
+# Use only local cache
+nix build .#package --no-net
+```
+
+### Rebuild Everything
+```bash
+# Force rebuild (ignore cache)
+nix build .#package --rebuild
+
+# Build from source (no binary cache)
+nix build .#package --no-substitute
+```
+
+## Build Outputs
+
+### Multiple Outputs
+```bash
+# Packages can have multiple outputs
+# Common: out, dev, doc, lib
+
+# Build specific output
+nix build .#package.dev    # Development files
+nix build .#package.doc    # Documentation
+nix build .#package.lib    # Libraries only
+
+# View all outputs
+nix show-derivation .#package | jq '.[] | .outputs'
+```
+
+### Inspect Build Result
+```bash
+# After building, result symlink created
+ls -l result/
+
+# View store path
+readlink result
+
+# Inspect contents
+tree result/
+
+# Check dependencies
+nix-store -q --references result
+nix-store -q --requisites result
+```
+
+## Build Caching
+
+### Using Binary Caches
+```bash
+# Add binary cache
+nix build .#package \
+  --extra-substituters https://cache.nixos.org \
+  --extra-trusted-public-keys cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=
+
+# Use cachix
+cachix use mycache
+nix build .#package
+```
+
+### Push to Cache
+```bash
+# Push to cachix
+nix build .#package
+cachix push mycache result
+
+# Push with nix copy
+nix copy --to https://cache.example.com result
+```
+
+## Build for Development
+
+### Enter Build Environment
+```bash
+# Enter environment for building
+nix develop .#package
+
+# Build manually
+unpackPhase
+cd $sourceRoot
+configurePhase
+buildPhase
+```
+
+### Iterative Building
+```bash
+# Build and keep build directory
+nix build .#package --keep-failed
+
+# Failed build directory preserved at:
+# /tmp/nix-build-package-*.drv-0/
+
+# Inspect failed build
+cd /tmp/nix-build-*
+```
+
+## Repository-Specific Builds
+
+### Home Repository
+```bash
+# Build current system
+make switch
+
+# Build without switching
+make dry-build
+
+# Build specific host
+make host/hostname/build
+
+# Build all packages
+nix build .#packages.x86_64-linux --all
+```
+
+### Build Custom Package
+```bash
+# Package in pkgs/mypackage/
+nix build .#mypackage
+
+# Test package
+nix build .#mypackage -L
+
+# Install locally
+nix profile install .#mypackage
+```
+
+## Debugging Builds
+
+### Verbose Output
+```bash
+# Show all build output
+nix build .#package -L
+
+# Show evaluation trace
+nix build .#package --show-trace
+
+# Maximum verbosity
+nix build .#package -vvv --show-trace
+```
+
+### Build Failures
+```bash
+# Keep failed build directory
+nix build .#package --keep-failed
+
+# Keep successful build directory too
+nix build .#package --keep-going
+
+# Inspect build directory
+cd /tmp/nix-build-*
+ls -la
+cat build.log
+```
+
+### Interactive Debugging
+```bash
+# Enter build environment
+nix develop .#package
+
+# Run build phases manually
+genericBuild
+# Or individual phases:
+unpackPhase
+patchPhase
+configurePhase
+buildPhase
+```
+
+## Build Performance
+
+### Speed Up Builds
+```bash
+# Use more cores
+nix build .#package --cores $(nproc)
+
+# Use binary caches
+nix build .#package --substituters https://cache.nixos.org
+
+# Parallel jobs
+nix build .#package --max-jobs auto
+```
+
+### Monitor Build Progress
+```bash
+# Real-time build logs
+nix build .#package -L
+
+# Follow log file
+tail -f /tmp/nix-build-*.log
+
+# Show build statistics
+nix build .#package --print-build-logs | ts
+```
+
+## Cross-Compilation
+
+### Build for ARM
+```bash
+# ARM 64-bit
+nix build .#package --system aarch64-linux
+
+# ARM 32-bit
+nix build .#package --system armv7l-linux
+
+# Using pkgsCross
+nix build .#package.pkgsCross.aarch64-multiplatform
+```
+
+### Build for Different Platform
+```bash
+# Build for Raspberry Pi
+nix build .#nixosConfigurations.rpi4-host.config.system.build.sdImage
+
+# Build for different NixOS version
+nix build github:nixos/nixpkgs/nixos-23.11#package
+```
+
+## Advanced Build Techniques
+
+### Override Package Attributes
+```bash
+# Override during build
+nix build --impure --expr '
+  (import <nixpkgs> {}).mypackage.overrideAttrs (old: {
+    version = "custom";
+  })
+'
+```
+
+### Build from Git
+```bash
+# Build from specific commit
+nix build github:owner/repo/commit-hash#package
+
+# Build from branch
+nix build github:owner/repo/branch-name#package
+
+# Build from local git
+nix build git+file:///path/to/repo#package
+```
+
+### Conditional Builds
+```bash
+# Build only if changed
+nix build .#package --rebuild
+
+# Build with different features
+nix build .#package --arg enableFeature true
+```
+
+## Build Artifacts
+
+### Store Paths
+```bash
+# Show store path without building
+nix eval .#package
+
+# Show closure size
+nix path-info -S .#package
+
+# Show all dependencies
+nix-store -qR result
+
+# Show why package is kept
+nix-store --query --roots result
+```
+
+### Build Logs
+```bash
+# View previous build log
+nix log .#package
+
+# View log of store path
+nix log /nix/store/...-package
+
+# Save build log
+nix build .#package -L 2>&1 | tee build.log
+```
+
+## Build Best Practices
+
+1. **Use binary caches**: Avoid rebuilding common packages
+2. **Pin versions**: Use flake.lock for reproducibility
+3. **Test locally first**: Build before deploying
+4. **Keep build logs**: Debug failures with `-L` flag
+5. **Use `--dry-build`**: Preview changes before building
+6. **Check closures**: Understand dependencies with `nix path-info`
+7. **Incremental builds**: Use `nix develop` for iteration
+8. **Parallel builds**: Utilize `--cores` and `--max-jobs`
+
+## Common Build Patterns
+
+### Build and Test
+```bash
+# Build package
+nix build .#mypackage -L
+
+# Run tests
+nix build .#mypackage.tests
+
+# Build and run
+nix run .#mypackage
+```
+
+### Build Multiple Outputs
+```bash
+# Build all outputs
+nix build .#package.all
+
+# Build specific combinations
+nix build .#package.out .#package.dev
+```
+
+### Build with Local Changes
+```bash
+# Build with local modifications
+nix build .#package --override-input nixpkgs path:/local/nixpkgs
+
+# Build with local flake
+nix build path:/local/repo#package
+```
+
+## Troubleshooting Builds
+
+### Hash Mismatches
+```bash
+# Update hash
+# 1. Set hash to lib.fakeSha256 or empty string
+# 2. Build to get error with correct hash
+nix build .#package 2>&1 | grep "got:"
+
+# For fetchFromGitHub
+nix-prefetch-github owner repo --rev commit-hash
+```
+
+### Disk Space Issues
+```bash
+# Clean old build artifacts
+nix-collect-garbage -d
+
+# Check store size
+du -sh /nix/store
+
+# Remove specific paths
+nix-store --delete /nix/store/...-package
+```
+
+### Permission Errors
+```bash
+# Build as root
+sudo nix build .#package
+
+# Build with different user
+sudo -u builder nix build .#package
+```
+
+## Resources
+
+- [Nix Build Manual](https://nixos.org/manual/nix/stable/command-ref/nix-build.html)
+- [NixOS Rebuild](https://nixos.org/manual/nixos/stable/#sec-changing-config)
+- [Nix Package Stdenv](https://nixos.org/manual/nixpkgs/stable/#chap-stdenv)
dots/.config/claude/skills/Nix/workflows/Debug.md
@@ -0,0 +1,591 @@
+# Debug Workflow
+
+Debug Nix expressions, evaluation errors, and build failures.
+
+## When to Use
+
+- "debug nix expression"
+- "nix evaluation error"
+- "troubleshoot nix build"
+- "nix error messages"
+
+## Quick Commands
+
+### Evaluation Debugging
+```bash
+# Show evaluation trace
+nix eval .#package --show-trace
+
+# Evaluate with verbosity
+nix eval .#package -vvv
+
+# Show derivation
+nix show-derivation .#package
+
+# Inspect attribute path
+nix eval .#nixosConfigurations.hostname.config.services
+```
+
+### Build Debugging
+```bash
+# Build with full logs
+nix build .#package -L
+nix build .#package --print-build-logs
+
+# Keep failed build directory
+nix build .#package --keep-failed
+
+# Show trace on error
+nix build .#package --show-trace
+
+# Maximum verbosity
+nix build .#package -vvv --show-trace -L
+```
+
+### Interactive Debugging
+```bash
+# Enter build environment
+nix develop .#package
+
+# Enter failed build directory
+cd /tmp/nix-build-*
+
+# Run phases manually
+unpackPhase
+patchPhase
+configurePhase
+buildPhase
+```
+
+## Understanding Error Messages
+
+### Infinite Recursion
+```
+error: infinite recursion encountered
+```
+
+**Cause**: Circular dependency or self-referencing attribute
+
+**Debug**:
+```nix
+# Problem
+{
+  x = y;
+  y = x;  # Infinite recursion!
+}
+
+# Fix: Break the cycle
+{
+  x = lib.mkDefault value;
+  y = config.x;
+}
+```
+
+### Attribute Not Found
+```
+error: attribute 'foo' missing
+```
+
+**Debug**:
+```bash
+# Check what attributes exist
+nix eval .#nixosConfigurations.hostname --apply builtins.attrNames
+
+# Check nested attributes
+nix eval .#nixosConfigurations.hostname.config --apply "x: builtins.attrNames x.services"
+
+# Use --show-trace to see where error originates
+nix eval .#package --show-trace
+```
+
+### Type Errors
+```
+error: value is a set while a string was expected
+```
+
+**Debug**:
+```bash
+# Check type of value
+nix eval .#value --apply builtins.typeOf
+
+# Print value for inspection
+nix eval .#value --apply "x: builtins.trace x x"
+
+# Show detailed type error
+nix eval .#value --show-trace
+```
+
+### Hash Mismatches
+```
+error: hash mismatch in fixed-output derivation
+  got:    sha256-AAAA...
+  wanted: sha256-BBBB...
+```
+
+**Fix**:
+```bash
+# Copy the "got" hash to your expression
+# Or use nix-prefetch for correct hash
+nix-prefetch-url https://example.com/file.tar.gz
+nix-prefetch-github owner repo --rev commit-hash
+```
+
+## Debugging Techniques
+
+### Trace Values
+```nix
+# Simple trace
+value = builtins.trace "Debug: ${toString someValue}" someValue;
+
+# Trace with lib
+value = lib.traceVal someValue;
+value = lib.traceValSeq "message" someValue;
+
+# Trace attribute names
+value = lib.traceSeq (builtins.attrNames attrs) attrs;
+
+# Deep trace
+value = lib.traceValSeqN 3 someNestedValue;
+```
+
+### Evaluate Expressions
+```bash
+# Evaluate simple expression
+nix eval --expr '1 + 1'
+
+# Evaluate with nixpkgs
+nix eval --expr 'with import <nixpkgs> {}; lib.version'
+
+# Evaluate flake attribute
+nix eval .#nixosConfigurations.hostname.config.networking.hostName
+
+# Evaluate and show as JSON
+nix eval .#package --json
+
+# Evaluate and show as XML
+nix eval .#package --xml
+```
+
+### Check Configuration
+```bash
+# Check NixOS configuration validity
+nixos-rebuild build --flake .#hostname --dry-run
+
+# Show configuration options
+nix eval .#nixosConfigurations.hostname.options
+
+# Check if option exists
+nix eval .#nixosConfigurations.hostname.options.services.nginx.enable.defined
+
+# Show option documentation
+nixos-option services.nginx.enable
+```
+
+## Debugging Build Failures
+
+### Inspect Build Environment
+```bash
+# Enter build environment
+nix develop .#package
+
+# Check environment variables
+env | grep -i nix
+printenv
+
+# Check build tools available
+which gcc make cmake
+
+# Check paths
+echo $PATH
+echo $PKG_CONFIG_PATH
+```
+
+### Manual Build Steps
+```bash
+# Enter development shell
+nix develop .#package
+
+# Run phases manually
+unpackPhase
+ls -la
+
+cd $sourceRoot
+patchPhase
+
+configurePhase
+# Fix any configuration issues
+
+buildPhase
+# Fix build errors
+
+checkPhase
+installPhase
+```
+
+### Inspect Failed Build
+```bash
+# Build with --keep-failed
+nix build .#package --keep-failed
+
+# Failed build kept at:
+cd /tmp/nix-build-package-*.drv-0/
+
+# Examine source
+ls -la
+find . -type f -name "*.log"
+
+# Check build log
+cat build.log
+
+# Re-run failed command manually
+./configure
+make
+```
+
+### Debug Build Script
+```bash
+# Show builder script
+nix show-derivation .#package | jq '.[].env.builder'
+
+# Show full derivation
+nix derivation show .#package
+
+# Print build environment
+nix develop .#package --command printenv
+```
+
+## Debugging Evaluation Errors
+
+### Stack Traces
+```bash
+# Show full stack trace
+nix eval .#package --show-trace
+
+# Example output:
+# error: undefined variable 'foo'
+#
+#        at /path/to/file.nix:42:5:
+#           41|   bar = {
+#           42|     baz = foo;
+#              |           ^
+#           43|   };
+```
+
+### Find Definition Location
+```bash
+# Find where option is defined
+nix eval .#nixosConfigurations.hostname.options.services.nginx.enable.definitionsWithLocations
+
+# Find where value is set
+nix eval .#nixosConfigurations.hostname.options.services.nginx.enable.files
+```
+
+### Check Module Evaluation
+```bash
+# Evaluate specific module
+nix eval -f ./module.nix
+
+# Check module with config
+nix eval --expr 'import ./module.nix { lib = import <nixpkgs/lib>; }'
+
+# Show module errors
+nix-instantiate --eval --strict ./module.nix
+```
+
+## Debugging Package Builds
+
+### Check Dependencies
+```bash
+# Show build dependencies
+nix-store -q --references $(nix-build -A package)
+
+# Show runtime dependencies
+nix-store -q --requisites $(nix-build -A package)
+
+# Show dependency tree
+nix-store -q --tree $(nix-build -A package)
+
+# Why is package kept?
+nix-store --query --roots $(nix-build -A package)
+```
+
+### Missing Dependencies
+```bash
+# Check what's needed
+ldd result/bin/program
+
+# Patch with nix
+nix develop -c ldd ./program
+
+# Auto-patch with autoPatchelfHook
+nativeBuildInputs = [ autoPatchelfHook ];
+```
+
+### Wrong Version Built
+```bash
+# Check what will be built
+nix-build '<nixpkgs>' -A package --dry-run
+
+# Check version in store
+nix-store -q --hash $(nix-build -A package)
+
+# Force specific version
+nix build nixpkgs/nixos-23.11#package
+```
+
+## Debugging NixOS Configurations
+
+### Configuration Evaluation
+```bash
+# Build configuration
+nixos-rebuild build --flake .#hostname --show-trace
+
+# Dry build to see what changes
+nixos-rebuild dry-build --flake .#hostname
+
+# Evaluate specific option
+nix eval .#nixosConfigurations.hostname.config.system.stateVersion
+```
+
+### Module Conflicts
+```
+error: The option `services.foo.enable' is defined multiple times
+```
+
+**Debug**:
+```bash
+# Find all definitions
+nix eval .#nixosConfigurations.hostname.options.services.foo.enable.definitionsWithLocations
+
+# Check module imports
+nix eval .#nixosConfigurations.hostname.options._module.args --apply "x: builtins.attrNames x"
+```
+
+### Service Failures
+```bash
+# Check service status after deployment
+systemctl status servicename
+
+# Check service logs
+journalctl -u servicename -n 50
+
+# Check generated config
+systemctl cat servicename
+
+# Verify config file
+cat /etc/systemd/system/servicename.service
+```
+
+## Debugging Flakes
+
+### Flake Evaluation
+```bash
+# Check flake
+nix flake check
+
+# Show flake outputs
+nix flake show
+
+# Evaluate flake metadata
+nix flake metadata
+
+# Lock file issues
+nix flake lock --update-input nixpkgs
+```
+
+### Input Problems
+```bash
+# Check inputs
+nix flake metadata | grep -A 10 Inputs
+
+# Update specific input
+nix flake update nixpkgs
+
+# Show input derivation
+nix flake metadata --json | jq .locks
+```
+
+### Pure Evaluation Errors
+```
+error: access to absolute path '/home/...' is forbidden in pure eval mode
+```
+
+**Fix**:
+```nix
+# Don't use absolute paths
+# Bad
+path = /home/user/file.nix;
+
+# Good
+path = ./file.nix;
+
+# Or use --impure flag (not recommended)
+nix build --impure
+```
+
+## Advanced Debugging
+
+### Debug with nix repl
+```bash
+# Start repl
+nix repl
+
+# Load flake
+:lf .
+
+# Explore outputs
+outputs.packages.x86_64-linux
+
+# Load nixpkgs
+:l <nixpkgs>
+
+# Test expressions
+lib.version
+pkgs.hello
+
+# Tab completion works
+outputs.nixosConf[TAB]
+```
+
+### Profile Evaluation
+```bash
+# Time evaluation
+time nix eval .#package
+
+# Show evaluation statistics
+nix eval .#package --show-stats
+
+# Profile build
+nix build .#package --profile /tmp/profile
+```
+
+### Debug with breakpoints
+```nix
+# In your expression
+value = builtins.break (someExpression);
+
+# Build will pause, entering debugger
+# Commands:
+# :continue - Continue evaluation
+# :quit - Abort evaluation
+# :env - Show environment
+# :value - Show current value
+```
+
+## Common Debug Patterns
+
+### Print and Return
+```nix
+# Debug helper
+debug = msg: val: builtins.trace msg val;
+
+# Usage
+result = debug "Processing ${name}" (processValue value);
+```
+
+### Conditional Debugging
+```nix
+# Only debug when flag is set
+let
+  debugFlag = false;
+  debug = msg: val:
+    if debugFlag
+    then builtins.trace msg val
+    else val;
+in
+  debug "Value" someValue
+```
+
+### Assert Debugging
+```nix
+# Use assertions to catch errors early
+{ ... }:
+
+assert someCondition; {
+  # Your config
+}
+
+# Better with message
+{ lib, ... }:
+
+lib.assertMsg someCondition "Error: condition not met"
+```
+
+## Debugging Tools
+
+### nix-tree
+```bash
+# Install
+nix-shell -p nix-tree
+
+# Explore dependencies interactively
+nix-tree $(nix-build -A package)
+```
+
+### nix-diff
+```bash
+# Compare two derivations
+nix-diff $(nix-build -A package1) $(nix-build -A package2)
+```
+
+### nix-du
+```bash
+# Analyze disk usage
+nix-du -s=500MB
+
+# Show largest paths
+nix-du | head -20
+```
+
+## Debugging Best Practices
+
+1. **Use --show-trace**: Always show full stack traces
+2. **Keep failed builds**: Use `--keep-failed` to inspect
+3. **Enable verbose logs**: Use `-L` flag for build logs
+4. **Use nix repl**: Interactive exploration is powerful
+5. **Check documentation**: Many options have examples
+6. **Test in isolation**: Build packages separately
+7. **Use nix develop**: Debug in build environment
+8. **Check flake.lock**: Ensure inputs are correct
+
+## Emergency Debugging
+
+### System Won't Boot
+```bash
+# Boot to previous generation (at boot menu)
+# Or from rescue system:
+
+# Mount nixos
+mount /dev/sdX /mnt
+mount /dev/sdY /mnt/boot
+
+# Chroot
+nixos-enter
+
+# List generations
+nix-env --list-generations --profile /nix/var/nix/profiles/system
+
+# Rollback
+/nix/var/nix/profiles/system-42-link/bin/switch-to-configuration switch
+```
+
+### Out of Disk Space
+```bash
+# Clean old generations
+nix-collect-garbage -d
+
+# Delete specific generation
+nix-env --delete-generations 10 11 12
+
+# Optimize store
+nix-store --optimize
+
+# Find large paths
+du -sh /nix/store/* | sort -h | tail -20
+```
+
+## Resources
+
+- [Nix Manual - Debugging](https://nixos.org/manual/nix/stable/language/operators.html#debugging)
+- [NixOS Debugging Guide](https://nixos.wiki/wiki/Debugging)
+- [Nix Pills - Debugging](https://nixos.org/guides/nix-pills/debugging.html)
dots/.config/claude/skills/Nix/workflows/Deploy.md
@@ -0,0 +1,507 @@
+# Deploy Workflow
+
+Deploy NixOS configurations safely to local and remote systems.
+
+## When to Use
+
+- "deploy nixos"
+- "nixos-rebuild switch"
+- "deploy to remote host"
+- "update nixos system"
+
+## Quick Commands
+
+### Local Deployment
+```bash
+# Build and switch
+sudo nixos-rebuild switch --flake .
+
+# Build and switch specific host
+sudo nixos-rebuild switch --flake .#hostname
+
+# Test without adding to boot
+sudo nixos-rebuild test --flake .#hostname
+
+# Boot (activate on next reboot)
+sudo nixos-rebuild boot --flake .#hostname
+```
+
+### Remote Deployment
+```bash
+# Deploy to remote host
+nixos-rebuild switch --flake .#remote-host \
+  --target-host user@remote-host \
+  --use-remote-sudo
+
+# Build locally, deploy remotely
+nixos-rebuild switch --flake .#remote-host \
+  --target-host user@remote-host \
+  --build-host localhost
+```
+
+## Safety Protocols
+
+### ALWAYS Ask Before Deploying
+
+**CRITICAL**: Never deploy to remote hosts without explicit user approval.
+
+1. **Show changes first**: Use `git diff` or explain what will be deployed
+2. **Ask for approval**: Get explicit confirmation from user
+3. **Suggest dry-run**: Offer to test build first
+4. **Confirm target**: Make sure user wants to deploy to that specific host
+
+### Pre-Deployment Checks
+```bash
+# 1. Check for uncommitted changes
+git status
+
+# 2. Review what will change
+git diff
+
+# 3. Dry build to verify
+nixos-rebuild dry-build --flake .#hostname
+
+# 4. Build without switching
+nixos-rebuild build --flake .#hostname
+
+# 5. Check for warnings
+nixos-rebuild build --flake .#hostname 2>&1 | grep -i warn
+```
+
+## Local Deployment
+
+### Standard Deployment
+```bash
+# Build and switch
+sudo nixos-rebuild switch --flake .
+
+# With specific flake
+sudo nixos-rebuild switch --flake /path/to/config
+
+# Update flake inputs first
+nix flake update
+sudo nixos-rebuild switch --flake .
+```
+
+### Test Before Committing
+```bash
+# Test configuration without bootloader
+sudo nixos-rebuild test --flake .#hostname
+
+# Test and verify
+systemctl status service-name
+journalctl -u service-name
+
+# If good, make permanent
+sudo nixos-rebuild switch --flake .#hostname
+```
+
+### Boot-Only Deployment
+```bash
+# Activate on next reboot
+sudo nixos-rebuild boot --flake .#hostname
+
+# Reboot when convenient
+sudo reboot
+```
+
+## Remote Deployment
+
+### SSH Setup
+```bash
+# Ensure SSH access
+ssh user@remote-host
+
+# Copy SSH key if needed
+ssh-copy-id user@remote-host
+
+# Test sudo access
+ssh user@remote-host sudo echo OK
+```
+
+### Deploy to Remote
+```bash
+# Full remote deployment
+nixos-rebuild switch --flake .#remote-host \
+  --target-host user@remote-host \
+  --use-remote-sudo
+
+# Build locally, deploy remotely (faster)
+nixos-rebuild switch --flake .#remote-host \
+  --target-host user@remote-host \
+  --build-host localhost \
+  --use-remote-sudo
+```
+
+### Deploy Multiple Hosts
+```bash
+# Deploy to multiple hosts
+for host in host1 host2 host3; do
+  echo "Deploying to $host..."
+  nixos-rebuild switch --flake .#$host \
+    --target-host user@$host \
+    --use-remote-sudo
+done
+```
+
+## Repository-Specific Deployment
+
+### Using Makefile
+```bash
+# Local deployment
+make switch
+
+# Dry build
+make dry-build
+
+# Build without switching
+make build
+
+# Remote deployment (ALWAYS ASK USER FIRST!)
+make host/hostname/switch
+make host/hostname/boot
+make host/hostname/build
+```
+
+### Direct Commands
+```bash
+# Build current system
+sudo nixos-rebuild switch --flake .
+
+# Build specific host
+sudo nixos-rebuild switch --flake .#hostname
+
+# Remote deployment
+nixos-rebuild switch --flake .#hostname \
+  --target-host hostname \
+  --use-remote-sudo
+```
+
+## Deployment Strategies
+
+### Canary Deployment
+```bash
+# 1. Deploy to test host first
+nixos-rebuild switch --flake .#test-host \
+  --target-host test-host \
+  --use-remote-sudo
+
+# 2. Verify it works
+ssh test-host systemctl status critical-service
+
+# 3. If good, deploy to production
+# (ALWAYS ASK USER FIRST!)
+nixos-rebuild switch --flake .#prod-host \
+  --target-host prod-host \
+  --use-remote-sudo
+```
+
+### Rolling Deployment
+```bash
+# Deploy one host at a time
+hosts=(web1 web2 web3)
+
+for host in "${hosts[@]}"; do
+  echo "Deploying to $host..."
+
+  # Deploy
+  nixos-rebuild switch --flake .#$host \
+    --target-host $host \
+    --use-remote-sudo
+
+  # Verify
+  ssh $host systemctl is-active nginx || {
+    echo "ERROR: Deployment to $host failed!"
+    exit 1
+  }
+
+  # Wait before next
+  sleep 30
+done
+```
+
+### Blue-Green Deployment
+```bash
+# Deploy to blue environment
+nixos-rebuild boot --flake .#host-blue \
+  --target-host host-blue \
+  --use-remote-sudo
+
+# Test blue environment
+ssh host-blue 'sudo reboot'
+sleep 60
+# ... test blue ...
+
+# Switch traffic to blue
+# Update load balancer, DNS, etc.
+
+# Deploy to green later
+```
+
+## Rollback Procedures
+
+### Immediate Rollback
+```bash
+# List generations
+sudo nixos-rebuild list-generations
+
+# Rollback to previous
+sudo nixos-rebuild switch --rollback
+
+# Or specific generation
+sudo nixos-rebuild switch --switch-generation 42
+```
+
+### Remote Rollback
+```bash
+# Rollback remote host
+ssh user@remote-host \
+  'sudo nixos-rebuild switch --rollback'
+
+# Or specific generation
+ssh user@remote-host \
+  'sudo nixos-rebuild switch --switch-generation 42'
+```
+
+### Boot Menu Rollback
+```
+# At boot, select previous generation from bootloader menu
+# GRUB or systemd-boot will show all generations
+```
+
+## Monitoring Deployment
+
+### Watch Deployment Progress
+```bash
+# Deploy with verbose output
+sudo nixos-rebuild switch --flake .#hostname --show-trace
+
+# Monitor systemd services
+watch systemctl status
+
+# Monitor logs in another terminal
+journalctl -f
+```
+
+### Verify Deployment
+```bash
+# Check system version
+nixos-version
+
+# Check active generation
+readlink /run/current-system
+
+# Check services
+systemctl --failed
+
+# Check recent journal
+journalctl -p err -b
+```
+
+## Deployment Best Practices
+
+1. **Always test locally first**: Build and test before remote deployment
+2. **Use dry-build**: Preview changes with `dry-build`
+3. **Commit before deploying**: Ensure configuration is tracked
+4. **Deploy during low traffic**: Minimize user impact
+5. **Monitor after deployment**: Check logs and services
+6. **Keep previous generation**: Don't delete immediately
+7. **Test rollback procedure**: Know how to revert
+8. **Document changes**: Note what was deployed and why
+9. **Use boot for risky changes**: Can revert at boot menu
+10. **Ask before remote deployment**: ALWAYS get user approval
+
+## Common Deployment Patterns
+
+### Update and Deploy
+```bash
+# Update flake inputs
+nix flake update
+
+# Review changes
+git diff flake.lock
+
+# Commit update
+git add flake.lock
+git commit -m "chore: update flake inputs"
+
+# Deploy
+sudo nixos-rebuild switch --flake .
+```
+
+### Staged Deployment
+```bash
+# 1. Build configuration
+nixos-rebuild build --flake .#hostname
+
+# 2. Review changes
+nix-diff /run/current-system ./result
+
+# 3. If good, switch
+sudo nixos-rebuild switch --flake .#hostname
+```
+
+### Emergency Deploy
+```bash
+# For urgent fixes, can skip dry-build
+# But still test first!
+
+# Quick build and test
+sudo nixos-rebuild test --flake .#hostname
+
+# If urgent and working
+sudo nixos-rebuild switch --flake .#hostname
+
+# Monitor closely
+journalctl -f
+```
+
+## Troubleshooting Deployments
+
+### Build Failures
+```bash
+# Build fails during deployment
+sudo nixos-rebuild switch --flake .#hostname --show-trace
+
+# Check build logs
+journalctl -u nixos-rebuild -n 100
+
+# Fix configuration
+vim configuration.nix
+
+# Try again
+sudo nixos-rebuild switch --flake .
+```
+
+### Service Failures After Deploy
+```bash
+# Check failed services
+systemctl --failed
+
+# Check service status
+systemctl status service-name
+
+# View logs
+journalctl -u service-name -n 50
+
+# If broken, rollback
+sudo nixos-rebuild switch --rollback
+```
+
+### SSH Connection Lost
+```bash
+# If remote deployment loses connection
+# Wait for deployment to complete
+# Or connect via console/IPMI
+
+# Check if system is accessible
+ping remote-host
+
+# Try to reconnect
+ssh user@remote-host
+
+# If accessible, check status
+ssh user@remote-host systemctl status
+```
+
+### Disk Space Issues
+```bash
+# Clean old generations before deploying
+sudo nix-collect-garbage -d
+
+# Optimize store
+sudo nix-store --optimize
+
+# Check space
+df -h /nix
+```
+
+## Automation
+
+### Automated Deployment Script
+```bash
+#!/usr/bin/env bash
+set -euo pipefail
+
+HOST=$1
+
+echo "Deploying to $HOST..."
+
+# Build configuration
+echo "Building..."
+nixos-rebuild build --flake .#$HOST
+
+# Ask for confirmation
+read -p "Deploy to $HOST? [y/N] " -n 1 -r
+echo
+if [[ ! $REPLY =~ ^[Yy]$ ]]; then
+    echo "Deployment cancelled"
+    exit 1
+fi
+
+# Deploy
+echo "Deploying..."
+nixos-rebuild switch --flake .#$HOST \
+  --target-host $HOST \
+  --use-remote-sudo
+
+# Verify
+echo "Verifying..."
+ssh $HOST systemctl is-system-running --wait
+
+echo "Deployment complete!"
+```
+
+### CI/CD Integration
+```bash
+# Example GitHub Actions workflow
+# .github/workflows/deploy.yml
+
+name: Deploy
+on:
+  push:
+    branches: [main]
+
+jobs:
+  deploy:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3
+      - uses: cachix/install-nix-action@v20
+
+      # Build only, don't deploy automatically
+      - name: Build configuration
+        run: nix build .#nixosConfigurations.hostname.config.system.build.toplevel
+
+      # Manual deployment approval required
+```
+
+## Security Considerations
+
+### Secrets in Deployment
+```bash
+# Never deploy with secrets in plain text
+# Use agenix for secrets management
+
+# Secrets are deployed encrypted
+# Decrypted at activation time
+```
+
+### Deployment Authentication
+```bash
+# Use SSH keys, not passwords
+ssh-keygen -t ed25519
+
+# Add to remote host
+ssh-copy-id user@remote-host
+
+# Restrict sudo if needed
+# In /etc/sudoers.d/nixos-rebuild:
+# user ALL=(ALL) NOPASSWD: /run/current-system/sw/bin/nixos-rebuild
+```
+
+## Resources
+
+- [NixOS Deployment](https://nixos.org/manual/nixos/stable/#sec-changing-config)
+- [nixos-rebuild Manual](https://nixos.org/manual/nixos/stable/index.html#sec-nixos-rebuild)
+- [Remote Deployment](https://nixos.wiki/wiki/Nixos-rebuild)
dots/.config/claude/skills/Nix/workflows/Develop.md
@@ -0,0 +1,626 @@
+# Develop Workflow
+
+Create and use Nix development environments with direnv integration.
+
+## When to Use
+
+- "nix development shell"
+- "nix develop"
+- "development environment"
+- "direnv with nix"
+
+## Quick Commands
+
+### Development Shells
+```bash
+# Enter development shell
+nix develop
+
+# Enter shell for specific package
+nix develop .#package-name
+
+# Run command in shell
+nix develop -c make build
+nix develop --command npm test
+
+# Print shell environment
+nix develop --print-build-logs
+```
+
+### direnv Integration
+```bash
+# Create .envrc
+echo "use flake" > .envrc
+
+# Allow direnv
+direnv allow
+
+# Reload environment
+direnv reload
+
+# Check status
+direnv status
+```
+
+## Creating Development Shells
+
+### Basic devShell
+```nix
+# flake.nix
+{
+  outputs = { self, nixpkgs }: {
+    devShells.x86_64-linux.default = let
+      pkgs = nixpkgs.legacyPackages.x86_64-linux;
+    in pkgs.mkShell {
+      buildInputs = with pkgs; [
+        go
+        gopls
+        golangci-lint
+      ];
+
+      shellHook = ''
+        echo "Welcome to dev environment"
+        go version
+      '';
+    };
+  };
+}
+```
+
+### Multi-Shell Setup
+```nix
+# Multiple development shells
+{
+  outputs = { self, nixpkgs }: {
+    devShells.x86_64-linux = {
+      default = pkgs.mkShell {
+        buildInputs = [ pkgs.go ];
+      };
+
+      rust = pkgs.mkShell {
+        buildInputs = with pkgs; [
+          rustc
+          cargo
+          rust-analyzer
+        ];
+      };
+
+      python = pkgs.mkShell {
+        buildInputs = with pkgs; [
+          python3
+          python3Packages.pip
+        ];
+      };
+    };
+  };
+}
+```
+
+### Access Specific Shell
+```bash
+# Use default shell
+nix develop
+
+# Use named shell
+nix develop .#rust
+nix develop .#python
+```
+
+## Shell Configuration
+
+### Environment Variables
+```nix
+pkgs.mkShell {
+  buildInputs = [ pkgs.go ];
+
+  shellHook = ''
+    export GOPATH=$PWD/.go
+    export GOCACHE=$PWD/.cache/go-build
+    export PATH=$GOPATH/bin:$PATH
+
+    # Create directories
+    mkdir -p $GOPATH $GOCACHE
+  '';
+
+  # Or use env
+  env = {
+    GOPATH = "$PWD/.go";
+    GOCACHE = "$PWD/.cache/go-build";
+  };
+}
+```
+
+### Shell Hooks
+```nix
+pkgs.mkShell {
+  buildInputs = [ pkgs.nodejs ];
+
+  shellHook = ''
+    # Print banner
+    echo "================================"
+    echo "Node.js Development Environment"
+    echo "================================"
+    node --version
+    npm --version
+
+    # Install dependencies
+    if [ ! -d "node_modules" ]; then
+      npm install
+    fi
+
+    # Setup git hooks
+    if [ ! -f ".git/hooks/pre-commit" ]; then
+      echo "Setting up git hooks..."
+      npx husky install
+    fi
+  '';
+}
+```
+
+### Package-Specific Shell
+```nix
+# For a specific package's dev environment
+{
+  outputs = { self, nixpkgs }: {
+    packages.x86_64-linux.myapp = /* package definition */;
+
+    devShells.x86_64-linux.default = let
+      pkgs = nixpkgs.legacyPackages.x86_64-linux;
+    in pkgs.mkShell {
+      # Include all build inputs from package
+      inputsFrom = [ self.packages.x86_64-linux.myapp ];
+
+      # Add development tools
+      buildInputs = with pkgs; [
+        go-tools
+        delve
+        gopls
+      ];
+    };
+  };
+}
+```
+
+## direnv Integration
+
+### Setup direnv
+```bash
+# Install direnv
+nix profile install nixpkgs#direnv
+nix profile install nixpkgs#nix-direnv
+
+# Configure shell (bash)
+eval "$(direnv hook bash)"
+
+# Configure shell (zsh)
+eval "$(direnv hook zsh)"
+```
+
+### Basic .envrc
+```bash
+# .envrc
+use flake
+
+# Optional: Use specific flake output
+# use flake .#rust
+```
+
+### Advanced .envrc
+```bash
+# .envrc
+use flake
+
+# Watch additional files
+watch_file shell.nix
+watch_file flake.nix
+watch_file flake.lock
+
+# Set environment variables
+export EDITOR=vim
+export DATABASE_URL=postgresql://localhost/mydb
+
+# Source local secrets
+if [ -f .env.local ]; then
+  dotenv .env.local
+fi
+
+# Layout for different languages
+# layout python  # Auto-create venv
+# layout node    # Add node_modules/.bin to PATH
+```
+
+### nix-direnv Configuration
+```bash
+# ~/.config/direnv/direnvrc or ~/.direnvrc
+source $HOME/.nix-profile/share/nix-direnv/direnvrc
+
+# Or if installed via home-manager
+# It's automatically configured
+```
+
+### Performance with nix-direnv
+```bash
+# nix-direnv caches the environment
+# Much faster reloads!
+
+# First load (slow)
+$ cd project/
+direnv: loading ~/project/.envrc
+direnv: using flake
+# ... downloads and builds ...
+
+# Subsequent loads (instant!)
+$ cd project/
+direnv: loading ~/project/.envrc
+direnv: using cached flake environment
+```
+
+## Common Development Patterns
+
+### Go Development
+```nix
+{
+  devShells.x86_64-linux.default = pkgs.mkShell {
+    buildInputs = with pkgs; [
+      go
+      gopls
+      gotools
+      golangci-lint
+      delve
+    ];
+
+    shellHook = ''
+      export GOPATH=$PWD/.go
+      export GOCACHE=$PWD/.cache/go-build
+      export PATH=$GOPATH/bin:$PATH
+      mkdir -p $GOPATH $GOCACHE
+    '';
+  };
+}
+```
+
+### Rust Development
+```nix
+{
+  devShells.x86_64-linux.default = pkgs.mkShell {
+    buildInputs = with pkgs; [
+      rustc
+      cargo
+      rustfmt
+      rust-analyzer
+      clippy
+    ];
+
+    RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}";
+  };
+}
+```
+
+### Node.js Development
+```nix
+{
+  devShells.x86_64-linux.default = pkgs.mkShell {
+    buildInputs = with pkgs; [
+      nodejs_20
+      nodePackages.npm
+      nodePackages.typescript
+      nodePackages.prettier
+    ];
+
+    shellHook = ''
+      export NODE_PATH=$PWD/node_modules
+      export PATH=$PWD/node_modules/.bin:$PATH
+    '';
+  };
+}
+```
+
+### Python Development
+```nix
+{
+  devShells.x86_64-linux.default = let
+    python = pkgs.python3.withPackages (ps: with ps; [
+      flask
+      requests
+      pytest
+    ]);
+  in pkgs.mkShell {
+    buildInputs = [ python ];
+
+    shellHook = ''
+      # Create virtual environment if needed
+      if [ ! -d "venv" ]; then
+        python -m venv venv
+      fi
+      source venv/bin/activate
+    '';
+  };
+}
+```
+
+### C/C++ Development
+```nix
+{
+  devShells.x86_64-linux.default = pkgs.mkShell {
+    buildInputs = with pkgs; [
+      gcc
+      cmake
+      gnumake
+      gdb
+      clang-tools
+    ];
+
+    shellHook = ''
+      export CC=gcc
+      export CXX=g++
+    '';
+  };
+}
+```
+
+## Advanced Shell Features
+
+### Multiple Package Sets
+```nix
+{
+  devShells.x86_64-linux.default = let
+    pkgs = nixpkgs.legacyPackages.x86_64-linux;
+    unstable = inputs.nixpkgs-unstable.legacyPackages.x86_64-linux;
+  in pkgs.mkShell {
+    buildInputs = [
+      pkgs.go             # Stable Go
+      unstable.gopls      # Latest gopls
+    ];
+  };
+}
+```
+
+### Conditional Tools
+```nix
+pkgs.mkShell {
+  buildInputs = with pkgs; [
+    go
+    gopls
+  ] ++ lib.optionals stdenv.isLinux [
+    # Linux-specific tools
+    strace
+    ltrace
+  ] ++ lib.optionals stdenv.isDarwin [
+    # macOS-specific tools
+    darwin.apple_sdk.frameworks.Security
+  ];
+}
+```
+
+### Project-Specific Scripts
+```nix
+pkgs.mkShell {
+  buildInputs = [ pkgs.go ];
+
+  shellHook = ''
+    # Create helper scripts
+    cat > run.sh <<'EOF'
+    #!/usr/bin/env bash
+    go run ./cmd/server
+    EOF
+    chmod +x run.sh
+
+    cat > test.sh <<'EOF'
+    #!/usr/bin/env bash
+    go test ./... -v
+    EOF
+    chmod +x test.sh
+
+    echo "Helper scripts created: run.sh, test.sh"
+  '';
+}
+```
+
+## Development Workflow
+
+### Typical Session
+```bash
+# Enter project
+cd myproject/
+
+# direnv automatically loads environment
+direnv: loading ~/myproject/.envrc
+direnv: using flake
+
+# Environment ready
+go version
+gopls version
+
+# Work on project
+vim main.go
+go build
+go test
+
+# Leave project
+cd ..
+
+# Environment unloaded
+direnv: unloading
+```
+
+### Update Development Environment
+```bash
+# Update flake inputs
+nix flake update
+
+# Reload direnv
+direnv reload
+
+# Or manually re-enter
+nix develop
+```
+
+### Share Environment
+```bash
+# Commit flake.nix and flake.lock
+git add flake.nix flake.lock
+git commit -m "chore: add nix development environment"
+
+# Team members get same environment
+git clone repo
+cd repo
+direnv allow  # Or nix develop
+```
+
+## Troubleshooting
+
+### direnv Not Loading
+```bash
+# Check direnv status
+direnv status
+
+# Manually allow
+direnv allow
+
+# Check .envrc syntax
+cat .envrc
+
+# Test flake
+nix flake check
+```
+
+### Slow Shell Activation
+```bash
+# Install nix-direnv for caching
+nix profile install nixpkgs#nix-direnv
+
+# Configure in ~/.config/direnv/direnvrc
+source $HOME/.nix-profile/share/nix-direnv/direnvrc
+
+# Reload
+direnv reload
+```
+
+### Environment Variables Not Set
+```bash
+# Check environment
+nix develop --command printenv
+
+# Verify shellHook
+nix develop --command bash -c 'echo $MY_VAR'
+
+# Debug direnv
+direnv exec . env | grep MY_VAR
+```
+
+### Binary Cache Issues
+```bash
+# Use substituters
+nix develop --extra-substituters https://cache.nixos.org
+
+# Build locally if needed
+nix develop --no-substitute
+```
+
+## Best Practices
+
+1. **Use direnv**: Automatic environment loading
+2. **Install nix-direnv**: Much faster reloads with caching
+3. **Commit flake.lock**: Ensure reproducibility
+4. **Pin versions**: Use specific nixpkgs inputs
+5. **Minimal dependencies**: Only what's needed for development
+6. **Document setup**: Add README with instructions
+7. **Use inputsFrom**: Inherit from package definitions
+8. **Test environment**: Verify with fresh clone
+
+## Integration with Editors
+
+### VS Code
+```json
+// .vscode/settings.json
+{
+  "nix.enableLanguageServer": true,
+  "nix.serverPath": "nixd"
+}
+```
+
+```bash
+# Install nixd language server in devShell
+buildInputs = [ pkgs.nixd ];
+```
+
+### Vim/Neovim
+```bash
+# Install LSPs in devShell
+buildInputs = with pkgs; [
+  gopls        # Go
+  rust-analyzer # Rust
+  nodePackages.typescript-language-server # TypeScript
+];
+```
+
+### Emacs
+```elisp
+;; direnv integration
+(use-package direnv
+  :config
+  (direnv-mode))
+```
+
+## Common Patterns
+
+### Database Development
+```nix
+pkgs.mkShell {
+  buildInputs = with pkgs; [
+    postgresql
+    pgcli
+  ];
+
+  shellHook = ''
+    export PGDATA=$PWD/.postgres
+    export PGHOST=$PWD/.postgres
+    export PGDATABASE=mydb
+
+    if [ ! -d "$PGDATA" ]; then
+      initdb --no-locale --encoding=UTF8
+      echo "unix_socket_directories = '$PGHOST'" >> $PGDATA/postgresql.conf
+      pg_ctl start -l $PGDATA/logfile
+      createdb $PGDATABASE
+    else
+      pg_ctl start -l $PGDATA/logfile
+    fi
+  '';
+}
+```
+
+### Docker Development
+```nix
+pkgs.mkShell {
+  buildInputs = with pkgs; [
+    docker
+    docker-compose
+  ];
+
+  shellHook = ''
+    export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock
+  '';
+}
+```
+
+### Multiple Environments
+```bash
+# .envrc
+# Choose environment based on directory
+if [ -f "Cargo.toml" ]; then
+  use flake .#rust
+elif [ -f "go.mod" ]; then
+  use flake .#go
+elif [ -f "package.json" ]; then
+  use flake .#node
+else
+  use flake
+fi
+```
+
+## Resources
+
+- [nix develop Manual](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-develop.html)
+- [direnv Documentation](https://direnv.net/)
+- [nix-direnv](https://github.com/nix-community/nix-direnv)
+- [Development Environments](https://nixos.wiki/wiki/Development_environment_with_nix-shell)
dots/.config/claude/skills/Nix/workflows/Flakes.md
@@ -0,0 +1,613 @@
+# Flakes Workflow
+
+Work with Nix flakes: create, update, manage inputs and outputs.
+
+## When to Use
+
+- "create nix flake"
+- "update flake inputs"
+- "flake.lock"
+- "nix flake"
+
+## Quick Commands
+
+### Basic Flake Commands
+```bash
+# Initialize new flake
+nix flake init
+
+# Initialize with template
+nix flake init -t templates#simple
+
+# Show flake outputs
+nix flake show
+
+# Show flake metadata
+nix flake metadata
+
+# Check flake validity
+nix flake check
+
+# Update all inputs
+nix flake update
+
+# Update specific input
+nix flake update nixpkgs
+```
+
+### Lock File Management
+```bash
+# Lock dependencies
+nix flake lock
+
+# Update lock file
+nix flake update
+
+# Update specific input
+nix flake lock --update-input nixpkgs
+
+# Show lock file info
+nix flake metadata --json | jq .locks
+```
+
+## Flake Structure
+
+### Basic Flake Template
+```nix
+{
+  description = "A very basic flake";
+
+  inputs = {
+    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
+  };
+
+  outputs = { self, nixpkgs }: {
+    packages.x86_64-linux.default = nixpkgs.legacyPackages.x86_64-linux.hello;
+  };
+}
+```
+
+### Complete Flake Template
+```nix
+{
+  description = "Complete flake example";
+
+  inputs = {
+    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
+    home-manager = {
+      url = "github:nix-community/home-manager";
+      inputs.nixpkgs.follows = "nixpkgs";
+    };
+  };
+
+  outputs = { self, nixpkgs, home-manager }: let
+    system = "x86_64-linux";
+    pkgs = nixpkgs.legacyPackages.${system};
+  in {
+    # Packages
+    packages.${system} = {
+      default = pkgs.hello;
+      myapp = pkgs.callPackage ./pkgs/myapp { };
+    };
+
+    # NixOS configurations
+    nixosConfigurations = {
+      hostname = nixpkgs.lib.nixosSystem {
+        inherit system;
+        modules = [ ./configuration.nix ];
+      };
+    };
+
+    # Home-manager configurations
+    homeConfigurations = {
+      "user@hostname" = home-manager.lib.homeManagerConfiguration {
+        inherit pkgs;
+        modules = [ ./home.nix ];
+      };
+    };
+
+    # Development shells
+    devShells.${system}.default = pkgs.mkShell {
+      buildInputs = with pkgs; [ go gopls ];
+    };
+  };
+}
+```
+
+## Flake Inputs
+
+### Input Formats
+```nix
+inputs = {
+  # GitHub repository (latest)
+  nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
+
+  # Specific branch
+  nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-24.05";
+
+  # Specific commit
+  nixpkgs-pinned.url = "github:nixos/nixpkgs/abc123...";
+
+  # GitLab
+  myrepo.url = "gitlab:user/repo";
+
+  # Git repository
+  mylib.url = "git+https://git.example.com/repo.git";
+
+  # Local path
+  locallib.url = "path:/home/user/projects/lib";
+
+  # Flake in subdirectory
+  subflake.url = "github:owner/repo?dir=subdir";
+
+  # With specific ref
+  tagged.url = "github:owner/repo/v1.0.0";
+};
+```
+
+### Following Inputs
+```nix
+inputs = {
+  nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
+
+  # Make home-manager use same nixpkgs
+  home-manager = {
+    url = "github:nix-community/home-manager";
+    inputs.nixpkgs.follows = "nixpkgs";
+  };
+
+  # Multiple follows
+  package = {
+    url = "github:owner/repo";
+    inputs = {
+      nixpkgs.follows = "nixpkgs";
+      flake-utils.follows = "flake-utils";
+    };
+  };
+};
+```
+
+## Flake Outputs
+
+### Output Types
+```nix
+outputs = { self, nixpkgs }: {
+  # Packages
+  packages.x86_64-linux.myapp = /* derivation */;
+
+  # Default package
+  packages.x86_64-linux.default = /* derivation */;
+
+  # Apps
+  apps.x86_64-linux.myapp = {
+    type = "app";
+    program = "${self.packages.x86_64-linux.myapp}/bin/myapp";
+  };
+
+  # Development shells
+  devShells.x86_64-linux.default = /* mkShell */;
+
+  # NixOS configurations
+  nixosConfigurations.hostname = /* nixosSystem */;
+
+  # Home-manager configurations
+  homeConfigurations."user@host" = /* homeManagerConfiguration */;
+
+  # Overlays
+  overlays.default = final: prev: {
+    mypackage = /* derivation */;
+  };
+
+  # NixOS modules
+  nixosModules.default = /* module */;
+
+  # Checks
+  checks.x86_64-linux.test = /* derivation */;
+
+  # Formatter
+  formatter.x86_64-linux = nixpkgs.legacyPackages.x86_64-linux.nixfmt;
+};
+```
+
+### Per-System Outputs
+```nix
+{
+  outputs = { self, nixpkgs }: let
+    # Helper to generate for each system
+    forAllSystems = nixpkgs.lib.genAttrs [
+      "x86_64-linux"
+      "aarch64-linux"
+      "x86_64-darwin"
+      "aarch64-darwin"
+    ];
+  in {
+    packages = forAllSystems (system: {
+      default = nixpkgs.legacyPackages.${system}.hello;
+    });
+
+    devShells = forAllSystems (system: let
+      pkgs = nixpkgs.legacyPackages.${system};
+    in {
+      default = pkgs.mkShell {
+        buildInputs = [ pkgs.go ];
+      };
+    });
+  };
+}
+```
+
+### Using flake-utils
+```nix
+{
+  inputs = {
+    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
+    flake-utils.url = "github:numtide/flake-utils";
+  };
+
+  outputs = { self, nixpkgs, flake-utils }:
+    flake-utils.lib.eachDefaultSystem (system: let
+      pkgs = nixpkgs.legacyPackages.${system};
+    in {
+      packages.default = pkgs.hello;
+      devShells.default = pkgs.mkShell {
+        buildInputs = [ pkgs.go ];
+      };
+    });
+}
+```
+
+## Managing Lock Files
+
+### Lock File Structure
+```json
+{
+  "nodes": {
+    "nixpkgs": {
+      "locked": {
+        "lastModified": 1234567890,
+        "narHash": "sha256-...",
+        "owner": "nixos",
+        "repo": "nixpkgs",
+        "rev": "abc123...",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nixos",
+        "ref": "nixos-unstable",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    }
+  }
+}
+```
+
+### Lock File Operations
+```bash
+# Create or update lock file
+nix flake lock
+
+# Update all inputs
+nix flake update
+
+# Update single input
+nix flake lock --update-input nixpkgs
+
+# Update and commit
+nix flake update
+git add flake.lock
+git commit -m "chore: update flake inputs"
+```
+
+### Pin Specific Revision
+```nix
+inputs = {
+  # Pin to specific commit
+  nixpkgs.url = "github:nixos/nixpkgs/abc123def456";
+  # Or in lock file manually, then:
+};
+```
+
+```bash
+# Lock without updating
+nix flake lock --no-update-lock-file
+
+# Override locked input temporarily
+nix build --override-input nixpkgs github:nixos/nixpkgs/main
+```
+
+## Flake Templates
+
+### Create Template
+```nix
+# templates/go/flake.nix
+{
+  description = "Go project template";
+
+  inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
+
+  outputs = { self, nixpkgs }: let
+    system = "x86_64-linux";
+    pkgs = nixpkgs.legacyPackages.${system};
+  in {
+    devShells.${system}.default = pkgs.mkShell {
+      buildInputs = with pkgs; [
+        go
+        gopls
+        golangci-lint
+      ];
+    };
+  };
+}
+```
+
+### Use Template
+```bash
+# List available templates
+nix flake show templates
+
+# Initialize from template
+nix flake init -t templates#go
+
+# Use remote template
+nix flake init -t github:user/repo#template-name
+```
+
+### Provide Templates
+```nix
+# In your flake
+{
+  outputs = { self }: {
+    templates = {
+      go = {
+        path = ./templates/go;
+        description = "Go project template";
+      };
+      rust = {
+        path = ./templates/rust;
+        description = "Rust project template";
+      };
+    };
+
+    defaultTemplate = self.templates.go;
+  };
+}
+```
+
+## Flake Registries
+
+### Add Registry Entry
+```bash
+# Add flake to registry
+nix registry add myflake github:user/repo
+
+# Use registry entry
+nix build myflake#package
+```
+
+### Pin Registry Entry
+```bash
+# Pin to specific revision
+nix registry pin nixpkgs
+
+# Remove pin
+nix registry remove nixpkgs
+```
+
+### Custom Registry
+```nix
+# ~/.config/nix/registry.json
+{
+  "flakes": [
+    {
+      "from": {
+        "id": "myflake",
+        "type": "indirect"
+      },
+      "to": {
+        "owner": "user",
+        "repo": "repo",
+        "type": "github"
+      }
+    }
+  ],
+  "version": 2
+}
+```
+
+## Flake Development Workflows
+
+### Local Development
+```bash
+# Test changes without committing
+nix build .
+
+# Test with dirty tree
+nix build .#package --impure
+
+# Build from specific commit
+nix build github:user/repo/commit-hash
+```
+
+### Override Inputs
+```bash
+# Override input temporarily
+nix build --override-input nixpkgs path:/local/nixpkgs
+
+# Use local checkout
+nix build --override-input mylib path:/home/user/mylib
+```
+
+### Flake References
+```bash
+# Current directory
+nix build .
+nix build .#package
+
+# GitHub
+nix build github:user/repo
+nix build github:user/repo/branch
+nix build github:user/repo/commit-hash
+nix build github:user/repo#package
+
+# GitLab
+nix build gitlab:user/repo
+
+# Path
+nix build path:/absolute/path
+nix build path:./relative/path
+
+# URL
+nix build git+https://example.com/repo.git
+```
+
+## Flake Compatibility
+
+### For Non-Flake Users
+```nix
+# default.nix
+(import (
+  fetchTarball {
+    url = "https://github.com/edolstra/flake-compat/archive/master.tar.gz";
+    sha256 = "0000000000000000000000000000000000000000000000000000";
+  }
+) {
+  src = ./.;
+}).defaultNix
+```
+
+### Shell.nix for Legacy
+```nix
+# shell.nix
+(import (
+  fetchTarball {
+    url = "https://github.com/edolstra/flake-compat/archive/master.tar.gz";
+    sha256 = "0000000000000000000000000000000000000000000000000000";
+  }
+) {
+  src = ./.;
+}).shellNix
+```
+
+## Flake Best Practices
+
+1. **Always commit flake.lock**: Ensures reproducibility
+2. **Use follows for inputs**: Avoid duplicate dependencies
+3. **Pin critical inputs**: Use specific commits for stability
+4. **Update regularly**: Keep inputs fresh for security
+5. **Document inputs**: Comment why each input is needed
+6. **Test before updating**: Use `nix flake check`
+7. **Use templates**: Standardize project structure
+8. **Version outputs**: Tag releases properly
+9. **Minimal inputs**: Only include what's needed
+10. **Use flake-utils**: Simplify multi-system outputs
+
+## Common Patterns
+
+### Multi-System Support
+```nix
+{
+  outputs = { self, nixpkgs }: let
+    systems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
+    forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f system);
+  in {
+    packages = forAllSystems (system: {
+      default = nixpkgs.legacyPackages.${system}.hello;
+    });
+  };
+}
+```
+
+### Overlay Pattern
+```nix
+{
+  outputs = { self, nixpkgs }: {
+    overlays.default = final: prev: {
+      mypackage = final.callPackage ./pkgs/mypackage { };
+    };
+
+    packages.x86_64-linux = let
+      pkgs = import nixpkgs {
+        system = "x86_64-linux";
+        overlays = [ self.overlays.default ];
+      };
+    in {
+      inherit (pkgs) mypackage;
+    };
+  };
+}
+```
+
+### Module Pattern
+```nix
+{
+  outputs = { self, nixpkgs }: {
+    nixosModules.myservice = { config, lib, pkgs, ... }: {
+      options.services.myservice = {
+        enable = lib.mkEnableOption "my service";
+        port = lib.mkOption {
+          type = lib.types.port;
+          default = 8080;
+        };
+      };
+
+      config = lib.mkIf config.services.myservice.enable {
+        # service configuration
+      };
+    };
+
+    nixosConfigurations.hostname = nixpkgs.lib.nixosSystem {
+      modules = [
+        self.nixosModules.myservice
+        ./configuration.nix
+      ];
+    };
+  };
+}
+```
+
+## Troubleshooting
+
+### Dirty Tree Errors
+```
+error: Git tree is dirty
+```
+
+```bash
+# Commit changes
+git add .
+git commit -m "wip"
+
+# Or use --impure
+nix build --impure
+```
+
+### Input Not Found
+```
+error: input 'nixpkgs' not found
+```
+
+```bash
+# Check inputs are defined
+nix flake metadata
+
+# Update lock file
+nix flake lock
+```
+
+### Lock File Conflicts
+```bash
+# After merge conflict in flake.lock
+nix flake lock
+
+# Commit resolved lock file
+git add flake.lock
+git commit
+```
+
+## Resources
+
+- [Nix Flakes Manual](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-flake.html)
+- [Flakes Wiki](https://nixos.wiki/wiki/Flakes)
+- [Flake Templates](https://github.com/nix-community/templates)
+- [Flake Tutorial](https://serokell.io/blog/practical-nix-flakes)
dots/.config/claude/skills/Nix/workflows/Package.md
@@ -0,0 +1,638 @@
+# Package Workflow
+
+Create, maintain, and debug Nix packages.
+
+## When to Use
+
+- "create nix package"
+- "package application with nix"
+- "write nix derivation"
+- "buildGoModule"
+
+## Quick Commands
+
+### Building Packages
+```bash
+# Build package
+nix build .#package-name
+
+# Test package
+nix build .#package-name -L
+
+# Run package
+nix run .#package-name
+
+# Install package
+nix profile install .#package-name
+```
+
+### Testing Packages
+```bash
+# Build and test
+nix build .#package-name --rebuild
+
+# Check meta attributes
+nix eval .#package-name.meta --json
+
+# Check outputs
+nix eval .#package-name.outputs
+```
+
+## Package Structure
+
+### Basic Package Template
+```nix
+# pkgs/mypackage/default.nix
+{ lib
+, stdenv
+, fetchFromGitHub
+}:
+
+stdenv.mkDerivation rec {
+  pname = "mypackage";
+  version = "1.0.0";
+
+  src = fetchFromGitHub {
+    owner = "owner";
+    repo = "repo";
+    rev = "v${version}";
+    hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
+  };
+
+  meta = with lib; {
+    description = "Short package description";
+    homepage = "https://github.com/owner/repo";
+    license = licenses.mit;
+    maintainers = with maintainers; [ ];
+    platforms = platforms.all;
+  };
+}
+```
+
+### Using callPackage
+```nix
+# pkgs/default.nix
+{ pkgs }:
+{
+  mypackage = pkgs.callPackage ./mypackage { };
+  anotherpkg = pkgs.callPackage ./anotherpkg { };
+}
+```
+
+## Language-Specific Packaging
+
+### Go Packages
+```nix
+{ lib
+, buildGoModule
+, fetchFromGitHub
+}:
+
+buildGoModule rec {
+  pname = "mygoapp";
+  version = "1.0.0";
+
+  src = fetchFromGitHub {
+    owner = "owner";
+    repo = "repo";
+    rev = "v${version}";
+    hash = "sha256-...";
+  };
+
+  vendorHash = "sha256-...";
+  # Or if no vendor directory:
+  # vendorHash = null;
+
+  # Flags passed to go build
+  ldflags = [
+    "-s"
+    "-w"
+    "-X main.version=${version}"
+  ];
+
+  # Subdirectory with main package
+  subPackages = [ "cmd/myapp" ];
+
+  meta = with lib; {
+    description = "My Go application";
+    homepage = "https://github.com/owner/repo";
+    license = licenses.mit;
+    maintainers = with maintainers; [ ];
+  };
+}
+```
+
+#### Getting vendorHash
+```bash
+# Method 1: Use fake hash
+# Set: vendorHash = lib.fakeSha256;
+# Build will fail with correct hash
+
+# Method 2: Use nix-prefetch
+nix-prefetch -f '<nixpkgs>' '{
+  mygoapp = (import ./. {}).mygoapp.go-modules;
+}'
+
+# Method 3: Build and copy error
+nix build .#mygoapp 2>&1 | grep "got:"
+```
+
+### Rust Packages
+```nix
+{ lib
+, rustPlatform
+, fetchFromGitHub
+, pkg-config
+, openssl
+}:
+
+rustPlatform.buildRustPackage rec {
+  pname = "myrustapp";
+  version = "1.0.0";
+
+  src = fetchFromGitHub {
+    owner = "owner";
+    repo = "repo";
+    rev = "v${version}";
+    hash = "sha256-...";
+  };
+
+  cargoHash = "sha256-...";
+
+  nativeBuildInputs = [ pkg-config ];
+  buildInputs = [ openssl ];
+
+  meta = with lib; {
+    description = "My Rust application";
+    homepage = "https://github.com/owner/repo";
+    license = licenses.mit;
+    maintainers = with maintainers; [ ];
+  };
+}
+```
+
+### Python Packages
+```nix
+{ lib
+, python3Packages
+, fetchPypi
+}:
+
+python3Packages.buildPythonPackage rec {
+  pname = "mypythonpkg";
+  version = "1.0.0";
+
+  src = fetchPypi {
+    inherit pname version;
+    hash = "sha256-...";
+  };
+
+  propagatedBuildInputs = with python3Packages; [
+    requests
+    flask
+  ];
+
+  checkInputs = with python3Packages; [
+    pytest
+  ];
+
+  pythonImportsCheck = [ "mypythonpkg" ];
+
+  meta = with lib; {
+    description = "My Python package";
+    homepage = "https://github.com/owner/repo";
+    license = licenses.mit;
+    maintainers = with maintainers; [ ];
+  };
+}
+```
+
+### Node.js Packages
+```nix
+{ lib
+, buildNpmPackage
+, fetchFromGitHub
+}:
+
+buildNpmPackage rec {
+  pname = "mynodeapp";
+  version = "1.0.0";
+
+  src = fetchFromGitHub {
+    owner = "owner";
+    repo = "repo";
+    rev = "v${version}";
+    hash = "sha256-...";
+  };
+
+  npmDepsHash = "sha256-...";
+
+  # Skip npm install phase if needed
+  dontNpmBuild = true;
+
+  meta = with lib; {
+    description = "My Node.js application";
+    homepage = "https://github.com/owner/repo";
+    license = licenses.mit;
+    maintainers = with maintainers; [ ];
+  };
+}
+```
+
+## Source Fetchers
+
+### fetchFromGitHub
+```nix
+src = fetchFromGitHub {
+  owner = "owner";
+  repo = "repo";
+  rev = "v${version}";  # Or specific commit
+  hash = "sha256-...";
+};
+
+# Get hash with:
+nix-prefetch-github owner repo --rev v1.0.0
+```
+
+### fetchurl
+```nix
+src = fetchurl {
+  url = "https://example.com/file-${version}.tar.gz";
+  hash = "sha256-...";
+};
+
+# Get hash with:
+nix-prefetch-url https://example.com/file.tar.gz
+```
+
+### fetchgit
+```nix
+src = fetchgit {
+  url = "https://git.example.com/repo.git";
+  rev = "commit-hash";
+  hash = "sha256-...";
+};
+```
+
+### fetchzip
+```nix
+src = fetchzip {
+  url = "https://example.com/archive.zip";
+  hash = "sha256-...";
+  stripRoot = false;  # If archive doesn't have single root directory
+};
+```
+
+## Build Phases
+
+### Standard Phases
+```nix
+stdenv.mkDerivation {
+  # ...
+
+  # Phases run in order:
+  # unpackPhase    - Extract source
+  # patchPhase     - Apply patches
+  # configurePhase - Run ./configure
+  # buildPhase     - Run make
+  # checkPhase     - Run tests
+  # installPhase   - Install files
+  # fixupPhase     - Fix up outputs
+
+  # Override phases
+  buildPhase = ''
+    make all
+  '';
+
+  installPhase = ''
+    mkdir -p $out/bin
+    cp myapp $out/bin/
+  '';
+}
+```
+
+### Custom Phases
+```nix
+stdenv.mkDerivation {
+  # ...
+
+  preBuild = ''
+    echo "Before build"
+  '';
+
+  postInstall = ''
+    echo "After install"
+    # Wrap binary with runtime dependencies
+    wrapProgram $out/bin/myapp \
+      --prefix PATH : ${lib.makeBinPath [ dependency ]}
+  '';
+}
+```
+
+### Skip Phases
+```nix
+stdenv.mkDerivation {
+  # ...
+
+  # Skip configure phase
+  dontConfigure = true;
+
+  # Skip build phase
+  dontBuild = true;
+
+  # Skip tests
+  doCheck = false;
+}
+```
+
+## Dependencies
+
+### Types of Dependencies
+```nix
+stdenv.mkDerivation {
+  # Build-time dependencies (native to build platform)
+  nativeBuildInputs = [
+    pkg-config
+    cmake
+    makeWrapper
+  ];
+
+  # Runtime dependencies (target platform)
+  buildInputs = [
+    openssl
+    zlib
+  ];
+
+  # Dependencies for running tests
+  checkInputs = [
+    pytest
+  ];
+
+  # Propagated to things that depend on this
+  propagatedBuildInputs = [
+    libxml2
+  ];
+}
+```
+
+### Finding Dependencies
+```bash
+# Search for package
+nix search nixpkgs openssl
+
+# Check package contents
+nix-locate bin/openssl
+
+# Find library
+nix-locate --top-level lib/libssl.so
+```
+
+## Multiple Outputs
+
+### Define Outputs
+```nix
+stdenv.mkDerivation {
+  pname = "myapp";
+  version = "1.0.0";
+
+  outputs = [ "out" "dev" "doc" ];
+
+  installPhase = ''
+    # Main output
+    mkdir -p $out/bin
+    cp myapp $out/bin/
+
+    # Development files
+    mkdir -p $dev/include
+    cp *.h $dev/include/
+
+    # Documentation
+    mkdir -p $doc/share/doc
+    cp README.md $doc/share/doc/
+  '';
+}
+```
+
+### Use Specific Output
+```bash
+# Build specific output
+nix build .#package.dev
+
+# Install specific output
+nix profile install .#package.doc
+```
+
+## Overriding Packages
+
+### Override Attributes
+```nix
+# Override specific attributes
+mypackage = pkgs.mypackage.overrideAttrs (old: {
+  version = "2.0.0";
+  src = fetchFromGitHub {
+    # new source
+  };
+});
+```
+
+### Override Arguments
+```nix
+# Override function arguments
+mypackage = pkgs.mypackage.override {
+  enableFeature = true;
+};
+```
+
+### Add Patches
+```nix
+mypackage = pkgs.mypackage.overrideAttrs (old: {
+  patches = (old.patches or []) ++ [
+    ./fix-bug.patch
+  ];
+});
+```
+
+## Meta Attributes
+
+### Complete Meta Example
+```nix
+meta = with lib; {
+  description = "Short one-line description";
+  longDescription = ''
+    Longer multi-line description
+    explaining the package.
+  '';
+  homepage = "https://example.com";
+  changelog = "https://example.com/changelog";
+  license = licenses.mit;
+  # Or multiple licenses
+  # license = with licenses; [ mit asl20 ];
+  maintainers = with maintainers; [ username ];
+  platforms = platforms.linux;
+  # Or specific platforms
+  # platforms = [ "x86_64-linux" "aarch64-linux" ];
+  broken = false;
+  # Mark as unfree if needed
+  # unfree = true;
+};
+```
+
+### Common Licenses
+```nix
+licenses.mit
+licenses.gpl3
+licenses.gpl3Only
+licenses.gpl3Plus
+licenses.asl20
+licenses.bsd3
+licenses.mpl20
+licenses.unfree
+```
+
+## Testing Packages
+
+### Build and Test
+```bash
+# Build package
+nix build .#mypackage -L
+
+# Run tests
+nix build .#mypackage --rebuild
+
+# Check specific test
+nix build .#mypackage.tests.sometest
+```
+
+### Test Installation
+```bash
+# Install to temporary profile
+nix profile install .#mypackage --profile /tmp/test-profile
+
+# Test binary
+/tmp/test-profile/bin/myapp --version
+
+# Clean up
+rm -rf /tmp/test-profile
+```
+
+### Check Dependencies
+```bash
+# List runtime dependencies
+nix-store -q --references $(nix build .#mypackage --no-link --print-out-paths)
+
+# List all dependencies (recursive)
+nix-store -q --requisites $(nix build .#mypackage --no-link --print-out-paths)
+
+# Check for unwanted dependencies
+nix-store -q --tree result | grep unwanted
+```
+
+## Debugging Packages
+
+### Build Failures
+```bash
+# Keep build directory on failure
+nix build .#mypackage --keep-failed
+
+# Inspect failed build
+cd /tmp/nix-build-mypackage-*.drv-0/
+ls -la
+cat build.log
+```
+
+### Enter Build Environment
+```bash
+# Enter environment
+nix develop .#mypackage
+
+# Run build phases manually
+unpackPhase
+cd $sourceRoot
+configurePhase
+buildPhase
+```
+
+### Check Build Script
+```bash
+# Show derivation
+nix show-derivation .#mypackage
+
+# Show builder
+nix show-derivation .#mypackage | jq '.[].env.builder'
+
+# Show build args
+nix show-derivation .#mypackage | jq '.[].args'
+```
+
+## Package Best Practices
+
+1. **Pin versions explicitly**: Use specific version numbers
+2. **Add meta attributes**: Description, homepage, license, platforms
+3. **Use appropriate fetcher**: fetchFromGitHub, fetchurl, etc.
+4. **Include tests**: Enable doCheck when tests exist
+5. **Multiple outputs**: Separate dev files, docs, etc.
+6. **Minimal dependencies**: Only include what's needed
+7. **Wrap binaries properly**: Use makeWrapper for runtime deps
+8. **Document patches**: Comment why patches are needed
+9. **Test cross-platform**: Build for different platforms
+10. **Follow nixpkgs conventions**: Look at similar packages
+
+## Common Patterns
+
+### Wrapper Script
+```nix
+{ lib, stdenv, makeWrapper, myapp, dependency }:
+
+stdenv.mkDerivation {
+  pname = "myapp-wrapped";
+  version = myapp.version;
+
+  nativeBuildInputs = [ makeWrapper ];
+
+  buildCommand = ''
+    makeWrapper ${myapp}/bin/myapp $out/bin/myapp \
+      --prefix PATH : ${lib.makeBinPath [ dependency ]}
+  '';
+}
+```
+
+### Conditional Features
+```nix
+{ lib
+, stdenv
+, enableFeature ? false
+, optionalDependency
+}:
+
+stdenv.mkDerivation {
+  pname = "myapp";
+
+  buildInputs = [ ]
+    ++ lib.optional enableFeature optionalDependency;
+
+  configureFlags = [ ]
+    ++ lib.optional enableFeature "--enable-feature";
+}
+```
+
+### Platform-Specific
+```nix
+{ lib, stdenv, darwin }:
+
+stdenv.mkDerivation {
+  pname = "myapp";
+
+  buildInputs = [ ]
+    ++ lib.optionals stdenv.isLinux [ linuxDep ]
+    ++ lib.optionals stdenv.isDarwin [
+      darwin.apple_sdk.frameworks.Security
+    ];
+}
+```
+
+## Resources
+
+- [Nixpkgs Manual - Stdenv](https://nixos.org/manual/nixpkgs/stable/#chap-stdenv)
+- [Nixpkgs Manual - Languages](https://nixos.org/manual/nixpkgs/stable/#chap-language-support)
+- [Nixpkgs Manual - Fetchers](https://nixos.org/manual/nixpkgs/stable/#chap-pkgs-fetchers)
+- [Package Tutorials](https://nixos.wiki/wiki/Packaging)
dots/.config/claude/skills/Nix/workflows/Secrets.md
@@ -0,0 +1,522 @@
+# Secrets Workflow
+
+Manage secrets with agenix for NixOS and home-manager.
+
+## When to Use
+
+- "manage secrets with nix"
+- "agenix secrets"
+- "encrypt secrets nixos"
+- "age encryption"
+
+## Quick Commands
+
+### Basic Operations
+```bash
+# Edit secret
+agenix -e secrets/mySecret.age
+
+# Re-key all secrets (after adding keys)
+agenix -r
+
+# Re-key specific secret
+agenix -e secrets/mySecret.age -r
+```
+
+### In Configuration
+```nix
+# Use secret in NixOS
+age.secrets.mySecret = {
+  file = ../secrets/mySecret.age;
+  owner = "myuser";
+  group = "mygroup";
+};
+
+# Reference secret path
+services.myservice.passwordFile = config.age.secrets.mySecret.path;
+```
+
+## Setup agenix
+
+### Install agenix
+```nix
+# In flake.nix inputs
+{
+  inputs = {
+    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
+    agenix = {
+      url = "github:ryantm/agenix";
+      inputs.nixpkgs.follows = "nixpkgs";
+    };
+  };
+
+  outputs = { self, nixpkgs, agenix }: {
+    nixosConfigurations.hostname = nixpkgs.lib.nixosSystem {
+      modules = [
+        agenix.nixosModules.default
+        ./configuration.nix
+      ];
+    };
+  };
+}
+```
+
+### Install agenix CLI
+```bash
+# Install globally
+nix profile install github:ryantm/agenix
+
+# Or in dev shell
+nix-shell -p agenix
+```
+
+## Creating Secrets
+
+### Define secrets.nix
+```nix
+# secrets/secrets.nix
+let
+  # User SSH keys (for editing secrets)
+  user1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIUser1PublicKey user1@example.com";
+  user2 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIUser2PublicKey user2@example.com";
+
+  # System SSH keys (for decrypting on host)
+  system1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAISystem1PublicKey root@system1";
+  system2 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAISystem2PublicKey root@system2";
+
+  # Group keys together
+  users = [ user1 user2 ];
+  systems = [ system1 system2 ];
+  all = users ++ systems;
+in
+{
+  # Secret accessible by all
+  "database-password.age".publicKeys = all;
+
+  # Secret only for system1
+  "system1-api-key.age".publicKeys = [ user1 system1 ];
+
+  # Secret for specific systems
+  "shared-secret.age".publicKeys = users ++ [ system1 system2 ];
+}
+```
+
+### Get SSH Public Keys
+```bash
+# User SSH key
+cat ~/.ssh/id_ed25519.pub
+
+# System SSH key
+cat /etc/ssh/ssh_host_ed25519_key.pub
+
+# Or from known_hosts
+ssh-keyscan hostname
+
+# Convert to age format (if needed)
+ssh-keygen -y -f ~/.ssh/id_ed25519 | ssh-to-age
+```
+
+## Encrypt and Edit Secrets
+
+### Create New Secret
+```bash
+# Create and edit secret
+agenix -e secrets/mySecret.age
+
+# Opens $EDITOR with decrypted content
+# Save and exit to encrypt
+```
+
+### Edit Existing Secret
+```bash
+# Edit secret
+agenix -e secrets/database-password.age
+
+# Update password in editor
+# Save and exit to re-encrypt
+```
+
+### Non-Interactive Encryption
+```bash
+# Encrypt from file
+echo "super-secret-value" | agenix -e secrets/mySecret.age
+
+# Or pipe content
+cat plain-secret.txt | agenix -e secrets/mySecret.age
+```
+
+## Using Secrets in Configuration
+
+### NixOS Configuration
+```nix
+{ config, pkgs, ... }:
+
+{
+  # Import agenix module
+  imports = [ agenix.nixosModules.default ];
+
+  # Define secret
+  age.secrets.database-password = {
+    file = ../secrets/database-password.age;
+    owner = "postgres";
+    group = "postgres";
+    mode = "0440";
+  };
+
+  # Use secret in service
+  services.postgresql = {
+    enable = true;
+    # Secret path available at runtime
+    # Don't use in Nix expressions directly!
+  };
+
+  # Use in systemd service
+  systemd.services.myservice = {
+    serviceConfig = {
+      EnvironmentFile = config.age.secrets.database-password.path;
+    };
+  };
+}
+```
+
+### Home-Manager Configuration
+```nix
+{ config, pkgs, ... }:
+
+{
+  imports = [ agenix.homeManagerModules.default ];
+
+  age.secrets.github-token = {
+    file = ../secrets/github-token.age;
+    path = "${config.home.homeDirectory}/.config/github/token";
+  };
+
+  # Use in programs
+  programs.git = {
+    extraConfig = {
+      credential.helper = "store --file=${config.age.secrets.github-token.path}";
+    };
+  };
+}
+```
+
+### Secret Options
+```nix
+age.secrets.mySecret = {
+  # Path to encrypted secret file
+  file = ../secrets/mySecret.age;
+
+  # Where to place decrypted secret (default: /run/agenix/<name>)
+  path = "/var/lib/myapp/secret";
+
+  # Ownership
+  owner = "myuser";
+  group = "mygroup";
+
+  # Permissions (octal)
+  mode = "0440";
+
+  # Symlink instead of copy
+  symlink = true;
+
+  # Name in /run/agenix/ (default: attribute name)
+  name = "custom-name";
+};
+```
+
+## Common Secret Patterns
+
+### Database Credentials
+```nix
+age.secrets.postgres-password = {
+  file = ../secrets/postgres-password.age;
+  owner = "postgres";
+  mode = "0440";
+};
+
+services.postgresql = {
+  enable = true;
+  authentication = ''
+    # Use password from secret
+  '';
+};
+
+# Create database user with secret password
+systemd.services.postgres-init = {
+  after = [ "postgresql.service" ];
+  wantedBy = [ "multi-user.target" ];
+  script = ''
+    ${pkgs.postgresql}/bin/psql -c \
+      "ALTER USER myuser PASSWORD '$(cat ${config.age.secrets.postgres-password.path})';"
+  '';
+};
+```
+
+### API Keys
+```nix
+age.secrets.api-key = {
+  file = ../secrets/api-key.age;
+  owner = "myservice";
+};
+
+systemd.services.myservice = {
+  script = ''
+    export API_KEY=$(cat ${config.age.secrets.api-key.path})
+    ${pkgs.myservice}/bin/myservice
+  '';
+};
+```
+
+### SSH Keys
+```nix
+age.secrets.deploy-key = {
+  file = ../secrets/deploy-key.age;
+  owner = "git";
+  mode = "0600";
+  path = "/home/git/.ssh/deploy_key";
+};
+```
+
+### Certificates
+```nix
+age.secrets.tls-cert = {
+  file = ../secrets/tls-cert.age;
+  owner = "nginx";
+  group = "nginx";
+  mode = "0440";
+};
+
+age.secrets.tls-key = {
+  file = ../secrets/tls-key.age;
+  owner = "nginx";
+  group = "nginx";
+  mode = "0400";
+};
+
+services.nginx.virtualHosts."example.com" = {
+  forceSSL = true;
+  sslCertificate = config.age.secrets.tls-cert.path;
+  sslCertificateKey = config.age.secrets.tls-key.path;
+};
+```
+
+## Re-keying Secrets
+
+### Add New Host
+```nix
+# 1. Get new host SSH key
+ssh-keyscan new-host
+
+# 2. Add to secrets.nix
+let
+  newHost = "ssh-ed25519 AAAAC3... root@new-host";
+in
+{
+  "mySecret.age".publicKeys = [ user1 system1 newHost ];
+}
+```
+
+```bash
+# 3. Re-key all secrets
+agenix -r
+
+# 4. Commit changes
+git add secrets/
+git commit -m "chore: re-key secrets for new-host"
+```
+
+### Rotate User Keys
+```bash
+# 1. Update secrets.nix with new keys
+
+# 2. Re-key all secrets
+agenix -r
+
+# 3. Old keys can no longer decrypt
+# Ensure all secrets are updated before removing old keys!
+```
+
+### Emergency Re-key
+```bash
+# If key is compromised
+# 1. Remove compromised key from secrets.nix
+# 2. Re-key all secrets immediately
+agenix -r
+
+# 3. Deploy to all systems
+# 4. Verify secrets still work
+# 5. Rotate actual secret values
+```
+
+## Yubikey Integration
+
+### Setup Yubikey for Secrets
+```bash
+# Generate age key from yubikey
+age-plugin-yubikey --generate
+
+# Get public key
+age-plugin-yubikey --list
+```
+
+### Use Yubikey in secrets.nix
+```nix
+let
+  yubikey1 = "age1yubikey1...";
+  yubikey2 = "age1yubikey1...";
+in
+{
+  "mySecret.age".publicKeys = [ yubikey1 yubikey2 ];
+}
+```
+
+## Best Practices
+
+1. **Never commit plaintext secrets**: Always encrypt before committing
+2. **Use specific keys**: Only give access to those who need it
+3. **Separate secrets by environment**: Different secrets for dev/prod
+4. **Rotate secrets regularly**: Especially after team changes
+5. **Backup encryption keys**: Store SSH keys securely
+6. **Test secret decryption**: Verify after re-keying
+7. **Use git-crypt for repositories**: Additional layer for entire repo
+8. **Document secret purpose**: Comment what each secret is for
+9. **Monitor secret access**: Log when secrets are accessed
+10. **Plan for key compromise**: Know your re-key procedure
+
+## Troubleshooting
+
+### Cannot Decrypt Secret
+```
+error: Failed to decrypt
+```
+
+**Check:**
+1. Is host SSH key in secrets.nix?
+2. Does /etc/ssh/ssh_host_ed25519_key exist?
+3. Was secret encrypted with correct keys?
+
+```bash
+# Verify host key matches
+cat /etc/ssh/ssh_host_ed25519_key.pub
+
+# Re-key if needed
+agenix -r
+```
+
+### Secret File Not Found
+```
+error: file 'secrets/mySecret.age' does not exist
+```
+
+**Fix:**
+```bash
+# Create the secret
+agenix -e secrets/mySecret.age
+
+# Or check path is correct
+ls secrets/
+```
+
+### Permission Denied
+```
+error: cannot create symlink
+```
+
+**Fix:**
+```nix
+# Ensure parent directory exists
+systemd.tmpfiles.rules = [
+  "d /var/lib/myapp 0755 myuser mygroup -"
+];
+
+age.secrets.mySecret = {
+  file = ../secrets/mySecret.age;
+  path = "/var/lib/myapp/secret";
+  owner = "myuser";
+  group = "mygroup";
+};
+```
+
+## Advanced Patterns
+
+### Multi-Environment Secrets
+```nix
+# secrets/secrets.nix
+let
+  prodSystems = [ prod1 prod2 ];
+  devSystems = [ dev1 dev2 ];
+in
+{
+  "prod-db-password.age".publicKeys = users ++ prodSystems;
+  "dev-db-password.age".publicKeys = users ++ devSystems;
+}
+```
+
+### Conditional Secrets
+```nix
+{ config, lib, ... }:
+
+{
+  age.secrets = lib.mkIf config.services.database.enable {
+    db-password = {
+      file = ../secrets/db-password.age;
+      owner = config.services.database.user;
+    };
+  };
+}
+```
+
+### Templated Secrets
+```nix
+# Generate config from secret
+systemd.services.myservice = {
+  preStart = ''
+    cat > /etc/myservice/config.json <<EOF
+    {
+      "api_key": "$(cat ${config.age.secrets.api-key.path})",
+      "database_url": "postgresql://user:$(cat ${config.age.secrets.db-password.path})@localhost/db"
+    }
+    EOF
+  '';
+};
+```
+
+## Migration to agenix
+
+### From Plain Files
+```bash
+# 1. Create secrets.nix
+
+# 2. Encrypt existing secrets
+for file in /etc/secrets/*; do
+  secret_name=$(basename "$file")
+  agenix -e "secrets/${secret_name}.age" < "$file"
+done
+
+# 3. Update configuration to use agenix
+
+# 4. Remove plain files after verification
+```
+
+### From sops-nix
+```bash
+# 1. Decrypt sops secrets
+sops -d secrets.yaml > plaintext.yaml
+
+# 2. Split into individual files
+# Extract each secret
+
+# 3. Encrypt with agenix
+for secret in secrets/*; do
+  agenix -e "$secret.age" < "$secret"
+done
+
+# 4. Update configuration
+```
+
+## Resources
+
+- [agenix Documentation](https://github.com/ryantm/agenix)
+- [age Encryption](https://age-encryption.org/)
+- [age-plugin-yubikey](https://github.com/str4d/age-plugin-yubikey)
+- [NixOS Secrets Management](https://nixos.wiki/wiki/Comparison_of_secret_managing_schemes)
dots/.config/claude/skills/Nix/workflows/Troubleshoot.md
@@ -0,0 +1,687 @@
+# Troubleshoot Workflow
+
+Common Nix issues, error messages, and solutions.
+
+## When to Use
+
+- "nix error"
+- "troubleshoot nix"
+- "nix build failing"
+- "fix nix issue"
+
+## Common Errors
+
+### Hash Mismatch
+
+**Error:**
+```
+error: hash mismatch in fixed-output derivation
+  specified: sha256-AAAA...
+  got:        sha256-BBBB...
+```
+
+**Solution:**
+```nix
+# Copy the "got" hash
+src = fetchFromGitHub {
+  owner = "owner";
+  repo = "repo";
+  rev = "v1.0.0";
+  hash = "sha256-BBBB...";  # Use hash from error
+};
+```
+
+**Get Hash Correctly:**
+```bash
+# For GitHub
+nix-prefetch-github owner repo --rev v1.0.0
+
+# For URLs
+nix-prefetch-url https://example.com/file.tar.gz
+
+# For Git
+nix-prefetch-git https://git.example.com/repo.git --rev commit-hash
+```
+
+### Infinite Recursion
+
+**Error:**
+```
+error: infinite recursion encountered
+```
+
+**Common Causes:**
+```nix
+# 1. Self-referencing attribute
+{
+  x = x;  # Infinite recursion!
+}
+
+# 2. Circular dependency
+{
+  a = b;
+  b = a;  # Infinite recursion!
+}
+
+# 3. Overlay recursion
+final: prev: {
+  mypackage = prev.mypackage.override {  # Infinite!
+    # ...
+  };
+}
+```
+
+**Solutions:**
+```nix
+# Use lib.mkDefault or lib.mkForce
+{ lib, ... }:
+{
+  value = lib.mkDefault something;
+}
+
+# Break overlay recursion with super
+final: prev: {
+  mypackage = (prev.mypackage.override {
+    # ...
+  }).overrideAttrs (old: {
+    # ...
+  });
+}
+
+# Use rec carefully
+rec {
+  x = 1;
+  y = x + 1;  # OK
+}
+```
+
+### Attribute Not Found
+
+**Error:**
+```
+error: attribute 'foo' missing
+error: undefined variable 'bar'
+```
+
+**Debug:**
+```bash
+# Check what attributes exist
+nix eval .#nixosConfigurations.hostname --apply builtins.attrNames
+
+# Check nested path
+nix eval .#nixosConfigurations.hostname.config.services --apply builtins.attrNames
+
+# Use --show-trace
+nix eval .#value --show-trace
+```
+
+**Common Fixes:**
+```nix
+# Check spelling
+services.nginx.enable = true;  # Not nginX or nginx
+
+# Import missing module
+imports = [ ./missing-module.nix ];
+
+# Check if package exists
+nix search nixpkgs package-name
+```
+
+### File Not Found
+
+**Error:**
+```
+error: getting status of '/nix/store/.../file': No such file or directory
+error: path '/path/to/file' does not exist
+```
+
+**Solutions:**
+```nix
+# Use relative paths in flakes
+src = ./path/to/file;  # Not /absolute/path
+
+# Check file exists
+# ls path/to/file
+
+# In pure eval, paths must be relative
+# Don't use: /home/user/file
+# Use: ./file or ./relative/path
+```
+
+### Import from Derivation (IFD)
+
+**Error:**
+```
+error: cannot build '/nix/store/...' during evaluation
+```
+
+**Cause:**
+Import from Derivation - importing result of a build
+
+**Workarounds:**
+```nix
+# Avoid when possible
+# Bad:
+let
+  generated = import (pkgs.runCommand "gen" {} ''
+    echo "{ value = 42; }" > $out
+  '');
+in
+  generated.value
+
+# Good: Use builtins or pure Nix
+let
+  generated = { value = 42; };
+in
+  generated.value
+```
+
+### Restricted Mode / Pure Eval
+
+**Error:**
+```
+error: access to absolute path '/home/...' is forbidden in pure eval mode
+error: cannot look up '<nixpkgs>' in pure evaluation mode
+```
+
+**Solutions:**
+```nix
+# Use relative paths
+path = ./file.nix;  # Not /absolute/path
+
+# Use flake inputs instead of <nixpkgs>
+{ inputs, ... }:
+  inputs.nixpkgs.legacyPackages.x86_64-linux.hello
+
+# For development, use --impure
+nix build --impure
+```
+
+## Build Failures
+
+### Compilation Errors
+
+**Check Build Log:**
+```bash
+# View last build log
+nix log .#package
+
+# Keep build directory on failure
+nix build .#package --keep-failed
+
+# Inspect failed build
+cd /tmp/nix-build-package-*.drv-0/
+cat build.log
+ls -la
+```
+
+**Common Issues:**
+```bash
+# Missing dependencies
+# Add to buildInputs or nativeBuildInputs
+
+# Wrong C/C++ compiler
+# Set CC, CXX environment variables
+
+# Missing pkg-config
+# Add pkg-config to nativeBuildInputs
+
+# Library not found
+# Add to buildInputs and check PKG_CONFIG_PATH
+```
+
+### Test Failures
+
+**Skip Tests Temporarily:**
+```nix
+stdenv.mkDerivation {
+  # ...
+  doCheck = false;  # Disable tests
+}
+```
+
+**Debug Tests:**
+```bash
+# Run tests manually
+nix develop .#package
+unpackPhase
+cd $sourceRoot
+configurePhase
+buildPhase
+checkPhase  # Run tests with full output
+```
+
+### Missing Files in Output
+
+**Check Output:**
+```bash
+# What's in the output?
+nix build .#package
+tree result/
+ls -R result/
+
+# Check if files were created during build
+nix build .#package --keep-failed
+cd /tmp/nix-build-*/
+find . -name "expected-file"
+```
+
+**Fix Install Phase:**
+```nix
+installPhase = ''
+  runHook preInstall
+
+  mkdir -p $out/bin
+  cp myapp $out/bin/
+
+  # Install other files
+  mkdir -p $out/share/doc
+  cp README.md $out/share/doc/
+
+  runHook postInstall
+'';
+```
+
+## Runtime Issues
+
+### Executable Not Found
+
+**Error:**
+```
+bash: command not found
+```
+
+**Check:**
+```bash
+# Is package installed?
+which command-name
+
+# Check package output
+nix build .#package
+ls result/bin/
+
+# Check PATH
+echo $PATH
+
+# Install package
+nix profile install .#package
+```
+
+### Library Not Found
+
+**Error:**
+```
+error while loading shared libraries: libfoo.so.1: cannot open shared object file
+```
+
+**Solutions:**
+```bash
+# Use autoPatchelfHook
+nativeBuildInputs = [ autoPatchelfHook ];
+
+# Add runtime dependencies
+buildInputs = [ libfoo ];
+
+# Check dependencies
+ldd result/bin/program
+
+# Patch manually
+patchelf --set-rpath ${lib.makeLibraryPath [ libfoo ]} $out/bin/program
+```
+
+### Permission Denied
+
+**Check Permissions:**
+```bash
+# File permissions in store
+ls -l result/
+
+# Files should be readable
+# Executables should have +x
+```
+
+**Fix:**
+```nix
+postInstall = ''
+  chmod +x $out/bin/myapp
+'';
+```
+
+## Disk Space Issues
+
+### Out of Disk Space
+
+**Check Space:**
+```bash
+# Check /nix/store size
+du -sh /nix/store
+
+# Check total disk usage
+df -h
+
+# Find large paths
+nix path-info --closure-size .#package | sort -h
+```
+
+**Clean Up:**
+```bash
+# Delete old generations
+nix-collect-garbage -d
+
+# Delete generations older than 30 days
+nix-collect-garbage --delete-older-than 30d
+
+# Optimize store (deduplicate)
+nix-store --optimize
+
+# Delete specific paths
+nix-store --delete /nix/store/...-package
+```
+
+### Garbage Collection Issues
+
+**Error:**
+```
+error: cannot delete path '...' because it is in use by '...'
+```
+
+**Solutions:**
+```bash
+# Find what's using the path
+nix-store --query --roots /nix/store/...-package
+
+# Remove from profiles
+nix profile remove package-name
+
+# Delete old generations first
+nix-env --delete-generations old
+nix-collect-garbage
+```
+
+## Network Issues
+
+### Download Failures
+
+**Error:**
+```
+error: unable to download 'https://...'
+error: curl error: Connection timeout
+```
+
+**Solutions:**
+```bash
+# Check network
+ping example.com
+
+# Try with different substituter
+nix build --substituters https://cache.nixos.org
+
+# Build without network (use only local)
+nix build --offline
+
+# Build without binary cache
+nix build --no-substitute
+```
+
+### Binary Cache Issues
+
+**Error:**
+```
+error: cannot add path '...' to the store
+warning: ignoring substitute for '...'
+```
+
+**Solutions:**
+```bash
+# Add cache manually
+nix build --substituters https://cache.nixos.org \
+  --trusted-public-keys cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=
+
+# Configure in nix.conf
+# trusted-substituters = https://cache.nixos.org
+
+# Use cachix
+cachix use cachename
+```
+
+## Configuration Issues
+
+### Syntax Errors
+
+**Error:**
+```
+error: syntax error, unexpected IF
+error: undefined variable 'if'
+```
+
+**Common Mistakes:**
+```nix
+# 1. Missing semicolon
+{
+  option1 = value1
+  option2 = value2;  # ERROR: missing ; after value1
+}
+
+# 2. Wrong if syntax
+if condition value1 value2  # ERROR: missing 'then' and 'else'
+if condition then value1 else value2  # Correct
+
+# 3. Missing 'in'
+let x = 1; x + 1  # ERROR: missing 'in'
+let x = 1; in x + 1  # Correct
+
+# 4. Comments
+/* Multi-line comment */
+# Single-line comment
+```
+
+### Module Conflicts
+
+**Error:**
+```
+error: The option `services.foo.enable' is defined multiple times
+```
+
+**Solutions:**
+```nix
+# Use lib.mkForce to override
+services.foo.enable = lib.mkForce true;
+
+# Or remove duplicate definition
+# Check all imported modules
+
+# Use lib.mkMerge for lists
+services.foo.extraConfig = lib.mkMerge [
+  (lib.mkIf condition1 [ value1 ])
+  (lib.mkIf condition2 [ value2 ])
+];
+```
+
+### Type Mismatches
+
+**Error:**
+```
+error: value is a set while a string was expected
+error: value is a string while a list was expected
+```
+
+**Solutions:**
+```nix
+# Check types
+builtins.typeOf value
+
+# Convert as needed
+toString 42  # "42"
+lib.splitString "," "a,b,c"  # [ "a" "b" "c" ]
+[ value ]  # Wrap in list
+
+# Check option type
+# Look at option definition to see expected type
+```
+
+## System Issues
+
+### System Won't Boot
+
+**Recovery:**
+```bash
+# 1. Boot to previous generation
+# Select older generation in bootloader menu
+
+# 2. From rescue system
+mount /dev/sdX /mnt
+mount /dev/sdY /mnt/boot
+nixos-enter --root /mnt
+
+# Rollback
+nixos-rebuild switch --rollback
+
+# Or specific generation
+/nix/var/nix/profiles/system-42-link/bin/switch-to-configuration switch
+```
+
+### Service Failures
+
+**Debug:**
+```bash
+# Check service status
+systemctl status service-name
+
+# View logs
+journalctl -u service-name -n 50
+
+# View service definition
+systemctl cat service-name
+
+# Check generated config
+cat /etc/systemd/system/service-name.service
+```
+
+**Common Issues:**
+```nix
+# Wrong user
+systemd.services.myservice.serviceConfig.User = "correct-user";
+
+# Missing dependency
+systemd.services.myservice.after = [ "network.target" ];
+
+# Wrong paths
+# Use full store paths or ${}
+ExecStart = "${pkgs.myapp}/bin/myapp";
+```
+
+### Home-Manager Issues
+
+**Error:**
+```
+error: collision between files
+```
+
+**Solutions:**
+```nix
+# Let home-manager manage conflicts
+home.file."conflict".source = ./file;
+
+# Force overwrite
+home.file."conflict" = {
+  source = ./file;
+  force = true;
+};
+
+# Disable conflicting package
+home.packages = lib.filter (p: p != pkgs.conflicting) config.home.packages;
+```
+
+## Performance Issues
+
+### Slow Evaluation
+
+**Profile:**
+```bash
+# Time evaluation
+time nix eval .#nixosConfigurations.hostname.config.system.build.toplevel
+
+# Show stats
+nix eval --show-stats .#value
+```
+
+**Optimize:**
+```nix
+# Avoid expensive operations in hot paths
+# Use builtins when possible
+# Minimize use of import
+# Cache computed values
+```
+
+### Slow Builds
+
+**Speed Up:**
+```bash
+# Use more cores
+nix build --cores $(nproc)
+
+# Parallel jobs
+nix build --max-jobs auto
+
+# Use binary caches
+nix build --substituters https://cache.nixos.org
+
+# Build without downloads
+nix build --offline
+```
+
+## Emergency Recovery
+
+### Corrupted Nix Store
+
+**Check:**
+```bash
+# Verify store
+nix-store --verify --check-contents
+
+# Repair
+nix-store --verify --repair
+```
+
+### Locked Nix Database
+
+**Error:**
+```
+error: cannot open Nix database: database is locked
+```
+
+**Fix:**
+```bash
+# Stop nix-daemon
+systemctl stop nix-daemon
+
+# Remove lock
+rm /nix/var/nix/db/db.lock
+
+# Restart daemon
+systemctl start nix-daemon
+```
+
+### Full Disk
+
+**Emergency Clean:**
+```bash
+# Delete old generations
+sudo nix-env --delete-generations +5
+
+# Garbage collect
+sudo nix-collect-garbage -d
+
+# Optimize
+sudo nix-store --optimize
+
+# Remove build artifacts
+rm -rf /tmp/nix-build-*
+```
+
+## Resources
+
+- [Nix Error Messages](https://nixos.org/manual/nix/stable/language/index.html)
+- [NixOS Troubleshooting](https://nixos.wiki/wiki/Troubleshooting)
+- [Nix Pills - Debugging](https://nixos.org/guides/nix-pills/debugging.html)
+- [Common Issues](https://nixos.wiki/wiki/FAQ)
dots/.config/claude/skills/Nix/SKILL.md
@@ -1,5 +1,5 @@
 ---
-name: nix
+name: Nix
 description: Expert guidance on Nix, NixOS, and home-manager best practices. USE WHEN working with Nix expressions, NixOS configuration, home-manager, flakes, or Nix package development.
 ---
 
@@ -8,6 +8,26 @@ description: Expert guidance on Nix, NixOS, and home-manager best practices. USE
 ## Purpose
 Expert guidance on Nix, NixOS, and home-manager following best practices.
 
+## Workflow Routing
+
+When the user's request matches specific Nix operations, route to the appropriate workflow:
+
+| Workflow | Trigger | File |
+|----------|---------|------|
+| **Build** | "build nix package", "nixos-rebuild build", "compile nix" | `workflows/Build.md` |
+| **Debug** | "debug nix", "nix error", "troubleshoot build", "evaluation error" | `workflows/Debug.md` |
+| **Develop** | "development shell", "nix develop", "devShell", "direnv" | `workflows/Develop.md` |
+| **Deploy** | "deploy nixos", "nixos-rebuild switch", "remote deployment" | `workflows/Deploy.md` |
+| **Package** | "create package", "nix derivation", "buildGoModule", "package app" | `workflows/Package.md` |
+| **Flakes** | "create flake", "flake.lock", "update inputs", "flake outputs" | `workflows/Flakes.md` |
+| **Secrets** | "manage secrets", "agenix", "encrypt secrets", "age encryption" | `workflows/Secrets.md` |
+| **Troubleshoot** | "hash mismatch", "nix failing", "common errors", "fix nix issue" | `workflows/Troubleshoot.md` |
+
+**When to use workflows:**
+- Route when the user explicitly asks about one of these operations
+- Workflows provide comprehensive, focused guidance for specific Nix tasks
+- For general Nix guidance or module configuration, continue with this main skill
+
 ## Core Principles
 
 ### 1. Declarative Configuration Over Imperative