Rebuilding a Machine from Scratch¶
How to wipe a machine and rebuild it from this repository. The shape is the same
on every platform; only three things differ — how the machine gets erased, what
has to exist before install.sh can run, and which bookends the automation
deliberately refuses because they need a secret, an interactive sign-in, or a
freshly generated identity.
Every tool and config here is reproducible from this repo plus a package manager. What is genuinely at risk is the machine-local state that no repo holds, which is why the capture step comes first.
The shape¶
- Capture the machine-local state, while the old system is still alive.
- Wipe and reinstall the OS.
- Install
gitwith the system package manager — the one bootstrap dependency. - Clone this repo over HTTPS. No SSH key exists yet on a fresh machine.
- Restore the captured state.
./install.sh --machine NAME, which installs the CLI and stops.dotfiles apply --machine NAME, which is the install proper.- Verify, then do the manual steps.
Capture what no git repo holds¶
safekeep takes dated, tagged snapshots of exactly this; safekeep --help
covers the verbs and safekeep tags list says what a given tag would bring back.
Getting the capture set right is the hard part, because what dies in a wipe is
unobvious. dotfiles machines requirements answers the half the repo can prove —
every value and file a machine needs that apply will never write — and
--safekeep emits those files as [[back_up_paths]] blocks to paste straight
into the config, each tagged dotfiles.
That is a floor and not the set. It covers what is declared, which is by
definition narrower than what is worth keeping: ~/.env below its # OVERRIDES
marker is hand-written and exists nowhere else, the repo registry the trust
variant's repos_registry points at is hand-edited and generated by nothing, and
credentials, SSH keys and anything under ~/.config that was authored rather
than deployed are all outside the register entirely. Anything found that way and worth checking
forever belongs in required_files:, which is what makes dotfiles check report
it on every machine from then on.
Confirm the destination survives the wipe: a snapshot inside the machine you are about to erase is not a backup. On WSL that means a Windows or network path, not somewhere under the distro's own filesystem.
Seed phrases are the exception to all of this. Record them offline, restore-test each wallet on a different machine before wiping, and never let a seed pass through a networked tool.
Restore before the install, not after¶
The env resource regenerates ~/.env from the manifest at Stage.ENVIRONMENT,
the first stage of the walk, preserving everything below the # OVERRIDES marker.
Restore first and the managed half is rebuilt against the current manifest while
the hand-edits and secrets survive intact.
Restore afterwards and you reinstate the old machine's generated half — a stale
MACHINE and stale flags — by which point every stage has already run on
defaults. src/dotfiles/resources/env.py records why it is first: everything
below it reads the file, and MACHINE is what selects the manifest, so a run
that starts from the wrong one resolves the wrong machine entirely and ignores
every flag override for its whole length.
macOS¶
Apple Silicon and T2 Intel Macs reset cleanly without a Recovery reinstall: System Settings → General → Transfer or Reset → Erase All Content and Settings. Have the Apple ID password ready; the reset clears Activation Lock as part of the flow.
Xcode Command Line Tools is the bootstrap dependency, being where git comes
from. The apply self-bootstraps Homebrew and everything after it.
Arch Linux¶
Do a base install, ensure git and sudo are present, then run install.sh
and the apply it prints. The installer owns everything above the base system,
including the AUR helper.
WSL — the restricted machine¶
Measure the firewall and build the offline bundle before the wipe. Both need the old box alive and networked, and neither is recoverable afterwards (Restricted Networks covers the machinery). Re-measure rather than trusting an old reading — the blocked set has twice been wrong in the direction of carrying tools that were never actually blocked.
Rebuild by registering the new Ubuntu rootfs as the distro. Get the bundle onto
the new WSL filesystem and install from there rather than across a mounted drive;
--offline unpacks it into the cache itself, so nothing needs unpacking by hand.
Where a remote is configured, dotfiles bundle download fetches it onto the new
filesystem in one command and there is nothing to carry at all.
./install.sh --machine wsl-work-workstation --offline
dotfiles plan --machine wsl-work-workstation --offline
dotfiles apply --machine wsl-work-workstation --offline
--offline belongs on all three, and on the plan for a reason of its own: every
read verb measures upstream unless told not to, so a bare plan here asks GitHub
about every declared release, fetches every plugin clone and refreshes a copy of
the apt index — none of which this box can reach. --offline measures against the
staged bundle instead, and --cached is the same decline where there is no bundle.
The plan in between matters most on this box, where a run started without one
has sat on a blocked cargo download having never said what it meant to fetch.
Neither of the last two lines needs the bootstrap again. A bundle that arrives
later — a newer one carried over to a machine already built — is unpacked by the
next apply --offline, which stages the newest archive in the download cache,
./ or ~/ unless that archive is the one already staged. dotfiles bundle
stage unpacks without installing, for looking at a bundle before it lands.
This box replicates nothing between machines. Every directory the fleet shares that way is absent here. A tool depending on one is either off the manifest or configured differently, which is a property of the machine rather than something the install detects.
Verify¶
dotfiles plan # symlink, package and flag drift in one place
dotfiles packages check # declared but not installed
syncer check # repos the registry expects, against what is on disk
Open the editor and confirm plugins loaded without errors. dotfiles apply is
idempotent, so anything that failed can be fixed and the whole thing re-run
without going near the bootstrap again.
After the install¶
Generate a new SSH key rather than carrying the old one forward, and re-authorize it — a fresh key forces the pruning of dead authorizations. Restore wallets from their seeds, and sign into the applications holding their own credentials.
File sync needs peering, not just installation: each side has to add the other and agree to share each folder, so configure both ends.