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

Battery panel shows only the first battery on dual-battery laptops (ThinkPad BAT0 + BAT1)

Reported by TobiasVeiga00 · filed Oct 10, 2026 · open at source

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

Battery panel shows only the first battery on dual-battery laptops (ThinkPad BAT0 + BAT1)revision 1 · captured 2026-10-10 00:26 UTC via poll

System details

Lenovo ThinkPad T480, Intel Core i5-8350U, Intel UHD Graphics 620, Omarchy 4.0.4-1 (dual battery: BAT0 internal ~18 Wh + BAT1 external ~45 Wh)

What's wrong?

On laptops with two batteries (e.g. ThinkPad T480/T470/T580 with internal BAT0 + hot-swappable external BAT1), the Power panel in the Omarchy shell shows the charge of the first battery only, while the bar widget percentage shows the real combined charge. The two numbers disagree.

omarchy-battery-status picks the first UPower device matching BAT:

# /usr/share/omarchy/bin/omarchy-battery-status:21
battery=$(upower -e 2>/dev/null | grep BAT | head -n 1)

The bar widget (plugins/panels/power/Panel.qml) uses UPower.displayDevice, which is the combined device. The panel's hero percentage, size, rate and time come from omarchy-battery-status --shell, which only reads BAT0.

Steps to reproduce

  1. Use a laptop with two batteries, where BAT0 is full and BAT1 is partially charged.
  2. Enable showPercentage on omarchy.power (the bar shows e.g. 86%).
  3. Click the battery widget to open the Power panel.

Expected

The panel shows the same combined charge as the bar (86%, 63 Wh), with combined rate and time remaining.

Actual

The panel shows only BAT0: 100%, 18Wh, state fully-charged, while BAT1 (45 Wh, 80%, charging) is ignored.

$ upower -i /org/freedesktop/UPower/devices/battery_BAT0 | grep percentage   # 100%
$ upower -i /org/freedesktop/UPower/devices/battery_BAT1 | grep percentage   # 80%
$ upower -i /org/freedesktop/UPower/devices/DisplayDevice | grep percentage  # 85.8%
$ omarchy-battery-status --shell | head -1                                  # percentage 100%

Suggested fix

Prefer the combined DisplayDevice and fall back to the first BAT:

battery=$(upower -e 2>/dev/null | grep -m1 DisplayDevice)
[[ -z $battery ]] && battery=$(upower -e 2>/dev/null | grep BAT | head -n 1)

I tested this locally: it reports 86% / 63 Wh with combined rate and time. Charge thresholds are still read from BAT* sysfs as before. Note that cycles and the threshold lines still come from the first battery (BAT*/... | head -1), which is acceptable but could also be made per-battery.

View raw text
### System details

Lenovo ThinkPad T480, Intel Core i5-8350U, Intel UHD Graphics 620, Omarchy 4.0.4-1 (dual battery: BAT0 internal ~18 Wh + BAT1 external ~45 Wh)

### What's wrong?

On laptops with two batteries (e.g. ThinkPad T480/T470/T580 with internal BAT0 + hot-swappable external BAT1), the Power panel in the Omarchy shell shows the charge of the first battery only, while the bar widget percentage shows the real combined charge. The two numbers disagree.

`omarchy-battery-status` picks the first UPower device matching `BAT`:

```bash
# /usr/share/omarchy/bin/omarchy-battery-status:21
battery=$(upower -e 2>/dev/null | grep BAT | head -n 1)
```

The bar widget (`plugins/panels/power/Panel.qml`) uses `UPower.displayDevice`, which is the combined device. The panel's hero percentage, size, rate and time come from `omarchy-battery-status --shell`, which only reads BAT0.

### Steps to reproduce

1. Use a laptop with two batteries, where BAT0 is full and BAT1 is partially charged.
2. Enable `showPercentage` on `omarchy.power` (the bar shows e.g. 86%).
3. Click the battery widget to open the Power panel.

### Expected

The panel shows the same combined charge as the bar (86%, 63 Wh), with combined rate and time remaining.

### Actual

The panel shows only BAT0: `100%`, `18Wh`, state `fully-charged`, while BAT1 (45 Wh, 80%, charging) is ignored.

```
$ upower -i /org/freedesktop/UPower/devices/battery_BAT0 | grep percentage   # 100%
$ upower -i /org/freedesktop/UPower/devices/battery_BAT1 | grep percentage   # 80%
$ upower -i /org/freedesktop/UPower/devices/DisplayDevice | grep percentage  # 85.8%
$ omarchy-battery-status --shell | head -1                                  # percentage 100%
```

### Suggested fix

Prefer the combined `DisplayDevice` and fall back to the first `BAT`:

```bash
battery=$(upower -e 2>/dev/null | grep -m1 DisplayDevice)
[[ -z $battery ]] && battery=$(upower -e 2>/dev/null | grep BAT | head -n 1)
```

I tested this locally: it reports 86% / 63 Wh with combined rate and time. Charge thresholds are still read from `BAT*` sysfs as before. Note that `cycles` and the threshold lines still come from the first battery (`BAT*/... | head -1`), which is acceptable but could also be made per-battery.

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-10 05:17 UTC