Captures from macOS 26.5 (Apple Silicon MacBook), device "AGI Bench 1.2.5" - a BLE HID composite (keyboard + consumer + mouse, HID over GATT, nRF52840) paired over Bluetooth. Same firmware and descriptor that drops Shift on iPhone. hid-descriptor-raw.txt ReportDescriptor hex pulled from ioreg for the device hid-descriptor-decoded.txt same descriptor decoded item by item (report IDs 1/2/3) macos-raw-hid-reports.log IOHIDManager capture while the device typed "A" then "xAx". The "A" arrives as one report: 01 02 00 04 ... i.e. report ID 1, modifier 0x02 (left shift), keycode 0x04. Each report shows up 3x because macOS exposes the device as multiple IOHIDDevice services. macos-eventtap.log CGEventTap for the same keystrokes: flagsChanged keycode=56 SHIFT=1, then keyDown keycode=0 with SHIFT=1 - macOS applies the modifier and TextEdit shows "A" / "xAx". On iPhone these same reports produce "a" / "xax". two-service-split-firmware.patch the isolation experiment: same keyboard-only service that works when it's alone, plus a separate mouse-only HID service on the same device. Cursor works on iPhone, Shift still dropped. capture-tools/ the small tools used above (IOHIDManager monitor, event tap, descriptor decoder, and the CoreBluetooth helper that sends the device its "type" command).