deploy.sh is unsafe to run beside a live session — this makes it safe
I preflighted the real deploy authorised after #43 and stopped: what I told you the run
touches — "only symlink owners, no file contents" — was wrong. sync also loads dconf and enable --nows units. Two of those actions were harmful on this box, and a third thing the
preflight caught was a wrong-box value already living in your settings. Refs #44. The
deploy has not been run.
what sync would have done
measured state
now
enable --now swayidle-lock.service
enabled / inactive, no swayidle process, not in autostart.kdl
started only if systemd reports nothing-yet — screens stay unlocked
enable --now live-sync.service
linked, timer-driven
enabled, not started; the heartbeat keeps its own schedule
dconf load /
6 of 24 keys carry /home/dank paths
those 6 keys deleted; picture-options='zoom' (a real preference) kept
1. The unit rule, and why the exit status is a trap
swayidle-lock.service is installed and deliberately not running. --now would have armed
a lock timer mid-conversation. A unit is now started only when its state is empty or disabled — a fresh box, which still gets everything up. Reading "already installed" from $? is wrong: is-enabled exits 1 for linked, the same code it gives disabled, so my
first version treated the timer-driven live-sync.service as uninstalled and started it. The
rule reads the printed state.
2. A sentence I committed in #43 that measurement contradicts
--check 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 and .zshrc all did here, with the links already correct, because the walk visits base first and
reports the intermediate owner change. So my "RELINK noise is the sound of a stale override
waiting" is too strong; it is corrected to: the link target and actions=0 decide, the line
alone proves nothing. The layout.kdl hazard #43 deleted was real — the signal for it is readlink, not the line.
3. Six keys from another box, five of them invisible to a diff
The last five showed no conflict, because blankpad's live tree already held the same /home/dank values — an earlier deploy had written them here. A foreign value that agrees
with live is invisible to any diff and still wrong; this is why the acceptance check compares
keys rather than diffing text (dconf load writes only keys present, so a diff misleads in
both directions). The dump is now 18 keys, 0 conflicts against live, no /home/ values
at all. As part of landing this I also clear the two live wallpaper URIs on blankpad
(gsettings … picture-uri '' and -dark) — niri draws the wallpaper, noctalia owns it, and
nothing reads a dead path.
Tests
tests/deploy.bats +4 over a stub systemctl, because the real one on this box is
precisely what must not run from a test. Red before: an enabled unit and a linked unit
both get --now. Green after, including both directions that keep the fix 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.
Once merged: I fast-forward ~/.omp, run the real deploy.sh, and the acceptance is actions=0, no ENABLE … started for swayidle-lock.service, and the live dconf keys
cleared. If you would rather not have the deploy run at all, say so and this lands as
code-and-docs only.
# `deploy.sh` is unsafe to run beside a live session — this makes it safe
I preflighted the real deploy authorised after #43 and stopped: what I told you the run
touches — "only symlink owners, no file contents" — was wrong. `sync` also loads dconf and
`enable --now`s units. Two of those actions were harmful on this box, and a third thing the
preflight caught was a wrong-box value already living in your settings. Refs #44. **The
deploy has not been run.**
|what `sync` would have done|measured state|now|
|---|---|---|
|`enable --now swayidle-lock.service`|`enabled` / `inactive`, no swayidle process, not in `autostart.kdl`|started only if systemd reports nothing-yet — screens stay unlocked|
|`enable --now live-sync.service`|`linked`, timer-driven|`enable`d, not started; the heartbeat keeps its own schedule|
|`dconf load /`|6 of 24 keys carry `/home/dank` paths|those 6 keys deleted; `picture-options='zoom'` (a real preference) kept|
## 1. The unit rule, and why the exit status is a trap
`swayidle-lock.service` is installed and deliberately not running. `--now` would have armed
a lock timer mid-conversation. A unit is now started only when its state is empty or
`disabled` — a fresh box, which still gets everything up. Reading "already installed" from
`$?` is wrong: `is-enabled` exits **1** for `linked`, the same code it gives `disabled`, so my
first version treated the timer-driven `live-sync.service` as uninstalled and started it. The
rule reads the printed state.
## 2. A sentence I committed in #43 that measurement contradicts
`--check` 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` and
`.zshrc` all did here, with the links already correct, because the walk visits base first and
reports the intermediate owner change. So my "RELINK noise is the sound of a stale override
waiting" is too strong; it is corrected to: the link target and `actions=0` decide, the line
alone proves nothing. The `layout.kdl` hazard #43 deleted was real — the signal for it is
`readlink`, not the line.
## 3. Six keys from another box, five of them invisible to a diff
[org/gnome/portal/filechooser/firefox] last-folder-path repo '/home/dank/Downloads' live '/home/blank/Downloads'
[org/gnome/nautilus/window-state] initial-size, initial-size-file-chooser, maximized
[org/gnome/desktop/background] picture-uri, picture-uri-dark = file:///home/dank/.config/background
The last five showed **no** conflict, because blankpad's live tree already held the same
`/home/dank` values — an earlier deploy had written them here. A foreign value that agrees
with live is invisible to any diff and still wrong; this is why the acceptance check compares
keys rather than diffing text (`dconf load` writes only keys present, so a diff misleads in
both directions). The dump is now 18 keys, **0 conflicts** against live, **no `/home/` values
at all**. As part of landing this I also clear the two live wallpaper URIs on blankpad
(`gsettings … picture-uri ''` and `-dark`) — niri draws the wallpaper, noctalia owns it, and
nothing reads a dead path.
## Tests
`tests/deploy.bats` +4 over a **stub `systemctl`**, because the real one on this box is
precisely what must not run from a test. Red before: an `enabled` unit and a `linked` unit
both get `--now`. Green after, including both directions that keep the fix 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.
## Verification and what follows
`bats tests/` **70/70**, `kb-lint.sh omp-docs` 0, `kb-coverage.py` 0, `bash -n` clean.
Once merged: I fast-forward `~/.omp`, run the real `deploy.sh`, and the acceptance is
`actions=0`, no `ENABLE … started` for `swayidle-lock.service`, and the live dconf keys
cleared. If you would rather not have the deploy run at all, say so and this lands as
code-and-docs only.
---
cwd: /home/blank/.omp/wt/wt-20261019-125509-7c8a99d · session: 01a155bb-6474-7366-be9d-629f74af0e05
Build worktree: `~/.omp/wt/wt-deploy-live-safe` off `origin/main`. Refs #44
`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.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
deploy.shis unsafe to run beside a live session — this makes it safeI preflighted the real deploy authorised after #43 and stopped: what I told you the run
touches — "only symlink owners, no file contents" — was wrong.
syncalso loads dconf andenable --nows units. Two of those actions were harmful on this box, and a third thing thepreflight caught was a wrong-box value already living in your settings. Refs #44. The
deploy has not been run.
syncwould have doneenable --now swayidle-lock.serviceenabled/inactive, no swayidle process, not inautostart.kdlenable --now live-sync.servicelinked, timer-drivenenabled, not started; the heartbeat keeps its own scheduledconf load //home/dankpathspicture-options='zoom'(a real preference) kept1. The unit rule, and why the exit status is a trap
swayidle-lock.serviceis installed and deliberately not running.--nowwould have armeda lock timer mid-conversation. A unit is now started only when its state is empty or
disabled— a fresh box, which still gets everything up. Reading "already installed" from$?is wrong:is-enabledexits 1 forlinked, the same code it givesdisabled, so myfirst version treated the timer-driven
live-sync.serviceas uninstalled and started it. Therule reads the printed state.
2. A sentence I committed in #43 that measurement contradicts
--checkprintsRELINKfor every path thezztier carries, even when the live linkalready points at the override —
rules.kdl,keybinds.kdl,misc.kdl,autostart.kdland.zshrcall did here, with the links already correct, because the walk visits base first andreports the intermediate owner change. So my "RELINK noise is the sound of a stale override
waiting" is too strong; it is corrected to: the link target and
actions=0decide, the linealone proves nothing. The
layout.kdlhazard #43 deleted was real — the signal for it isreadlink, not the line.3. Six keys from another box, five of them invisible to a diff
The last five showed no conflict, because blankpad's live tree already held the same
/home/dankvalues — an earlier deploy had written them here. A foreign value that agreeswith live is invisible to any diff and still wrong; this is why the acceptance check compares
keys rather than diffing text (
dconf loadwrites only keys present, so a diff misleads inboth directions). The dump is now 18 keys, 0 conflicts against live, no
/home/valuesat all. As part of landing this I also clear the two live wallpaper URIs on blankpad
(
gsettings … picture-uri ''and-dark) — niri draws the wallpaper, noctalia owns it, andnothing reads a dead path.
Tests
tests/deploy.bats+4 over a stubsystemctl, because the real one on this box isprecisely what must not run from a test. Red before: an
enabledunit and alinkedunitboth get
--now. Green after, including both directions that keep the fix honest — adisabledunit is stillenable --now'd so a fresh box comes up, and a unit whoseExecStartis absent here is never touched.
Verification and what follows
bats tests/70/70,kb-lint.sh omp-docs0,kb-coverage.py0,bash -nclean.Once merged: I fast-forward
~/.omp, run the realdeploy.sh, and the acceptance isactions=0, noENABLE … startedforswayidle-lock.service, and the live dconf keyscleared. If you would rather not have the deploy run at all, say so and this lands as
code-and-docs only.
cwd: /home/blank/.omp/wt/wt-20261019-125509-7c8a99d · session: 01a155bb-6474-7366-be9d-629f74af0e05
Build worktree:
~/.omp/wt/wt-deploy-live-safeofforigin/main. Refs #44