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.
Last-resort fontconfig rule only covers Arabic — every other non-Latin script (Tamil, Devanagari, etc.) renders as tofu boxes in Chromium/Electron
Reported by ganjeez · filed Sep 9, 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
Omarchy issue: 50-omarchy.conf's last-resort append only covers Arabic, so all other non-Latin scripts get no Chromium/Electron fallback and render as missing-glyph boxes
Where this file lives
default/fontconfig/conf.avail/50-omarchy.conf(installed as/etc/fonts/conf.d/50-omarchy.conf)- Omarchy
4.0.2-1, fontconfig2:2.18.3-2, Arch/Hyprland
Summarize the problem
Typing/rendering Tamil (and likely any other script not covered by Liberation Sans, JetBrainsMono Nerd Font, Noto Color Emoji, or Noto Naskh Arabic) in Chromium/Chrome/Brave/Electron produces tofu boxes (missing-glyph placeholders), even though the corresponding Noto font (e.g. noto-fonts → Noto Sans Tamil) is installed and fc-match resolves it correctly for lang-tagged queries.
The cause
50-omarchy.conf reassigns the generic families with mode="assign" binding="strong":
<match target="pattern">
<test name="family" qual="any"><string>sans-serif</string></test>
<edit name="family" mode="assign" binding="strong"><string>Liberation Sans</string></edit>
</match>This replaces sans-serif in the pattern with Liberation Sans before noto-fonts's own conf.d rules (46-noto-sans.conf, 66-noto-sans.conf, processed later by filename order) ever get a chance to append the full Noto family fallback list to sans-serif. The family alias chain that ships with noto-fonts for broad script coverage never fires.
The file already special-cases this exact failure mode for Arabic, with this comment:
<!-- Chromium and Electron resolve missing glyphs one character at a time
without lang on the pattern, so the rules above never fire for them and
fontconfig falls through to a raw charset scan that lands on Nastaliq
(or on Kufi, once the latin alias chains have widened the pattern).
Naming Naskh as a last-resort family covers that path. ... -->
<match target="pattern">
<edit name="family" mode="append" binding="strong">
<string>Noto Naskh Arabic</string>
</edit>
</match>This unconditional append is scoped to Arabic only. Every other script that isn't covered by Liberation Sans/Serif, JetBrainsMono Nerd Font, or Noto Color Emoji — Tamil, Devanagari, Sinhala, Thai, Georgian, etc. — has no equivalent last-resort entry, so Chromium's per-character glyph-fallback walk (which the same comment describes) exhausts the shortened family list and gives up with a missing-glyph box.
Steps to reproduce
- Stock Omarchy install,
noto-fontsinstalled (ships Noto Sans Tamil and friends). - Open Chrome/Brave/Chromium, go to any page that renders Tamil text (e.g. https://www.google.co.in/inputtools/try/, language set to Tamil).
- Type a transliterated word (e.g.
puzhu). - Expected: proper Tamil glyphs (
புழு). Actual: empty boxes (tofu). - Confirm fonts are present and correctly registered:
fc-match -a ":lang=ta"findsNoto Sans Tamil, butfc-match -a "sans-serif:lang=ta"does not include it until a fallback entry is added — because the generic-family alias chain was truncated by the strongassignabove. - Confirm fix: adding an unconditional last-resort append for
Noto Sans Tamil(mirroring the existing Naskh Arabic rule) in a new/etc/fonts/conf.d/*.conffile resolves it immediately for new browser processes.
Expected behavior
Any installed script-specific Noto font should remain reachable as a fallback for generic families in Chromium/Electron, not just Arabic.
Root-cause hypothesis
Same category of bug as #8404 and #8928 — global rules in 50-omarchy.conf (and the omarchy-font-set mechanism) interact with Chromium/Electron's own font-fallback quirks in ways the generic-family shortening didn't anticipate. Here specifically: the last-resort catch-all was built to patch one observed symptom (Arabic tofu) rather than restoring the full generic fallback chain for all scripts, so every other non-Latin script regressed the same way and nobody's filed it yet.
Suggested direction (for maintainers to weigh in)
- Instead of (or in addition to) a per-script last-resort append, consider appending the broad
Noto Sans/Noto Serifalias chain itself (or justsans-serif's original upstream fallback list) after the strongassign, so every script Noto covers stays reachable — not just the ones someone happened to hit a bug report for. - Alternatively, use
mode="prepend"instead ofassignfor the generic-family redirect, soLiberation Sanswins first without deleting the rest of the chain that later conf.d files (likenoto-fonts's) still append to.
Workaround (user config, for now)
A file in /etc/fonts/conf.d/ (higher priority number than 50-omarchy.conf, e.g. 51-tamil-fallback.conf) with:
<match target="pattern">
<edit name="family" mode="append" binding="strong">
<string>Noto Sans Tamil</string>
</edit>
</match>Verified: after fc-cache -f and fully restarting the browser, fc-match -a "sans-serif:lang=ta" includes Noto Sans Tamil, and the input-tools page above renders correctly. (User-level ~/.config/fontconfig/fonts.conf does not work here — this system's /etc/fonts/fonts.conf has no <include> for the XDG user config path at all, only <include>conf.d</include>, so any fix needs to live in /etc/fonts/conf.d/.)
System
- Omarchy version: 4.0.2-1
- Kernel: 7.1.9-arch1-2
- CPU: Intel Core i7-4770HQ
- GPU: Intel Crystal Well (Iris Pro, i915 driver)
- RAM: ~15.5 GiB
- Display / scale: eDP-1, scale 2
- Window manager: Hyprland (Omarchy)
- Locale: en_US.UTF-8
- fontconfig: 2:2.18.3-2
- noto-fonts: 1:2026.08.01-1
- JetBrainsMono Nerd Font package: ttf-jetbrains-mono-nerd-basic 3.5.0-1
Filed by Claude Sonnet 5 via Claude Code.
View raw text
# Omarchy issue: 50-omarchy.conf's last-resort append only covers Arabic, so all other non-Latin scripts get no Chromium/Electron fallback and render as missing-glyph boxes
## Where this file lives
- `default/fontconfig/conf.avail/50-omarchy.conf` (installed as `/etc/fonts/conf.d/50-omarchy.conf`)
- Omarchy `4.0.2-1`, fontconfig `2:2.18.3-2`, Arch/Hyprland
## Summarize the problem
Typing/rendering Tamil (and likely any other script not covered by Liberation Sans, JetBrainsMono Nerd Font, Noto Color Emoji, or Noto Naskh Arabic) in Chromium/Chrome/Brave/Electron produces tofu boxes (missing-glyph placeholders), even though the corresponding Noto font (e.g. `noto-fonts` → Noto Sans Tamil) is installed and `fc-match` resolves it correctly for lang-tagged queries.
## The cause
`50-omarchy.conf` reassigns the generic families with `mode="assign" binding="strong"`:
```xml
<match target="pattern">
<test name="family" qual="any"><string>sans-serif</string></test>
<edit name="family" mode="assign" binding="strong"><string>Liberation Sans</string></edit>
</match>
```
This replaces `sans-serif` in the pattern with `Liberation Sans` *before* `noto-fonts`'s own conf.d rules (`46-noto-sans.conf`, `66-noto-sans.conf`, processed later by filename order) ever get a chance to append the full Noto family fallback list to `sans-serif`. The family alias chain that ships with `noto-fonts` for broad script coverage never fires.
The file already special-cases this exact failure mode for Arabic, with this comment:
```xml
<!-- Chromium and Electron resolve missing glyphs one character at a time
without lang on the pattern, so the rules above never fire for them and
fontconfig falls through to a raw charset scan that lands on Nastaliq
(or on Kufi, once the latin alias chains have widened the pattern).
Naming Naskh as a last-resort family covers that path. ... -->
<match target="pattern">
<edit name="family" mode="append" binding="strong">
<string>Noto Naskh Arabic</string>
</edit>
</match>
```
This unconditional append is scoped to Arabic only. Every other script that isn't covered by Liberation Sans/Serif, JetBrainsMono Nerd Font, or Noto Color Emoji — Tamil, Devanagari, Sinhala, Thai, Georgian, etc. — has no equivalent last-resort entry, so Chromium's per-character glyph-fallback walk (which the same comment describes) exhausts the shortened family list and gives up with a missing-glyph box.
## Steps to reproduce
1. Stock Omarchy install, `noto-fonts` installed (ships Noto Sans Tamil and friends).
2. Open Chrome/Brave/Chromium, go to any page that renders Tamil text (e.g. https://www.google.co.in/inputtools/try/, language set to Tamil).
3. Type a transliterated word (e.g. `puzhu`).
4. Expected: proper Tamil glyphs (`புழு`). Actual: empty boxes (tofu).
5. Confirm fonts are present and correctly registered: `fc-match -a ":lang=ta"` finds `Noto Sans Tamil`, but `fc-match -a "sans-serif:lang=ta"` does **not** include it until a fallback entry is added — because the generic-family alias chain was truncated by the strong `assign` above.
6. Confirm fix: adding an unconditional last-resort append for `Noto Sans Tamil` (mirroring the existing Naskh Arabic rule) in a new `/etc/fonts/conf.d/*.conf` file resolves it immediately for new browser processes.
## Expected behavior
Any installed script-specific Noto font should remain reachable as a fallback for generic families in Chromium/Electron, not just Arabic.
## Root-cause hypothesis
Same category of bug as #8404 and #8928 — global rules in `50-omarchy.conf` (and the `omarchy-font-set` mechanism) interact with Chromium/Electron's own font-fallback quirks in ways the generic-family shortening didn't anticipate. Here specifically: the last-resort catch-all was built to patch *one* observed symptom (Arabic tofu) rather than restoring the full generic fallback chain for all scripts, so every other non-Latin script regressed the same way and nobody's filed it yet.
## Suggested direction (for maintainers to weigh in)
- Instead of (or in addition to) a per-script last-resort append, consider appending the broad `Noto Sans`/`Noto Serif` alias chain itself (or just `sans-serif`'s original upstream fallback list) after the strong `assign`, so every script Noto covers stays reachable — not just the ones someone happened to hit a bug report for.
- Alternatively, use `mode="prepend"` instead of `assign` for the generic-family redirect, so `Liberation Sans` wins first without deleting the rest of the chain that later conf.d files (like `noto-fonts`'s) still append to.
## Workaround (user config, for now)
A file in `/etc/fonts/conf.d/` (higher priority number than `50-omarchy.conf`, e.g. `51-tamil-fallback.conf`) with:
```xml
<match target="pattern">
<edit name="family" mode="append" binding="strong">
<string>Noto Sans Tamil</string>
</edit>
</match>
```
Verified: after `fc-cache -f` and fully restarting the browser, `fc-match -a "sans-serif:lang=ta"` includes `Noto Sans Tamil`, and the input-tools page above renders correctly. (User-level `~/.config/fontconfig/fonts.conf` does **not** work here — this system's `/etc/fonts/fonts.conf` has no `<include>` for the XDG user config path at all, only `<include>conf.d</include>`, so any fix needs to live in `/etc/fonts/conf.d/`.)
## System
- **Omarchy version:** 4.0.2-1
- **Kernel:** 7.1.9-arch1-2
- **CPU:** Intel Core i7-4770HQ
- **GPU:** Intel Crystal Well (Iris Pro, i915 driver)
- **RAM:** ~15.5 GiB
- **Display / scale:** eDP-1, scale 2
- **Window manager:** Hyprland (Omarchy)
- **Locale:** en_US.UTF-8
- **fontconfig:** 2:2.18.3-2
- **noto-fonts:** 1:2026.08.01-1
- **JetBrainsMono Nerd Font package:** ttf-jetbrains-mono-nerd-basic 3.5.0-1
Filed by Claude Sonnet 5 via Claude Code.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:20 UTC