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.
omarchy font set repoints explicitly named monospace families, not just generic "monospace"
Reported by shawn1905 · filed Sep 21, 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
Summary
omarchy font set <X> writes a fontconfig rule that prepends <X> to every pattern whose family list mentions monospace. Because 48-guessfamily.conf appends monospace to the family list of any family whose name contains mono, that rule also captures patterns that explicitly asked for a different monospace family. After a font change, no other monospace family can be selected by name anymore — which also makes a per-app monospace font (e.g. a terminal that deliberately asks for JetBrainsMono Nerd Font) impossible without removing the rule.
Environment
- Omarchy 4.0.4-1, Arch Linux x86_64
- Hyprland 0.56.2
- fontconfig 2:2.18.3-2
Steps to reproduce
omarchy font set "Sarasa Mono SC"
fc-match "DejaVu Sans Mono" # -> Sarasa Mono SC (expected: DejaVu Sans Mono)
fc-match "JetBrainsMono Nerd Font" # -> Sarasa Mono SC (expected: JetBrainsMono Nerd Font)
fc-match "Noto Sans Mono" # -> Sarasa Mono SC (expected: Noto Sans Mono)
fc-match "monospace" # -> Sarasa Mono SC (expected)Same with any other choice (omarchy font set "FiraCode Nerd Font Mono" makes all four return FiraCode Nerd Font Mono).
Root cause
omarchy-font-setwrites~/.config/fontconfig/fonts.conf:
<match target="pattern">
<test name="family" qual="any">
<string>monospace</string>
</test>
<edit name="family" mode="prepend_first" binding="strong">
<string>$font_name</string>
</edit>
</match>/etc/fonts/conf.d/50-user.confincludes that file, so it is evaluated after48-guessfamily.confand50-omarchy.conf.48-guessfamily.confruns, for any pattern whose family name containsmono:
<edit name="family" mode="append_last"><string>monospace</string></edit>So by the time the rule from step 1 runs, an explicit request for DejaVu Sans Mono / Sarasa Mono SC / JetBrainsMono Nerd Font already carries monospace in its family list: the qual="any" test matches, prepend_first binding="strong" puts the chosen family at the head of the list, and it wins the match. The rule exists to override 50-omarchy.conf's monospace → assign JetBrainsMono Nerd Font, which is the only reason it cannot simply be dropped.
Evidence
FcConfigSubstitute pattern dumps with only the package configs active (no user rule), showing monospace sitting in the family list of explicitly named families:
monospace : 73 families, "monospace" at index 64, 67, 71 first two: JetBrainsMono Nerd Font, DejaVu LGC Sans Mono
DejaVu Sans Mono : 76 families, "monospace" at index 66, 69, 71, 74 first two: DejaVu Sans Mono, DejaVu LGC Sans Mono
JetBrainsMono Nerd Font : 73 families, "monospace" at index 65, 71 first two: JetBrainsMono Nerd Font, JetBrainsMono Nerd Font
Sarasa Mono SC : 73 families, "monospace" at index 65, 71 first two: Sarasa Mono SC, JetBrainsMono Nerd FontSuggested fixes (both measured with fc-match)
A — exact, needs a config file ordered before `48-guessfamily.conf`. A rule evaluated earlier sees family = ["monospace"] for a generic request and ["Sarasa Mono SC", …] for a named one, so keying it on the first family value is enough:
<!-- /etc/fonts/conf.d/47-omarchy-font.conf, rewritten by `omarchy font set` -->
<match target="pattern">
<test qual="first" name="family" compare="eq">
<string>monospace</string>
</test>
<edit name="family" mode="prepend_first" binding="strong">
<string>Sarasa Mono SC</string>
</edit>
</match>Measured with that file symlinked in at position 47, everything else stock:
| query | result |
|---|---|
monospace | Sarasa Mono SC ✅ |
Sarasa Mono SC | Sarasa Mono SC ✅ |
JetBrainsMono Nerd Font | JetBrainsMono Nerd Font ✅ |
DejaVu Sans Mono | DejaVu Sans Mono ✅ |
Noto Sans Mono, Liberation Mono, iA Writer Mono S | themselves ✅ |
:charset=e0b0 (Nerd Font glyph) | JetBrainsMono Nerd Font ✅ |
:charset=4e2d (中) | Sarasa Mono CL ✅ |
Caveat: the rule then lives under /etc, so omarchy font set would need a privileged write for it (or a package/migration-owned file that it rewrites).
B — no privilege change. Keep writing ~/.config/fontconfig/fonts.conf, but test the first family against the family 50-omarchy.conf currently assigns (read out of that file at write time, so it survives a changed default):
<test qual="first" name="family" compare="eq">
<string>JetBrainsMono Nerd Font</string> <!-- 50-omarchy.conf's monospace assign -->
</test>Measured: monospace → chosen font ✅; Sarasa Mono SC, DejaVu Sans Mono, Noto Sans Mono, Liberation Mono → themselves ✅. One residual case stays broken: an explicit request for JetBrainsMono Nerd Font is still repointed, since after 50-omarchy.conf's assign a generic request and that explicit request differ only by a duplicated first family value, which the match language cannot distinguish.
Workaround in use locally
Option B, regenerated by a ~/.config/omarchy/hooks/font-set.d/ hook so it survives every omarchy font set.
View raw text
## Summary
`omarchy font set <X>` writes a fontconfig rule that prepends `<X>` to **every** pattern whose family list mentions `monospace`. Because `48-guessfamily.conf` appends `monospace` to the family list of any family whose *name* contains `mono`, that rule also captures patterns that explicitly asked for a different monospace family. After a font change, no other monospace family can be selected by name anymore — which also makes a per-app monospace font (e.g. a terminal that deliberately asks for `JetBrainsMono Nerd Font`) impossible without removing the rule.
## Environment
- Omarchy 4.0.4-1, Arch Linux x86_64
- Hyprland 0.56.2
- fontconfig 2:2.18.3-2
## Steps to reproduce
```bash
omarchy font set "Sarasa Mono SC"
fc-match "DejaVu Sans Mono" # -> Sarasa Mono SC (expected: DejaVu Sans Mono)
fc-match "JetBrainsMono Nerd Font" # -> Sarasa Mono SC (expected: JetBrainsMono Nerd Font)
fc-match "Noto Sans Mono" # -> Sarasa Mono SC (expected: Noto Sans Mono)
fc-match "monospace" # -> Sarasa Mono SC (expected)
```
Same with any other choice (`omarchy font set "FiraCode Nerd Font Mono"` makes all four return `FiraCode Nerd Font Mono`).
## Root cause
1. `omarchy-font-set` writes `~/.config/fontconfig/fonts.conf`:
```xml
<match target="pattern">
<test name="family" qual="any">
<string>monospace</string>
</test>
<edit name="family" mode="prepend_first" binding="strong">
<string>$font_name</string>
</edit>
</match>
```
2. `/etc/fonts/conf.d/50-user.conf` includes that file, so it is evaluated *after* `48-guessfamily.conf` and `50-omarchy.conf`.
3. `48-guessfamily.conf` runs, for any pattern whose family name contains `mono`:
```xml
<edit name="family" mode="append_last"><string>monospace</string></edit>
```
So by the time the rule from step 1 runs, an explicit request for `DejaVu Sans Mono` / `Sarasa Mono SC` / `JetBrainsMono Nerd Font` already carries `monospace` in its family list: the `qual="any"` test matches, `prepend_first binding="strong"` puts the chosen family at the head of the list, and it wins the match. The rule exists to override `50-omarchy.conf`'s `monospace` → `assign JetBrainsMono Nerd Font`, which is the only reason it cannot simply be dropped.
## Evidence
`FcConfigSubstitute` pattern dumps with only the package configs active (no user rule), showing `monospace` sitting in the family list of explicitly named families:
```
monospace : 73 families, "monospace" at index 64, 67, 71 first two: JetBrainsMono Nerd Font, DejaVu LGC Sans Mono
DejaVu Sans Mono : 76 families, "monospace" at index 66, 69, 71, 74 first two: DejaVu Sans Mono, DejaVu LGC Sans Mono
JetBrainsMono Nerd Font : 73 families, "monospace" at index 65, 71 first two: JetBrainsMono Nerd Font, JetBrainsMono Nerd Font
Sarasa Mono SC : 73 families, "monospace" at index 65, 71 first two: Sarasa Mono SC, JetBrainsMono Nerd Font
```
## Suggested fixes (both measured with `fc-match`)
**A — exact, needs a config file ordered before `48-guessfamily.conf`.** A rule evaluated earlier sees `family = ["monospace"]` for a generic request and `["Sarasa Mono SC", …]` for a named one, so keying it on the *first* family value is enough:
```xml
<!-- /etc/fonts/conf.d/47-omarchy-font.conf, rewritten by `omarchy font set` -->
<match target="pattern">
<test qual="first" name="family" compare="eq">
<string>monospace</string>
</test>
<edit name="family" mode="prepend_first" binding="strong">
<string>Sarasa Mono SC</string>
</edit>
</match>
```
Measured with that file symlinked in at position 47, everything else stock:
| query | result |
|---|---|
| `monospace` | Sarasa Mono SC ✅ |
| `Sarasa Mono SC` | Sarasa Mono SC ✅ |
| `JetBrainsMono Nerd Font` | JetBrainsMono Nerd Font ✅ |
| `DejaVu Sans Mono` | DejaVu Sans Mono ✅ |
| `Noto Sans Mono`, `Liberation Mono`, `iA Writer Mono S` | themselves ✅ |
| `:charset=e0b0` (Nerd Font glyph) | JetBrainsMono Nerd Font ✅ |
| `:charset=4e2d` (中) | Sarasa Mono CL ✅ |
Caveat: the rule then lives under `/etc`, so `omarchy font set` would need a privileged write for it (or a package/migration-owned file that it rewrites).
**B — no privilege change.** Keep writing `~/.config/fontconfig/fonts.conf`, but test the first family against the family `50-omarchy.conf` currently assigns (read out of that file at write time, so it survives a changed default):
```xml
<test qual="first" name="family" compare="eq">
<string>JetBrainsMono Nerd Font</string> <!-- 50-omarchy.conf's monospace assign -->
</test>
```
Measured: `monospace` → chosen font ✅; `Sarasa Mono SC`, `DejaVu Sans Mono`, `Noto Sans Mono`, `Liberation Mono` → themselves ✅. One residual case stays broken: an explicit request for `JetBrainsMono Nerd Font` is still repointed, since after `50-omarchy.conf`'s `assign` a generic request and that explicit request differ only by a duplicated first family value, which the match language cannot distinguish.
## Workaround in use locally
Option B, regenerated by a `~/.config/omarchy/hooks/font-set.d/` hook so it survives every `omarchy font set`.
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 16:58 UTC