Recover a machine
Rebuild a Mac from the config repo: one line, one passphrase, the plan, the apply, and two commands that prove the result.
When to use this
Use this walk for a machine that is gone: a failed drive, a stolen laptop, a wipe you chose. It is also the walk for a machine that is new, because niwa does not tell the two apart.
What must already be true
All three are true days before you need them, or not at all.
- The config repo is pushed, with
niwa.lockin it. - If you seal secrets,
secrets/seal-key.ageis committed and you know its passphrase. - You can reach the repo from the new machine.
One line
curl -fsSL niwa.rs | sh -s -- --config github:you/dotfilesgithub:owner/repo is the shorthand and @ref pins one; anything else
reaches git as written, so an ssh URL or a path works too.
The installer refuses anything that is not macOS, and waits for the
Command Line Tools, because the config repo needs git. It verifies the
release checksum before it touches the machine: a mismatch installs
nothing. It puts one binary at ~/.local/bin/niwa and wires PATH exactly
once in your .zshrc, behind a marker comment, so running it again
replaces the binary and changes nothing else. Then it clones the config
to ~/.config/niwa, leaving any config already there alone. With a
terminal behind it, the installer walks on through the two steps below.
With none, it prints them instead.
One passphrase
niwa seal-key restoresecrets/seal-key.age is the repo's copy of your sealing key, encrypted
to a passphrase. Restoring writes it into this machine's state directory,
readable only by you. Without it, every sealed secret fails the plan, and
the failure says the file is there and did not decrypt.
The plan
niwa planRead it. This is a machine with nothing on it, so the plan is long, and
the first apply is the one worth reading in full. If your config pulls in
a shared module, run niwa update first: the lock names the module, this
machine does not have its bytes yet, and the run says so rather than
fetching behind a plan.
plan exits 0 in sync, 2 with changes pending, 1 on an error. On a fresh
machine, 2 is the answer you want.
The apply
niwa applyIt shows the plan, asks once, and executes. The manual checklist prints at the top of a long run, so the permissions and sign-ins you do by hand overlap with the installs instead of waiting behind them. Nothing asks you for a password on niwa's behalf: steps that need administrator rights are listed up front and run with your own rights.
Prove it
niwa apply --verify--verify applies and then re-checks everything. A second pass that
changes nothing is the property the whole tool rests on. Anything still
reporting a change is not idempotent: niwa names the resource and the
line that declared it, then exits 1.
3 resources · nothing to doniwa doctor --deepdoctor asks whether niwa itself is healthy: the journal reads at its
schema, the archives open, the config loads clean, every secret resolves,
the lockfile agrees with the declarations. --deep pays for the
expensive versions, including decrypting sealed archives. Exit 0 means
every check passed.
On a machine whose config arrived by clone, doctor notes that the
watcher is not installed. That is a note, not a failure: the watcher
notices and notifies, and nothing in this walk depends on it.
Next
- Many machines — it explains the stamp, the lock, and why a clone is enough to rebuild from
