Skip to content

docs: device-side HID facts from an independent shim, measured on firmware v0.6.1 - #7

Merged
thannous merged 3 commits into
mainfrom
docs/shim-device-side-observations
Aug 2, 2026
Merged

docs: device-side HID facts from an independent shim, measured on firmware v0.6.1#7
thannous merged 3 commits into
mainfrom
docs/shim-device-side-observations

Conversation

@thannous

@thannous thannous commented Aug 2, 2026

Copy link
Copy Markdown
Owner

Context

docs/research/hid-lighting-protocol.md was written entirely from the host
side: we write to the keyboard. The apps/micro-shim/ of
maxxspotter/codex-micro-app
(MIT) takes the opposite position, patching node-hid inside the Codex desktop
process to advertise a synthetic Micro. Its framing matches ours exactly
(report 0x06, channel 2, 61-byte chunks, same descriptor), which
corroborates our evidence matrix independently.

It supplied four facts about values, where we had only field names. Rather
than record them as third-party hearsay, all four were measured on hardware
— every control actuated by hand, plus a raw probe bypassing hid-frame.mjs
on firmware v0.6.1.

Results

Fact Shim's claim Measured
Action keycodes ACT06 fast … ACT12 send, ACT11 unexplained confirmed, and ACT11 explained
Joystick angles right 0, down 0.25, left 0.5, up 0.75 confirmed: 0.0107, 0.2388, 0.4894, 0.7614 at d = 1
Encoder act: 2 on rotation, ENC_CLK on click, CW/CC swapped confirmed: a declared-clockwise run gave 30 ENC_CC, 0 ENC_CW
Codex → device requests device.status with profile_index / layer_index confirmed: the real payload is readable from here

ACT11 is not a key

One press of the wide bottom key emits two keycodes, three times out of three:

23:14:14.245 ACT11 act1  +5ms ACT10 act1  … ACT10 act0  +3ms ACT11 act0
23:14:18.502 ACT11 act1  +6ms ACT10 act1  … ACT10 act0  +4ms ACT11 act0
23:14:21.334 ACT11 act1  +6ms ACT10 act1  … ACT10 act0  +6ms ACT11 act0

Invariant order, 3–6 ms nesting, hold durations in line with every other key.
One physical actuator on two matrix positions — hence the shim's apparent
gap. That settles the count too: 13 keycodes for 12 key actuators, plus the
wheel press, which is how the README's 13 switches are composed.

Codex's own traffic is readable from the host

The non-exclusive open broadcasts input reports to every reader, so the
device's answers to Codex are visible here as well. The real device.status
response arrives every 60.009 s:

{"version":"v0.6.1","profile_index":0,"layer_index":1,"battery":100,"is_charging":false}

layer_index reports the active layer — the roadmap's layer work can read it
with no device-side vantage point.

Two divergences from the shim

  • Joystick release: the device sends {a: 0, d: 0}, resetting the angle;
    the shim repeats the last angle with d: 0.
  • No ag field: Agent keys emit {k, act} only; the evidence matrix
    wrongly listed {k, act, ag}.

Firmware

A vendor update from v0.4.1 to v0.6.1 landed mid-investigation. Framing,
RPC channel and v.oai.thstatus are unchanged across it; the document records
both versions.

What is deliberately left open

Whether the device drops rotation notches at all is untested, and the
document says so. Earlier captures returned fewer events than intended, but the
ground truth was detents counted by hand and is not reliable, so no drop rate is
quoted. What the raw probe does establish is that any such loss would not be
ours: 38 reports, 30 notch events, zero unparseable lines.

Attribution

Sources credit the project and the MIT-licensed
Codex Micro Stream Deck emulator
its interception layer adapts, with an explicit note that no code from either is
reused — consistent with the existing "Legal framing, restated" section.

Verification

Documentation only, no code touched. node scripts/check-doc-links.mjs passes
(53 files).

🤖 Generated with Claude Code

The lighting protocol document was written entirely from the host side: we
write to the keyboard and never see what Codex sends to it. The micro-shim of
maxxspotter/codex-micro-app takes the opposite position, presenting a synthetic
Micro inside the Codex process, so it observes that half of the exchange.

Its framing matches ours exactly, which corroborates the evidence matrix
independently. Four value-level facts are new: the ACT06-ACT12 action key
names, the normalised angles of v.oai.rad, act 2 for encoder notches, and the
sys.version / device.status requests Codex sends to the device.

All four are marked as read from a third-party source and never reproduced
here, and three of them join the open questions. Where the shim's inferred
field labels contradict our hardware measurements, the document keeps the
measurement. Attribution added to Sources, for that project and for the
MIT-licensed Stream Deck emulator it adapts.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The English and French HID protocol research documents add independently sourced device observations, explicit verification caveats, unresolved measurement targets, and references to the MIT project and related emulator.

Changes

HID protocol documentation

Layer / File(s) Summary
Device-side observations
docs/research/hid-lighting-protocol.md, docs/fr/research/hid-lighting-protocol.md
The documents describe HID framing, action and agent key names, joystick and encoder event formats, and sys.version and device.status queries. They mark inferred fields and status data as unverified.
Verification targets and sources
docs/research/hid-lighting-protocol.md, docs/fr/research/hid-lighting-protocol.md
The documents add ACT11, the real device.status response, and the physical meaning of ENC_CW as open verification targets. They cite the MIT project, its shim, and its adapted emulator, and state that no code is reused.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title describes the HID observations but incorrectly states that they were measured on firmware v0.6.1, while the PR identifies them as unverified third-party observations. Replace “measured on firmware v0.6.1” with wording that identifies the observations as independently sourced and unverified.
✅ Passed checks (4 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/shim-device-side-observations

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
docs/research/hid-lighting-protocol.md (1)

147-151: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Pin both external citations to immutable source revisions.

The documents cite moving repository URLs. Add the commit SHA used for the observations and the access date in both language versions.

  • docs/research/hid-lighting-protocol.md#L147-L151: pin both cited repositories to their source commits.
  • docs/fr/research/hid-lighting-protocol.md#L152-L157: use the same pinned commits and date.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/research/hid-lighting-protocol.md` around lines 147 - 151, Pin both
cited repositories in docs/research/hid-lighting-protocol.md lines 147-151 to
their immutable source commit SHAs and include the access date. Apply the same
commit SHAs and date to the corresponding citations in
docs/fr/research/hid-lighting-protocol.md lines 152-157, preserving the existing
attribution and licensing context.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@docs/research/hid-lighting-protocol.md`:
- Around line 147-151: Pin both cited repositories in
docs/research/hid-lighting-protocol.md lines 147-151 to their immutable source
commit SHAs and include the access date. Apply the same commit SHAs and date to
the corresponding citations in docs/fr/research/hid-lighting-protocol.md lines
152-157, preserving the existing attribution and licensing context.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 20bb1c00-d748-4cce-bf20-308012c0dda7

📥 Commits

Reviewing files that changed from the base of the PR and between 471a6fa and 87408da.

📒 Files selected for processing (2)
  • docs/fr/research/hid-lighting-protocol.md
  • docs/research/hid-lighting-protocol.md

The four facts borrowed from the micro-shim were recorded as third-party and
unverified. Three are now measured here, by actuating every control by hand
against scripts/lighting.mjs listen. The fourth, what Codex sends to the
device, stays out of reach from the host side.

ACT11 is not a key. One press of the wide bottom key emits ACT11 then ACT10,
nested within 3 to 6 ms, three times out of three, with hold durations matching
every other key in the capture. It is a single actuator on two matrix
positions, which is why the shim has nothing to expose there. That also settles
the count: 13 keycodes for 12 key actuators, plus the wheel press.

The shim's joystick angles hold at the digit: 0.0107, 0.2388, 0.4894, 0.7614
for right, down, left, up. Two divergences appear against it — the device
resets the angle to zero on release rather than repeating it, and the Agent
keys carry no ag field, which the evidence matrix wrongly listed.

The channel itself survives the vendor update from v0.4.1 to v0.6.1 unchanged.

Dropped encoder notches join the open questions. Five slow notches produced
four events while a fast burst produced five, so speed does not explain the
loss and the 90 ms wheel calibration is not implicated; why an isolated slow
notch disappears is unexplained. The direction of rotation in that capture
rests on the operator's intent, not on an independent signal, so clockwise to
ENC_CC still stands on the earlier hardware measurement rather than on this
one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@thannous thannous changed the title docs: record device-side HID observations from an independent shim docs: device-side HID facts from an independent shim, measured on firmware v0.6.1 Aug 2, 2026
Two corrections to the section added in the previous commit, both from a raw
capture that bypasses hid-frame.mjs and logs every 64-byte report.

device.status was recorded as unreachable from the host side. It is not. The
non-exclusive open broadcasts input reports to every reader, so the device's
answers to Codex are visible here too, and the real payload arrives every
60.009 s carrying layer_index, which the roadmap's layer work can now read
without a device-side vantage point. The earlier reasoning confused being
unable to send Codex's requests with being unable to see the answers.

The dropped-notch anomaly is retracted as a phenomenon. It rested on comparing
event counts against detents counted by hand, a ground truth the operator
judged unreliable afterwards, so no drop rate follows from those runs. What the
raw capture does establish is that any such loss would not be ours: 38 reports,
30 notch events, zero unparseable lines. Settling the question needs an
independent counter rather than a human one.

The same capture also confirms the direction of rotation on a run whose
direction was declared in advance: 30 ENC_CC and 0 ENC_CW for clockwise.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@thannous
thannous merged commit d70d101 into main Aug 2, 2026
2 checks passed
@thannous
thannous deleted the docs/shim-device-side-observations branch August 2, 2026 23:33
Sign up for free to 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