Repository navigation
Integrate Apple Silicon stabilization fixes for 4.0.3rc1 - #377
Conversation
M3 has DCP scanout but no AGX render node, so Chromium and 1Password die in the GPU process and stay running with no window. PATH wrappers on /usr/local/bin add --ozone-platform=wayland --disable-gpu at launch when renderD* is missing, and become a no-op once a render GPU appears.
omarchy-notification-send rejects a quoted whole command so it cannot be split. The toast then exits 1, first-run skips the timezone card, and a Mac left on UTC never gets asked. Match wifi.sh and welcome.sh.
Apple Silicon MacBooks report lid events under 'Apple SMC power/lid events'. When Quattro introduced omarchy-system-lid-close to lock the session and coordinate pre-suspend display state, the Mac-specific switch:on binding was left wired to omarchy-hyprland-monitor-clamshell instead. As a result, closing the lid on an Apple Silicon MacBook bypassed omarchy-system-lid-close entirely, preventing the session from locking before suspend. Route switch:on:Apple SMC power/lid events to omarchy-system-lid-close, mirroring the generic switch:on:Lid Switch bind, and assert both bindings in monitor-recovery-test.sh.
wf-recorder follows the Asahi DSP clock into a 96 kHz AAC track that this PipeWire graph (and many players) play as silence. Pin the sample rate at 48 kHz. Stop/bar/menu matched ^wf-recorder, which misses argv[0] when it is a full path. Match the basename at a path or line boundary so Capture Stop and the bar indicator work on Apple Silicon. The webcam overlay already skipped initial focus; clicks still stole the session. Ignore focus and mouse-follow so the mini-me stays put.
asahi-audio publishes the beamformed laptop mics as AUX0. Recorders ask for FL/FR, so they fail to link or write left-only audio that loudnorm ruins. Duplicate AUX0 onto a low-priority stereo sink and use its monitor as the default source, without moving existing source-outputs (that steals the DSP capture). speakersafetyd can hit start-limit after a bad IV-sense sample and leave the speakers muted at -100 dB; clear that and try once more.
A new null sink can steal the session output. Putting the speaker convolver back unconditionally bounced headphones and Bluetooth to the internal speakers on every login. Snapshot the default first and restore it; only fall back to the convolver when the dummy sink is what is left.
…rmed Backport arm_expiry() from omacom/omarchy, which omarchy-mac does not carry. Both systemd-run call sites ran unchecked, so a failure to schedule the expiry timer left the NOPASSWD sudoers rule in place while the script still reported that access would expire in N minutes. The timer's `rm` also lacked -f, so disabling a window early caused the still-scheduled timer to fire against a missing file, exit non-zero, and strand the transient unit in failed state -- which then blocked the next `systemd-run --unit=` and reproduced the fail-open path on every subsequent enable. arm_expiry() uses `rm -f --` so the unit cannot strand itself, checks systemd-run's exit status, and revokes the grant immediately if the timer cannot be scheduled. Callers use `arm_expiry || exit 1`. The mac fork's restart-notice wording is intentionally kept: a file in /etc/sudoers.d survives reboot and is only cleaned up on the script's next invocation, so the existing message is more accurate than upstream's. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R5z6wirF6matApdUKH4fFT
…ntegration/4.0.3rc1-green
…ntegration/4.0.3rc1-green
…ntegration/4.0.3rc1-green
…ntegration/4.0.3rc1-green # Conflicts: # install/user/all.sh
…ntegration/4.0.3rc1-green
|
Stabilization status for this draft PR at
Keep this PR in draft while those local hardware checks are underway; mark it ready once they pass. These results cover a local package installation with the development checkout linked, not an upgrade through a published RC repository. ARM RC repository isolation and testing the exact published packages remain release gates. They do not necessarily need to block review of this integration PR. |
|
Review recommendation: request changes. The review found ten P2 issues in new behavior. The package-selection, boot-layout guard, immediate sudo-scheduling failure handling, and timezone changes passed their scoped checks. Existing repair gaps and release qualification limits are listed separately below. Reviewed head: Five subagents covered four implementation scopes plus independent aggregate QA. The parent covered CI/integration and corroborated findings; two of the reviewers also performed targeted cross-reviews. All 45 changed files were covered. The PR head and base were checked again before posting and still match these revisions. 1. P2: Recorder detection can select unrelated applications bin/omarchy-capture-screenrecording:54; the same pattern is used in default/omarchy/omarchy-menu.jsonc:60 and shell/plugins/bar/indicators/ScreenRecording.qml:18. The new slash alternative is unanchored. Because the process queries use full-command-line matching, a path in another application's arguments can satisfy the recorder pattern even when that application is not a recorder. This affects more than the indicator: existing stop logic uses the same pattern for SIGINT and eventual SIGKILL, and the regular toggle can enter that stop path based on the false match. Independent pure-string checks confirmed new false matches that the base rejected, alongside controls for legitimate absolute recorder paths and executable suffixes. No live process lookup or signaling was performed. Please constrain selection to the recorder executable/process identity and use the same identity policy for start, status, and stop. Preserve absolute-path support; simply restoring the old pattern would lose that improvement. 2. P2: Failed microphone links can replace a working input with a silent monitor bin/omarchy-audio-asahi-mic-map:45 and bin/omarchy-audio-asahi-mic-map:53. Exhausting the port-readiness loop does not stop setup. Both channel-link errors are then ignored, and the mapper still selects the monitor as the default source. The readiness check also does not establish that the right-channel port exists. Separate fixtures for absent ports, rejected links, and a missing right channel all replaced the previously working input. This is newly introduced behavior. Please verify that both required links exist before changing the default input. Treat already-existing links as idempotent success, preserve the previous input on failure, and clean up only resources created by the failed invocation. 3. P2: A custom launcher blocks user finalization and later migrations migrations/1788639443.sh:13 and install/user/hardware/apple/electron-gl.sh:13; refusal originates in bin/omarchy-cmd-electron-gl-wrap:46. The wrapper helper correctly refuses to overwrite an unmanaged launcher or non-legacy symlink. However, both strict callers treat that ownership conflict as fatal. An otherwise valid administrator-managed Chromium launcher therefore aborts user finalization and stops the migration queue before unrelated later repairs. A custom 1Password launcher reaches the equivalent conflict later in the flow. The same inert custom-launcher state completes the base user-stage driver, while head exits nonzero. An isolated migration-runner fixture leaves the failed and later completion markers absent. Please preserve the ownership refusal while handling this optional wrapping conflict explicitly at the callers, for example by skipping with a clear diagnostic or using a distinct managed launcher. Actual write/install failures should still propagate. 4. P2: Chromium setup destroys existing desktop customizations install/user/hardware/apple/electron-gl.sh:18. The script writes a transformed copy of the system desktop file directly over the user's The custom-desktop fixture lost its profile selection and custom fields; the base had no corresponding writer. Please preserve an existing user entry and make only the necessary targeted executable repair, retaining arguments and desktop actions. Seed a generated entry only when appropriate, and preserve a backup when changing existing content. 5. P2: An unseeded Chromium wrapper adds a background sudo requirement install/user/hardware/apple/electron-gl.sh:13 and bin/omarchy-cmd-electron-gl-wrap:95. The concrete failing state is pending or forced graphical user finalization on an Apple machine with Chromium installed, an absent/incorrect global Chromium wrapper, and no usable noninteractive sudo authorization. The newly added leaf reaches privileged operations in Static tracing of the real caller and exact companion recipes found no package or root hardware stage that guarantees the Chromium wrapper. A denying sudo mock produced a head-only failure at this new boundary. This is not every first login: matching wrappers need no sudo, completed finalization skips the path, and the interactive installer can authenticate earlier. Successful fresh 1Password setup also seeds its own wrapper, so Chromium is the independently supported case. The hosted installation user's unrestricted NOPASSWD sudo does not exercise this condition. Please provision machine-wide Chromium wrappers in root-scoped setup and leave per-user desktop work in the user leaf. 6. P2: Login replaces an explicitly selected external microphone bin/omarchy-audio-asahi-mic-map:73. When the built-in DSP source exists, every invocation selects its monitor regardless of whether the user selected a working USB, Bluetooth, or headset microphone. The new autostart repeats this at login. The fixture with a selected, available USB input was switched to the remap. Please preserve explicit input choice and select the remap only when replacing the intended built-in source or establishing an otherwise unconfigured default. Output-device restoration does not preserve the input-device choice. 7. P2: Repeated mapping resets microphone gain bin/omarchy-audio-asahi-mic-map:56. DSP source, sink, and monitor volumes are reset to 100% even when reusing an existing mapping. A fixture with calibrated gain at 42% lost that setting on the next invocation. The new login call makes this a recurring reset. Please separate initial graph setup from repeat invocation and retain the effective user-selected input gain and mapped-source volume. 8. P2: Restart Audio loses the new microphone mapping default/hypr/autostart.lua:15 and bin/omarchy-audio-asahi-mic-map:40; related existing caller: bin/omarchy-restart-audio:6. The null sink and links are created as runtime graph objects. The only creation paths are login and setup, while the existing Restart Audio command restarts the services owning those objects without rebuilding them. Static lifecycle tracing and an inert model of service restart leave the new mapping absent after the restart helper returns success. Please tie graph creation/recovery to the audio-service or node lifecycle through persistent supported configuration or supervised remapping that also preserves user choice. This is a lifecycle gap in the new feature; physical audio recovery was not tested. 9. P2: The audio migration reports success after real mapper failures install/user/hardware/apple/mic.sh:13, reached by migrations/1788820499.sh:10. The standalone mapper returns nonzero when module creation fails, but the sourced leaf suppresses both status and diagnostics. The migration can consequently finish successfully without completing the live-session repair. The standalone module-load-failure fixture correctly failed; the same failure through the leaf/migration was suppressed. Please distinguish expected deferral when no audio session exists from real failures in a live session, and propagate the latter. The login autostart does retry on the next login. This finding concerns silent failure and migration completion during the current update, not a claim that retries can never occur. 10. P2: The migration overwrites a customized same-name WirePlumber policy install/user/hardware/apple/mic.sh:10. The new migration unconditionally copies over This is narrowly conditional on that exact filename; other drop-ins are unaffected. Normal login invokes the mapper rather than this copying leaf, so it is not an every-login overwrite. Please seed absent files and preserve custom existing content. If a known managed version must be updated, identify it explicitly and preserve a backup or reconcile the intended property. Existing defects / incomplete upgrade repairs, excluded from the ten new findings
Validation and limits The added checks below are fixture assertions or reported scenarios, not independent full installations. Some checks deliberately assert expected failure handling or establish an unchanged baseline defect.
These 211 checks do not mean 17 distinct bugs: fourteen failed invariants support the ten new findings, one demonstrates the older 1Password repair gap, and two demonstrate the same pre-existing recorder cleanup defect at base/head. Native pacman tests used synthetic databases and print-only resolution, not host package installation. Independent aggregate QA completed both revisions normally:
The Mac help assertion fails identically in unchanged baseline code in the isolated environment. The head-only pacman test is blocked by the aggregate executable restrictions but passed separately under the package reviewer's isolated native-pacman setup. The clipboard lifecycle test is blocked on both revisions because All eight settings-package staging combinations passed: stable/current source, stable/development flavor, and ARM/x86 architecture. The stable source pin was fetched explicitly to avoid silently skipping those cases. The Snapper dependency assertion also passed. Parse-only checks passed for 1,032 Bash and five Python files. The existing source CI and ARM installation run were successful when reviewed. The ARM log independently records the exact head/base merge and pinned companion recipes. Both fresh and repeat installation assertions retain Release assessment: HOLD. The package-selection changes have positive bounded evidence, but existing-user migration behavior needs revision. Companion #341 was still open/unmerged when reviewed. Old published-package upgrades, physical M1/M2 boot/GPU/audio/recording/lid/suspend/recovery, isolated RC artifacts and canary qualification were not tested here. Current-stack remediation and repeat installation do not substitute for those gates. Suggested repair order: constrain recorder selection; make microphone setup transactional and preserve device/gain choices; restore mapping across audio restarts and propagate real failures; preserve customized files and provision global wrappers at the correct privilege stage; then close existing-install migration gaps. Re-run the failed invariants and affected integration checks before merge approval, followed by qualification of the exact packaged artifacts before release. |
Follow-up review (1/2): remaining findings at
|
Follow-up review (2/2): fix dispositions and validation at
|
| Earlier finding | Status | Current evidence |
|---|---|---|
| 1. Recorder argument matching selects unrelated processes | FIXED | Actual executable identity replaces command-line matching; callers share the helper. Absolute/deleted executable paths, owner filtering and mocked pidfd selection pass. No live signaling or kernel race-freedom claim. |
| 2. Failed mic links select a silent monitor | FIXED | Required endpoints, link readiness and final identities are checked before selection; rollback preserves pre-existing resources. |
| 3. Unmanaged launchers block finalization/migrations | PARTIAL | Regular custom files and other-target/dangling symlinks are handled. Same-target Chromium aliases still fail before ownership classification. |
| 4. Chromium desktop customizations are overwritten | FIXED | Targeted token repair preserves arguments, actions and custom metadata, with backups and repeat/idempotence checks. Already-lost historical customization cannot be reconstructed. |
| 5. Unseeded Chromium adds background sudo | FIXED | Root-scoped hardware setup provisions wrappers; user setup uses read-only readiness and safely skips unready wrappers without sudo. |
| 6. Mapper overwrites the chosen microphone | PARTIAL | Stable USB/Bluetooth selections are preserved; a choice during the final graph query can still be overwritten. |
| 7. Repeated mapping resets mic gain | FIXED | Asymmetric channel gains and mute survive repeat reconciliation and modeled daemon-loss restoration. |
| 8. Restart Audio loses mapping | FIXED in modeled lifecycle | Supervised watcher and restart wiring recover from modeled daemon/DSP disappearance, query failure and link failure. Actual hardware/service lifecycle remains untested. |
| 9. Mic migration hides mapper errors | FIXED | Real failures propagate with diagnostics. Explicit deferred status 75 is accepted intentionally with persisted service setup, rather than masking a live failure. |
| 10. Customized WirePlumber policy is overwritten | FIXED | Absent policy is seeded; existing custom regular files and symlinks are preserved. |
Additional existing-install repairs
- 1Password direct-path desktop routing: FIXED in inert fixtures. The new migration reaches users with the old marker complete, repairs the effective desktop route without modifying the vendor file, preserves arguments/backups, and is idempotent. Fresh/repeat installation and second-user cases also pass.
- Missing Snapper root after an old migration marker: FIXED through new migration
1788981069.sh. Old-marked users receive a new repair attempt; repeats and a second user's migration state do not recreate a healthy backend. - False readiness for a partial Snapper backend: FIXED. Registration, settings, non-symlink subvolume and successful listing are required. Partial/conflicting state is preserved and rejected; automatic reconstruction of arbitrary broken state is not implemented. Manual repair remains necessary, with migration completion withheld.
- Preservation improvements: PASS. Custom root retention, additional configs, snapshots and global timeline scheduling survive the new Snapper setup fixtures.
- The previously excluded recorder-startup audio-module cleanup limitation remains unchanged; it was not rerun or counted as a new regression here.
Targeted validation
| Independent added checks | PASS | Failed invariants |
|---|---|---|
| Recorder identity and caller behavior | 139 | 0 |
| Audio endpoint, choice, gain, rollback and lifecycle | 40 | 1 |
| Electron, desktop, install and migration boundaries | 46 | 4 |
| Snapper backend, migration and service contracts | 26 | 5 |
| Total | 251 | 10 |
These are 261 counted fixture checks/assertions, not full installations. The ten failures support five issues: four P2 findings and one P3. Supplied tests repeated by scoped reviewers overlap aggregate coverage and are not added again to this total. Seven additional native desktop-resolver cross-check observations matched expectations, including deliberately invalid-output controls.
One audio case initially hit a sandbox refusal to bind a dummy socket and passed its isolated retry; it is not a product failure. An initial Electron lifecycle harness omitted a fake filesystem parent and was excluded as invalid; the corrected fresh/repeat/second-user checks all passed. Raw logs and these adaptations were retained rather than presenting the initial attempts as product failures or silently discarding them.
Aggregate QA
| Suite | PASS files | FAIL files | SKIPPED files | BLOCKED files | Passing assertions | Failing assertions |
|---|---|---|---|---|---|---|
| CLI | 1 | 0 | 0 | 0 | 116 | 0 |
| Shell | 243 | 1 | 20 | 0 | 3,083 | 1 |
| Mac | 8 | 1 | 1 | 0 | 228 | 1 |
| Total | 252 | 2 | 21 | 0 | 3,427 | 2 |
No aggregate/file timeout occurred. All six changed/new supplied test files passed applicable checks. Parse-only checks passed for 1,037 Bash and eight Python files.
The aggregate is not entirely green:
- The Mac piped-help failure matches the earlier baseline, in unchanged source.
- The emoji fixture failed on head in the aggregate and a focused run; a focused original-base run passed. The fixture, command and relevant helpers are unchanged. Its removed delays around an asynchronous writer provide a plausible timing explanation, not an isolated causal proof. This is retained as an unresolved test failure, not established as an introduced product regression.
- Safety/compositor/privileged skips remain documented. Private overlays redirected temporary paths and constrained external actions, so these are not unrestricted desktop/hardware suite results.
The earlier aggregate pacman and clipboard blockers were removed within the isolated QA setup: print-only native pacman resolution passed three assertions, and the clipboard suite passed 73 after exposing setpriv within the restriction. No host package installation occurred.
All eight settings staging combinations passed: current/stable source, settings/settings-dev, ARM/x86. These checks are already included in aggregate counts; stable-pin cases executed rather than being counted as skipped passes.
Hosted evidence and acceptance limits
All four checks were green when refreshed: syntax/shellcheck, test/all, tests/all, and ARM installation. See CI and ARM installation.
The CI merge commit 8738d9e has the same file tree as reviewed head 40c5c15. Its ARM log covers fresh setup and current-stack remediation/reinstallation, including system and user finalization on repeat. Selected versions remain hyprland 0.56.2-3, hyprtoolkit 0.5.4-5.1, and hyprland-guiutils 0.2.2-3.
That is not a real old-published-stack upgrade fixture. Companion omarchy-pkgs#341 was still open/unmerged at the pinned revision when revalidation completed.
NOT TESTED: physical Apple audio/DSP/hotplug, GPU/UI operation, native recorder signaling, real systemd lifecycle, suspend/resume, physical boot/upgrade/recovery, and actual snapshot restore. Earlier reported M2 checks were on the previous head, not this revision.
All generated fixtures, overlays, caches and logs used verified disk-backed storage. No source fixes, installed-system configuration changes, real host audio/service/boot operations or application launches were performed.
Next step: resolve the four P2 items from comment 1/2 and rerun those focused cases while retaining the passing preservation and lifecycle controls. Treat the P3 separately. Exact-package integration and physical acceptance remain distinct release gates, not claims established by hosted userspace success.
|
Validation update at
Ready for renewed review. #341 remains unmerged. These are local source-linked package tests; signed published-package upgrades, fresh encrypted installation, snapshot restore and canary qualification remain outstanding. Resume-time DCP and Wi-Fi/P2P warnings were recorded despite successful desktop/audio recovery. |
Apple Silicon stabilization for the next 4.0.3 release candidate: first-login and Snapper fixes, bounded-sudo scheduling failure handling, lid locking, audio/recording repairs, and compositor update fixes. The combined branch passes hosted source CI and ARM fresh/repeat installation checks.
Changes
pacman -Syu --neededskipped unchanged explicit compositor targets, then upgradedhyprtoolkitfrom a different repository. Transaction-local ignores preserve the selected repository while allowing explicit upgrades/downgrades and ordinary system upgrades.6d27290193109c07b0134360d382e64790ae5dda. The ARM harness privately stages those same recipes for both installation passes and handles linked-worktree Git metadata.plans/4.0.3rc1-green-integration.md.Validation
Tested head:
8ee210a57a4d263be874be374db659d7cd101303.test/all,tests/all, syntax, and ShellCheck.hyprtoolkit 0.5.4-5.1.Dependencies and release gates
Package PR #341 must land before production builds can rely on upstream's default recipes; this PR pins it explicitly for CI. ISO companion omarchy-mac/omarchy-mac-iso#19 remains separate.
This PR does not bump the version or publish an RC. ARM channel isolation, published-artifact upgrade testing, M1/M2 hardware qualification, and canary validation remain required. M3 remains experimental. Passwordless sudo persistence across reboot is a preexisting separate gap; #376 fixes failure to schedule expiry. Hosted ARM containers do not qualify Apple boot, GPU, audio, or suspend behavior.
Closes #361
Closes #368