Add omarchy-crash-mute to mute and unmute one program

The mute was reachable only as `omarchy-toggle crash-ignore/<program>`, which asks whoever runs it to know the flag layout, to reduce a binary's path to the name the watcher keys on, and to have read the rule that a name climbing out of that directory writes an unrelated toggle. All of that was carried in the skill's prose, which is the wrong place for a rule that has to hold: prose is advice, and the thing being advised about is a name the crashed program chose.

So it is a command now. `omarchy crash mute hyprland` silences that program, `off` lifts it, `toggle` flips it, and no argument lists what is muted. It takes the binary's path as readily as the name and reduces it the way the watcher does, so the `Executable:` line from `coredumpctl` can be handed straight to it; it refuses what is not one component of a name, so it cannot be talked into writing outside its own directory whatever it is given; and it re-reads the flag afterwards and reports what is now true rather than what was asked for. The listing counts only regular files, because that is all the watcher honours -- anything else in there would read as muted while the crashes kept arriving. A leading `--` is consumed so a program named `-h`, which the router would otherwise answer with its own help, can still be muted.

The watcher gained an unrelated fix that this uncovered. Its fields are read with `IFS=$'\t'`, and tab is IFS whitespace, so an empty field collapsed into the next delimiter and shifted every field after it along one: a crash whose comm was empty had a path read as its pid and was discarded as somebody else's. A process can set its comm to nothing, so that was reachable. Empty fields now arrive as a dash like missing ones, and a dash joins the empty and dot cases that fall back to `unknown`.

Co-Authored-By: Codex XHigh <noreply@openai.com>
This commit is contained in:
Omarchybot
2026-08-27 11:26:28 +02:00
committed by David Heinemeier Hansson
co-authored by Codex XHigh
parent eeb4206c7b
commit ea6ee9440a
6 changed files with 264 additions and 43 deletions
+27 -26
View File
@@ -98,39 +98,40 @@ dumps core every time it exits, a driver that misbehaves on this hardware. Finis
by offering to silence crash notifications for **that one program**:
```bash
omarchy-toggle 'crash-ignore/<program>' on
omarchy-crash-mute '<program>'
```
`<program>` is the `process:` name in the crash facts, verbatim. The watcher works
that name out and then announces it, so what you were handed is already the exact
string the mute is keyed on — do not re-derive it from `coredumpctl` when you were
given it, because the two agree for ordinary names and not for strange ones.
`<program>` is the `process:` name in the crash facts, or the `binary:` path —
the command reduces a path to the same name the watcher keys on, so passing
`/usr/lib/chromium/chromium-browser` and passing `chromium-browser` land on the
same flag. Prefer the binary's path wherever the crash recorded one: the kernel
truncates the process name to 15 characters and does not truncate a basename, and
a mute on the truncated form matches nothing, forever, while looking like it
worked.
A diagnosis started by hand from `omarchy agent crash <pid>` is given no name, so
there you do have to work it out the way the watcher does: the executable's
basename when an absolute `Executable:` was recorded, otherwise the process name
with everything up to the last `/` dropped, and `unknown` when that leaves
nothing, `.` or `..`. Prefer the executable — the kernel truncates the process
name to 15 characters and does not truncate the basename, so a mute on the
truncated one matches nothing, forever, while looking like it worked.
That is also the answer for a diagnosis started by hand from `omarchy agent crash
<pid>`, which is handed no name at all: give the command the `Executable:` line
from `coredumpctl info` and let it do the reducing. Some crashes record no
executable — pass the process name then, and `unknown` where the crash has
neither, which is the name such a crash is announced under.
The name is whatever the crashed program's author chose to call a file, so handle
it as hostile text rather than as a word. Single quotes hold a space or a `$(...)`,
but a name containing a single quote closes them and the rest of it runs as your
shell — escape it, or the program that just crashed chooses the command. Then
check the flag actually arrived, which is also how you learn a name was too long
for the filesystem to keep:
```bash
omarchy-toggle-enabled 'crash-ignore/<program>' && echo muted
```
The name is still whatever the crashed program's author chose to call a file, so
handle it as hostile text rather than as a word. The command refuses a name that
is not one — it cannot be talked into writing a flag outside its own directory —
but that is no help if the name reaches a shell unescaped first: single quotes
hold a space or a `$(...)`, and a name containing a single quote closes them and
runs the rest as your shell. Escape it, or the program that just crashed picks
the command.
Offer it; never run it unprompted. The user may well want to keep being told.
Say how to undo it in the same breath, so it is not a one-way door: the same
command with `off` un-mutes, and each mute is one file in
`~/.local/state/omarchy/toggles/crash-ignore/`, which `ls -A` lists — the
directory appears with the first mute, so before that there is nothing to list.
Say how to undo it in the same breath, so it is not a one-way door — and the
command answers both halves itself:
```bash
omarchy-crash-mute '<program>' off # un-mute this one
omarchy-crash-mute # list what is muted
```
The key is a bare name, so programs sharing one share a mute, and anything run
through an interpreter is keyed as the interpreter. Muting `python3.13` or `node`