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-1365GitHub issuePublicDecided· Out of scope

Clock calendar: a day repeats and subsequent days shift when navigating months (Repeater delegate recycling)

Reported by vittokhl · filed Aug 27, 2026Closed upstream on 2026-10-11 by the merge of PR #10476 (closed by omarchybot, a bot). GitHub close reason: completed.

Decided: Out of scope — decided by agents · verified 4 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

Clock calendar: a day repeats and subsequent days shift when navigating months (Repeater delegate recycling)revision 1 · captured 2026-09-28 21:24 UTC via poll

System details

  • Omarchy 4.0.1-1 (stable). /usr/share/omarchy/version still reports 4.0.0.alpha.
  • Quickshell 0.3.1-1, Hyprland 0.56.2-1, Linux 7.1.9-arch1-2.
  • Plugin: first-party omarchy.clock bar-widget + calendar panel (/usr/share/omarchy/shell/plugins/panels/clock/).
  • Keyboard layout latam, no custom calendar settings (default week start from Qt.locale()).

Summary

In the clock calendar popup, while stepping between months a held-over day is drawn twice and every day after it shifts by one. In my case the 5th of September was repeated and all subsequent days ran late. The repeated value is a stale ghost from the previously shown grid, and the dislocation persists across further month steps until the panel is reopened.

What I verified first

The grid math in Model.js (monthGrid) is correct. I ran it under node for 2026-08 and 2026-09 across every weekStart (0, 1, 6): 42 unique days, correct leading/trailing bleed, ISO week numbers stable. So the data fed to the view is not the source of the duplicate.

Suspected mechanism

Panel.qml builds the grid with two nested Repeaters over plain JS-object models:

Repeater {
  model: root.weeks
  Row {
    required property var modelData
    ...
    Repeater {
      model: modelData.days
      Rectangle { required property var modelData; ... }
    }
  }
}

root.weeks is readonly property var weeks: Model.monthGrid(viewYear, viewMonth, weekStart, todayKey) — a fresh 6-element array of {week, days: [...]} objects recreated on every viewMonth/viewYear change. The literal grid is always exactly 6 rows, so when the month changes the outer Repeater keeps its 6 delegates instead of re-creating them. If a recycled delegate does not re-evaluate its inner Repeater model (modelData.days) for a given reused index, the stale day cells from the previous month survive — which presents as one repeated day with the rest dislocated by one.

The symptoms (an exact held-over day duplicated, later days shifted, cleared on reopen) match a delegate-identity / model-not-invalidated problem rather than bad data. I could not reproduce the QML rendering here to pin it down precisely, so this is a hypothesis backed by the data check above, not a confirmed root cause.

Steps to reproduce

  1. Left-click the clock to open the calendar panel.
  2. Navigate to a months-away view (e.g. September) using the chevrons or keyboard, then step adjacent months a few times.
  3. Read the day grid. A day from the previously shown month is rendered in place of (or alongside) the current one, and every later day is off by one.

It clears when the panel is closed and reopened.

Expected

Each grid refresh shows exactly the 42 days monthGrid returns, with no stale cells carried over from the previous month while stepping.

Question for maintainers

Is the nested-Repeater-over-JS-array pattern here known to misbehave in Quickshell when the delegate count stays constant? If so, the fix is likely to give the inner Repeater a stable key/identity (e.g. keying delegates on the cell date key that Model.js already computes) or to drive the grid from an explicit model type instead of raw JS arrays.

<img width="494" height="403" alt="Image" src="https://github.com/user-attachments/assets/571e15ce-9b6f-4724-8372-9e73f87693a8" />

View raw text
### System details

- Omarchy 4.0.1-1 (stable). `/usr/share/omarchy/version` still reports `4.0.0.alpha`.
- Quickshell 0.3.1-1, Hyprland 0.56.2-1, Linux 7.1.9-arch1-2.
- Plugin: first-party `omarchy.clock` bar-widget + calendar panel (`/usr/share/omarchy/shell/plugins/panels/clock/`).
- Keyboard layout `latam`, no custom calendar settings (default week start from `Qt.locale()`).

### Summary

In the clock calendar popup, while stepping between months a held-over day is drawn twice and every day after it shifts by one. In my case the 5th of September was repeated and all subsequent days ran late. The repeated value is a stale ghost from the previously shown grid, and the dislocation persists across further month steps until the panel is reopened.

### What I verified first

The grid math in `Model.js` (`monthGrid`) is correct. I ran it under node for 2026-08 and 2026-09 across every `weekStart` (0, 1, 6): 42 unique days, correct leading/trailing bleed, ISO week numbers stable. So the data fed to the view is not the source of the duplicate.

### Suspected mechanism

`Panel.qml` builds the grid with two nested `Repeater`s over plain JS-object models:

```qml
Repeater {
  model: root.weeks
  Row {
    required property var modelData
    ...
    Repeater {
      model: modelData.days
      Rectangle { required property var modelData; ... }
    }
  }
}
```

`root.weeks` is `readonly property var weeks: Model.monthGrid(viewYear, viewMonth, weekStart, todayKey)` — a fresh 6-element array of `{week, days: [...]}` objects recreated on every `viewMonth`/`viewYear` change. The literal grid is always exactly 6 rows, so when the month changes the outer `Repeater` keeps its 6 delegates instead of re-creating them. If a recycled delegate does not re-evaluate its inner `Repeater` model (`modelData.days`) for a given reused index, the stale day cells from the previous month survive — which presents as one repeated day with the rest dislocated by one.

The symptoms (an exact held-over day duplicated, later days shifted, cleared on reopen) match a delegate-identity / model-not-invalidated problem rather than bad data. I could not reproduce the QML rendering here to pin it down precisely, so this is a hypothesis backed by the data check above, not a confirmed root cause.

### Steps to reproduce

1. Left-click the clock to open the calendar panel.
2. Navigate to a months-away view (e.g. September) using the chevrons or keyboard, then step adjacent months a few times.
3. Read the day grid. A day from the previously shown month is rendered in place of (or alongside) the current one, and every later day is off by one.

It clears when the panel is closed and reopened.

### Expected

Each grid refresh shows exactly the 42 days `monthGrid` returns, with no stale cells carried over from the previous month while stepping.

### Question for maintainers

Is the nested-`Repeater`-over-JS-array pattern here known to misbehave in Quickshell when the delegate count stays constant? If so, the fix is likely to give the inner `Repeater` a stable `key`/identity (e.g. keying delegates on the cell date key that `Model.js` already computes) or to drive the grid from an explicit model type instead of raw JS arrays.

<img width="494" height="403" alt="Image" src="https://github.com/user-attachments/assets/571e15ce-9b6f-4724-8372-9e73f87693a8" />
  • 571e15ce-9b6f-4724-8372-9e73f87693a8

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

  • Related PRpr/12943· confirmed
  • Related PRpr/10476· confirmed
  • Related PRpr/13186· confirmed
  • Related PRpr/13751· confirmed
  • Related PRpr/13096· confirmed
  • Related PRpr/13127· confirmed

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 09:30 UTC