Proof Portal

Project overview

Omarchy

ProbeLabs65 findings · 95 requirements

A 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.

Inbox
ReportR-862GitHub issuePublicDecided· Out of scope

Reminders use a monotonic timer, so the countdown pauses while the laptop is suspended

Reported by mnemonicspace · filed Sep 7, 2026 · open at source

Decided: Out of scope — decided by agents · verified 3 days ago.

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

Reminders use a monotonic timer, so the countdown pauses while the laptop is suspendedrevision 1 · captured 2026-09-28 21:23 UTC via poll

Summary

Reminders are scheduled with a systemd monotonic timer, so their countdown pauses while the laptop is suspended. Set a 500-minute reminder, close the lid for 8 hours, open it again, and there are still ~500 minutes left. On a laptop that suspends nightly, a long reminder can drift by days.

This is distinct from #5762 (which was the show display reading the wrong clock, since fixed) — this one is the scheduling clock itself.

Steps to reproduce

  1. omarchy reminder 500 "Test" — the confirmation says "You'll be reminded at 19:24"
  2. Suspend the machine (close the lid) for an hour or more
  3. Resume and run omarchy reminder show
  4. Expected: ~440 minutes left, still due around 19:24
  5. Actual: ~500 minutes left, now due around 20:24 — the clock stood still, and the wall-clock time promised in the confirmation has silently moved

Root cause

bin/omarchy-reminder:197 schedules via OnActiveSec=:

systemd-run --user --quiet --collect --on-active="${minutes}m" --unit="$unit" \
  bash -c '...'

OnActiveSec= is a monotonic timer running on CLOCK_MONOTONIC, which does not advance across suspend. From systemd.timer(5):

These are monotonic timers, independent of wall-clock time and timezones. If the computer is temporarily suspended, the monotonic clock generally pauses, too. Note that if WakeSystem= is used, a different monotonic clock is selected that continues to advance while the system is suspended [...]

WakeSystem=true would switch it to CLOCK_BOOTTIME, but the same man page notes it "requires privileges and is thus generally only available in the system service manager" — these are --user transient units, so that route isn't available.

Inspecting a transient timer created exactly the way the script creates one:

$ systemd-run --user --quiet --collect --on-active="500m" --unit="probe" /bin/true
$ systemctl --user show probe.timer -p TimersMonotonic -p NextElapseUSecRealtime -p WakeSystem
TimersMonotonic={ OnActiveUSec=8h 20min ; next_elapse=2d 18h 49min 55.925289s }
NextElapseUSecRealtime=
WakeSystem=no

There is no wall-clock anchor at all. The divergence on the machine I hit this on, mid-boot:

  • CLOCK_MONOTONIC (systemd's reference): ~240,595 s
  • CLOCK_BOOTTIME (/proc/uptime): ~407,955 s
  • difference: ~197,000 s — about 2.3 days of suspend the timer never counted

Worth noting the script already contradicts itself here: the confirmation notification promises a wall-clock time,

remind_at=$(date -d "+${minutes} minutes" +%H:%M)
confirmation="You'll be reminded at $remind_at"

which the monotonic timer doesn't honor once the machine sleeps.

Suggested fix

Anchor the timer to wall-clock time instead. A calendar timer that elapses during suspend fires immediately on resume, which is the behavior users expect from "remind me in N minutes":

systemd-run --user --quiet --collect \
  --on-calendar="$(date -d "+${minutes} minutes" +'%Y-%m-%d %H:%M:%S')" --unit="$unit" \
  bash -c '...'

I checked that this is a drop-in change:

  • the transient unit still gets RemainAfterElapse=no, so it cleans itself up the same way
  • active_reminder_timers() reads .next from systemctl list-timers --output=json, which is already a wall-clock value and works identically for calendar timers
  • show, show --json, the bar indicator, and clear all key off the unit name and list-timers output, none of which change

It still won't wake a sleeping machine — that needs WakeSystem=, which a user manager can't do — but the reminder fires the moment the lid opens rather than resetting its countdown, and the time shown in the confirmation becomes true.

Environment

  • Omarchy 4.0.2-1 (also present on quattro, dev, and master as of filing)
  • Arch Linux, systemd 261 (261.2-1-arch)
  • Hyprland 0.56.2
  • Framework Laptop 13 Pro (Intel Core Ultra Series 3)
View raw text
## Summary

Reminders are scheduled with a systemd **monotonic** timer, so their countdown pauses while the laptop is suspended. Set a 500-minute reminder, close the lid for 8 hours, open it again, and there are still ~500 minutes left. On a laptop that suspends nightly, a long reminder can drift by days.

This is distinct from #5762 (which was the `show` *display* reading the wrong clock, since fixed) — this one is the scheduling clock itself.

## Steps to reproduce

1. `omarchy reminder 500 "Test"` — the confirmation says *"You'll be reminded at 19:24"*
2. Suspend the machine (close the lid) for an hour or more
3. Resume and run `omarchy reminder show`
4. **Expected:** ~440 minutes left, still due around 19:24
5. **Actual:** ~500 minutes left, now due around 20:24 — the clock stood still, and the wall-clock time promised in the confirmation has silently moved

## Root cause

`bin/omarchy-reminder:197` schedules via `OnActiveSec=`:

```bash
systemd-run --user --quiet --collect --on-active="${minutes}m" --unit="$unit" \
  bash -c '...'
```

`OnActiveSec=` is a monotonic timer running on `CLOCK_MONOTONIC`, which does not advance across suspend. From `systemd.timer(5)`:

> These are monotonic timers, independent of wall-clock time and timezones. If the computer is temporarily suspended, the monotonic clock generally pauses, too. Note that if `WakeSystem=` is used, a different monotonic clock is selected that continues to advance while the system is suspended [...]

`WakeSystem=true` would switch it to `CLOCK_BOOTTIME`, but the same man page notes it "requires privileges and is thus generally only available in the system service manager" — these are `--user` transient units, so that route isn't available.

Inspecting a transient timer created exactly the way the script creates one:

```
$ systemd-run --user --quiet --collect --on-active="500m" --unit="probe" /bin/true
$ systemctl --user show probe.timer -p TimersMonotonic -p NextElapseUSecRealtime -p WakeSystem
TimersMonotonic={ OnActiveUSec=8h 20min ; next_elapse=2d 18h 49min 55.925289s }
NextElapseUSecRealtime=
WakeSystem=no
```

There is no wall-clock anchor at all. The divergence on the machine I hit this on, mid-boot:

- `CLOCK_MONOTONIC` (systemd's reference): ~240,595 s
- `CLOCK_BOOTTIME` (`/proc/uptime`): ~407,955 s
- difference: ~197,000 s — about **2.3 days of suspend the timer never counted**

Worth noting the script already contradicts itself here: the confirmation notification promises a wall-clock time,

```bash
remind_at=$(date -d "+${minutes} minutes" +%H:%M)
confirmation="You'll be reminded at $remind_at"
```

which the monotonic timer doesn't honor once the machine sleeps.

## Suggested fix

Anchor the timer to wall-clock time instead. A calendar timer that elapses during suspend fires immediately on resume, which is the behavior users expect from "remind me in N minutes":

```bash
systemd-run --user --quiet --collect \
  --on-calendar="$(date -d "+${minutes} minutes" +'%Y-%m-%d %H:%M:%S')" --unit="$unit" \
  bash -c '...'
```

I checked that this is a drop-in change:

- the transient unit still gets `RemainAfterElapse=no`, so it cleans itself up the same way
- `active_reminder_timers()` reads `.next` from `systemctl list-timers --output=json`, which is already a wall-clock value and works identically for calendar timers
- `show`, `show --json`, the bar indicator, and `clear` all key off the unit name and `list-timers` output, none of which change

It still won't *wake* a sleeping machine — that needs `WakeSystem=`, which a user manager can't do — but the reminder fires the moment the lid opens rather than resetting its countdown, and the time shown in the confirmation becomes true.

## Environment

- Omarchy 4.0.2-1 (also present on `quattro`, `dev`, and `master` as of filing)
- Arch Linux, systemd 261 (261.2-1-arch)
- Hyprland 0.56.2
- Framework Laptop 13 Pro (Intel Core Ultra Series 3)

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 11:05 UTC