Claude Code Can Write Your Dotfiles, But It Cannot Own Your System State
Source: lobsters
Will Morrison’s experiment in handing Claude Code an Arch Linux install and asking it to configure things is worth examining closely, not because the outcome is surprising, but because it maps the current edge of what agentic coding tools can reliably do. The parts that work are genuinely useful. The parts that struggle reveal something structural about the difference between manipulating configuration text and managing system state, and that distinction matters for anyone thinking seriously about AI tooling for infrastructure work.
What Claude Code Is Doing
Claude Code is Anthropic’s terminal-based agentic assistant, released in 2025 as a tool that can read files, write files, execute shell commands, and reason across multiple steps to complete software engineering tasks. Unlike a chatbot you copy-paste suggestions from, Claude Code acts directly. It reads your directory structure, examines your existing configs, runs commands, observes the output, and adjusts. The loop looks roughly like this:
observe current state
→ decide on an action (edit file, run pacman, modify systemd unit)
→ execute
→ observe result
→ continue or revise
Underneath, this is the same ReAct-style reasoning-action loop that drives most capable agents, with Claude’s tool use API handling the structured transitions between thinking and doing. Claude Code has access to Bash, Read, Write, Edit, and Glob primitives by default, with an approval mechanism that pauses on destructive operations. The permission model matters here: out of the box, Claude Code will ask before running something like pacman -Syu or overwriting a system file. You can disable confirmations with --dangerouslySkipPermissions, which is exactly as alarming as it sounds.
What Makes Arch Configuration Hard
Arch Linux is an interesting test case for this kind of experiment. The Arch installation guide is thorough, the ArchWiki is one of the best documentation resources in open source, and the system is built on the assumption that you understand what you’re configuring. Nothing is set up for you. A minimal install gives you a bootable system with a shell and package manager; everything else, including a working GPU driver, audio stack, network manager, display server, and any user environment, requires deliberate configuration choices.
The difficulty isn’t that the configuration files are arcane. Most of them are readable, well-documented text. The difficulty is that the correct configuration depends on runtime state that isn’t captured in any single file: what GPU is present, what kernel modules loaded successfully, what AUR packages built without errors, whether a particular mkinitcpio hook ran before or after another one. The system is a function of its hardware, its history, and the specific ordering of operations, not just of the files on disk.
This is what makes it a genuinely hard problem for any tool that reasons about configuration by reading and writing text.
Where Claude Code Performs Well
For the parts of Arch configuration that are genuinely about text, Claude Code is capable. Given access to your system, it can:
- Read your existing
/etc/pacman.conf, identify missing mirrors or[multilib]being commented out, and edit it correctly. - Walk through
~/.configdirectories, understand what dotfiles belong to what applications, and reorganize them into a structure compatible with a tool like chezmoi. - Generate a valid Hyprland or Sway config based on your hardware output from
lspciandwlr-randr. - Write correct
systemdunit files for services you describe in plain language. - Cross-reference the ArchWiki for the right
pacman -Sincantation for a given use case.
For dotfiles management specifically, this is legitimately useful. The ArchWiki dotfiles article covers the major approaches: bare git repositories, GNU Stow symlink farms, chezmoi with its template and encryption capabilities, and the simpler yadm which wraps git with some convenience. Claude Code can look at your home directory, understand what you’re using, and help you migrate from a bare git repo to chezmoi, generating the correct .chezmoi.toml and handling the chezmoi add workflow for your existing files.
Here is an example of the kind of chezmoi configuration Claude Code can correctly generate:
# ~/.config/chezmoi/chezmoi.toml
[data]
name = "your name"
email = "your@email.com"
[diff]
pager = "delta"
[merge]
command = "nvim"
args = ["-d", "{{ .Destination }}", "{{ .Source }}", "{{ .Target }}"]
With a template like ~/.config/git/config.tmpl that uses {{ .chezmoi.data.name }}, you get machine-specific configs generated from a single source. Claude Code understands the template syntax and can restructure your dotfiles accordingly. That kind of work, reading intent from existing files and producing well-structured output in an established tool’s format, is a legitimate strength.
Where It Falls Apart
The problems show up when configuration stops being about text and starts being about state transitions.
Consider GPU driver setup on Arch. If you have an NVIDIA card, the correct procedure involves nvidia, nvidia-utils, and lib32-nvidia-utils from the official repos, a mkinitcpio.conf that includes nvidia nvidia_modeset nvidia_uvm nvidia_drm in the MODULES array, a kernel parameter of nvidia-drm.modeset=1 in your bootloader config, and a pacman hook that regenerates your initramfs when the driver updates. Getting any one of these wrong produces a system that may boot, may display nothing, or may work until the next kernel update. Claude Code can read the ArchWiki, understand all of this, and write the correct files. But it cannot know whether the initramfs actually regenerated correctly, whether the bootloader picked up the new kernel parameter, or whether the module loaded until you reboot and observe the result.
The agentic loop assumes that executing an action and observing stdout is enough feedback to verify success. For system configuration, it often isn’t. mkinitcpio -P exits zero and prints output that looks fine even when something is subtly wrong. pacman -S nvidia succeeds but the driver still needs the initramfs update and bootloader configuration to take effect. The ground truth is the booted system, not the command output.
This gap is deeper than just “Claude Code needs to handle errors better.” It reflects something about how LLM agents are currently designed. The feedback loop is fast, text-based, and session-scoped. System configuration has feedback that comes after a reboot, reveals itself through hardware interaction, and depends on accumulated state across multiple sessions. An agent that cannot persist state across a reboot, observe post-boot hardware behavior, and reason about changes made across separate sessions is missing a fundamental capability for this class of work.
The NixOS Comparison
The reason NixOS has attracted serious interest isn’t just declarative configuration as a concept. It’s that Nix makes configuration and system state genuinely the same thing. When your configuration.nix says you have an NVIDIA driver with DRM modesetting enabled, nixos-rebuild switch either produces exactly that system or fails with an error that points to the specific contradiction. There is no “the file looks right but the system isn’t configured correctly” failure mode because the system is derived from the files.
Home Manager extends this to user-level dotfiles. Your entire user environment, from shell init to Neovim config to font installation, becomes a reproducible derivation. You can commit your home.nix and get the same environment on any machine. The config is the state, not a description of the state.
Claude Code on Arch is working against the grain of how Arch is designed. Arch gives you maximum control and expects you to maintain the mental model of your system yourself. An LLM agent that lacks persistent memory across sessions and cannot observe hardware behavior is ill-suited to hold that mental model reliably over time. On NixOS, the config file holds the model, and the agent just needs to edit the file correctly. The problem becomes tractable.
This is probably why Nix-specific LLM helpers have gotten more traction than equivalent Arch tooling. When configuration is fully declarative and evaluation is hermetic, an LLM that reads and writes config files is operating on the complete ground truth. When configuration is imperative and state-dependent, reading the files tells you what was intended, not necessarily what is.
What This Means for Dotfiles Tooling
For pure dotfiles work, the picture is better. Dotfiles are mostly about user-space configuration: shell aliases, editor settings, window manager keybindings, tool configuration. These are text files that change independently of hardware state and don’t require reboots to take effect. An agent that can read your current configs, understand what you’re trying to accomplish, and produce a well-structured chezmoi or yadm repository is doing real work.
The comparison worth making is between Claude Code and a tool like Ansible for local machine configuration. Ansible is designed to manage system state through idempotent operations with explicit feedback about what changed. It models the gap between current state and desired state explicitly, accumulates state across runs, and is designed to be re-run safely. Claude Code is not any of these things, and trying to use it as a system configuration manager stretches it past what the current tool design supports.
That said, Morrison’s experiment surfaces a genuinely interesting use case: using Claude Code as an interactive assistant while you configure your system yourself. You run a command, paste the output, and ask what it means. You describe the behavior you want and ask which package provides it. You show it your existing config and ask where to put a new option. This is different from asking it to autonomously configure your system, and it plays to the tool’s actual strengths. The constraint isn’t capability; it’s autonomy. The less you ask Claude Code to act independently on a live system, the more reliably useful it becomes.
The more interesting question this raises is what agentic tooling for system configuration would actually look like if designed for the problem. It would need persistent state that survives across sessions and reboots, a model of system state distinct from file contents, hardware feedback integrated into the observation loop, and rollback primitives for when configurations interact badly. That’s a different tool from what exists today, and it looks more like a configuration management system with an LLM reasoning layer than a coding assistant with shell access. The experiment of letting Claude configure your Arch install is mostly valuable for clarifying that distinction.