Offer a source-build fallback when Voxtype's binary needs AVX2 - #8316
Offer a source-build fallback when Voxtype's binary needs AVX2#8316ironbract wants to merge 14 commits into
Conversation
voxtype-bin targets the x86-64-v3 baseline (AVX2, FMA, BMI1/2, F16C, MOVBE), so it SIGILLs on older CPUs. The install hook had no capability check, so it always installed the incompatible binary and, on any post-install failure, left a half-installed package behind with set -e. Add omarchy-hw-x86-64-v3 to detect the baseline, gate the install on it, and offer to build the AUR voxtype package from source instead (with a warning about build time and possible performance). Roll back via omarchy-voxtype-remove if setup fails partway through instead of abandoning a broken install. Fixes omacom#8312 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds CPU compatibility detection and a source-build fallback for Voxtype, with rollback handling and documentation.
Changes:
- Detect x86-64-v3 support and select binary or source installation.
- Improve failed-install cleanup and package removal.
- Add shell tests and user documentation.
Tip
If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.
Reviewed changes
Copilot reviewed 3 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
bin/omarchy-hw-x86-64-v3 |
Detects required CPU capabilities. |
bin/omarchy-voxtype-install |
Adds fallback selection and rollback. |
bin/omarchy-voxtype-remove |
Removes either Voxtype package variant. |
manual/11-text-extraction-dictation.md |
Documents compatibility and fallback behavior. |
test/shell.d/hw-x86-64-v3-test.sh |
Tests CPU capability detection. |
test/shell.d/voxtype-install-test.sh |
Tests installation paths and rollback invocation. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
voxtype-bin declares Provides=voxtype, so yay -S --noconfirm --needed voxtype silently resolved to the repo-provided voxtype-bin instead of building the AUR voxtype package -- defeating the fallback and reinstalling the exact binary that SIGILLs on pre-AVX2 CPUs. omarchy-pkg-aur-add now accepts an optional repo/ prefix (e.g. aur/voxtype) to force resolution from a specific source while still verifying/erroring against the bare package name pacman reports. omarchy-voxtype-install passes aur/voxtype to use it. Verified on real pre-AVX2 hardware: the source build now actually compiles and installs voxtype (not voxtype-bin), and the resulting systemd service starts and runs correctly.
|
Pushed a follow-up fix after testing the source-build fallback on real pre-AVX2 hardware (an Ivy Bridge i7-3520M). Bug found: Fix: Re-verified on the same hardware: the source build now genuinely compiles (~20 min) and installs Also added (Disclosure: this fix, like the rest of the PR, was developed with AI assistance — Claude Code, reviewed and tested by me on real hardware before pushing.) |
omarchy-restart-shell was the last command in install_voxtype, so its exit status became the function's, and the new rollback treated it as a failed install: omarchy-voxtype-remove drops the package and deletes ~/.config/voxtype and ~/.local/share/voxtype, taking the 150MB model that had just downloaded with it. It exits non-zero for reasons unrelated to Voxtype -- a locked session, or the shell not answering its ping within two seconds, which is likeliest on exactly the older CPUs this fallback targets, and after a 20+ minute source build. Reloading Hyprland and restarting the shell only load the new bindings, so they belong on the success path rather than inside the rollback boundary. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Exiting 0 on aarch64 said the CPU satisfies an x86 baseline, which the installer reads as "the prebuilt binary is fine" and reaches for voxtype-bin -- an x86_64-only package. Every other omarchy-hw-* detector answers 0 only for a match; unknown hardware exits non-zero. With that, an ARM machine takes the source-build path instead, and the AUR voxtype package builds for aarch64. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-Authored-By: Codex XHigh <noreply@openai.com>
Both entries keyed off voxtype-bin, which the source-build fallback never installs: Remove > AI > Dictation stayed hidden, so the population this fallback exists for had no way to uninstall, and Install > AI > Dictation stayed enabled and would re-run the installer over a working setup -- overwriting ~/.config/voxtype with the default and, on any later failure, rolling the whole thing back. omarchy-cmd-present answers for either package, the way omarchy-voxtype-remove and the Ollama entries already do. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-Authored-By: Codex XHigh <noreply@openai.com>
|
Reviewed on a disposable VM, with an independent second opinion from Codex at xhigh reasoning. Three defects found and fixed on this branch; the rest is listed below for you to judge. Pushed to
Open, left for you or the maintainer:
Verified, not just read: Tests: on a disposable Omarchy VM, after the pushed commits — Second opinion: Codex at xhigh agreed independently on the rollback, the non-x86_64 exit code, and the stale menu guards — though its independence is not currently guaranteed, since it can read this session's own transcript. It contributed three things this review had not reasoned about and that stand on their own: the missing LZCNT/ Waiting on: the maintainer. #7890 (kx0101) changes the same file and the same test filename to reject Voxtype outright on non-AVX2 CPUs rather than offer an alternative — the two conflict, and choosing between them is not this review's call. This PR closes #8312 and would also answer #7883 and #8197. |
|
Tested this on Apple Silicon (MacBook Air M1, aarch64, Asahi) — filed #8530 for the ARM side before finding this PR. Good news: Two things still bite on ARM: 1. The three machine=${OMARCHY_UNAME_M:-$(uname -m)}
[[ $machine == "x86_64" ]] || exit 1With 2. The message is wrong on ARM. "Your CPU is missing instructions (AVX2/x86-64-v3)" isn't true of an M1 — nothing is missing, there's just no prebuilt binary for the architecture. Same for "may result in noticeably slower dictation": the source build is native there. Branching the copy on I have these as two commits on top of your branch, tested on real M1 hardware ( |
|
Re-reviewed at #8530 is fixed by this PR, functionally. Traced at this head: on aarch64 Checked the AUR side on a disposable VM rather than taking it on trust: @twitchax's first point holds; reproduced it. Running On the name: PR #8149 ( @twitchax's second point holds too, and it reaches one more line than the comment names. The source-build path fails without leaving a half-installed Voxtype, but it does not tell the user much. Walked every failure: an unreachable AUR at the preflight gets the explicit red message and exits; a It does not fire where the binary would have worked. On an x86 host reporting accurate flags there is no false-positive path — the six flags at Second opinion: Codex at xhigh reasoning, pinned to Waiting on you and the maintainer. @twitchax has both fixes as commits tested on real M1 hardware and offered them either way; they are his to land, and nothing was pushed here that would collide with them. The x86 population is unaffected by either. Still open from the last review and unchanged: |
|
@twitchax Thanks for testing on real M1 hardware — I'd like to take your fix. Could you open the two commits as a PR against |
hw-x86-64-v3-test.sh couldn't exercise the non-x86_64 rejection since it only overrode OMARCHY_CPUINFO_PATH, not the machine check; add an OMARCHY_UNAME_M override and a case asserting aarch64 is rejected even with x86-64-v3 flags present. Also stop telling non-x86_64 machines (e.g. Apple Silicon) their CPU is "missing instructions" or warning of slower dictation when the fallback build there is native, not a degraded compatibility build. Based on a report and fix from @twitchax on omacom#8316, tested on real M1 hardware; applied here and verified against the x86_64 test suite since ARM hardware wasn't available locally.
|
Pushed |
|
Follow-up: I asked for your commits and then, before waiting for a reply, went ahead and pushed my own reconstruction anyway (AI over-enthusiasm on my end — sorry for the mixed signal). What's on the branch now is my best-effort implementation from your writeup, verified only against the x86_64 suite since I don't have ARM hardware. Your actual commits, tested on real M1 hardware, are still what I'd prefer over my reconstruction — if you push them (or open them as a PR against this branch), I'll swap them in over what's there now. |
|
@ironbract, sorry, let me open them as a PR against your branch, but let me pull the latest first, so we don't conflict. |
|
Verified
5/5. The Haswell case now genuinely exercises the flags path on ARM rather than being short-circuited by the machine check, which was the actual bug. Full I diffed your version against my local commits: One thing I have not verified: that the source build actually produces working dictation on ARM. I've confirmed |
The installer's copy branches on `uname -m` while the suite stubbed only the predicate, so on an x86_64 host the non-x86_64 message was unreachable and neither prompt was asserted. Stubbing `uname` lets both branches run on any host; flipping the branch in either direction now fails the file. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Reviewed What the gate actually does on aarch64, read from source rather than inferred. @twitchax's 5/5, reproduced from the other side. Running The one thing missing, now pushed as Tests, all on a disposable worker, never here. Second opinion: Codex at xhigh reasoning, pinned to New since the last review: issue #8645. It reports the whole Install menu offering x86_64-only packages on aarch64, and it says explicitly that nothing in the tree checks architecture, so no menu entry can gate on one today. This PR adds the first one. That sharpens the naming question already raised against #8149, which calls its seams Waiting on the maintainer, for the choice between this and #7890 — which still changes the same file and the same test filename to refuse the install rather than offer an alternative — and for the predicate naming above. The open items listed in the previous review are unchanged; none of them are regressions from this commit. |
|
I had trouble getting voxtype to compile on pre-haswell CPUs and didn'thave the hardware at the time to test. I'll revisit shipping a pre-haswell binary to make this faster / easier for the end user. |
|
Update here - I have figured out how to ship binaries for pre-haswell CPUs. Hopefully that makes things a little simpler. They'll be in voxtype 1.0.1 shipping (optimistically) tonight. ARM binaries will be in there too. |
|
Thanks for the update — great news that 1.0.1 will carry pre-Haswell/pre-AVX2 binaries. I'll watch for the release and test on the same hardware this PR was built against (Ivy Bridge i7-3520M, no AVX2/FMA/BMI1/BMI2). If the new binary works cleanly there, this PR's source-build fallback may no longer be needed — happy to help reconcile once 1.0.1 is out. (Disclosure: posted with AI assistance — Claude Code.) |
|
Reporting back as promised — thanks for turning 1.0.1 around so quickly, and the ARM builds did land ( Tested on the same Ivy Bridge i7-3520M ( One thing that might be useful to you: the new variant guard can't fire, because it lives inside a binary that won't execute — Building 1.0.1 from source on this same machine works and dictation runs fine, so I'd suggest keeping this PR's fallback for now rather than treating 1.0.1 as superseding it. Happy to revisit if a pre-Haswell binary shows up in a later release — and glad to test it here whenever you want a machine to try it on. (Disclosure: posted with AI assistance — Claude Code.) |
pacman -Q resolves provides, so with voxtype-bin installed "pacman -Q voxtype" answers "voxtype-bin 1.0.0-2" and exits 0. The aur/ prefix was therefore measured against the provider it exists to bypass: on a machine already carrying voxtype-bin, "omarchy-pkg-aur-add aur/voxtype" found nothing missing, never ran yay, and then took that same provider as proof the package had installed, exiting 0 having built nothing. A prefixed target is now checked with "pacman -Qq", which prints the real package name, and compared against the name asked for. Plain targets keep the old provides-resolving check, so no existing caller changes behaviour. The test's pacman stub modelled -Q as exact-name only, which is why the suite was green; it now answers for a provided name the way pacman does. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
voxtype-bin declares conflicts=('voxtype'), and pacman answers no to its conflict prompt under --noconfirm, aborting with "unresolvable package conflicts detected". A machine still carrying the prebuilt binary -- which is every machine this fallback exists for, since the way users arrive here is a voxtype-bin that SIGILLs -- would build for twenty minutes and then fail to install what it built.
The drop runs only on the source-build branch, after the user has confirmed the build, and omarchy-pkg-drop is a no-op when the package is absent. On a non-x86_64 machine voxtype-bin cannot be installed in the first place, so nothing changes there.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Re-reviewed at A correction to our own earlier review. The last two passes called the So on a machine that already carries
So even with the missing-check fixed, the build would run for twenty minutes and then fail to install what it built. The source-build branch now runs On @peteonrails' 1.0.1 and your report from yesterday. Read the release assets directly. You are right that 1.0.1 has no baseline x86_64 build; through That does not retire this PR yet, and there is a second thing in the way beyond the version bump: @twitchax: the aarch64 assets have shipped in every release since 1.0.0 ( Tests, all on a disposable VM, never on the machine holding credentials. At the pushed head: Second opinion: Codex at xhigh reasoning, pinned to Still open, unchanged, none of them regressions. Waiting on the maintainer for the choice against #7890, which still changes the same file and the same test filename to refuse the install rather than offer an alternative, and for the seam naming shared with #8149 and #8645 — three items now want an architecture predicate and there is still no agreed name for one. |
wtype was installed before the CPU capability decision, so declining the source build on a machine that cannot run the prebuilt binary left the package behind on a system that got no dictation -- while the test's own comment claimed the declining path "installs nothing". It now waits until after the decision, on both the prebuilt and source-build paths. The declining case asserts no package is installed at all rather than only that voxtype-bin isn't, which is what makes the regression visible. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0143VhE2XACsuXdHLRkWoy37
LZCNT is part of the x86-64-v3 baseline, and Voxtype's binaries are built with target-cpu=haswell, which may emit it. The predicate checked the other six flags, so a CPU -- or a VM presenting a masked CPUID -- carrying everything but LZCNT was accepted and could still take the SIGILL this branch exists to avoid. It is reported as "abm" in /proc/cpuinfo on both Intel and AMD. The Haswell fixture already carried the flag with nothing asserting it; the new case is the full baseline minus that one flag, and it fails without this change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0143VhE2XACsuXdHLRkWoy37
Dropping the conflicting prebuilt binary before the build means a build that then fails leaves the machine with no voxtype at all, where it previously had a crash-looping one. That is no loss on the hardware this branch exists for, but the user saw only yay's own output and was left to work out what state they were in. The failure now says what happened, that the prebuilt binary is gone and why it was never usable here anyway, and how to retry. Also quotes the voxtype-bin literal in its comparison, per AGENTS.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0143VhE2XACsuXdHLRkWoy37
The tests checked which commands each path logged but never what the installer returned, so a path that did the right work and then exited wrong -- or the rollback branch reporting success -- would have passed. The menu and any caller act on that status. Every case now asserts it: success on the prebuilt, declining, and source-build paths, failure on an unreachable AUR and on a rolled-back setup. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0143VhE2XACsuXdHLRkWoy37
The drop of voxtype-bin was run for its effect and not for its status, so a machine where pacman refuses the removal still spent the build and then hit the conflict it was meant to clear. The failure message that followed told the user the prebuilt binary had been removed, which on that path is false, and sent them to Install > Dictation to retry -- an entry that stays disabled while voxtype-bin is installed, because the guard is `omarchy-cmd-present voxtype`. Nothing the build produces can be installed while the conflict stands, so the install now stops there and says what happened instead of spending twenty minutes to arrive at the same place. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-Authored-By: Codex XHigh <noreply@openai.com>
|
Re-reviewed at What the four commits fixed.
The source build, actually run. On a disposable Omarchy VM (4 vCPUs of a Ryzen 9 9955HX, 4 GB RAM), One thing nobody has raised, and it is the part that outlives the install. Reported rather than pushed. After a successful drop and a failed build, the running session keeps its Voxtype state: Tests, all on a disposable worker, never on the machine holding credentials. At the pushed head: Second opinion: Codex at xhigh reasoning, pinned to Waiting on the maintainer, unchanged: the choice against #7890, which still changes the same file and the same test filename to refuse the install rather than offer an alternative, and the predicate naming shared with #8149 and #8645. |
Fixes #8312
Problem
voxtype-bintargets the x86-64-v3 instruction baseline (AVX2, FMA, BMI1/2, F16C, MOVBE), so itSIGILLs on CPUs older than Haswell (~2013). The install hook (bin/omarchy-voxtype-install) had no capability check, so it always installed the incompatible binary. Worse, if a post-install step failed,set -eaborted the script mid-way and left the package +~/.config/voxtypeon disk with no cleanup.Fix
bin/omarchy-hw-x86-64-v3, a boolean predicate following the existingomarchy-hw-*convention, to detect the baseline via/proc/cpuinfoflags.voxtypepackage from source instead of the prebuilt binary, with an explicit warning that this can take 20+ minutes and may run noticeably slower — only proceeds on confirmation.omarchy-voxtype-removeif any post-install step fails, instead of abandoning a half-installed package.omarchy-voxtype-removeto drop whichever ofvoxtype-bin/voxtypeis actually installed.test/shell.d/hw-x86-64-v3-test.shandtest/shell.d/voxtype-install-test.sh, and a short note in the manual.Testing
./test/allpasses (208 shell test files + CLI suite), aside from pre-existing failures unrelated to this change (config-test.sh,snapper-test.sh,theme-install-guards-test.sh,unowned-system-paths-test.sh, and one CLI test needing a siblingomarchy-pkgscheckout not present in this sandbox — all reproduce identically onquattrobefore this change). Also manually verifiedomarchy-hw-x86-64-v3against a real Ivy Bridge CPU (i7-3520M) lacking AVX2.Disclosure
This fix was drafted and tested with AI assistance (Claude), in response to the project's own agent-contributing workflow (
default/agents/skills/omarchy/contributing.md). I filed #8312 after hitting this myself, then worked with Claude to build and test this patch before opening the PR.