Skip to content

macos: fix command8-mackie's sudo requirement at launch (partial); verify reaper/monitor - #3

Merged
alphonsom merged 1 commit into
mainfrom
fix-mackie-macos-claim-order
Aug 9, 2026
Merged

macos: fix command8-mackie's sudo requirement at launch (partial); verify reaper/monitor#3
alphonsom merged 1 commit into
mainfrom
fix-mackie-macos-claim-order

Conversation

@alphonsom

Copy link
Copy Markdown
Owner

Summary

  • Root cause found: command8-mackie constructed MackieBackend (which creates RtMidi/CoreMIDI virtual ports) before ever opening the UsbSurface. On macOS, merely initializing an RtMidi client — even just to publish unrelated virtual ports — causes that process's own future libusb claims of the Command|8 to race CoreMIDI's in-process device-notification handling for the same (malformed) MIDIStreaming interface, and lose (LIBUSB_ERROR_ACCESS), forcing sudo.
  • Fix: reorder command8-mackie's startup (macOS only — Linux/Windows don't share this problem and keep their original fail-fast order) so the UsbSurface is claimed beforeMackieBackend/RtMidi is constructed. Verified on hardware: first launch is now sudo-free.
  • Honest limitation, documented rather than hidden: this is a partial fix. Once RtMidi has been constructed in-process, a claim lost to a later unplug cannot be regained from that process without root. Verified on hardware that this is a standing condition, not a transient race (steady failure past 35s of retries) and that tearing down/rebuilding the CoreMIDI client around the reclaim attempt doesn't help either — that attempt was made, tested, found not to work, and reverted rather than shipped as dead code. A real fix would need a privilege-separated helper process holding the libusb claim, which is out of scope here.
  • command8-monitor / command8-reaper verified clean: neither ever touches RtMidi/CoreMIDI. command8-monitor claims the interface and gets live fader/encoder input + LED feedback unprivileged. command8-reaper does the same and was directly re-tested reclaiming the interface unprivileged after a live unplug/replug cycle (not inferred from shared code shape — actually re-run).

Testing (macOS 15.6, Intel, Homebrew, libusb 1.0.30)

  • Full rebuild (cmake -B build -G Ninja && cmake --build build): clean, zero warnings.
  • ctest: 3/3 pass (protocol, feedback, usb_packets) after every change in this branch.
  • command8-mackie: first launch confirmed unprivileged (no sudo) both before and after the fix was re-verified; replug still requires sudo, confirmed via a 35+ second observation window (steady failure, not a resolving race) and via a failed tear-down/rebuild mitigation attempt (reverted).
  • command8-reaper: confirmed unprivileged on first launch, and confirmed unprivileged reclaim after a live unplug/replug cycle.
  • command8-monitor: confirmed unprivileged fader/encoder input and select/mute/solo LED feedback on real hardware.

🤖 Generated with Claude Code

…ckie
command8-mackie constructed MackieBackend (which creates RtMidi/CoreMIDI
virtual ports) before ever opening the UsbSurface. On macOS, merely
initializing an RtMidi client -- even just to publish unrelated virtual
ports -- causes this process's own future libusb claims of the Command|8
to race CoreMIDI's in-process device-notification handling for the same
malformed MIDIStreaming interface, and lose (LIBUSB_ERROR_ACCESS),
requiring sudo.
Reordering startup so the Surface is claimed first (macOS only; Linux and
Windows don't share this problem and keep the original fail-fast order)
makes first launch sudo-free, verified on hardware.
This is a partial fix, not a full one. Once RtMidi has ever been
constructed in-process, a claim lost to a later unplug cannot be regained
from that process without root -- verified on hardware, including that
this doesn't resolve with more retries/time and that tearing down and
rebuilding the CoreMIDI client around the reclaim attempt doesn't help
either. Documented in both the code comment and the README rather than
papered over: replug-while-running still needs sudo for command8-mackie
specifically.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@alphonsom
alphonsom merged commit cde1ac0 into mainAug 9, 2026
4 checks passed
@alphonsom
alphonsom deleted the fix-mackie-macos-claim-order branch August 9, 2026 20:10
alphonsom added a commit that referenced this pull request Aug 10, 2026
Brings in the macOS work and meter ballistics merged via PRs #1-#3. Clean
merge, no conflicts; builds with no warnings and all three tests pass.
README: Windows no longer requires Digidesign/Avid's driver. The dongle makes
the surface enumerate as an ordinary class-compliant USB-MIDI device with no
driver at all, and the ports look the same to this engine either way.
Also spells out the exclusive-access trap, which is easy to hit and gives no
useful error: a DAW holding the Command|8 ports stops the engine opening the
device. The DAW talks to the engine over OSC or the MCU loopback pair, never
to the surface directly -- the Command|8 speaks a proprietary protocol, so a
DAW sending it generic MIDI just twitches the faders and leaves the display
Offline, which is exactly what a first Windows attempt looks like.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@alphonsom