Proof Portal
Omarchy
ProbeLabs65 findings · 95 requirementsA proof layer — requirements, tests and verified fixes — for two of Omarchy's subsystems: the application menu (launcher scripts, QML model, JSONC config, search and selection) and the lock screen (lock scripts, QML, PAM authentication). Scope is deliberately limited to those components of omacom/omarchy; the rest of the distribution is not covered.
snapper.sh overwrites /etc/conf.d/snapper, silently de-registering user configs (home) so omarchy-snapshot stops covering /home
Reported by CaptainVirgil · filed Sep 1, 2026 · open at source
At a glance
- 1 · What is claimed?
- Only the report text below — no validator has restated it as checkable claims yet.
- 2 · What does it affect?
- AreaOutside the audited area· Decided by agents · verified
- 3 · Is it reproducible?
- No validation has been run yet.
- 4 · What remains unclear?
- Not validated yet: no claims, no reproducer.
- 5 · What happens next?
- Decided by agents and verified by a second, independent agent — see the decision.
Original report
System details
Omarchy 4.0.2-1 (version file reports 4.0.0.alpha), snapper 0.13.1 / libsnapper 8.0.0, btrfs root with separate @home subvolume.
What's wrong?
install/config/snapper.sh writes /etc/conf.d/snapper with a truncating redirect rather than merging:
https://github.com/omacom/omarchy/blob/master/install/config/snapper.sh#L20
printf '%s\n' 'SNAPPER_CONFIGS="root"' >"$SNAPPER_CONF_PATH"SNAPPER_CONFIGS is what registers configs with snapperd. Overwriting it silently de-registers every other snapper config the user has, most commonly home on the standard @/@home layout.
The consequence is not limited to timeline snapshots. omarchy-snapshot create enumerates configs from that same registry:
mapfile -t CONFIGS < <(sudo snapper --csvout list-configs | awk -F, 'NR>1 {print $1}')
for config in "${CONFIGS[@]}"; do
sudo snapper -c "$config" create -c number -d "$DESC"so once home is de-registered, `/home` is silently dropped from pre-update snapshots too. The user keeps getting "Snapshots can be selected during boot" on every omarchy update while /home has no coverage at all.
It fails closed and silently: the config file is untouched and still valid, so nothing looks broken. snapper -c home list just returns Unknown config.
Reproduce
# given a working home config
sudo snapper list-configs # root, home
sudo bash install/config/snapper.sh
sudo systemctl restart snapperd
sudo snapper list-configs # root only
sudo snapper -c home list # Unknown config.
cat /etc/conf.d/snapper # SNAPPER_CONFIGS="root"Confirmed as the mechanism by round-tripping it (note snapperd caches the list at startup, so a restart is required to observe either direction):
printf 'SNAPPER_CONFIGS="root home"\n' | sudo tee /etc/conf.d/snapper
sudo systemctl restart snapperd
sudo snapper list-configs # root, home -> restored
sudo snapper -c home list # works, snapshots intactObserved on this machine
The config was de-registered on 2026-08-19 (mtime of the snapper.sh-installed /etc/snapper/configs/root is 08:19 that day). /home snapshots stop dead at that moment and none have been created since, across four subsequent omarchy update runs which each created a root snapshot:
# snapper --no-dbus -c home list (still readable directly)
40 │ Wed 19 Aug 2026 07:30 │ timeline │ timeline
41 │ Wed 19 Aug 2026 07:39 │ number │ 3.8.4
45 │ Wed 19 Aug 2026 08:18 │ number │ 3.8.5 <- last ever
# snapper -c root list
127 │ Wed 26 Aug 2026 13:12 │ number │ 4.0.0-1
128 │ Wed 26 Aug 2026 14:29 │ number │ 4.0.1-1
129 │ Mon 31 Aug 2026 07:40 │ number │ 4.0.1-1
130 │ Tue 01 Sep 2026 07:41 │ number │ 4.0.2-1The timing is unlucky: the same Aug 19 run was the quattro upgrade, which orphaned a lot of user config under /home. The pre-update /home snapshot that would have covered it was prevented by the same script, in the same run.
Suggested fix
Merge rather than truncate — preserve configs Omarchy did not create, while still guaranteeing root is present:
existing=""
[[ -f $SNAPPER_CONF_PATH ]] && existing="$(. "$SNAPPER_CONF_PATH" 2>/dev/null; printf '%s' "${SNAPPER_CONFIGS:-}")"
merged="root"
for c in $existing; do [[ $c == root ]] || merged+=" $c"; done
printf 'SNAPPER_CONFIGS="%s"\n' "$merged" >"$SNAPPER_CONF_PATH"If root-only is a deliberate policy rather than an oversight, then it would help a lot for the script to say so out loud when it drops a config, since today it is completely silent.
Related
- #5546 — migration
1776927490deleting user-configured timeline snapshots. Same theme (Omarchy vs a userhomeconfig) but a different mechanism: that one deletes snapshots, this one de-registers the config so nothing new is ever created, including thenumbersnapshotsomarchy-snapshotwould otherwise take.
Note snapper.sh also runs systemctl disable --now snapper-timeline.timer, which independently stops timeline snapshots for all configs. That part looks intentional and is arguably reasonable for a desktop; this report is specifically about the SNAPPER_CONFIGS overwrite, which additionally removes the event-driven pre-update coverage.
View raw text
### System details
Omarchy 4.0.2-1 (version file reports `4.0.0.alpha`), snapper 0.13.1 / libsnapper 8.0.0, btrfs root with separate `@home` subvolume.
### What's wrong?
`install/config/snapper.sh` writes `/etc/conf.d/snapper` with a truncating redirect rather than merging:
https://github.com/omacom/omarchy/blob/master/install/config/snapper.sh#L20
```bash
printf '%s\n' 'SNAPPER_CONFIGS="root"' >"$SNAPPER_CONF_PATH"
```
`SNAPPER_CONFIGS` is what registers configs with `snapperd`. Overwriting it silently **de-registers every other snapper config the user has**, most commonly `home` on the standard `@`/`@home` layout.
The consequence is not limited to timeline snapshots. `omarchy-snapshot create` enumerates configs from that same registry:
```bash
mapfile -t CONFIGS < <(sudo snapper --csvout list-configs | awk -F, 'NR>1 {print $1}')
for config in "${CONFIGS[@]}"; do
sudo snapper -c "$config" create -c number -d "$DESC"
```
so once `home` is de-registered, **`/home` is silently dropped from pre-update snapshots too**. The user keeps getting "Snapshots can be selected during boot" on every `omarchy update` while `/home` has no coverage at all.
It fails closed and silently: the config file is untouched and still valid, so nothing looks broken. `snapper -c home list` just returns `Unknown config.`
### Reproduce
```bash
# given a working home config
sudo snapper list-configs # root, home
sudo bash install/config/snapper.sh
sudo systemctl restart snapperd
sudo snapper list-configs # root only
sudo snapper -c home list # Unknown config.
cat /etc/conf.d/snapper # SNAPPER_CONFIGS="root"
```
Confirmed as the mechanism by round-tripping it (note `snapperd` caches the list at startup, so a restart is required to observe either direction):
```bash
printf 'SNAPPER_CONFIGS="root home"\n' | sudo tee /etc/conf.d/snapper
sudo systemctl restart snapperd
sudo snapper list-configs # root, home -> restored
sudo snapper -c home list # works, snapshots intact
```
### Observed on this machine
The config was de-registered on 2026-08-19 (mtime of the `snapper.sh`-installed `/etc/snapper/configs/root` is 08:19 that day). `/home` snapshots stop dead at that moment and none have been created since, across four subsequent `omarchy update` runs which each created a `root` snapshot:
```
# snapper --no-dbus -c home list (still readable directly)
40 │ Wed 19 Aug 2026 07:30 │ timeline │ timeline
41 │ Wed 19 Aug 2026 07:39 │ number │ 3.8.4
45 │ Wed 19 Aug 2026 08:18 │ number │ 3.8.5 <- last ever
# snapper -c root list
127 │ Wed 26 Aug 2026 13:12 │ number │ 4.0.0-1
128 │ Wed 26 Aug 2026 14:29 │ number │ 4.0.1-1
129 │ Mon 31 Aug 2026 07:40 │ number │ 4.0.1-1
130 │ Tue 01 Sep 2026 07:41 │ number │ 4.0.2-1
```
The timing is unlucky: the same Aug 19 run was the quattro upgrade, which orphaned a lot of user config under `/home`. The pre-update `/home` snapshot that would have covered it was prevented by the same script, in the same run.
### Suggested fix
Merge rather than truncate — preserve configs Omarchy did not create, while still guaranteeing `root` is present:
```bash
existing=""
[[ -f $SNAPPER_CONF_PATH ]] && existing="$(. "$SNAPPER_CONF_PATH" 2>/dev/null; printf '%s' "${SNAPPER_CONFIGS:-}")"
merged="root"
for c in $existing; do [[ $c == root ]] || merged+=" $c"; done
printf 'SNAPPER_CONFIGS="%s"\n' "$merged" >"$SNAPPER_CONF_PATH"
```
If root-only is a deliberate policy rather than an oversight, then it would help a lot for the script to say so out loud when it drops a config, since today it is completely silent.
### Related
- #5546 — migration `1776927490` deleting user-configured timeline snapshots. Same theme (Omarchy vs a user `home` config) but a different mechanism: that one deletes snapshots, this one de-registers the config so nothing new is ever created, including the `number` snapshots `omarchy-snapshot` would otherwise take.
Note `snapper.sh` also runs `systemctl disable --now snapper-timeline.timer`, which independently stops timeline snapshots for all configs. That part looks intentional and is arguably reasonable for a desktop; this report is specifically about the `SNAPPER_CONFIGS` overwrite, which additionally removes the event-driven pre-update coverage.
Validation
Not checked yet. A validator will restate this report as checkable claims, map it to the project's requirements and write a reproducer that the proof engine runs.
Linked
Not linked to any known issue, other report or change yet.
Decision
Decisions are recorded by our staff — or, where this project allows it, by agents: checked by a second, independent agent, or by a single agent where the project's policy says so. Any decision reached so far is shown below.
- Out of scopeDecided by agents · verified · 2026-10-09 10:27 UTC