Files
command-center/omp-docs/tools/dotfiles-deploy.md
T
Frank 411b32ff59 Stop tracking fiction, and stop carrying 80 MiB of wallpaper per clone
Three things were in history that should not have been, all invisible to the
tool that deploys them:

- `home/dank/.omp/dotfiles/**` — 3 files re-hosting `niri/cfg/autostart.kdl`,
  `niri/cfg/keybinds.kdl` and `systemd-user/…/swayidle-lock.service` under a
  prefix `scripts/deploy.sh` never reads (it walks `dotfiles/<pkg>/`). The live
  package is deployed and symlinked, so the copy asserted nothing; it only
  misled. Moved to `.AGENTTRASH/20261020-tracked-debt/`.
- `.pre-pull-backup/**` — 2 managed-skill files, a local backup in history,
  which `.gitignore` itself declares must stay on disk only. Same destination.
- `dotfiles/noctalia/.local/share/noctalia/wallpapers/` — 23 images, 80.4 MiB.
  Untracked, files left in place: `~/.local/share/noctalia/wallpapers` symlinks
  into this directory and the theme reads it, so deleting them would have gone
  black. Every filename carries its wallhaven ID, so a fresh box restores the
  set with one `curl` per file plus `deploy.sh`; losing the set is an acceptable
  outcome, 80 MiB per clone forever is not.

New page `omp-docs/tools/dotfiles-deploy.md` owns the deploy contract (the
`--check`/sync/`--adopt` modes, `zz-$(hostname)` override semantics, the dconf
and systemd-user special cases) because nothing documented it, plus two laws:
media the pipeline consumes is content not config, and `systemctl --user
enable` snapshots an absolute path — so enabling from a worktree means the
seven-day reap silently kills the unit while `is-enabled` keeps answering
`enabled`. That second law is not theoretical:
`default.target.wants/blankpad-desk-autoswitch.service` pointed into the reaped
`wt/de-redesign-20261009` and desk auto-switching had been off since. It is
relinked to `dotfiles/zz-blankpad/` and left inactive rather than started mid-
session; starting it applies a desk profile.

Refs #40
2026-10-20 16:48:33 -07:00

3.7 KiB

type, title, description, tags, timestamp, verified
type title description tags timestamp verified
reference Dotfiles deployment tier How dotfiles/ packages become live configuration — stow-equivalent symlinks, host override packages, and the two laws about theme media and systemd enable symlinks.
dotfiles
deployment
systemd
noctalia
2026-10-20 2026-10-20

Dotfiles deployment tier

dotfiles/ holds home-relative trees and scripts/deploy.sh is a stow-equivalent: the repo checkout is the deployment, and deploying replaces live files with symlinks into the repo, so git pull + deploy.sh is the whole propagation story. One directory per tool (niri, ghostty, gtk-3.0, systemd-user, …); a package named zz-$(hostname) is stowed last and its files replace symlinks coming from base packages.

Mode Effect
deploy.sh --check dry run — adopts identicals, reports what would be linked, lists divergents, writes nothing. Run this first, always
deploy.sh (sync) adopt identicals, link new, quarantine divergents into .quarantine/ and replace them
deploy.sh --adopt like sync, but divergents are reported and skipped rather than quarantined

Two package shapes are not symlinks: dconf/dump.txt is loaded with dconf load /, and systemd-user units get daemon-reload plus enable --now only when their ExecStart binary resolves on the current machine, so a unit belonging to another box stays inert instead of crash-looping.

The tracked unit is the file, not the directory. A live directory can be a real directory and still be fully tracked, because every file inside it is a symlink into the repo (niri is 12 tracked / 1 box-only; gtk-3.0 is 3/0). Any audit that classifies by directory mislabels the tree — classify per file with readlink -f. The live census and its classifier command are in home-config-census.

Law: media the theme pipeline consumes is content, not config

Wallpapers live at dotfiles/noctalia/.local/share/noctalia/wallpapers/ and are gitignored. They were tracked until 2026-10-20 — 23 files, 80 MiB — which meant every clone of a configuration repo carried a media library no diff can review, and the payload only ever grows because deleting a tracked blob from the tree does not delete it from history. Noctalia reads ~/.local/share/noctalia/wallpapers/, which is a set of symlinks into that directory, so the files stay on disk and untracking them broke nothing on this box.

Restore on a fresh box: every filename is wallhaven_<id>.<ext> and the ID is the whole address — curl -L -o <name> "https://wallhaven.cc/w/<id>" puts the library back, then deploy.sh relinks it. Losing the set is an acceptable outcome; 80 MB per clone forever is not.

Law: never systemctl --user enable a unit from a worktree

enable writes ~/.config/systemd/user/default.target.wants/<unit> as a symlink to the unit path it was handed, and that path is absolute. The heartbeat reaps wt/* worktrees older than seven days (live-sync), so a unit enabled from a worktree turns into a dangling symlink while systemctl --user is-enabled still answers enabled — the unit is dead and the status lies about it. Found on 2026-10-20: blankpad-desk-autoswitch.service pointed into the reaped wt/de-redesign-20261009, so desk auto-switching had been silently off since the reap.

Check the link target before the unit file:

ls -l ~/.config/systemd/user/default.target.wants/
# every target must resolve; a dangling one is a reaped worktree, not a config bug

Fix is to relink into the deployment checkout (~/.omp/dotfiles/…), systemctl --user daemon-reload, then confirm with is-active — is-enabled proves nothing.