Skip to content

feat(hotas-vkb): add protocol parser, configuration, and axis mapping#64

Open
EffortlessSteven wants to merge 2 commits into
mainfrom
feat/vkb-protocol
Open

feat(hotas-vkb): add protocol parser, configuration, and axis mapping#64
EffortlessSteven wants to merge 2 commits into
mainfrom
feat/vkb-protocol

Conversation

@EffortlessSteven
Copy link
Copy Markdown
Member

Summary

Adds VKB device protocol support to the flight-hotas-vkb crate with three new capabilities:

New Modules

  • configuration.rs — VKB firmware configuration parsing

    • VkbConfig, ConfigProfile, CurveType types
    • read_config_from_report() for HID report parsing
    • Per-axis sensitivity, dead zone, and curve settings
  • axis_mapping.rs — Device-family-specific axis resolution

    • VkbAxis enum covering all physical axes
    • GladiatorAxisMap and GunfighterAxisMap with resolution data
    • resolve_axis() and resolve_axis_by_name() helpers

Modified Modules

  • protocol.rs — Unified protocol handler

    • VkbProtocol struct with family detection and report parsing
    • StickState / StickAxes unified state types
    • VkbProtocolParseError for structured error handling
  • lib.rs — Module registration and public re-exports

Testing

  • 42 new tests (11 configuration + 22 axis mapping + 9 protocol)
  • All 159 crate tests pass
  • cargo clippy -p flight-hotas-vkb -- -D warnings clean
  • cargo fmt clean

- Implement VKB USB HID protocol parsing with report descriptor decoding
- Add device family detection for Gladiator, Gunfighter, and SEM lines
- Add configuration reading for button/hat/axis layout from device reports
- Implement axis mapping with calibration, deadzone, and curve support
- Add 30+ unit tests covering protocol, configuration, and axis mapping

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 1, 2026 03:38
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@gemini-code-assist
Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 1, 2026

Warning

Rate limit exceeded

@EffortlessSteven has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 6 minutes and 20 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between cd2e54d and 79cae5b.

📒 Files selected for processing (4)
  • crates/flight-hotas-vkb/src/axis_mapping.rs
  • crates/flight-hotas-vkb/src/configuration.rs
  • crates/flight-hotas-vkb/src/lib.rs
  • crates/flight-hotas-vkb/src/protocol.rs
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/vkb-protocol

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 and usage tips.

@qodo-free-for-open-source-projects
Copy link
Copy Markdown

Review Summary by Qodo

Add VKB protocol parser, axis mapping, and configuration support

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Add VKB protocol parser with unified VkbProtocol struct for joystick-class devices
• Implement axis mapping module with device-family-specific resolution and normalization
• Add configuration parsing for firmware-level device settings (sensitivity, deadzone, curves)
• Provide 42 new unit tests covering protocol, axis mapping, and configuration parsing
Diagram
flowchart LR
  A["Raw HID Report"] -->|VkbProtocol| B["StickState"]
  A -->|axis_mapping| C["Normalized Axes"]
  A -->|configuration| D["VkbConfig"]
  B --> E["Unified API"]
  C --> E
  D --> E
Loading

Grey Divider

File Changes

1. crates/flight-hotas-vkb/src/axis_mapping.rs ✨ Enhancement +477/-0

Device-family axis mapping and normalization

• New module providing device-family-specific axis maps for Gladiator and Gunfighter devices
• Implements VkbAxis enum and AxisMapEntry struct for axis metadata
• Provides resolve_axis() and resolve_axis_by_name() functions for normalizing raw HID values
• Includes 22 unit tests validating axis resolution, normalization modes, and profile consistency

crates/flight-hotas-vkb/src/axis_mapping.rs


2. crates/flight-hotas-vkb/src/configuration.rs ✨ Enhancement +346/-0

VKB firmware configuration parsing

• New module for parsing VKB firmware configuration from HID feature reports
• Defines VkbConfig, ConfigProfile, and CurveType types for device settings
• Implements read_config_from_report() to extract sensitivity, deadzone, and curve data
• Includes 11 unit tests covering report parsing, error handling, and edge cases

crates/flight-hotas-vkb/src/configuration.rs


3. crates/flight-hotas-vkb/src/protocol.rs ✨ Enhancement +251/-0

Unified VKB protocol handler and stick state

• Add StickAxes struct representing unified 6-axis state (roll, pitch, yaw, throttle, mini_x,
 mini_y)
• Add StickState struct providing family-agnostic parsed report with axes, buttons, and hat
 switches
• Implement VkbProtocol struct with device family detection and unified report parsing
• Add VkbProtocolParseError for structured error handling
• Include 9 unit tests for protocol initialization, report parsing, and button/hat decoding

crates/flight-hotas-vkb/src/protocol.rs


View more (1)
4. crates/flight-hotas-vkb/src/lib.rs ✨ Enhancement +14/-3

Module registration and public API exports

• Register new axis_mapping and configuration modules
• Re-export public types and functions from axis mapping module (VkbAxis, resolve_axis, etc.)
• Re-export public types and functions from configuration module (VkbConfig,
 read_config_from_report, etc.)
• Re-export new protocol types (StickAxes, StickState, VkbProtocol, VkbProtocolParseError)

crates/flight-hotas-vkb/src/lib.rs


Grey Divider

Qodo Logo

@qodo-free-for-open-source-projects
Copy link
Copy Markdown

qodo-free-for-open-source-projects Bot commented Mar 1, 2026

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Protocol accepts non-stick families🐞 Bug ✓ Correctness
Description
VkbProtocol::new() can construct a protocol for families like SemThq/GladiatorMk2 (because
from_pid returns them), but parse_report() always interprets the payload as the 6-axis stick
layout. This can silently return incorrect axes/buttons/hats for non-stick layouts, despite the docs
implying only joystick-class devices are accepted.
Code

crates/flight-hotas-vkb/src/protocol.rs[R339-390]

+impl VkbProtocol {
+    /// Create a protocol handler for a VKB device identified by VID/PID.
+    ///
+    /// Returns `None` if the VID is not VKB or the PID is not a known joystick.
+    pub fn new(vid: u16, pid: u16) -> Option<Self> {
+        if vid != VKB_VENDOR_ID {
+            return None;
+        }
+        VkbDeviceFamily::from_pid(pid).map(|family| Self {
+            family,
+            has_report_id: false,
+        })
+    }
+
+    /// Enable stripping a 1-byte HID report ID prefix before parsing.
+    pub fn with_report_id(mut self, enabled: bool) -> Self {
+        self.has_report_id = enabled;
+        self
+    }
+
+    /// Return the detected device family.
+    pub fn family(&self) -> VkbDeviceFamily {
+        self.family
+    }
+
+    /// Parse a raw HID report into a unified [`StickState`].
+    ///
+    /// Works for Gladiator NXT EVO, Gunfighter, and related joystick families.
+    /// For SEM THQ or STECS, use the dedicated parsers instead.
+    pub fn parse_report(&self, report: &[u8]) -> Result<StickState, VkbProtocolParseError> {
+        let payload = if self.has_report_id {
+            report.get(1..).unwrap_or(&[])
+        } else {
+            report
+        };
+
+        const MIN_LEN: usize = 12;
+        if payload.len() < MIN_LEN {
+            return Err(VkbProtocolParseError::ReportTooShort {
+                expected: MIN_LEN,
+                actual: payload.len(),
+            });
+        }
+
+        let axes = StickAxes {
+            roll: normalize_signed(le_u16(payload, 0)),
+            pitch: normalize_signed(le_u16(payload, 2)),
+            yaw: normalize_signed(le_u16(payload, 4)),
+            mini_x: normalize_signed(le_u16(payload, 6)),
+            mini_y: normalize_signed(le_u16(payload, 8)),
+            throttle: normalize_u16(le_u16(payload, 10)),
+        };
Evidence
VkbDeviceFamily::from_pid includes SEM THQ and Gladiator Mk2, so VkbProtocol::new will return
Some for those PIDs. However, the codebase already models SEM THQ as a different layout (4 axes,
no hat). VkbProtocol::parse_report still unconditionally parses 6 axes at offsets 0..10 and hat at
byte 20, which is incompatible with SEM THQ’s modeled layout.

crates/flight-hotas-vkb/src/protocol.rs[39-71]
crates/flight-hotas-vkb/src/protocol.rs[343-351]
crates/flight-hotas-vkb/src/protocol.rs[116-133]
crates/flight-hotas-vkb/src/protocol.rs[368-410]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`VkbProtocol::new()` currently accepts any PID recognized by `VkbDeviceFamily::from_pid`, including non-stick families like SEM THQ, but `parse_report()` always parses the 6-axis stick layout. This can silently mis-parse reports.
## Issue Context
The codebase already defines a distinct SEM THQ layout (4 axes, no hat) via `VKB_SEM_THQ_LAYOUT`/`report_layout_for_family`.
## Fix Focus Areas
- Add an explicit family gate in `VkbProtocol::new()` (or `parse_report()`) so only stick families are supported, or implement family-aware parsing and return an `UnsupportedFamily` error.
- Update docs/tests to reflect the enforced behavior.
### Focus references
- crates/flight-hotas-vkb/src/protocol.rs[339-419]
- crates/flight-hotas-vkb/src/protocol.rs[39-71]
- crates/flight-hotas-vkb/src/protocol.rs[106-133] সচ

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Config values not validated 🐞 Bug ⛯ Reliability
Description
read_config_from_report does not enforce documented invariants: axis_count can be 0,
sensitivity/deadzone bytes >100 produce values >1.0, and profile_slot is not checked for 0–3. This
can propagate invalid configuration values to consumers.
Code

crates/flight-hotas-vkb/src/configuration.rs[R148-189]

+pub fn read_config_from_report(data: &[u8]) -> Result<VkbConfig, ConfigParseError> {
+    if data.len() < VKB_CONFIG_MIN_REPORT_BYTES {
+        return Err(ConfigParseError::TooShort {
+            expected: VKB_CONFIG_MIN_REPORT_BYTES,
+            actual: data.len(),
+        });
+    }
+
+    if data[0] != VKB_CONFIG_REPORT_ID {
+        return Err(ConfigParseError::WrongReportId {
+            expected: VKB_CONFIG_REPORT_ID,
+            actual: data[0],
+        });
+    }
+
+    let axis_count = data[1];
+    if axis_count > VKB_MAX_CONFIG_AXES as u8 {
+        return Err(ConfigParseError::AxisCountOverflow {
+            count: axis_count,
+            max: VKB_MAX_CONFIG_AXES as u8,
+        });
+    }
+
+    let mut sensitivity = [0.0f32; VKB_MAX_CONFIG_AXES];
+    let mut deadzone = [0.0f32; VKB_MAX_CONFIG_AXES];
+    let mut curve_type = [CurveType::Linear; VKB_MAX_CONFIG_AXES];
+
+    for i in 0..VKB_MAX_CONFIG_AXES {
+        sensitivity[i] = data[2 + i] as f32 / 100.0;
+        deadzone[i] = data[8 + i] as f32 / 100.0;
+        curve_type[i] = CurveType::from_byte(data[14 + i]);
+    }
+
+    let profile_slot = data[20];
+
+    Ok(VkbConfig {
+        axis_count,
+        sensitivity,
+        deadzone,
+        curve_type,
+        profile_slot,
+    })
Evidence
The module docs and VkbConfig field docs declare ranges (axis_count 1–6, sensitivity/deadzone
0.0–1.0 derived from 0–100, profile_slot 0–3). The parser only checks for axis_count overflow (>6)
and otherwise directly divides raw bytes by 100, allowing out-of-range values without
error/clamping.

crates/flight-hotas-vkb/src/configuration.rs[16-23]
crates/flight-hotas-vkb/src/configuration.rs[78-89]
crates/flight-hotas-vkb/src/configuration.rs[163-182]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`read_config_from_report()` returns values that can violate the documented invariants of `VkbConfig` (axis_count 1–6; sensitivity/deadzone 0.0–1.0; profile_slot 0–3) because it doesn’t validate/clamp input bytes.
## Issue Context
HID feature reports can be corrupted/truncated or differ across firmware variants. Returning out-of-range values makes downstream code less reliable.
## Fix Focus Areas
- Enforce `axis_count &amp;gt;= 1` (return a new error variant for 0).
- Clamp or reject sensitivity/deadzone bytes outside 0..=100 (choose strict vs lenient behavior and document it).
- Validate `profile_slot &amp;lt;= 3` (new error variant or clamp).
- Add unit tests for the new validation behavior.
### Focus references
- crates/flight-hotas-vkb/src/configuration.rs[112-139]
- crates/flight-hotas-vkb/src/configuration.rs[148-190]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Comment on lines +339 to +390
impl VkbProtocol {
/// Create a protocol handler for a VKB device identified by VID/PID.
///
/// Returns `None` if the VID is not VKB or the PID is not a known joystick.
pub fn new(vid: u16, pid: u16) -> Option<Self> {
if vid != VKB_VENDOR_ID {
return None;
}
VkbDeviceFamily::from_pid(pid).map(|family| Self {
family,
has_report_id: false,
})
}

/// Enable stripping a 1-byte HID report ID prefix before parsing.
pub fn with_report_id(mut self, enabled: bool) -> Self {
self.has_report_id = enabled;
self
}

/// Return the detected device family.
pub fn family(&self) -> VkbDeviceFamily {
self.family
}

/// Parse a raw HID report into a unified [`StickState`].
///
/// Works for Gladiator NXT EVO, Gunfighter, and related joystick families.
/// For SEM THQ or STECS, use the dedicated parsers instead.
pub fn parse_report(&self, report: &[u8]) -> Result<StickState, VkbProtocolParseError> {
let payload = if self.has_report_id {
report.get(1..).unwrap_or(&[])
} else {
report
};

const MIN_LEN: usize = 12;
if payload.len() < MIN_LEN {
return Err(VkbProtocolParseError::ReportTooShort {
expected: MIN_LEN,
actual: payload.len(),
});
}

let axes = StickAxes {
roll: normalize_signed(le_u16(payload, 0)),
pitch: normalize_signed(le_u16(payload, 2)),
yaw: normalize_signed(le_u16(payload, 4)),
mini_x: normalize_signed(le_u16(payload, 6)),
mini_y: normalize_signed(le_u16(payload, 8)),
throttle: normalize_u16(le_u16(payload, 10)),
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Protocol accepts non-stick families 🐞 Bug ✓ Correctness

VkbProtocol::new() can construct a protocol for families like SemThq/GladiatorMk2 (because
from_pid returns them), but parse_report() always interprets the payload as the 6-axis stick
layout. This can silently return incorrect axes/buttons/hats for non-stick layouts, despite the docs
implying only joystick-class devices are accepted.
Agent Prompt
## Issue description
`VkbProtocol::new()` currently accepts any PID recognized by `VkbDeviceFamily::from_pid`, including non-stick families like SEM THQ, but `parse_report()` always parses the 6-axis stick layout. This can silently mis-parse reports.

## Issue Context
The codebase already defines a distinct SEM THQ layout (4 axes, no hat) via `VKB_SEM_THQ_LAYOUT`/`report_layout_for_family`.

## Fix Focus Areas
- Add an explicit family gate in `VkbProtocol::new()` (or `parse_report()`) so only stick families are supported, or implement family-aware parsing and return an `UnsupportedFamily` error.
- Update docs/tests to reflect the enforced behavior.

### Focus references
- crates/flight-hotas-vkb/src/protocol.rs[339-419]
- crates/flight-hotas-vkb/src/protocol.rs[39-71]
- crates/flight-hotas-vkb/src/protocol.rs[106-133] সচ

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Use report_layout_for_family() to dynamically select axis count, button
word offsets, and hat presence based on device family. Fixes silent
mis-parsing for non-stick families like SemThq (4 axes, no hat).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@qodo-free-for-open-source-projects
Copy link
Copy Markdown

CI Feedback 🧐

A test triggered by this PR failed. Here is an AI-generated analysis of the failure:

Action: Test Suite (windows-latest, 1.92.0)

Failed stage: Run tests [❌]

Failed test name: flight_ffb::integration_test::tests::test_ffb_mode_negotiation_and_trim_limits_integration

Failure summary:

The action failed during cargo test --all-features --workspace --lib --tests --exclude
flight-hub-examples because a Rust test panicked.
- Failing test:
flight_ffb::integration_test::tests::test_ffb_mode_negotiation_and_trim_limits_integration
- The
panic occurred in src/integration_test.rs:150 (backtrace shows the panic handler leading to this
test and file/line).
- Cargo exited with code 101 after reporting 611 passed; 1 failed, which caused
the GitHub Action step to fail.

Relevant error logs:
1:  ##[group]Runner Image Provisioner
2:  Hosted Compute Agent
...

172:  RUST_BACKTRACE: 1
173:  targets: 
174:  components: rustfmt, clippy
175:  ##[endgroup]
176:  ##[group]Run : set $CARGO_HOME
177:  �[36;1m: set $CARGO_HOME�[0m
178:  �[36;1mecho CARGO_HOME=${CARGO_HOME:-"$USERPROFILE\.cargo"} >> $GITHUB_ENV�[0m
179:  shell: C:\Program Files\Git\bin\bash.EXE --noprofile --norc -e -o pipefail {0}
180:  env:
181:  CARGO_TERM_COLOR: always
182:  RUST_BACKTRACE: 1
183:  ##[endgroup]
184:  ##[group]Run : install rustup if needed on windows
185:  �[36;1m: install rustup if needed on windows�[0m
186:  �[36;1mif ! command -v rustup &>/dev/null; then�[0m
187:  �[36;1m  curl --proto '=https' --tlsv1.2 --retry 10 --retry-connrefused --location --silent --show-error --fail https://win.rustup.rs/x86_64 --output 'D:\a\_temp\rustup-init.exe'�[0m
188:  �[36;1m  'D:\a\_temp\rustup-init.exe' --default-toolchain none --no-modify-path -y�[0m
...

268:  �[36;1m  if rustc +1.92.0 --version --verbose | grep -q '^release: 1\.6[89]\.'; then�[0m
269:  �[36;1m    touch "D:\a\_temp"/.implicit_cargo_registries_crates_io_protocol || true�[0m
270:  �[36;1m    echo CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse >> $GITHUB_ENV�[0m
271:  �[36;1m  elif rustc +1.92.0 --version --verbose | grep -q '^release: 1\.6[67]\.'; then�[0m
272:  �[36;1m    touch "D:\a\_temp"/.implicit_cargo_registries_crates_io_protocol || true�[0m
273:  �[36;1m    echo CARGO_REGISTRIES_CRATES_IO_PROTOCOL=git >> $GITHUB_ENV�[0m
274:  �[36;1m  fi�[0m
275:  �[36;1mfi�[0m
276:  shell: C:\Program Files\Git\bin\bash.EXE --noprofile --norc -e -o pipefail {0}
277:  env:
278:  CARGO_TERM_COLOR: always
279:  RUST_BACKTRACE: 1
280:  CARGO_HOME: C:\Users\runneradmin\.cargo
281:  CARGO_INCREMENTAL: 0
282:  ##[endgroup]
283:  ##[group]Run : work around spurious network errors in curl 8.0
284:  �[36;1m: work around spurious network errors in curl 8.0�[0m
285:  �[36;1m# https://rust-lang.zulipchat.com/#narrow/stream/246057-t-cargo/topic/timeout.20investigation�[0m
...

453:  - D:\a\OpenFlight\OpenFlight\examples\Cargo.toml
454:  - D:\a\OpenFlight\OpenFlight\installer\Cargo.toml
455:  - D:\a\OpenFlight\OpenFlight\specs\Cargo.toml
456:  - D:\a\OpenFlight\OpenFlight\xtask\Cargo.toml
457:  ##[endgroup]
458:  ... Restoring cache ...
459:  No cache found.
460:  ##[group]Run cargo fmt --all -- --check
461:  �[36;1mcargo fmt --all -- --check�[0m
462:  shell: C:\Program Files\Git\bin\bash.EXE --noprofile --norc -e -o pipefail {0}
463:  env:
464:  CARGO_TERM_COLOR: always
465:  RUST_BACKTRACE: 1
466:  CARGO_HOME: C:\Users\runneradmin\.cargo
467:  CARGO_INCREMENTAL: 0
468:  CACHE_ON_FAILURE: false
469:  ##[endgroup]
470:  ##[group]Run cargo clippy --workspace --all-features --lib --tests --exclude flight-hub-examples
471:  �[36;1mcargo clippy --workspace --all-features --lib --tests --exclude flight-hub-examples�[0m
472:  shell: C:\Program Files\Git\bin\bash.EXE --noprofile --norc -e -o pipefail {0}
473:  env:
474:  CARGO_TERM_COLOR: always
475:  RUST_BACKTRACE: 1
476:  CARGO_HOME: C:\Users\runneradmin\.cargo
477:  CARGO_INCREMENTAL: 0
478:  CACHE_ON_FAILURE: false
479:  ##[endgroup]
...

652:  �[1m�[92m  Downloaded�[0m bytes v1.11.1
653:  �[1m�[92m  Downloaded�[0m wait-timeout v0.2.1
654:  �[1m�[92m  Downloaded�[0m vigem-client v0.1.4
655:  �[1m�[92m  Downloaded�[0m version_check v0.9.5
656:  �[1m�[92m  Downloaded�[0m uuid-simd v0.8.0
657:  �[1m�[92m  Downloaded�[0m unarray v0.1.4
658:  �[1m�[92m  Downloaded�[0m typetag-impl v0.2.21
659:  �[1m�[92m  Downloaded�[0m typeid v1.0.3
660:  �[1m�[92m  Downloaded�[0m try-lock v0.2.5
661:  �[1m�[92m  Downloaded�[0m tower-service v0.3.3
662:  �[1m�[92m  Downloaded�[0m tower-layer v0.3.3
663:  �[1m�[92m  Downloaded�[0m tonic-build v0.14.5
664:  �[1m�[92m  Downloaded�[0m tokio-macros v2.6.0
665:  �[1m�[92m  Downloaded�[0m tinytemplate v1.2.1
666:  �[1m�[92m  Downloaded�[0m thread_local v1.1.9
667:  �[1m�[92m  Downloaded�[0m thiserror-impl v2.0.18
668:  �[1m�[92m  Downloaded�[0m thiserror v2.0.18
669:  �[1m�[92m  Downloaded�[0m terminal_size v0.4.3
...

687:  �[1m�[92m  Downloaded�[0m scopeguard v1.2.0
688:  �[1m�[92m  Downloaded�[0m same-file v1.0.6
689:  �[1m�[92m  Downloaded�[0m rustc_version v0.4.1
690:  �[1m�[92m  Downloaded�[0m rand_chacha v0.9.0
691:  �[1m�[92m  Downloaded�[0m quote v1.0.44
692:  �[1m�[92m  Downloaded�[0m quinn-udp v0.5.14
693:  �[1m�[92m  Downloaded�[0m pulldown-cmark-to-cmark v22.0.0
694:  �[1m�[92m  Downloaded�[0m memchr v2.8.0
695:  �[1m�[92m  Downloaded�[0m heapless v0.7.17
696:  �[1m�[92m  Downloaded�[0m slab v0.4.12
697:  �[1m�[92m  Downloaded�[0m simd-adler32 v0.3.8
698:  �[1m�[92m  Downloaded�[0m signature v2.2.0
699:  �[1m�[92m  Downloaded�[0m shlex v1.3.0
700:  �[1m�[92m  Downloaded�[0m sha2 v0.10.9
701:  �[1m�[92m  Downloaded�[0m protoc-bin-vendored-linux-ppcle_64 v3.2.0
702:  �[1m�[92m  Downloaded�[0m serde_path_to_error v0.1.20
703:  �[1m�[92m  Downloaded�[0m protoc-bin-vendored-linux-x86_32 v3.2.0
704:  �[1m�[92m  Downloaded�[0m rand_core v0.9.5
705:  �[1m�[92m  Downloaded�[0m quick-error v1.2.3
706:  �[1m�[92m  Downloaded�[0m postcard v1.1.3
...

891:  �[1m�[92m  Downloaded�[0m form_urlencoded v1.2.2
892:  �[1m�[92m  Downloaded�[0m foldhash v0.2.0
893:  �[1m�[92m  Downloaded�[0m crossbeam-epoch v0.9.18
894:  �[1m�[92m  Downloaded�[0m cmake v0.1.57
895:  �[1m�[92m  Downloaded�[0m allocator-api2 v0.2.21
896:  �[1m�[92m  Downloaded�[0m adler2 v2.0.1
897:  �[1m�[92m  Downloaded�[0m aws-lc-sys v0.37.1
898:  �[1m�[92m  Downloaded�[0m windows v0.62.2
899:  �[1m�[92m Downloading�[0m crates ...
900:  �[1m�[92m  Downloaded�[0m nix v0.31.2
901:  �[1m�[92m   Compiling�[0m proc-macro2 v1.0.106
902:  �[1m�[92m   Compiling�[0m quote v1.0.44
903:  �[1m�[92m   Compiling�[0m unicode-ident v1.0.24
904:  �[1m�[92m   Compiling�[0m serde_core v1.0.228
905:  �[1m�[92m   Compiling�[0m serde v1.0.228
906:  �[1m�[92m   Compiling�[0m thiserror v2.0.18
907:  �[1m�[92m   Compiling�[0m getrandom v0.3.4
...

920:  �[1m�[92m   Compiling�[0m serde_json v1.0.149
921:  �[1m�[92m    Checking�[0m pin-project-lite v0.2.17
922:  �[1m�[92m   Compiling�[0m version_check v0.9.5
923:  �[1m�[92m    Checking�[0m log v0.4.29
924:  �[1m�[92m    Checking�[0m tracing-core v0.1.36
925:  �[1m�[92m   Compiling�[0m typenum v1.19.0
926:  �[1m�[92m   Compiling�[0m generic-array v0.14.7
927:  �[1m�[92m    Checking�[0m regex-syntax v0.8.10
928:  �[1m�[92m    Checking�[0m fnv v1.0.7
929:  �[1m�[92m    Checking�[0m rand_core v0.9.5
930:  �[1m�[92m    Checking�[0m fastrand v2.3.0
931:  �[1m�[92m    Checking�[0m bitflags v2.11.0
932:  �[1m�[92m    Checking�[0m bit-vec v0.8.0
933:  �[1m�[92m    Checking�[0m memchr v2.8.0
934:  �[1m�[92m    Checking�[0m bit-set v0.8.0
935:  �[1m�[92m    Checking�[0m quick-error v1.2.3
936:  �[1m�[92m    Checking�[0m wait-timeout v0.2.1
937:  �[1m�[92m    Checking�[0m rand_xorshift v0.4.0
938:  �[1m�[92m    Checking�[0m unarray v0.1.4
939:  �[1m�[92m    Checking�[0m itoa v1.0.17
940:  �[1m�[92m   Compiling�[0m anyhow v1.0.102
941:  �[1m�[92m   Compiling�[0m crossbeam-utils v0.8.21
942:  �[1m�[92m    Checking�[0m windows-targets v0.53.5
943:  �[1m�[92m    Checking�[0m windows-sys v0.60.2
944:  �[1m�[92m   Compiling�[0m semver v1.0.27
945:  �[1m�[92m   Compiling�[0m rustc_version v0.4.1
946:  �[1m�[92m    Checking�[0m bytes v1.11.1
947:  �[1m�[92m    Checking�[0m socket2 v0.6.2
948:  �[1m�[92m   Compiling�[0m serde_derive v1.0.228
949:  �[1m�[92m   Compiling�[0m thiserror-impl v2.0.18
950:  �[1m�[92m   Compiling�[0m tracing-attributes v0.1.31
...

1184:  �[1m�[92m   Compiling�[0m protoc-bin-vendored-linux-x86_64 v3.2.0
1185:  �[1m�[92m   Compiling�[0m protoc-bin-vendored-linux-ppcle_64 v3.2.0
1186:  �[1m�[92m   Compiling�[0m protoc-bin-vendored-linux-aarch_64 v3.2.0
1187:  �[1m�[92m   Compiling�[0m protoc-bin-vendored-linux-s390_64 v3.2.0
1188:  �[1m�[92m   Compiling�[0m protoc-bin-vendored-macos-x86_64 v3.2.0
1189:  �[1m�[92m   Compiling�[0m protoc-bin-vendored-win32 v3.2.0
1190:  �[1m�[92m   Compiling�[0m protoc-bin-vendored-linux-x86_32 v3.2.0
1191:  �[1m�[92m   Compiling�[0m protoc-bin-vendored-macos-aarch_64 v3.2.0
1192:  �[1m�[92m    Checking�[0m tracing-subscriber v0.3.22
1193:  �[1m�[92m   Compiling�[0m protoc-bin-vendored v3.2.0
1194:  �[1m�[92m   Compiling�[0m tonic-prost-build v0.14.5
1195:  �[1m�[92m    Checking�[0m tokio-tungstenite v0.28.0
1196:  �[1m�[92m    Checking�[0m axum-core v0.5.6
1197:  �[1m�[92m    Checking�[0m serde_urlencoded v0.7.1
1198:  �[1m�[92m    Checking�[0m futures-executor v0.3.32
1199:  �[1m�[92m    Checking�[0m serde_path_to_error v0.1.20
1200:  �[1m�[92m    Checking�[0m matchit v0.8.4
...

1392:  �[1m�[96m--> �[0mcrates\flight-watchdog\src\lib.rs:1134:9
1393:  �[1m�[96m|�[0m
1394:  �[1m�[96m1134�[0m �[1m�[96m|�[0m         config.enable_nan_guards = true;
1395:  �[1m�[96m|�[0m         �[1m�[93m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^�[0m
1396:  �[1m�[96m|�[0m
1397:  �[1m�[92mnote�[0m: consider initializing the variable with `WatchdogConfig { enable_nan_guards: true, ..Default::default() }` and removing relevant reassignments
1398:  �[1m�[96m--> �[0mcrates\flight-watchdog\src\lib.rs:1133:9
1399:  �[1m�[96m|�[0m
1400:  �[1m�[96m1133�[0m �[1m�[96m|�[0m         let mut config = WatchdogConfig::default();
1401:  �[1m�[96m|�[0m         �[1m�[92m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^�[0m
1402:  �[1m�[96m= �[0m�[1m�[97mhelp�[0m: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#field_reassign_with_default
1403:  �[1m�[96m= �[0m�[1m�[97mnote�[0m: `#[warn(clippy::field_reassign_with_default)]` on by default
1404:  �[1m�[93mwarning�[0m�[1m�[97m: field assignment outside of initializer for an instance created with Default::default()�[0m
1405:  �[1m�[96m--> �[0mcrates\flight-watchdog\src\lib.rs:1158:9
1406:  �[1m�[96m|�[0m
1407:  �[1m�[96m1158�[0m �[1m�[96m|�[0m         config.max_consecutive_failures = 2; // Lower threshold for testing
1408:  �[1m�[96m|�[0m         �[1m�[93m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^�[0m
1409:  �[1m�[96m|�[0m
1410:  �[1m�[92mnote�[0m: consider initializing the variable with `WatchdogConfig { max_consecutive_failures: 2, ..Default::default() }` and removing relevant reassignments
1411:  �[1m�[96m--> �[0mcrates\flight-watchdog\src\lib.rs:1157:9
...

1508:  �[1m�[93mwarning[E0133]�[0m�[1m�[97m: call to unsafe function `flight_axis::Node::step_soa` is unsafe and requires unsafe block�[0m
1509:  �[1m�[96m--> �[0mcrates\flight-axis\tests\detent_tests.rs:25:5
1510:  �[1m�[96m|�[0m
1511:  �[1m�[96m25�[0m �[1m�[96m|�[0m     node.step_soa(frame, state_ptr);
1512:  �[1m�[96m|�[0m     �[1m�[93m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^�[0m �[1m�[93mcall to unsafe function�[0m
1513:  �[1m�[96m|�[0m
1514:  �[1m�[96m= �[0m�[1m�[97mnote�[0m: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
1515:  �[1m�[96m= �[0m�[1m�[97mnote�[0m: consult the function's documentation for information on how to avoid undefined behavior
1516:  �[1m�[92mnote�[0m: an unsafe function restricts its caller, but its body is safe by default
1517:  �[1m�[96m--> �[0mcrates\flight-axis\tests\detent_tests.rs:23:1
1518:  �[1m�[96m|�[0m
1519:  �[1m�[96m23�[0m �[1m�[96m|�[0m unsafe fn process_frame_soa(node: &DetentNode, frame: &mut AxisFrame, state: &mut DetentState) {
1520:  �[1m�[96m|�[0m �[1m�[92m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^�[0m
1521:  �[1m�[96m= �[0m�[1m�[97mnote�[0m: `#[warn(unsafe_op_in_unsafe_fn)]` (part of `#[warn(rust_2024_compatibility)]`) on by default
1522:  �[1m�[93mwarning�[0m: `flight-axis` (test "mixer_tests") generated 1 warning (run `cargo clippy --fix --test "mixer_tests" -p flight-axis` to apply 1 suggestion)
1523:  �[1m�[97mFor more information about this error, try `rustc --explain E0133`.�[0m
1524:  �[1m�[93mwarning�[0m: `flight-axis` (test "detent_tests") generated 1 warning (run `cargo clippy --fix --test "detent_tests" -p flight-axis` to apply 1 suggestion)
...

1820:  �[1m�[96m--> �[0mcrates\flight-core\src\lib.rs:131:30
1821:  �[1m�[96m|�[0m
1822:  �[1m�[96m131�[0m �[1m�[96m|�[0m         let r: Result<u32> = Ok(42);
1823:  �[1m�[96m|�[0m                              �[1m�[96m^^^^^^�[0m
1824:  �[1m�[96m= �[0m�[1m�[97mhelp�[0m: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#unnecessary_literal_unwrap
1825:  �[1m�[96m= �[0m�[1m�[97mnote�[0m: `#[warn(clippy::unnecessary_literal_unwrap)]` on by default
1826:  �[1m�[93mwarning�[0m�[1m�[97m: used `unwrap_err()` on `Err` value�[0m
1827:  �[1m�[96m--> �[0mcrates\flight-core\src\lib.rs:136:17
1828:  �[1m�[96m|�[0m
1829:  �[1m�[96m136�[0m �[1m�[96m|�[0m         assert!(e.unwrap_err().to_string().contains("Rules validation"));
1830:  �[1m�[96m|�[0m                 �[1m�[93m^^^^^^^^^^^^^^�[0m
1831:  �[1m�[96m|�[0m
1832:  �[1m�[96mhelp�[0m: remove the `Err` and `unwrap_err()`
1833:  �[1m�[96m--> �[0mcrates\flight-core\src\lib.rs:134:30
1834:  �[1m�[96m|�[0m
1835:  �[1m�[96m134�[0m �[1m�[96m|�[0m         let e: Result<u32> = Err(FlightError::RulesValidation("bad rule".to_string()));
1836:  �[1m�[96m|�[0m                              �[1m�[96m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^�[0m
...

2189:  �[36;1m# Apply strict warnings to core crates that must maintain high quality�[0m
2190:  �[36;1mcargo clippy -p flight-core --lib -- $STRICT_FLAGS�[0m
2191:  �[36;1mcargo clippy -p flight-axis --lib -- $STRICT_FLAGS�[0m
2192:  �[36;1mcargo clippy -p flight-bus --lib -- $STRICT_FLAGS�[0m
2193:  �[36;1mcargo clippy -p flight-hid --lib -- $STRICT_FLAGS�[0m
2194:  �[36;1mcargo clippy -p flight-ipc --lib -- $STRICT_FLAGS�[0m
2195:  �[36;1mcargo clippy -p flight-service --lib -- $STRICT_FLAGS�[0m
2196:  �[36;1mcargo clippy -p flight-simconnect --lib -- $STRICT_FLAGS�[0m
2197:  �[36;1mcargo clippy -p flight-panels --lib -- $STRICT_FLAGS�[0m
2198:  shell: C:\Program Files\Git\bin\bash.EXE --noprofile --norc -e -o pipefail {0}
2199:  env:
2200:  CARGO_TERM_COLOR: always
2201:  RUST_BACKTRACE: 1
2202:  CARGO_HOME: C:\Users\runneradmin\.cargo
2203:  CARGO_INCREMENTAL: 0
2204:  CACHE_ON_FAILURE: false
2205:  ##[endgroup]
...

2213:  �[1m�[92m   Compiling�[0m num-traits v0.2.19
2214:  �[1m�[92m    Checking�[0m crossbeam-epoch v0.9.18
2215:  �[1m�[92m    Checking�[0m aho-corasick v1.1.4
2216:  �[1m�[92m    Checking�[0m hashbrown v0.16.1
2217:  �[1m�[92m    Checking�[0m mio v1.1.1
2218:  �[1m�[92m    Checking�[0m regex-automata v0.4.14
2219:  �[1m�[92m    Checking�[0m indexmap v2.13.0
2220:  �[1m�[92m    Checking�[0m crossbeam-deque v0.8.6
2221:  �[1m�[92m    Checking�[0m crossbeam-channel v0.5.15
2222:  �[1m�[92m    Checking�[0m crossbeam-queue v0.3.12
2223:  �[1m�[92m    Checking�[0m tempfile v3.26.0
2224:  �[1m�[92m    Checking�[0m crossbeam v0.8.4
2225:  �[1m�[92m    Checking�[0m flight-metrics v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-metrics)
2226:  �[1m�[92m    Checking�[0m regex v1.12.3
2227:  �[1m�[92m   Compiling�[0m serde_derive v1.0.228
2228:  �[1m�[92m   Compiling�[0m thiserror-impl v2.0.18
2229:  �[1m�[92m   Compiling�[0m windows-interface v0.59.3
2230:  �[1m�[92m   Compiling�[0m windows-implement v0.60.2
2231:  �[1m�[92m   Compiling�[0m tracing-attributes v0.1.31
2232:  �[1m�[92m    Checking�[0m windows-core v0.62.2
2233:  �[1m�[92m   Compiling�[0m tokio-macros v2.6.0
2234:  �[1m�[92m    Checking�[0m thiserror v2.0.18
2235:  �[1m�[92m    Checking�[0m windows-numerics v0.3.1
...

2455:  �[1m�[92m    Checking�[0m flight-panels-saitek v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-panels-saitek)
2456:  �[1m�[92m    Checking�[0m flight-panels v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-panels)
2457:  �[1m�[92m    Finished�[0m `dev` profile [unoptimized + debuginfo] target(s) in 1.20s
2458:  ##[group]Run echo "🔍 Running file descriptor safety tests for public API crates..."
2459:  �[36;1mecho "🔍 Running file descriptor safety tests for public API crates..."�[0m
2460:  �[36;1m# Test that public API crates use typed file descriptors instead of RawFd�[0m
2461:  �[36;1mcargo test -p flight-hid fd_safety_tests�[0m
2462:  �[36;1mcargo test -p flight-ipc fd_safety_tests�[0m
2463:  �[36;1mcargo test -p flight-service fd_safety_tests�[0m
2464:  shell: C:\Program Files\Git\bin\bash.EXE --noprofile --norc -e -o pipefail {0}
2465:  env:
2466:  CARGO_TERM_COLOR: always
2467:  RUST_BACKTRACE: 1
2468:  CARGO_HOME: C:\Users\runneradmin\.cargo
2469:  CARGO_INCREMENTAL: 0
2470:  CACHE_ON_FAILURE: false
2471:  ##[endgroup]
2472:  🔍 Running file descriptor safety tests for public API crates...
2473:  �[1m�[92m   Compiling�[0m windows-link v0.2.1
2474:  �[1m�[92m   Compiling�[0m serde_core v1.0.228
2475:  �[1m�[92m   Compiling�[0m cfg-if v1.0.4
2476:  �[1m�[92m   Compiling�[0m once_cell v1.21.3
2477:  �[1m�[92m   Compiling�[0m windows-sys v0.61.2
2478:  �[1m�[92m   Compiling�[0m thiserror v2.0.18
2479:  �[1m�[92m   Compiling�[0m typenum v1.19.0
...

2547:  �[1m�[92m   Compiling�[0m flight-session v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-session)
2548:  �[1m�[92m   Compiling�[0m ppv-lite86 v0.2.21
2549:  �[1m�[92m   Compiling�[0m toml v0.8.23
2550:  �[1m�[92m   Compiling�[0m flight-blackbox v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-blackbox)
2551:  �[1m�[92m   Compiling�[0m windows-sys v0.59.0
2552:  �[1m�[92m   Compiling�[0m flight-writers v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-writers)
2553:  �[1m�[92m   Compiling�[0m flight-watchdog v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-watchdog)
2554:  �[1m�[92m   Compiling�[0m flight-units v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-units)
2555:  �[1m�[92m   Compiling�[0m flight-rules v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-rules)
2556:  �[1m�[92m   Compiling�[0m flight-hid-types v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-hid-types)
2557:  �[1m�[92m   Compiling�[0m fnv v1.0.7
2558:  �[1m�[92m   Compiling�[0m bit-vec v0.8.0
2559:  �[1m�[92m   Compiling�[0m encode_unicode v1.0.0
2560:  �[1m�[92m   Compiling�[0m flight-metrics v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-metrics)
2561:  �[1m�[92m   Compiling�[0m wait-timeout v0.2.1
2562:  �[1m�[92m   Compiling�[0m quick-error v1.2.3
2563:  �[1m�[92m   Compiling�[0m rusty-fork v0.3.1
...

2568:  �[1m�[92m   Compiling�[0m hidapi v2.6.5
2569:  �[1m�[92m   Compiling�[0m rand_chacha v0.9.0
2570:  �[1m�[92m   Compiling�[0m rand v0.9.2
2571:  �[1m�[92m   Compiling�[0m rand_xorshift v0.4.0
2572:  �[1m�[92m   Compiling�[0m unarray v0.1.4
2573:  �[1m�[92m   Compiling�[0m similar v2.7.0
2574:  �[1m�[92m   Compiling�[0m bitflags v2.11.0
2575:  �[1m�[92m   Compiling�[0m proptest v1.10.0
2576:  �[1m�[92m   Compiling�[0m flight-hid v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-hid)
2577:  �[1m�[92m   Compiling�[0m insta v1.46.3
2578:  �[1m�[92m    Finished�[0m `test` profile [unoptimized + debuginfo] target(s) in 57.10s
2579:  �[1m�[92m     Running�[0m unittests src\lib.rs (target\debug\deps\flight_hid-043f7d3037b68f2b.exe)
2580:  running 2 tests
2581:  test fd_safety_tests::clippy_config::test_fd_usage_examples ... ok
2582:  test fd_safety_tests::windows_tests::test_typed_handle_usage ... ok
2583:  test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 200 filtered out; finished in 0.00s
2584:  �[1m�[92m     Running�[0m tests\integration.rs (target\debug\deps\integration-a81f826ce256a4c3.exe)
2585:  running 0 tests
2586:  test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 14 filtered out; finished in 0.00s
2587:  �[1m�[92m     Running�[0m tests\proptest_axis_calibration.rs (target\debug\deps\proptest_axis_calibration-452cbfb4e1ccccd9.exe)
2588:  running 0 tests
2589:  test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 13 filtered out; finished in 0.00s
2590:  �[1m�[92m     Running�[0m tests\snapshots.rs (target\debug\deps\snapshots-40569faf95b9e0fe.exe)
2591:  running 0 tests
2592:  test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 5 filtered out; finished in 0.00s
2593:  �[1m�[92m   Compiling�[0m windows-sys v0.61.2
...

2712:  �[1m�[92m   Compiling�[0m plotters v0.3.7
2713:  �[1m�[92m   Compiling�[0m matchers v0.2.0
2714:  �[1m�[92m   Compiling�[0m tinytemplate v1.2.1
2715:  �[1m�[92m   Compiling�[0m thread_local v1.1.9
2716:  �[1m�[92m   Compiling�[0m anes v0.1.6
2717:  �[1m�[92m   Compiling�[0m oorandom v11.1.5
2718:  �[1m�[92m   Compiling�[0m tracing-subscriber v0.3.22
2719:  �[1m�[92m   Compiling�[0m criterion v0.8.2
2720:  �[1m�[92m   Compiling�[0m proptest v1.10.0
2721:  �[1m�[92m   Compiling�[0m tokio-test v0.4.5
2722:  �[1m�[92m    Finished�[0m `test` profile [unoptimized + debuginfo] target(s) in 1m 26s
2723:  �[1m�[92m     Running�[0m unittests src\lib.rs (target\debug\deps\flight_ipc-79b4f8e059ecd494.exe)
2724:  running 2 tests
2725:  test fd_safety_tests::fd_usage_examples::test_ipc_fd_usage_examples ... ok
2726:  test fd_safety_tests::windows_tests::test_typed_handle_usage_ipc ... ok
2727:  test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 171 filtered out; finished in 0.00s
2728:  �[1m�[92m     Running�[0m tests\grpc_tests.rs (target\debug\deps\grpc_tests-799f22426cd2e282.exe)
2729:  running 0 tests
2730:  test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 21 filtered out; finished in 0.00s
2731:  �[1m�[92m     Running�[0m tests\ipc_fuzz_tests.rs (target\debug\deps\ipc_fuzz_tests-cea6c6991d4cd9b8.exe)
2732:  running 0 tests
2733:  test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 5 filtered out; finished in 0.00s
2734:  �[1m�[92m     Running�[0m tests\proto_tests.rs (target\debug\deps\proto_tests-dd5405f9784363ea.exe)
2735:  running 0 tests
2736:  test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 25 filtered out; finished in 0.00s
2737:  �[1m�[92m   Compiling�[0m windows-link v0.2.1
...

2740:  �[1m�[92m   Compiling�[0m serde v1.0.228
2741:  �[1m�[92m   Compiling�[0m windows-sys v0.61.2
2742:  �[1m�[92m   Compiling�[0m cc v1.2.56
2743:  �[1m�[92m   Compiling�[0m pin-project-lite v0.2.17
2744:  �[1m�[92m   Compiling�[0m serde_core v1.0.228
2745:  �[1m�[92m   Compiling�[0m num-traits v0.2.19
2746:  �[1m�[92m   Compiling�[0m once_cell v1.21.3
2747:  �[1m�[92m   Compiling�[0m bytes v1.11.1
2748:  �[1m�[92m   Compiling�[0m memchr v2.8.0
2749:  �[1m�[92m   Compiling�[0m itoa v1.0.17
2750:  �[1m�[92m   Compiling�[0m tracing v0.1.44
2751:  �[1m�[92m   Compiling�[0m windows_x86_64_msvc v0.53.1
2752:  �[1m�[92m   Compiling�[0m windows-targets v0.53.5
2753:  �[1m�[92m   Compiling�[0m tracing-core v0.1.36
2754:  �[1m�[92m   Compiling�[0m windows-sys v0.60.2
2755:  �[1m�[92m   Compiling�[0m thiserror v2.0.18
2756:  �[1m�[92m   Compiling�[0m stable_deref_trait v1.2.1
...

2872:  �[1m�[92m   Compiling�[0m icu_properties_data v2.1.2
2873:  �[1m�[92m   Compiling�[0m icu_normalizer_data v2.1.1
2874:  �[1m�[92m   Compiling�[0m flight-simconnect-sys v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-simconnect-sys)
2875:  �[1m�[92m   Compiling�[0m ryu v1.0.23
2876:  �[1m�[92m   Compiling�[0m untrusted v0.9.0
2877:  �[1m�[92m   Compiling�[0m icu_normalizer v2.1.1
2878:  �[1m�[92m   Compiling�[0m icu_properties v2.1.2
2879:  �[1m�[92m   Compiling�[0m tonic-prost-build v0.14.5
2880:  �[1m�[92m   Compiling�[0m http-body-util v0.1.3
2881:  �[1m�[92m   Compiling�[0m subtle v2.6.1
2882:  �[1m�[92m   Compiling�[0m flight-ipc v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-ipc)
2883:  �[1m�[92m   Compiling�[0m idna_adapter v1.2.1
2884:  �[1m�[92m   Compiling�[0m serde_urlencoded v0.7.1
2885:  �[1m�[92m   Compiling�[0m axum-core v0.5.6
2886:  �[1m�[92m   Compiling�[0m num-integer v0.1.46
2887:  �[1m�[92m   Compiling�[0m serde_path_to_error v0.1.20
2888:  �[1m�[92m   Compiling�[0m utf8_iter v1.0.4
...

2964:  �[1m�[92m   Compiling�[0m flight-hotas-vkb v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-hotas-vkb)
2965:  �[1m�[92m   Compiling�[0m matchers v0.2.0
2966:  �[1m�[92m   Compiling�[0m thread_local v1.1.9
2967:  �[1m�[92m   Compiling�[0m reserve-port v2.3.0
2968:  �[1m�[92m   Compiling�[0m unsafe-libyaml v0.2.11
2969:  �[1m�[92m   Compiling�[0m bytesize v2.3.1
2970:  �[1m�[92m   Compiling�[0m axum-test v18.7.0
2971:  �[1m�[92m   Compiling�[0m serde_yaml_ng v0.10.0
2972:  �[1m�[92m   Compiling�[0m tokio-test v0.4.5
2973:  �[1m�[92m   Compiling�[0m flight-service v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-service)
2974:  �[1m�[92m    Finished�[0m `test` profile [unoptimized + debuginfo] target(s) in 3m 13s
2975:  �[1m�[92m     Running�[0m unittests src\lib.rs (target\debug\deps\flight_service-d8f82d75b9ff0e24.exe)
2976:  running 2 tests
2977:  test fd_safety_tests::fd_usage_examples::test_service_fd_usage_examples ... ok
2978:  test fd_safety_tests::windows_tests::test_service_system_handle_safety ... ok
2979:  test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 408 filtered out; finished in 0.00s
2980:  �[1m�[92m     Running�[0m unittests src\main.rs (target\debug\deps\flightd-84913256cb38b6a4.exe)
2981:  running 0 tests
2982:  test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
2983:  �[1m�[92m     Running�[0m tests\service_integration.rs (target\debug\deps\service_integration-db98d8c9f0c173a1.exe)
2984:  running 0 tests
2985:  test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 9 filtered out; finished in 0.00s
2986:  �[1m�[92m     Running�[0m tests\service_integration_tests.rs (target\debug\deps\service_integration_tests-fcdf243b87b47859.exe)
2987:  running 0 tests
2988:  test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 11 filtered out; finished in 0.00s
2989:  ##[group]Run echo "🔍 Verifying critical patterns are fixed..."
...

3008:  �[36;1mfi�[0m
3009:  �[36;1m�[0m
3010:  �[36;1m# Check for criterion::black_box usage�[0m
3011:  �[36;1mif git grep -n "criterion::black_box" -- 'crates/' 'benches/'; then�[0m
3012:  �[36;1m  echo "❌ Found criterion::black_box - should be std::hint::black_box"�[0m
3013:  �[36;1m  exit 1�[0m
3014:  �[36;1mfi�[0m
3015:  �[36;1m�[0m
3016:  �[36;1mecho "✅ All critical patterns verified"�[0m
3017:  shell: C:\Program Files\Git\bin\bash.EXE --noprofile --norc -e -o pipefail {0}
3018:  env:
3019:  CARGO_TERM_COLOR: always
3020:  RUST_BACKTRACE: 1
3021:  CARGO_HOME: C:\Users\runneradmin\.cargo
3022:  CARGO_INCREMENTAL: 0
3023:  CACHE_ON_FAILURE: false
3024:  ##[endgroup]
3025:  🔍 Verifying critical patterns are fixed...
3026:  ✅ All critical patterns verified
3027:  ##[group]Run cargo test --all-features --workspace --lib --tests --exclude flight-hub-examples
3028:  �[36;1mcargo test --all-features --workspace --lib --tests --exclude flight-hub-examples�[0m
3029:  shell: C:\Program Files\Git\bin\bash.EXE --noprofile --norc -e -o pipefail {0}
3030:  env:
3031:  CARGO_TERM_COLOR: always
3032:  RUST_BACKTRACE: 1
3033:  CARGO_HOME: C:\Users\runneradmin\.cargo
3034:  CARGO_INCREMENTAL: 0
3035:  CACHE_ON_FAILURE: false
3036:  ##[endgroup]
...

3168:  �[1m�[92m   Compiling�[0m flight-hotas-logitech v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-hotas-logitech)
3169:  �[1m�[92m   Compiling�[0m flight-hotas-ch v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-hotas-ch)
3170:  �[1m�[92m   Compiling�[0m flight-hotas-virpil v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-hotas-virpil)
3171:  �[1m�[92m   Compiling�[0m flight-hotas-honeycomb v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-hotas-honeycomb)
3172:  �[1m�[92m   Compiling�[0m flight-hotas-vpforce v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-hotas-vpforce)
3173:  �[1m�[92m   Compiling�[0m flight-hotas-saitek v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-hotas-saitek)
3174:  �[1m�[92m   Compiling�[0m flight-hotas-brunner v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-hotas-brunner)
3175:  �[1m�[92m   Compiling�[0m crossbeam-utils v0.8.21
3176:  �[1m�[92m   Compiling�[0m flight-integration-tests v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-integration-tests)
3177:  �[1m�[92m   Compiling�[0m num-integer v0.1.46
3178:  �[1m�[92m   Compiling�[0m crossbeam-epoch v0.9.18
3179:  �[1m�[92m   Compiling�[0m crossbeam-deque v0.8.6
3180:  �[1m�[92m   Compiling�[0m num-bigint v0.4.6
3181:  �[1m�[92m   Compiling�[0m crossbeam-channel v0.5.15
3182:  �[1m�[92m   Compiling�[0m crossbeam-queue v0.3.12
3183:  �[1m�[92m   Compiling�[0m quick-error v1.2.3
3184:  �[1m�[92m   Compiling�[0m wait-timeout v0.2.1
...

3399:  �[1m�[93mwarning�[0m: `flight-axis` (test "detent_integration") generated 9 warnings
3400:  �[1m�[93mwarning[E0133]�[0m�[1m�[97m: call to unsafe function `flight_axis::Node::step_soa` is unsafe and requires unsafe block�[0m
3401:  �[1m�[96m--> �[0mcrates\flight-axis\tests\detent_tests.rs:25:5
3402:  �[1m�[96m|�[0m
3403:  �[1m�[96m25�[0m �[1m�[96m|�[0m     node.step_soa(frame, state_ptr);
3404:  �[1m�[96m|�[0m     �[1m�[93m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^�[0m �[1m�[93mcall to unsafe function�[0m
3405:  �[1m�[96m|�[0m
3406:  �[1m�[96m= �[0m�[1m�[97mnote�[0m: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
3407:  �[1m�[96m= �[0m�[1m�[97mnote�[0m: consult the function's documentation for information on how to avoid undefined behavior
3408:  �[1m�[92mnote�[0m: an unsafe function restricts its caller, but its body is safe by default
3409:  �[1m�[96m--> �[0mcrates\flight-axis\tests\detent_tests.rs:23:1
3410:  �[1m�[96m|�[0m
3411:  �[1m�[96m23�[0m �[1m�[96m|�[0m unsafe fn process_frame_soa(node: &DetentNode, frame: &mut AxisFrame, state: &mut DetentState) {
3412:  �[1m�[96m|�[0m �[1m�[92m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^�[0m
3413:  �[1m�[96m= �[0m�[1m�[97mnote�[0m: `#[warn(unsafe_op_in_unsafe_fn)]` (part of `#[warn(rust_2024_compatibility)]`) on by default
3414:  �[1m�[97mFor more information about this error, try `rustc --explain E0133`.�[0m
3415:  �[1m�[93mwarning�[0m: `flight-axis` (test "detent_tests") generated 1 warning (run `cargo fix --test "detent_tests" -p flight-axis` to apply 1 suggestion)
...

3454:  test tests::applies_profile_replaces_existing_managed_block ... ok
3455:  test tests::managed_block_is_idempotent ... ok
3456:  test tests::install_creates_dir_and_file ... ok
3457:  test tests::installs_with_backup ... ok
3458:  test tests::rc_mode_index_values ... ok
3459:  test tests::renders_all_rc_modes ... ok
3460:  test tests::renders_managed_block ... ok
3461:  test tests::steam_input_hint_is_nonempty ... ok
3462:  test tests::validates_empty_profile_name ... ok
3463:  test tests::validates_out_of_range_deadzone ... ok
3464:  test tests::validates_out_of_range_exponent ... ok
3465:  test tests::validates_out_of_range_scale ... ok
3466:  test tests::property_valid_exponent_range_accepted ... ok
3467:  test tests::property_valid_deadzone_range_accepted ... ok
3468:  test tests::property_valid_scale_range_accepted ... ok
3469:  test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s
3470:  �[1m�[92m     Running�[0m unittests src\lib.rs (target\debug\deps\flight_ac7_protocol-79ecd42f070e313c.exe)
3471:  running 13 tests
3472:  test tests::aircraft_label_trims_whitespace ... ok
3473:  test tests::parses_valid_packet ... ok
3474:  test tests::defaults_schema_and_label ... ok
3475:  test tests::json_round_trip ... ok
3476:  test tests::property_pitch_control_is_bounded ... ok
3477:  test tests::property_bounded_altitude_valid ... ok
3478:  test tests::rejects_invalid_json ... ok
3479:  test tests::rejects_negative_speed ... ok
3480:  test tests::property_out_of_bounds_throttle_rejected ... ok
3481:  test tests::rejects_out_of_range_control_value ... ok
3482:  test tests::rejects_out_of_range_altitude ... ok
3483:  test tests::rejects_wrong_schema ... ok
3484:  test tests::property_all_bounded_controls_valid ... ok
3485:  test result: ok. 13 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
3486:  �[1m�[92m     Running�[0m unittests src\lib.rs (target\debug\deps\flight_ac7_telemetry-c0c6090b90882fbf.exe)
3487:  running 10 tests
3488:  test tests::metrics_registry_tracks_config ... ok
3489:  test tests::adapter_initial_state_is_disconnected ... ok
3490:  test tests::snapshot_has_correct_sim_id ... ok
3491:  test tests::snapshot_control_inputs_mapped ... ok
3492:  test tests::converts_packet_to_snapshot ... ok
3493:  test tests::snapshot_validity_partial_packet ... ok
3494:  test tests::snapshot_validity_flags_set_from_full_packet ... ok
3495:  test tests::start_stop_cycle ... ok
3496:  test tests::udp_poll_receives_packet ... ok
3497:  test tests::poll_updates_source_addr ... ok
3498:  test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
3499:  �[1m�[92m     Running�[0m unittests src\lib.rs (target\debug\deps\flight_adapter_common-3fd27606273cc5dd.exe)
3500:  running 19 tests
3501:  test metrics::tests::test_record_aircraft_change ... ok
3502:  test metrics::tests::test_record_update_tracks_samples ... ok
3503:  test reconnect_backoff::tests::test_exponential_growth ... ok
3504:  test reconnect_backoff::tests::test_first_delay_equals_initial ... ok
3505:  test reconnect_backoff::tests::test_jitter_stays_within_bounds ... ok
3506:  test reconnect_backoff::tests::test_jitter_zero_means_no_jitter ... ok
3507:  test reconnect_backoff::tests::test_max_delay_cap ... ok
3508:  test reconnect_backoff::tests::test_reset_restarts_sequence ... ok
3509:  test reconnection::tests::test_backoff_progression ... ok
3510:  test reconnection::tests::test_should_retry ... ok
3511:  test tests::adapter_error_display_variants ... ok
3512:  test tests::adapter_metrics_summary_format ... ok
3513:  test tests::adapter_metrics_total_updates_increment ... ok
3514:  test tests::adapter_state_all_variants_debug ... ok
3515:  test tests::adapter_state_equality ... ok
3516:  test tests::reconnection_strategy_initial_backoff_on_first_attempt ... ok
3517:  test tests::reconnection_strategy_max_backoff_caps ... ok
3518:  test reconnect_backoff::tests::test_invalid_jitter_panics - should panic ... ok
3519:  test reconnect_backoff::tests::test_invalid_multiplier_panics - should panic ... ok
3520:  test result: ok. 19 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.15s
3521:  �[1m�[92m     Running�[0m unittests src\lib.rs (target\debug\deps\flight_aerofly-4369114a3a30ae5e.exe)
3522:  running 36 tests
3523:  test tests::adapter_default_port ... ok
3524:  test tests::adapter_custom_port ... ok
3525:  test tests::adapter_no_telemetry_initially ... ok
3526:  test tests::adapter_process_datagram_updates_last ... ok
3527:  test tests::adapter_process_invalid_datagram_returns_error ... ok
3528:  test tests::adapter_process_text_updates_last ... ok
3529:  test tests::adapter_process_json_updates_last ... ok
3530:  test tests::aircraft_type_case_insensitive ... ok
3531:  test tests::aircraft_type_from_name ... ok
3532:  test tests::airspeed_conversion_knots_to_ms ... ok
3533:  test tests::altitude_conversion_ft_to_m ... ok
3534:  test tests::attitude_conversion_deg_to_rad ... ok
3535:  test tests::bad_magic_returns_error ... ok
3536:  test tests::empty_frame_returns_error ... ok
3537:  test tests::flaps_ratio_clamped_below_zero ... ok
3538:  test tests::frame_too_short_returns_error ... ok
3539:  test tests::gear_down_byte_nonzero ... ok
3540:  test tests::gear_up_byte_zero ... ok
3541:  test tests::invalid_json_returns_error ... ok
3542:  test tests::json_vspeed_defaults_to_zero_when_absent ... ok
3543:  test tests::parse_text_all_fields ... ok
3544:  test tests::parse_text_empty_returns_error ... ok
3545:  test tests::parse_text_gear_state_boundary ... ok
3546:  test tests::parse_text_invalid_numbers_default_to_zero ... ok
3547:  test tests::parse_text_negative_altitude ... ok
3548:  test tests::parse_text_throttle_clamped ... ok
3549:  test tests::parse_text_partial_uses_defaults ... ok
3550:  test tests::parse_text_unknown_keys_ignored ... ok
3551:  test tests::parse_text_whitespace_tolerance ... ok
3552:  test tests::parse_valid_binary_frame ... ok
3553:  test tests::telemetry_default_values ... ok
3554:  test tests::parse_valid_json ... ok
3555:  test tests::throttle_clamped_above_one ... ok
3556:  test tests::vspeed_conversion_fpm_to_ms ... ok
3557:  test tests::telemetry_serde_round_trip ... ok
3558:  test tests::zero_altitude_conversion ... ok
3559:  test result: ok. 36 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
3560:  �[1m�[92m     Running�[0m tests\integration_tests.rs (target\debug\deps\integration_tests-dfca06ac3711825a.exe)
3561:  running 10 tests
3562:  test airspeed_and_vertical_state_fields_present ... ok
3563:  test attitude_roll_pitch_heading_in_correct_units ... ok
3564:  test adapter_processes_binary_and_json_paths ... ok
3565:  test adapter_json_round_trip_preserves_all_fields ... ok
3566:  test coordinates_altitude_and_heading_decoded_correctly ... ok
3567:  test unit_conversion_helpers_are_consistent ... ok
3568:  test text_format_parsed_and_all_three_paths_work ... ok
3569:  test valid_json_telemetry_packet_parsed ... ok
3570:  test missing_fields_in_json_returns_error_gracefully ... ok
3571:  test malformed_json_returns_error_not_panic ... ok
3572:  test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
3573:  �[1m�[92m     Running�[0m unittests src\lib.rs (target\debug\deps\flight_axis-40c750a44d747997.exe)
...

3580:  test accumulator::tests::test_reset_to_zero ... ok
3581:  test accumulator::tests::test_scale_factor ... ok
3582:  test accumulator::tests::test_wrap_negative ... ok
3583:  test accumulator::tests::test_wrap_positive ... ok
3584:  test blackbox::tests::test_annotator_creation ... ok
3585:  test blackbox::tests::test_buffer_flush ... ok
3586:  test blackbox::tests::test_conflict_annotation ... ok
3587:  test blackbox::tests::test_conflict_data_conversion ... ok
3588:  test blackbox::tests::test_disabled_annotation ... ok
3589:  test blackbox::tests::test_disabled_annotator ... ok
3590:  test blackbox::tests::test_resolution_annotation ... ok
3591:  test buttons::tests::test_axis_offset_action ... ok
3592:  test buttons::tests::test_axis_set_action ... ok
3593:  test buttons::tests::test_chord_partial_press_no_fire ... ok
3594:  test buttons::tests::test_chord_requires_all_buttons ... ok
3595:  test buttons::tests::test_chord_too_many_buttons_error ... ok
3596:  test buttons::tests::test_clear_removes_all_macros ... ok
3597:  test buttons::tests::test_duplicate_button_error ... ok
3598:  test buttons::tests::test_empty_chord_error ... ok
3599:  test buttons::tests::test_hold_fires_after_threshold ... ok
...

3622:  test calibration::tests::test_calbank_insert_and_get ... ok
3623:  test calibration::tests::test_calbank_unknown_axis_uses_default ... ok
3624:  test calibration::tests::test_normalize_8bit ... ok
3625:  test calibration::tests::test_normalize_above_deadband ... ok
3626:  test calibration::tests::test_normalize_center_is_zero ... ok
3627:  test calibration::tests::test_normalize_clamped_above_max ... ok
3628:  test calibration::tests::test_normalize_clamped_below_min ... ok
3629:  test buttons::tests::proptest_output_count_never_exceeds_8 ... ok
3630:  test calibration::tests::test_normalize_deadband_near_center ... ok
3631:  test calibration::tests::test_normalize_max_is_one ... ok
3632:  test calibration::tests::test_normalize_midpoint_above_center ... ok
3633:  test calibration::tests::test_normalize_midpoint_below_center ... ok
3634:  test calibration::tests::test_normalize_min_equals_max ... ok
3635:  test calibration::tests::test_normalize_min_is_neg_one ... ok
3636:  test calibration::tests::test_normalize_virpil_14bit ... ok
3637:  test calibration_wizard::tests::center_detection_noisy_fails ... ok
3638:  test calibration_wizard::tests::center_detection_stable_succeeds ... ok
3639:  test calibration_wizard::tests::complete_produces_result ... ok
3640:  test calibration_wizard::tests::deadzone_recommends_value ... ok
3641:  test calibration_wizard::tests::initial_state_is_not_started ... ok
3642:  test calibration_wizard::tests::progress_increases_through_steps ... ok
3643:  test calibration_wizard::tests::reset_returns_to_not_started ... ok
3644:  test calibration_wizard::tests::samples_ignored_in_terminal_states ... ok
3645:  test calibration_wizard::tests::start_transitions_to_center_detection ... ok
3646:  test calibration_wizard::tests::sweep_detects_full_range ... ok
3647:  test calibration_wizard::tests::sweep_insufficient_range_fails ... ok
3648:  test calibration_wizard::tests::timeout_fails_center_detection ... ok
3649:  test calibration_wizard::tests::verification_fails_non_monotonic ... ok
3650:  test calibration_wizard::tests::verification_passes_linear ... ok
...

3738:  test curve::tests::test_expo_neg_one_input_maps_to_neg_one ... ok
3739:  test curve::tests::test_expo_negative_increases_center_sensitivity ... ok
3740:  test curve::tests::test_expo_one_input_maps_to_one ... ok
3741:  test curve::tests::test_expo_positive_reduces_center_sensitivity ... ok
3742:  test curve::tests::test_expo_zero_input_maps_to_zero ... ok
3743:  test curve::tests::test_expo_zero_is_linear ... ok
3744:  test curve::tests::test_is_monotone_identity ... ok
3745:  test curve::tests::test_linear_identity_constructor ... ok
3746:  test curve::tests::test_linear_identity_evaluates_x ... ok
3747:  test curve::tests::test_linear_identity_one ... ok
3748:  test curve::tests::test_linear_identity_zero ... ok
3749:  test curve::tests::test_linear_interpolation_midpoint ... ok
3750:  test curve::tests::test_monotone_cubic_identity ... ok
3751:  test curve::tests::test_monotone_cubic_preserves_monotone ... ok
3752:  test curve::tests::test_standard_deadzone_expo_curve ... ok
3753:  test curve::tests::test_too_few_points_error ... ok
3754:  test curve::tests::test_unsorted_points_error ... ok
3755:  test curve::tests::prop_output_always_in_range ... ok
...

3762:  test deadzone::tests::test_asymmetric_negative_deadzone ... ok
3763:  test deadzone::tests::test_asymmetric_positive_deadzone ... ok
3764:  test deadzone::tests::test_asymmetric_symmetric_matches_center_only ... ok
3765:  test deadzone::tests::test_asymmetric_zero_positive_passes_positive ... ok
3766:  test deadzone::tests::test_bank_apply ... ok
3767:  test deadzone::tests::test_bank_set_config ... ok
3768:  test deadzone::tests::test_center_deadzone_full_deflection ... ok
3769:  test deadzone::tests::test_center_deadzone_negative ... ok
3770:  test deadzone::tests::test_center_deadzone_outside_zone ... ok
3771:  test deadzone::tests::test_center_deadzone_within_zone ... ok
3772:  test deadzone::tests::test_clamp_above_one ... ok
3773:  test deadzone::tests::test_clamp_below_neg_one ... ok
3774:  test deadzone::tests::test_combined_center_and_edge ... ok
3775:  test deadzone::tests::test_edge_deadzone_below ... ok
3776:  test deadzone::tests::test_edge_deadzone_saturation ... ok
3777:  test deadzone::tests::test_invalid_center_error ... ok
3778:  test deadzone::tests::test_overlap_error ... ok
3779:  test deadzone::tests::test_zero_deadzone_passthrough ... ok
...

3901:  test invert::tests::test_invert_disabled_passthrough ... ok
3902:  test invert::tests::test_invert_enabled_negates ... ok
3903:  test invert::tests::test_invert_negative_one ... ok
3904:  test invert::tests::test_invert_positive_one ... ok
3905:  test invert::tests::test_invert_toggle ... ok
3906:  test invert::tests::test_invert_zero_unchanged ... ok
3907:  test lag_compensator::tests::first_sample_passes_through ... ok
3908:  test lag_compensator::tests::max_prediction_clamped ... ok
3909:  test lag_compensator::tests::moving_axis_is_predicted_ahead ... ok
3910:  test lag_compensator::tests::nan_passes_through_unchanged ... ok
3911:  test lag_compensator::tests::negative_movement_predicts_backward ... ok
3912:  test lag_compensator::tests::output_is_clamped_to_valid_range ... ok
3913:  test lag_compensator::tests::reset_clears_initialized ... ok
3914:  test lag_compensator::tests::static_axis_unchanged ... ok
3915:  test lag_compensator::tests::zero_dt_uses_last_dt ... ok
3916:  test mixer::tests::add_input_beyond_max_fails ... ok
3917:  test mixer::tests::add_input_increments_count ... ok
...

3993:  test pid::tests::test_pid_bank_reset_not_needed ... ok
3994:  test pid::tests::test_pid_bank_update_known_axis ... ok
3995:  test pid::tests::test_pid_bank_update_unknown_axis ... ok
3996:  test pid::tests::test_pid_converges_step_response ... ok
3997:  test pid::tests::test_pid_derivative_on_step ... ok
3998:  test pid::tests::test_pid_derivative_zero_first_tick ... ok
3999:  test pid::tests::test_pid_integral_accumulates ... ok
4000:  test pid::tests::test_pid_integral_windup_limited ... ok
4001:  test pid::tests::test_pid_output_clamped_to_1 ... ok
4002:  test pid::tests::test_pid_output_clamped_to_neg1 ... ok
4003:  test pid::tests::test_pid_proportional_only ... ok
4004:  test pid::tests::test_pid_reset_clears_state ... ok
4005:  test pid::tests::test_pid_set_integral_clamped ... ok
4006:  test pid::tests::test_pid_setpoint_above_pv ... ok
4007:  test pid::tests::test_pid_setpoint_below_pv ... ok
4008:  test pid::tests::test_pid_zero_error ... ok
4009:  test pipeline::tests::test_alignment ... ok
4010:  test pipeline::tests::test_bypass_out_of_bounds ... ok
4011:  test pipeline::tests::test_bypass_stage ... ok
4012:  test pipeline::tests::test_clamp_stage ... ok
4013:  test pipeline::tests::test_curve_stage_expo ... ok
4014:  test pipeline::tests::test_curve_stage_linear ... ok
4015:  test pipeline::tests::test_deadzone_stage_center ... ok
4016:  test pipeline::tests::test_deadzone_stage_full_deflection ... ok
4017:  test pipeline::tests::test_deadzone_stage_negative ... ok
4018:  test pipeline::tests::test_deadzone_stage_rescale ... ok
4019:  test pid::tests::proptest_zero_error_zero_output ... ok
4020:  test pipeline::tests::test_default_pipeline_is_empty ... ok
...

4109:  test recording::tests::test_playback_advance_returns_samples_in_window ... ok
4110:  test recording::tests::test_playback_is_finished_at_end ... ok
4111:  test recording::tests::test_playback_looping_wraps_around ... ok
4112:  test recording::tests::test_playback_rewind ... ok
4113:  test recording::tests::test_record_multiple_samples ... ok
4114:  test recording::tests::test_record_single_sample ... ok
4115:  test recording::tests::test_recording_duration ... ok
4116:  test recording::tests::test_recording_empty_by_default ... ok
4117:  test recording::tests::test_samples_in_range ... ok
4118:  test scale::tests::test_bank_apply ... ok
4119:  test scale::tests::test_bank_set_scale ... ok
4120:  test scale::tests::test_scale_clamp_max ... ok
4121:  test scale::tests::test_scale_clamp_min ... ok
4122:  test scale::tests::test_scale_default_passthrough ... ok
4123:  test scale::tests::test_scale_factor_half ... ok
4124:  test scale::tests::test_scale_invalid_range_error ... ok
4125:  test scale::tests::test_scale_nan_factor_error ... ok
4126:  test scale::tests::test_scale_negative_factor ... ok
...

4245:  test stages::tests::very_large_values_handled ... ok
4246:  test throttle_zone::tests::prop_output_always_in_range ... ok
4247:  test throttle_zone::tests::test_afterburner_zone_event ... ok
4248:  test throttle_zone::tests::test_builder_pattern ... ok
4249:  test throttle_zone::tests::prop_event_count_never_exceeds_4 ... ok
4250:  test throttle_zone::tests::test_combined_cut_and_milpower ... ok
4251:  test throttle_zone::tests::test_cut_zone_above_threshold ... ok
4252:  test throttle_zone::tests::test_cut_zone_at_threshold ... ok
4253:  test throttle_zone::tests::test_cut_zone_below_threshold ... ok
4254:  test throttle_zone::tests::test_max_zone_below_threshold ... ok
4255:  test throttle_zone::tests::test_max_zone_saturation ... ok
4256:  test throttle_zone::tests::test_milpower_zone_event_on_entry ... ok
4257:  test throttle_zone::tests::test_milpower_zone_event_on_exit ... ok
4258:  test throttle_zone::tests::test_no_zones_passthrough ... ok
4259:  test throttle_zone::tests::test_process_clamped_input_above_one ... ok
4260:  test throttle_zone::tests::test_validate_cut_above_max_error ... ok
4261:  test throttle_zone::tests::test_validate_invalid_cut_threshold ... ok
...

4286:  test trim::tests::test_trimbank_apply_unknown_axis ... ok
4287:  test trim::tests::test_trimbank_get_or_insert ... ok
4288:  test trim::tests::test_trimbank_reset_all ... ok
4289:  test trim::tests::proptest_apply_output_bounded ... ok
4290:  test velocity::tests::test_velocity_invalid_alpha_panics - should panic ... ok
4291:  test velocity::tests::test_velocity_negative_movement ... ok
4292:  test velocity::tests::test_velocity_no_smoothing ... ok
4293:  test velocity::tests::test_velocity_positive_movement ... ok
4294:  test velocity::tests::test_velocity_invalid_period_panics - should panic ... ok
4295:  test velocity::tests::test_velocity_reset ... ok
4296:  test trim::tests::proptest_decrement_bounded ... ok
4297:  test velocity::tests::test_velocity_smoothing ... ok
4298:  test velocity::tests::test_velocity_units ... ok
4299:  test velocity::tests::test_velocity_zero_at_rest ... ok
4300:  test trim::tests::proptest_increment_bounded ... ok
4301:  test result: ok. 726 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.59s
4302:  �[1m�[92m     Running�[0m tests\detent_integration.rs (target\debug\deps\detent_integration-e4480f02c14a395d.exe)
4303:  running 8 tests
4304:  test test_detent_builder_api ... ok
4305:  test test_detent_hysteresis_with_slew ... ok
4306:  test test_detent_events_in_pipeline ... ok
4307:  test test_detent_in_complete_pipeline ... ok
4308:  test test_detent_output_snapping ... ok
4309:  test test_detent_with_curve_interaction ... ok
4310:  test test_multiple_detent_transitions ... ok
4311:  test test_detent_performance_in_pipeline ... ok
4312:  test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.65s
4313:  �[1m�[92m     Running�[0m tests\detent_tests.rs (target\debug\deps\detent_tests-20ec193189a81072.exe)
4314:  running 13 tests
4315:  test test_detent_zone_containment ... ok
4316:  test test_detent_zone_clamping ... ok
4317:  test test_detent_role_names ... ok
4318:  test test_detent_zone_creation ... ok
4319:  test test_hysteresis_prevents_flapping ... ok
4320:  test test_multiple_detents_no_overlap ... ok
4321:  test test_no_snap_detent ... ok
4322:  test test_node_trait_implementation ... ok
4323:  test test_single_detent_entry_exit ... ok
4324:  test test_sweep_single_transitions ... ok
4325:  test test_zone_sorting ... ok
4326:  test test_hysteresis_stability ... ok
4327:  test test_deterministic_detent_behavior ... ok
4328:  test result: ok. 13 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.05s
4329:  �[1m�[92m     Running�[0m tests\filter_tests.rs (target\debug\deps\filter_tests-6526b0b860e21a54.exe)
4330:  running 10 tests
4331:  test test_filter_alpha_one_is_identity ... ok
4332:  test test_filter_alpha_zero_holds_initial_value ... ok
4333:  test test_b104_spike_rejection_ignores_single_transient ... ok
4334:  test test_filter_converges_toward_constant_input ... ok
4335:  test test_filter_ema_smoothing_on_step_input ... ok
4336:  test test_filter_first_sample_passthrough ... ok
4337:  test test_filter_inf_does_not_panic ... ok
4338:  test test_filter_nan_does_not_panic ... ok
4339:  test test_filter_output_bounded_for_valid_inputs ... ok
4340:  test filter_output_in_range ... ok
4341:  test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
4342:  �[1m�[92m     Running�[0m tests\integration_tests.rs (target\debug\deps\integration_tests-06c91449628a7bc8.exe)
4343:  running 26 tests
4344:  test test_allocation_guard ... ok
4345:  test test_axis_engine_creation ... ok
4346:  test test_axis_engine_process_without_pipeline ... ok
4347:  test test_atomic_pipeline_swap_with_ack ... ok
4348:  test test_axis_engine_with_config ... ok
4349:  test test_axis_frame_creation ... ok
4350:  test test_axis_frame_derivative_calculation ... ok
4351:  test test_compile_failure_safety ... ok
4352:  test test_curve_node_exponential ... ok
...

4355:  test test_deadzone_node_symmetric ... ok
4356:  test test_end_to_end_pipeline_processing ... ok
4357:  test test_deterministic_processing ... ok
4358:  test test_node_state_sizes ... ok
4359:  test test_node_type_identification ... ok
4360:  test test_performance_snapshot ... ok
4361:  test test_pipeline_builder ... ok
4362:  test test_pipeline_state_validation ... ok
4363:  test test_runtime_counters ... ok
4364:  test test_runtime_counters_averaging ... ok
4365:  test test_slew_node_rate_limiting ... ok
4366:  test test_zero_allocation_constraint_validation ... ok
4367:  test test_zero_allocation_guarantee ... ok
4368:  test test_processing_performance ... ok
4369:  test test_performance_under_load ... ok
4370:  test result: ok. 26 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.73s
4371:  �[1m�[92m     Running�[0m tests\mixer_tests.rs (target\debug\deps\mixer_tests-5e53fcb2ba9fde26.exe)
...

4388:  test test_mixer_input_creation ... ok
4389:  test test_mixer_input_with_scale ... ok
4390:  test test_mixer_mathematical_properties ... ok
4391:  test test_mixer_node_creation ... ok
4392:  test test_mixer_node_creation_with_invalid_config ... ok
4393:  test test_mixer_node_trait_implementation ... ok
4394:  test test_mixer_process_inputs_basic ... ok
4395:  test test_mixer_process_inputs_no_clamp ... ok
4396:  test test_mixer_process_inputs_with_gain ... ok
4397:  test test_mixer_soa_step_processing ... ok
4398:  test test_mixer_state_initialization ... ok
4399:  test test_mixer_unit_handling_validation ... ok
4400:  test test_mixer_zero_allocation_constraint ... ok
4401:  test test_mixer_zero_allocation_integration ... ok
4402:  test test_mixer_performance_characteristics ... ok
4403:  test result: ok. 30 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s
4404:  �[1m�[92m     Running�[0m tests\performance_validation.rs (target\debug\deps\performance_validation-089fcfcc16391971.exe)
4405:  running 4 tests
4406:  test test_atomic_swap_performance ... ok
4407:  test test_jitter_requirements ... ok
4408:  test test_rt_performance_requirements ... ok
4409:  test test_zero_allocation_validation ... ok
4410:  test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.59s
4411:  �[1m�[92m     Running�[0m tests\pipeline_composition_tests.rs (target\debug\deps\pipeline_composition_tests-a708998be0ddc904.exe)
4412:  running 11 tests
4413:  test test_deadzone_curve_output_is_monotone_for_positive_inputs ... ok
4414:  test test_filter_smooths_step_after_deadzone ... ok
4415:  test test_max_positive_input_stays_bounded_through_deadzone_curve_slew ... ok
4416:  test test_nan_input_does_not_panic_in_full_pipeline ... ok
4417:  test test_neg_inf_does_not_panic_in_deadzone_pipeline ... ok
4418:  test test_positive_inf_does_not_panic_in_full_pipeline ... ok
4419:  test test_slew_limits_sudden_large_jump ... ok
4420:  test test_zero_input_stays_zero_through_deadzone_curve_slew ... ok
4421:  test deadzone_curve_output_in_range ... ok
4422:  test full_pipeline_output_in_range ... ok
4423:  test deadzone_curve_is_monotone_for_positive_inputs ... ok
4424:  test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
4425:  �[1m�[92m     Running�[0m tests\pipeline_integration.rs (target\debug\deps\pipeline_integration-7cd534de7282c6a7.exe)
4426:  running 7 tests
4427:  test test_pipeline_center_no_processing ... ok
4428:  test test_pipeline_max_input_max_trim_clamps ... ok
4429:  test test_pipeline_max_input_no_trim ... ok
4430:  test test_pipeline_min_input_no_trim ... ok
4431:  test test_pipeline_output_always_bounded ... ok
4432:  test test_pipeline_rate_limit_slows_changes ... ok
4433:  test test_pipeline_smoothing_reduces_step_response ... ok
4434:  test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
4435:  �[1m�[92m     Running�[0m tests\proptest_invariants.rs (target\debug\deps\proptest_invariants-266413960930285b.exe)
4436:  running 14 tests
4437:  test clamp_never_exceeds_bounds ... ok
4438:  test expo_preserves_sign ... ok
4439:  test expo_output_bounded ... ok
4440:  test deadzone_output_zero_within_zone ... ok
4441:  test rt_deadzone_output_bounded ... ok
4442:  test rt_curve_expo_monotone ... ok
4443:  test pipeline_output_finite ... ok
4444:  test rt_pipeline_output_finite ... ok
4445:  test saturation_bipolar_bounds ... ok
4446:  test slew_rate_unlimited_passthrough ... ok
4447:  test saturation_output_within_bounds ... ok
4448:  test smoothing_ema_converges_to_constant ... ok
4449:  test slew_rate_delta_bounded ... ok
4450:  test smoothing_output_always_finite ... ok
4451:  test result: ok. 14 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.05s
4452:  �[1m�[92m     Running�[0m tests\rt_coverage.rs (target\debug\deps\rt_coverage-c809db928d4cfe76.exe)
...

4463:  test test_combined_deadzone_expo_zeroes_inside_zone ... ok
4464:  test test_curve_expo_one_max_curvature ... ok
4465:  test test_curve_expo_zero_is_linear ... ok
4466:  test test_curve_scurve_reduces_centre_gain ... ok
4467:  test test_deadzone_negative_boundary ... ok
4468:  test test_deadzone_value_at_exact_threshold ... ok
4469:  test test_deadzone_value_inside_is_zero ... ok
4470:  test test_deadzone_value_just_outside_is_nonzero ... ok
4471:  test test_range_clamp_at_limits ... ok
4472:  test test_split_bipolar_half_positive ... ok
4473:  test test_split_bipolar_negative_one ... ok
4474:  test test_split_bipolar_positive_one ... ok
4475:  test test_split_bipolar_zero ... ok
4476:  test prop_split_bipolar_sum_equals_abs ... ok
4477:  test prop_combine_differential_bounded ... ok
4478:  test result: ok. 24 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
4479:  �[1m�[92m     Running�[0m tests\rt_timing_test.rs (target\debug\deps\rt_timing_test-d544fa381936811a.exe)
4480:  running 2 tests
4481:  test axis_pipeline_p99_within_4ms_budget ... ok
4482:  test axis_pipeline_fits_in_rt_budget ... ok
4483:  test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.07s
4484:  �[1m�[92m     Running�[0m tests\snapshot_tests.rs (target\debug\deps\snapshot_tests-1111d5c199650f93.exe)
4485:  running 3 tests
4486:  test snapshot_curve_node_expo_0_4_outputs ... ok
4487:  test snapshot_deadzone_expo_pipeline_output_values ... ok
4488:  test snapshot_deadzone_expo_pipeline_metadata ... ok
4489:  test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.16s
4490:  �[1m�[92m     Running�[0m unittests src\lib.rs (target\debug\deps\flight_bdd_metrics-6c5f6221692ddcc3.exe)
4491:  running 14 tests
4492:  test tests::bdd_traceability_row_coverage_methods ... ok
4493:  test tests::coverage_percent_zero_denominator_returns_zero ... ok
4494:  test tests::bdd_scenario_ac_tags_filters_non_ac_tags ... ok
4495:  test tests::coverage_percent_full_coverage ... ok
4496:  test tests::coverage_status_compute_all_branches ... ok
4497:  test tests::is_crate_name_candidate_valid_and_invalid ... ok
4498:  test tests::extract_crates_from_command_parses_p_flag ... ok
4499:  test tests::extract_crates_from_reference_cmd_prefix ... ok
4500:  test tests::extract_crates_from_reference_double_colon_notation ... ok
4501:  test tests::is_scenario_header_recognises_scenario_types ... ok
4502:  test tests::normalize_crate_name_strips_quotes_and_underscores ... ok
4503:  test tests::parse_tags_from_line_extracts_tags ... ok
4504:  test tests::with_workspace_crates_filters_non_workspace_rows ... ok
4505:  test tests::with_workspace_crates_preserves_unmapped_row ... ok
4506:  test result: ok. 14 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
4507:  �[1m�[92m     Running�[0m unittests src\lib.rs (target\debug\deps\flight_blackbox-8985d4d59c430f37.exe)
...

4532:  test recorder::tests::iterator_exact_size ... ok
4533:  test export::tests::json_csv_agree_on_axis_count ... ok
4534:  test recorder::tests::mixed_record_types_in_buffer ... ok
4535:  test recorder::tests::new_recorder_is_empty ... ok
4536:  test recorder::tests::record_and_retrieve_axis ... ok
4537:  test recorder::tests::record_event_stores_correctly ... ok
4538:  test recorder::tests::record_ffb_stores_correctly ... ok
4539:  test recorder::tests::large_overflow_preserves_newest ... ok
4540:  test recorder::tests::record_telemetry_stores_correctly ... ok
4541:  test recorder::tests::ring_buffer_exact_capacity_fill ... ok
4542:  test recorder::tests::ring_buffer_overflow_drops_oldest ... ok
4543:  test recorder::tests::zero_alloc_on_hot_path ... ok
4544:  test recorder::tests::zero_capacity_clamped_to_one ... ok
4545:  test tests::blackbox_config_defaults ... ok
4546:  test tests::blackbox_writer_starts_not_running ... ok
4547:  test tests::double_start_returns_error ... ok
4548:  test tests::export_doc_is_json_serializable ... ok
...

4550:  test tests::prop_blackbox_footer_roundtrip ... ok
4551:  test tests::record_queue_capacity_clamps_to_max ... ok
4552:  test tests::prop_index_entry_roundtrip ... ok
4553:  test tests::record_queue_capacity_clamps_to_min ... ok
4554:  test tests::stream_type_to_index ... ok
4555:  test time::tests::elapsed_to_ns_one_second ... ok
4556:  test time::tests::elapsed_to_ns_saturates_on_overflow ... ok
4557:  test time::tests::elapsed_to_ns_zero_duration ... ok
4558:  test time::tests::monotonic_now_ns_is_non_negative ... ok
4559:  test time::tests::to_ns_from_ms_basic ... ok
4560:  test time::tests::to_ns_from_ms_saturates_on_overflow ... ok
4561:  test time::tests::unix_now_ns_is_after_epoch ... ok
4562:  test time::tests::monotonic_now_ns_increases_over_time ... ok
4563:  test tests::prop_blackbox_header_roundtrip ... ok
4564:  test tests::blackbox_write_read_roundtrip ... ok
4565:  test result: ok. 56 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.02s
4566:  �[1m�[92m     Running�[0m unittests src\lib.rs (target\debug\deps\flight_bus-a6be027b05246855.exe)
...

4589:  test adapters::tests::msfs_tests::test_msfs_percentage_conversion ... ok
4590:  test adapters::tests::msfs_tests::test_msfs_rpm_conversion ... ok
4591:  test adapters::tests::msfs_tests::test_msfs_speed_conversion ... ok
4592:  test adapters::tests::validation_tests::test_altitude_validation ... ok
4593:  test adapters::tests::validation_tests::test_angle_validation ... ok
4594:  test adapters::tests::validat...

Copy link
Copy Markdown
Member Author

Not auto-merging in this PR review pass — this branch is now ~2 months stale and the merge would delete ~3,000 lines of flight-hotas-vkb test infrastructure (vkb_protocol_depth.rs, several snapshot_tests__*.snap fixtures) that's been added on main since, plus a workspace-wide ~195K-line delete from drift.

The new configuration.rs / axis_mapping.rs modules and the VkbProtocol parser look useful, but a forward-port needs device-specific judgement on whether the new types should layer on top of the post-March VKB test snapshots or replace them. Could you rebase onto current main? Happy to land it once the diff is just the additive parts vs. current flight-hotas-vkb.


Generated by Claude Code

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.

2 participants