docs: add Bosun PRD (Spec Desk, doc-only, M1 scope) - #3
Conversation
Co-authored-by: RaapTechllc <RaapTechllc@users.noreply.github.com>
Co-authored-by: RaapTechllc <RaapTechllc@users.noreply.github.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b6e0bd6fa8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| | AC-6 | Decode maps bits `0..=21` and `24..=35` to named keys with pressed = 1 and emits edge events (down/up) by diffing against the previous report. Toggling bits 22, 23, 36, 37, 38, 39 emits **no** key event. Stick bytes decode to 0–255 axes. | Golden fixture tests replaying captured 8-byte reports; a dedicated test flips each ignored bit and asserts an empty event stream. | | ||
| | AC-7 | `bosunctl device watch` prints decoded named key/axis events. `record` writes raw 8-byte reports to a fixture file. | HW: press each control; every one of 34 names appears. Mock: `watch` over `MockTransport` emits the expected events; `record` output round-trips through the decoder. | | ||
| | AC-8 | `bosunctl device rgb R G B` sends feature report 7 and reads it back; `leds MASK` sends feature report 5; `lcd test` sends one 992-byte report 3 with byte 0 = `0x03`, bytes 1–31 zero, rows 43–47 zero. Feature report 6 is never written by any command. | Mock: assert exact bytes written per command; assert no write with report ID 6 across the whole CLI surface. HW: backlight visibly changes and readback matches; M-LEDs match the mask; LCD shows the pattern. | | ||
| | AC-9 | Hot-plug: after unplug/replug, `watch` resumes delivering events within 2 s and prints one reconnect line. | Mock: scripted disconnect followed by reports; assert recovery. HW: stopwatch or timestamp diff ≤ 2 s. | |
There was a problem hiding this comment.
Require the reconnect test to open a new transport
The proposed mock check can pass without implementing real hot-plug recovery: the current MockTransport::read simply consumes Disconnect, so the next read on that same object returns any subsequently queued report. A watch loop that retries a permanently dead handle would therefore satisfy this test even though HidTransport must re-enumerate and open a new handle after replug. Model separate connection instances and assert that a second open occurs.
Useful? React with 👍 / 👎.
|
|
||
| | ID | Criterion | How to check | | ||
| |---|---|---| | ||
| | **AC-R1** | **Shared input while LGS runs.** With `LCore.exe` running and holding its shared handle, a second reader opened by Bosun receives ≥1 input report (8 bytes, ID `0x01`) during 15 s of physical keypresses. | HW: `BOSUN_HW=1 BOSUN_HW_PATH=<path from device list> cargo test -p bosun-hid --test hardware -- --ignored r1_shared_input_reports_reach_a_second_reader --nocapture`. Record the outcome in `docs/hardware-notes.md` as one of: **pass with LGS running**, **pass only with LGS closed**, **fail both**. If zero reports with LGS running, quit LGS and rerun before any redesign. "Fail both" stops M1 for Kyle's review. | |
There was a problem hiding this comment.
Validate the input report before passing AC-R1
The named hardware test currently increments reports for every ReadOutcome::Report(len) and only asserts reports > 0; it never checks len == 8 or buf[0] == 0x01. Consequently, an unexpected or truncated report can make this exact acceptance command pass without proving the input protocol stated here. Add those validations to the test before treating it as the AC-R1 check.
AGENTS.md reference: AGENTS.md:L20-L22
Useful? React with 👍 / 👎.
| | AC-8 | `bosunctl device rgb R G B` sends feature report 7 and reads it back; `leds MASK` sends feature report 5; `lcd test` sends one 992-byte report 3 with byte 0 = `0x03`, bytes 1–31 zero, rows 43–47 zero. Feature report 6 is never written by any command. | Mock: assert exact bytes written per command; assert no write with report ID 6 across the whole CLI surface. HW: backlight visibly changes and readback matches; M-LEDs match the mask; LCD shows the pattern. | | ||
| | AC-9 | Hot-plug: after unplug/replug, `watch` resumes delivering events within 2 s and prints one reconnect line. | Mock: scripted disconnect followed by reports; assert recovery. HW: stopwatch or timestamp diff ≤ 2 s. | | ||
| | AC-10 | Hardware fixtures are committed: at least one raw report per control, plus stick center, four cardinals, four corners, and diagonals. `docs/hardware-notes.md` names the physical thumb button for each of `LEFT`, `DOWN`, `TOP` and replaces its "Pending M1 capture" section. | File presence in the repo; fixture files parse and drive AC-6. | | ||
| | AC-11 | Gates are green: `cargo fmt --all -- --check`, `cargo clippy --workspace --all-targets --all-features -- -D warnings`, `cargo test --workspace --all-features`, `cargo-deny`. Hardware tests are `#[ignore]` and skip with a message unless `BOSUN_HW=1`. | CI on all three OSes; `cargo test -- --ignored` without `BOSUN_HW` prints the skip message and passes. | |
There was a problem hiding this comment.
Select bosun-hid when checking ignored hardware tests
At the workspace root, Cargo.toml sets default-members = ["apps/bosunctl"], while Cargo documents --workspace as the option that selects all packages. Thus cargo test -- --ignored tests only bosunctl; it cannot execute crates/bosun-hid/tests/hardware.rs or print that suite's skip message. Use -p bosun-hid --test hardware or --workspace so AC-11 actually checks the hardware gate.
AGENTS.md reference: AGENTS.md:L15-L15
Useful? React with 👍 / 👎.
|
|
||
| The Logitech G13 (USB `046D:C21C`) has 34 buttons, an analog stick, a 160×43 LCD, and a global RGB backlight. It is discontinued, unsupported by G HUB, and kept alive on Windows 11 only by Logitech Gaming Software 9.04.x (Spec Desk notes, 2026-09-11). Every existing third-party driver is a gaming macro tool, most are libusb forks that need a driver swap, and the most complete ones are GPL. | ||
|
|
||
| Phase 0 (2026-08-30, `desktop-2QF5HUN`) measured that the whole G13 feature set — input, LCD, RGB, M-LEDs — is reachable from userspace through the stock OS HID stack, concurrently with LGS, with no driver change (`docs/BOSUN-PLAN.md` §2). The hardware problem is solved. The software does not exist. |
There was a problem hiding this comment.
Keep shared-input feasibility marked unverified
Phase 0 did not measure input working concurrently with LGS: docs/BOSUN-PLAN.md records zero reports during a window with nobody pressing keys, and this PRD itself calls the result unverified in R1. Claiming that input was reached and the hardware problem is solved contradicts the mandatory first M1 hardware experiment and can cause stakeholders to treat the central feasibility risk as closed; restrict this statement to the open/output paths until AC-R1 is run.
AGENTS.md reference: AGENTS.md:L27-L27
Useful? React with 👍 / 👎.
Plan
Doc-only deliverable. No M1 product code is added or changed; this PR is not to be merged without Kyle's review.
AGENTS.md,docs/BOSUN-PLAN.md,docs/PLAN-REVIEW.md,docs/M1-KICKOFF.md, ADR-0001,docs/hardware-notes.md,README.md) and skimdocs/MARKET-WATCH.md/docs/CODEX-MICRO-COMPLAINTS.md.bosun-hid,bosunctl,devices/logitech-g13.toml, hardware-gated tests) so the PRD states what already exists onmainversus what M1 still owes.docs/PRD.mdas a standalone PRD with the eight required sections: Problem, Buyer + Agent-First intent, MVP (M1) scope, Non-goals, Acceptance criteria, Risks, Open Kyle decisions, After M1.README.mdandAGENTS.md(one sentence each).cargo fmt --check,cargo clippy -D warnings,cargo test) to confirm nothing in the workspace is affected.What is in
docs/PRD.mdMARKET-WATCH.md.M1-KICKOFF.md/PLAN-REVIEW.md; output-report facts (feature 7, feature 5, 992-byte report 3, feature 6 never written); a "current repository state" note listing what is already onmain.cargo testinvocation and the three recordable outcomes) and AC-2…AC-13, each with a concrete check (unit test, mock assertion, CI gate, or HW step).BOSUN-PLAN.md§11, explicitly not committed.Hard rules honored
MARKET-WATCH.mdhard exclusions (resale figure, on-device radial claim) are respected.AGENTS.md.Verification
cargo fmt --all -- --check,cargo clippy --workspace --all-targets --all-features -- -D warnings, andcargo test --workspace --all-featurespass locally on Linux (doc-only change; no Rust files touched).