Only check for pending migrations at login

omarchy-update-user-notify.path watched /usr/share/omarchy/migrations, but
pacman writes that directory during every update, including the blessed
omarchy update, which runs omarchy-migrate a step later. The watcher fired a
critical notification for the migrations the update was already applying in
the visible terminal. A watcher cannot tell that apart from a bypassed
pacman -Syu, so the only trigger that never collides with a running update is
a once-per-login check.

The service that already ran at graphical-session.target is now the whole
mechanism, renamed after the command it runs. That is also all the second-user
case needs: markers are per-user, so anyone who did not run the update finds
them missing at their next login.

Login timing means the toast can be sent before the shell has claimed
org.freedesktop.Notifications, so the notifier waits for a live server first.
The wait is omarchy-first-run's, lifted into omarchy-notification-wait rather
than duplicated.

The package keeps omarchy-update-user-notify.service as a symlink onto the new
unit. Existing users hold an absolute wants symlink to the old path, and the
migration that repoints it only runs for users who run an update, which is the
opposite of who the notifier is for.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
David Heinemeier Hansson
2026-07-26 14:53:29 -07:00
co-authored by Claude Opus 5
parent 171b6374c6
commit 425c3ff84d
16 changed files with 184 additions and 106 deletions
@@ -0,0 +1,16 @@
[Unit]
Description=Notify about pending Omarchy migrations
# Login-only. There used to be an omarchy-update-user-notify.path watching
# /usr/share/omarchy/migrations, but pacman writes that directory during every
# update -- including the blessed `omarchy update`, which runs omarchy-migrate
# itself a step later -- so the watcher notified about migrations that were
# already being applied in the visible update terminal. Checking once per login
# is the only trigger that cannot collide with a running update.
ConditionPathIsDirectory=/usr/share/omarchy/migrations
[Service]
Type=oneshot
ExecStart=/usr/bin/omarchy-migrate-notify
[Install]
WantedBy=graphical-session.target
@@ -1,14 +0,0 @@
[Unit]
Description=Watch for Omarchy migrations
[Path]
# Edge-triggered watch only. PathExistsGlob= is level-triggered: it re-fires
# every time the triggered unit deactivates for as long as the glob matches,
# and applied migrations stay on disk forever, so a glob here busy-loops the
# oneshot service. The once-per-login check lives in the service's own
# WantedBy=graphical-session.target instead.
PathModified=/usr/share/omarchy/migrations
Unit=omarchy-update-user-notify.service
[Install]
WantedBy=graphical-session.target
@@ -1,10 +0,0 @@
[Unit]
Description=Notify about pending Omarchy migrations
ConditionPathIsDirectory=/usr/share/omarchy/migrations
[Service]
Type=oneshot
ExecStart=/usr/bin/omarchy-migrate-notify
[Install]
WantedBy=graphical-session.target