`sync` on a box with a live session on it was unsafe in two independent ways, found by preflighting the run rather than performing it. Refs #44. **`enable --now` would have armed a screen lock mid-session.** The unit loop started every `systemd-user/` unit whose `ExecStart` resolves. `swayidle-lock.service` on blankpad is `enabled`/`inactive` — nothing started it, no swayidle process exists, `autostart.kdl` does not launch one — so one `deploy.sh` would have begun blanking and locking the monitors while the operator was mid-sentence. `live-sync.service` is `linked`, driven by its timer, and `--now` forces a heartbeat commit at an arbitrary moment. A unit is now started only when systemd reports it as nothing-yet (`""`/`disabled`), which is precisely a fresh box; anything already installed is merely `enable`d. The state has to come from the **printed state**: `is-enabled` exits 1 for `linked` exactly as for `disabled`, so exit status cannot distinguish "installed, timer-driven" from "never installed" — the first version of this fix got that wrong and the test caught it. **`--check` output was being read as more than it can mean.** It prints `RELINK` for every path the `zz` tier carries, even when the live link already points at the override (`rules.kdl`, `keybinds.kdl`, `misc.kdl`, `autostart.kdl`, `.zshrc` all did on blankpad), because the walk visits the base package first and reports the intermediate owner change. The sentence committed in #43 — RELINK noise is "the sound of a stale override waiting" — is too strong and is corrected: the line proves a pending change only when `readlink` shows the live target is not already the `zz-$HOST` file, and `actions=0` is the honest summary. The stale-override hazard #43 removed was and is real; the signal for it is the target, not the line. **The dconf dump carried six of its 24 keys from another box**, none of them preferences: a Firefox file-chooser `last-folder-path` of `/home/dank/Downloads`, a nautilus `window-state` section, and `picture-uri`/`picture-uri-dark` pointing at `file:///home/dank/.config/background`. The last five showed no conflict because blankpad's live tree *already* held those `/home/dank` values — an earlier deploy wrote them here — and a foreign value that agrees with live is invisible to any diff while still being wrong. They are dropped; `picture-options='zoom'` stays, because it is a preference. The live wallpaper URIs are cleared on the box as part of landing this (niri draws the wallpaper, noctalia owns it, nothing reads a dead path). `tests/deploy.bats` grows by four, over a stub `systemctl` — the real one on this box is exactly what must not be invoked from a test. Red before: an already-`enabled` unit and a `linked` unit both get `--now`. Green after, including the two directions that keep the change honest: a `disabled` unit is still `enable --now`'d so a fresh box comes up, and a unit whose `ExecStart` is absent here is never touched at all. Verification: `bats tests/` 70/70, `kb-lint.sh omp-docs` 0, `kb-coverage.py` 0. The dump now reconciles against live state with **0 conflicts and no `/home/` values in 18 keys**, proven by key-by-key comparison rather than `diff` — `dconf load` writes only the keys present, so a diff overstates the damage one way and hides it the other.
14 KiB
type, title, description, tags, created, census-date, verified, source
| type | title | description | tags | created | census-date | verified | source | ||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| reference | Home Configuration Census (blankpad) | Per-file tracked-vs-box-only census of ~/.config on blankpad — the input for the dotfiles pruning/adoption session. |
|
2026-08-28 | 2026-10-20 | 2026-10-20 | blankpad (CachyOS, /home/blank) |
This page is the input for the dotfiles pruning/adoption session: for every
~/.config entry it separates what the repo already tracks from what lives only
on this box, and sorts the box-only half into adopt / never-track / prune.
Method
Classification is per FILE, not per directory: the tracked unit is a symlink
into ~/.omp/dotfiles/. A directory can look "real" (a plain folder, not itself
a symlink) while every file inside it is a tracked symlink — niri and gtk-3.0
do exactly that. Conversely a directory can be a whole symlink into dotfiles
(lazyvim) and be entirely tracked. So a directory-level verdict lies; only the
leaf symlink target is ground truth.
- tracked = a file whose fully-resolved target (
readlink -f) is under/home/blank/.omp/dotfiles/. - box-only = a regular file, or a symlink that resolves elsewhere.
Rerun this classifier rather than trusting the table below:
DOT=/home/blank/.omp/dotfiles; CFG=/home/blank/.config
for d in "$CFG"/*; do
[ -L "$d" ] && case "$(readlink -f "$d")" in "$DOT"/*) echo "$(basename "$d"): tracked=ALL box-only=0"; continue;; esac
[ -d "$d" ] || { echo "$(basename "$d"): FILE (top-level)"; continue; }
tr=0; bo=0; names=""
while IFS= read -r -d '' f; do
if [ -L "$f" ]; then case "$(readlink -f "$f")" in "$DOT"/*) tr=$((tr+1)); continue;; esac; fi
bo=$((bo+1)); names+=" ${f#"$CFG"/}"
done < <(find "$d" -mindepth 1 \( -type f -o -type l \) -print0 2>/dev/null)
printf '%s: tracked=%d box-only=%d%s\n' "$(basename "$d")" "$tr" "$bo" "$names"
done
~/.config — tracked vs box-only
Profile/browser dirs (mozilla 5471 files, obsidian 99, FreeTube 56,
nirimod 116, google-chrome-for-testing 5) are app state, never tracked, and
are omitted as rows. Box-only bulk that is regenerated-by-the-program is named
by category, not file-by-file.
~/.config/ dir |
tracked | box-only | box-only files |
|---|---|---|---|
| alacritty | 1 | 1 | themes/noctalia.toml (generated) |
| autostart | 0 | 3 | Flameshot.desktop, cachyos-hello.desktop, .AGENTTRASH/Handy.desktop |
| bat | 0 | 2 | config, themes/noctalia.tmTheme (generated) |
| btop | 0 | 2 | btop.conf, themes/noctalia.theme (generated) |
| cachyos | 0 | 1 | cachyos-hello/cachyos-hello.log (state) |
| cava | 0 | 1 | themes/noctalia (generated) — program absent, prune |
| crush | 0 | 37 | skills/<37> — skills-CLI install |
| containers | 0 | 2 | systemd/franksign-db.container, systemd/postgres.env (see §Owned-elsewhere / secret tier) |
| dconf | 0 | 1 | user (compiled dconf db, state) |
| devin | 0 | 37 | skills/<37> — skills-CLI install |
| fastfetch | 0 | 1 | themes/noctalia.jsonc (generated) |
| fish | 2 | 1 | fish_variables (fish var store, state) |
| flameshot | 0 | 1 | flameshot.ini |
| foot | 0 | 2 | foot.ini, themes/noctalia (generated) — program absent, prune |
| fzf | 0 | 2 | themes/noctalia.sh, themes/noctalia.fish (generated) |
| ghostty | 2 | 1 | themes/noctalia (generated) |
| glow | 0 | 2 | glow.yml, noctalia.json (generated) |
| goose | 0 | 37 | skills/<37> — skills-CLI install |
| gtk-3.0 | 3 | 0 | — |
| gtk-4.0 | 2 | 1 | servers (KDE-generated) |
| helix | 0 | 1 | themes/noctalia.toml (generated) — hx absent, prune |
| herdr | 0 | 1 | noctalia-colors.toml (generated) |
| hypr | 0 | 2 | hyprland.conf, noctalia.conf (generated) — hyprland absent, prune |
| kimchi | 0 | 37 | harness/skills/<37> — skills-CLI install |
| kitty | 0 | 2 | kitty.conf, themes/noctalia.conf (generated) — program absent, prune |
| labwc | 0 | 2 | rc.xml, noctalia.conf (generated) — program absent, prune |
| lazygit | 0 | 2 | config.yml, themes/noctalia.yml (generated) |
| lazyvim | ALL | 0 | — (whole dir symlink → dotfiles/lazyvim) |
| mango | 0 | 2 | config.conf, noctalia.conf (generated) — program absent, prune |
| micro | 0 | 154 | adopt: settings.json, bindings.json; generated: colorschemes/noctalia.micro; bundled/state: syntax/* (146), buffers/history |
| mpv | 0 | 0 | — (empty) |
| nautilus | 0 | 0 | — (empty) |
| niri | 8 | 2 | 8 live KDL includes (5 from dotfiles/niri, 3 overridden by the zz-blankpad tier, whose own 7 niri files are counted in that tier — the stale layout.kdl duplicate and generated noctalia.kdl were removed by #43) + see Never track for the relic. Box-only: noctalia.kdl (generated include, refused by deploy.sh) and the retired copy |
| noctalia | 3 | 2672 | Tracked and live-linked: config.toml, palettes/Gruber Red.json, state/noctalia/settings.toml. Everything else is app state plus noctalia's downloaded catalog: community-palettes/ 66, community-templates/ 80, wallhaven/thumbs, clipboard/, plugins/, state.toml, usage_counts.json. The app's wallpaper library is ~/.local/share/noctalia/wallpapers — real files it owns; the repo's duplicate copy of 23 JPEGs was untracked by #41 and deleted from this checkout by the merge, which is what untracking does in every checkout |
| nvim | 0 | 0 | — (empty) |
| pywalfox | 0 | 1 | config.json — program absent, prune |
| qt5ct | 0 | 1 | colors/noctalia.conf (generated) — program absent, prune |
| qt6ct | 0 | 1 | colors/noctalia.conf (generated) — program absent, prune |
| rofi | 0 | 1 | noctalia.rasi (generated) — program absent, prune |
| scroll | 0 | 2 | config, noctalia (generated) — program absent, prune |
| secrets | 0 | 4 | gitea, hf_token, hf_token_write, kagi_api_key (names only — secret tier) |
| shelly | 0 | 2 | config.json, settings.json |
| sway | 0 | 2 | config, noctalia (generated) — program absent, prune |
| systemd | 9 | 3 | user/fib-watchdog.service, user/fib-watchdog.timer, user/timers.target.wants/fib-watchdog.timer |
| tmux | 0 | 1 | themes/noctalia.conf (generated) |
| turborepo | 0 | 1 | telemetry.json — turbo absent, prune |
| umbriel | 0 | 2 | config.toml, noctalia.toml (generated) — program absent, prune |
| unity3d | 0 | 235 | RimWorld state: Saves (201), Config (21), other (13) — never track |
| wezterm | 0 | 1 | colors/Noctalia.toml (generated) — program absent, prune |
| yay | 0 | 0 | — (empty) |
| ytm-player | 0 | 1 | theme.toml — program absent, prune |
Top-level ~/.config files (not directories)
All regular files, none symlinked into dotfiles:
starship.toml (prune — starship absent), frank-job-hunt.env (secret tier),
kdeglobals, partitionmanagerrc, pavucontrol.ini, cachyos-hello.json,
user-dirs.dirs, user-dirs.locale (XDG/desktop state).
Adoption candidates (program passes command -v)
Pre-vetted box-only files worth moving into dotfiles. Authorship is from the
file contents, read directly.
| File | Program (path) | Authored or default |
|---|---|---|
~/.gitconfig |
git (/usr/bin/git) |
Authored — single setting line: credential.helper = store --file ~/.config/secrets/gitea (points at the secret tier; adopt the line, never the file it names) |
~/.config/bat/config |
bat (/usr/bin/bat) |
Authored — one line --theme=noctalia |
~/.config/lazygit/config.yml |
lazygit (/usr/bin/lazygit) |
Authored — 28-line custom noctalia color theme |
~/.config/micro/settings.json |
micro (/usr/bin/micro) |
Authored — {"colorscheme":"noctalia"} |
~/.config/micro/bindings.json |
micro (/usr/bin/micro) |
Default — empty {}, no custom bindings |
~/.config/flameshot/flameshot.ini |
flameshot (/usr/bin/flameshot) |
Authored — contrastOpacity=188, startupLaunch=true |
~/.config/glow/glow.yml |
glow (/usr/bin/glow) |
Default — shipped template, all default values (noctalia look comes from the generated noctalia.json, not this file) |
~/.config/autostart/Flameshot.desktop |
flameshot (/usr/bin/flameshot) |
Authored — Exec=flameshot, X-GNOME-Autostart-enabled=true |
Every ~/.config box-only row above lists each file, so the session can extend
beyond these seven (e.g. btop/btop.conf, shelly/* are also installed-program
configs).
Never track (box-only)
| Reason | Contents |
|---|---|
| Generated palette expansion | Every themes/noctalia*, */noctalia.*, */colors/noctalia* / Noctalia* (24 files outside app-profile dirs). Machine-written by matugen/noctalia, not hand-authored: the stat -c '%y %n' cluster 2026-10-14 19:05:40.330…40.813 -0700 writes 24 files in one second (alacritty/themes/noctalia.toml at .330212397, btop/themes/noctalia.theme at .334212456, tmux/themes/noctalia.conf at .813219586, …); later re-runs re-stamp singles — bat/themes/noctalia.tmTheme 2026-10-18 17:11:22, niri/noctalia.kdl 2026-10-18 17:36:27, mango/noctalia.conf 2026-10-17 18:23:37. A same-second mass-write is generation, never an edit. |
| App state / profiles | mozilla (5471), unity3d RimWorld state (235), nirimod (116), obsidian (99), FreeTube (56), google-chrome-for-testing (5); plus per-program state inside tracked dirs: dconf/user, fish/fish_variables, micro/syntax/*+micro/buffers/history, gtk-4.0/servers, cachyos/cachyos-hello.log. State hides inside a tracked file too: dconf/dump.txt carried last-folder-path, a nautilus window-state section and picture-uri/picture-uri-dark — all /home/dank values, and the wallpaper URIs were live on blankpad, i.e. already deployed here — dropped by #44, see tools/dotfiles-deploy. |
| Skills-CLI installs | crush (37), devin (37), goose (37), kimchi/harness (37) skill trees — provisioned by the skills CLI, owned by the store, not this repo. See skills/store-wiring. |
| Secret tier | ~/.config/secrets/ (gitea, hf_token, hf_token_write, kagi_api_key — names only), top-level frank-job-hunt.env, containers/systemd/postgres.env. Never tracked, values never printed. |
| Trash committed inside the tree | dotfiles/niri/.config/niri/cfg/.AGENTTRASH/display.kdl.superseded — a retired output config committed 2026-10-09, five days before .gitignore:54 gained .AGENTTRASH/ (2026-10-14). Tracked-then-ignored: an ignore rule never reaches an already-tracked path, so the only repair is git rm --cached, done by #41. The rule does match at depth — git check-ignore --no-index -v dotfiles/niri/.config/niri/cfg/.AGENTTRASH/x resolves to .gitignore:54 — so a fresh in-tree trash dir is ignored from birth and this does not recur on its own. |
Owned-elsewhere (do not adopt here)
~/.config/containers/systemd/franksign-db.container— header: "Installed byinfra/setup-dev.shinto~/.config/containers/systemd/." Owned by the franksign repo; its quadlet, not this box's config.~/.config/systemd/user/fib-watchdog.service+.timer— box-only.ExecStart=/usr/bin/bun src/cli.ts workerwithWorkingDirectory=/home/blank/Projects/frank-intelligence-bench.systemctl --user is-active fib-watchdog.timer→ inactive. This box holds the only copy. Do not adopt it intodotfiles:ExecStartandWorkingDirectoryare the bench project's internals, so that repo owns the unit — land it there and this row becomes "deployed by the bench repo". Until then it is a reinstall risk recorded here, not a dotfiles gap.- Hygiene finding, fixed 2026-10-20: the enable-symlink
~/.config/systemd/user/default.target.wants/blankpad-desk-autoswitch.servicepointed into~/.omp/wt/de-redesign-20261009/…, a worktree the heartbeat had already reaped — so desk auto-switching was silently off whilesystemctl --user is-enabledstill answeredenabled. Relinked todotfiles/zz-blankpad/.config/systemd/user/blankpad-desk-autoswitch.serviceanddaemon-reloaded; leftinactiveon purpose, because starting it mid- session applies a desk profile and the box is in use. Law and diagnosis: dotfiles-deploy.
Prune list (owning program absent from command -v)
All verified with command -v <prog> (git resolves to /usr/bin/git; a session
alias can mask it, so probe in a clean shell).
| Config | Program checked |
|---|---|
sway, hypr, labwc, mango, scroll, umbriel |
sway hyprland labwc mango scroll umbriel — all ABSENT |
wezterm, kitty, foot |
wezterm kitty foot — all ABSENT |
rofi, helix, cava, ytm-player, starship.toml |
rofi hx cava ytm-player starship — all ABSENT |
pywalfox, qt5ct, qt6ct, turborepo |
pywalfox qt5ct qt6ct turbo — all ABSENT |
The first three rows are the expected set (all 14 confirmed absent). My check
disagrees with the expected set by extending it: pywalfox, qt5ct, qt6ct,
turborepo are also installed-nowhere config dirs and belong in the prune list.
Note the orphan dirs cava, rofi, helix, wezterm, qt5ct, qt6ct contain
only a generated noctalia palette file — pruning them removes no authored
config. crush/devin/goose/kimchi also fail command -v but are the
skills-CLI tier above, not this session's prune targets.
Links
- skills/store-wiring — owns the skills-CLI tier
claim (
crush/devin/goose/kimchi). - KB index — knowledge-base entry point.