Declare intent, converge state, move on.
Arch is imperative. You run commands, packages accumulate, configs scatter. Six months later you can't explain half your system. Reinstalling means archaeology. Syncing machines means drift.
We want repeatability without NixOS complexity. Not hermetic builds, not byte-identical closures. Just a declaration that describes the system, and a tool that makes it so.
Your system should match what you declare, nothing more. If it's declared, it exists. If it's not declared, it gets removed. No exceptions, no "I'll clean that up later."
If you can't explain why a package exists, it shouldn't. Every package belongs to a module. Every module has a purpose. Loose packages are how systems rot.
Simplicity beats features. We don't handle every edge case. We don't recover gracefully from partial failures. Something broke? Fix your declaration, run sync again. The tool is simple so you can understand it completely.
-
Declare everything you want installed. Packages, dotfiles, services, hooks - if it's part of your system, it's in a module.
-
Let the package manager handle dependencies. You declare what you want, pacman resolves the rest. Optional dependencies you actually use must be declared explicitly.
-
Remove what you stop declaring. Undeclared packages and orphaned dependencies are removed every sync. Nothing lingers.
-
One owner per dotfile. Two modules targeting the same path is an error. The sync fails until you fix the conflict.
-
Declare services alongside packages. If a module needs a service running, say so. Services enable when the module is enabled, disable when it's not.
-
Write hooks that can run twice. Hooks are tracked after success, but you might reset them. They must tolerate re-runs.
-
List modules in the order they apply. First listed, first applied. Order matters when it matters.
-
Trust the declaration over stored state. State exists to compute diffs. When state and declaration disagree, declaration wins.
-
Expect sync to be repeatable. Run it once or ten times, same result. Clone your config to a new machine, run sync, walk away.
Pin versions. Arch is rolling. If you want reproducible builds, use a different distro.
Manage /etc declaratively. We symlink dotfiles in your home. System files are out of scope. Hooks exist for when you need to touch /etc - use them, document them.
Replace pacman. We're a layer above. Pacman does the work; we decide what work to do.
Merge file contents. We symlink whole files. If two modules need lines in the same file, refactor into one module or use a hook.
Handle partial failure gracefully. If a hook fails, the sync fails. If a package won't install, the sync fails. Fix the problem, run again. We don't paper over errors.
Not NixOS. Not Ansible. Just enough to sleep well.