Skip to content

feat(hotas-winwing): add protocol parser, LED control, and detent system#66

Open
EffortlessSteven wants to merge 3 commits intomainfrom
feat/winwing-protocol
Open

feat(hotas-winwing): add protocol parser, LED control, and detent system#66
EffortlessSteven wants to merge 3 commits intomainfrom
feat/winwing-protocol

Conversation

@EffortlessSteven
Copy link
Member

Summary

Implements Winwing device protocol support for OpenFlight.

Devices Covered

  • Winwing Orion HOTAS (stick + throttle)
  • Winwing Orion2 HOTAS (updated sensors)
  • Winwing Super Taurus/Libra (throttle quadrant)
  • Winwing F18 Panel (UFC/IFEI)
  • Winwing F16EX Panel (ICP)

Changes

  • protocol.rs: Device detection (\DeviceType\ enum, \WinwingProtocol\ struct) and PID-based identification for 9 device types
  • led_control.rs: High-level LED zone (\LedCommand) and display character control (\DisplayCommand) with batch report building
  • detent_system.rs: Magnetic detent detection and snap (\WinwingDetentConfig, \MagneticDetent) with military/civilian presets

Tests

260 tests passing — covers protocol parsing, LED commands, detent positions, and all existing device families.

- Winwing USB HID protocol device detection for Orion, Super Taurus, F18/F16 panels
- LED and display control for panel backlight and UFC
- Throttle detent handling with magnetic positions
- 260 tests passing covering all device families

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 1, 2026 03:46
@gemini-code-assist
Copy link

Warning

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

@chatgpt-codex-connector
Copy link

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.

@coderabbitai
Copy link

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 5 minutes and 58 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 5188514.

📒 Files selected for processing (4)
  • crates/flight-hotas-winwing/src/detent_system.rs
  • crates/flight-hotas-winwing/src/led_control.rs
  • crates/flight-hotas-winwing/src/lib.rs
  • crates/flight-hotas-winwing/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/winwing-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

Review Summary by Qodo

Add WinWing device detection, LED control, and detent system

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Add device type detection and protocol handler for 9 WinWing device models
• Implement LED and display control with batch report building API
• Add magnetic detent system for throttle snap-to-position behavior
• Export new public APIs and update module structure
Diagram
flowchart LR
  A["USB PID"] -->|DeviceType::from_pid| B["DeviceType enum"]
  B -->|WinwingProtocol| C["Device capabilities"]
  C -->|has_leds/has_display/has_detents| D["Feature queries"]
  E["LedCommand/DisplayCommand"] -->|build_led_report| F["Feature report bytes"]
  E -->|build_display_report| F
  G["WinwingDetentConfig"] -->|detect_detent| H["ActiveDetent result"]
  H -->|magnetic snap| I["Snapped axis value"]
Loading

Grey Divider

File Changes

1. crates/flight-hotas-winwing/src/detent_system.rs ✨ Enhancement +446/-0

Throttle detent system with magnetic snap zones

• New module implementing magnetic detent detection and snap behavior
• MagneticDetent struct with centre, snap_radius, and strength parameters
• WinwingDetentConfig for managing multiple detents with military/civilian presets
• detect_detent() function to determine active detent zones
• 40+ comprehensive unit tests covering all detent scenarios

crates/flight-hotas-winwing/src/detent_system.rs


2. crates/flight-hotas-winwing/src/led_control.rs ✨ Enhancement +439/-0

Batch-oriented LED and display command API

• New high-level LED and display control module
• LedCommand enum for single/all button intensity and RGB control
• DisplayCommand enum for text, segments, brightness, and clear operations
• build_led_report() and build_display_report() batch builders
• 30+ tests validating command encoding and frame structure

crates/flight-hotas-winwing/src/led_control.rs


3. crates/flight-hotas-winwing/src/protocol.rs ✨ Enhancement +283/-0

Device type detection and protocol handler

• Add DeviceType enum with 9 WinWing device variants (Orion, Orion2, SuperTaurus, F18/F16 panels,
 TFRP, Skywalker)
• Implement DeviceType::from_pid() for PID-based device detection
• Add capability queries (has_leds(), has_display(), has_detents(), report_length())
• New WinwingProtocol struct wrapping device identification and capabilities
• 20+ tests covering all device types and capability detection

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


View more (1)
4. crates/flight-hotas-winwing/src/lib.rs ✨ Enhancement +10/-5

Module structure and public API updates

• Add detent_system and led_control module declarations
• Export public APIs from new modules (ActiveDetent, MagneticDetent, WinwingDetentConfig,
 detect_detent)
• Export LED/display command builders (LedCommand, DisplayCommand, build_led_report,
 build_display_report)
• Export device detection types (DeviceType, WinwingProtocol)
• Update protocol re-exports to include new device identification

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


Grey Divider

Qodo Logo

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

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. PID 0xBEA8 inconsistent🐞 Bug ✓ Correctness
Description
DeviceType::from_pid maps PID 0xBEA8 to F16Panel and advertises display/LED capabilities, but
the rest of the crate documents and parses 0xBEA8 as the F-16EX Grip. This inconsistency will make
WinwingProtocol report wrong device name/capabilities for the existing supported 0xBEA8 device,
leading callers to attempt panel-only operations (display/backlight) on the grip.
Code

crates/flight-hotas-winwing/src/protocol.rs[R539-596]

+    /// F-18 UFC / IFEI panel (button-only, display segments).
+    F18Panel,
+    /// F-16EX ICP panel (buttons, switches, 2 axes).
+    F16Panel,
+    /// TFRP rudder pedals (3 axes).
+    TfrpRudder,
+    /// Skywalker metal rudder pedals.
+    SkywalkerRudder,
+}
+
+impl DeviceType {
+    /// Detect the device type from a USB Product ID.
+    ///
+    /// Returns `None` if the PID is not recognised.
+    pub fn from_pid(pid: u16) -> Option<Self> {
+        match pid {
+            0xBE60 => Some(Self::OrionStick),
+            0xBE61 => Some(Self::OrionThrottle),
+            0xBE63 => Some(Self::Orion2Stick),
+            0xBE62 => Some(Self::Orion2Throttle),
+            0xBD64 => Some(Self::SuperTaurus),
+            0xBEDE => Some(Self::F18Panel),
+            0xBEA8 => Some(Self::F16Panel),
+            0xBE64 => Some(Self::TfrpRudder),
+            0xBEF0 => Some(Self::SkywalkerRudder),
+            _ => None,
+        }
+    }
+
+    /// Returns the expected HID input report length for this device.
+    pub fn report_length(&self) -> usize {
+        match self {
+            Self::OrionStick | Self::Orion2Stick => 12,
+            Self::OrionThrottle | Self::Orion2Throttle => 24,
+            Self::SuperTaurus => 13,
+            Self::F18Panel => 6,
+            Self::F16Panel => 10,
+            Self::TfrpRudder => 8,
+            Self::SkywalkerRudder => 8,
+        }
+    }
+
+    /// Returns `true` if this device supports LED / backlight control.
+    pub fn has_leds(&self) -> bool {
+        matches!(
+            self,
+            Self::OrionThrottle
+                | Self::Orion2Throttle
+                | Self::SuperTaurus
+                | Self::F18Panel
+                | Self::F16Panel
+        )
+    }
+
+    /// Returns `true` if this device has a display (UFC/IFEI/ICP).
+    pub fn has_display(&self) -> bool {
+        matches!(self, Self::F18Panel | Self::F16Panel)
+    }
Evidence
The new PID→DeviceType mapping and capability methods classify 0xBEA8 as an F-16EX panel with a
display and LEDs. However, the crate’s own documentation, parser module, and device profile all
define PID 0xBEA8 as the F-16EX Grip. These contradictory sources cannot all be correct
simultaneously; as a result, the new device detection layer will misrepresent the existing supported
device for PID 0xBEA8.

crates/flight-hotas-winwing/src/protocol.rs[523-596]
crates/flight-hotas-winwing/src/lib.rs[4-21]
crates/flight-hotas-winwing/src/f16ex_stick.rs[4-23]
crates/flight-hotas-winwing/src/profiles.rs[254-265]

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

## Issue description
`DeviceType::from_pid(0xBEA8)` currently returns `F16Panel` and reports `has_display()`/`has_leds()` as true, but the rest of the crate (docs, parser module, profiles) treats PID 0xBEA8 as the F-16EX Grip.
### Issue Context
This inconsistency will cause callers using `WinwingProtocol` for a 0xBEA8 device to get contradictory identity/capability information compared to the crate’s existing parsing/profile behavior.
### Fix Focus Areas
- crates/flight-hotas-winwing/src/protocol.rs[523-596]
- crates/flight-hotas-winwing/src/lib.rs[4-21]
- crates/flight-hotas-winwing/src/f16ex_stick.rs[4-23]
- crates/flight-hotas-winwing/src/profiles.rs[254-265]

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



Remediation recommended

2. UTF-8 truncation panic🐞 Bug ⛯ Reliability
Description
build_display_report truncates text using &text[..16], which slices by byte index and can
panic if byte 16 is not a UTF-8 character boundary. This turns a normal API call into a runtime
crash for non-ASCII input (even accidental), reducing reliability.
Code

crates/flight-hotas-winwing/src/led_control.rs[R126-140]

+            DisplayCommand::WriteText {
+                panel_id,
+                field_index,
+                text,
+            } => {
+                let truncated = if text.len() > 16 {
+                    &text[..16]
+                } else {
+                    text.as_str()
+                };
+                let mut payload = Vec::with_capacity(2 + truncated.len());
+                payload.push(*panel_id);
+                payload.push(*field_index);
+                payload.extend_from_slice(truncated.as_bytes());
+                FeatureReportFrame::new(
Evidence
Rust String slicing (&text[..16]) requires slicing on a UTF-8 character boundary; otherwise it
panics. The new led_control API accepts a String and performs this slicing without validating
ASCII or using char-safe truncation, so non-ASCII text can crash the caller. The existing low-level
protocol builder uses the same unsafe truncation pattern, so fixing it should be done in both places
(or centralized).

crates/flight-hotas-winwing/src/led_control.rs[126-140]
crates/flight-hotas-winwing/src/protocol.rs[327-338]

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

## Issue description
`&amp;amp;text[..16]` is byte-index slicing and can panic when `text` contains multi-byte UTF-8 characters and `16` is not on a char boundary.
### Issue Context
This occurs in the new high-level API (`build_display_report`) and also in the existing low-level builder (`build_display_text_command`). Since the protocol docs say “ASCII”, the API should either enforce ASCII or at least truncate safely without panicking.
### Fix Focus Areas
- crates/flight-hotas-winwing/src/led_control.rs[126-140]
- crates/flight-hotas-winwing/src/protocol.rs[327-338]

ⓘ 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 +539 to +596
/// F-18 UFC / IFEI panel (button-only, display segments).
F18Panel,
/// F-16EX ICP panel (buttons, switches, 2 axes).
F16Panel,
/// TFRP rudder pedals (3 axes).
TfrpRudder,
/// Skywalker metal rudder pedals.
SkywalkerRudder,
}

impl DeviceType {
/// Detect the device type from a USB Product ID.
///
/// Returns `None` if the PID is not recognised.
pub fn from_pid(pid: u16) -> Option<Self> {
match pid {
0xBE60 => Some(Self::OrionStick),
0xBE61 => Some(Self::OrionThrottle),
0xBE63 => Some(Self::Orion2Stick),
0xBE62 => Some(Self::Orion2Throttle),
0xBD64 => Some(Self::SuperTaurus),
0xBEDE => Some(Self::F18Panel),
0xBEA8 => Some(Self::F16Panel),
0xBE64 => Some(Self::TfrpRudder),
0xBEF0 => Some(Self::SkywalkerRudder),
_ => None,
}
}

/// Returns the expected HID input report length for this device.
pub fn report_length(&self) -> usize {
match self {
Self::OrionStick | Self::Orion2Stick => 12,
Self::OrionThrottle | Self::Orion2Throttle => 24,
Self::SuperTaurus => 13,
Self::F18Panel => 6,
Self::F16Panel => 10,
Self::TfrpRudder => 8,
Self::SkywalkerRudder => 8,
}
}

/// Returns `true` if this device supports LED / backlight control.
pub fn has_leds(&self) -> bool {
matches!(
self,
Self::OrionThrottle
| Self::Orion2Throttle
| Self::SuperTaurus
| Self::F18Panel
| Self::F16Panel
)
}

/// Returns `true` if this device has a display (UFC/IFEI/ICP).
pub fn has_display(&self) -> bool {
matches!(self, Self::F18Panel | Self::F16Panel)
}

Choose a reason for hiding this comment

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

Action required

1. Pid 0xbea8 inconsistent 🐞 Bug ✓ Correctness

DeviceType::from_pid maps PID 0xBEA8 to F16Panel and advertises display/LED capabilities, but
the rest of the crate documents and parses 0xBEA8 as the F-16EX Grip. This inconsistency will make
WinwingProtocol report wrong device name/capabilities for the existing supported 0xBEA8 device,
leading callers to attempt panel-only operations (display/backlight) on the grip.
Agent Prompt
### Issue description
`DeviceType::from_pid(0xBEA8)` currently returns `F16Panel` and reports `has_display()`/`has_leds()` as true, but the rest of the crate (docs, parser module, profiles) treats PID 0xBEA8 as the F-16EX Grip.

### Issue Context
This inconsistency will cause callers using `WinwingProtocol` for a 0xBEA8 device to get contradictory identity/capability information compared to the crate’s existing parsing/profile behavior.

### Fix Focus Areas
- crates/flight-hotas-winwing/src/protocol.rs[523-596]
- crates/flight-hotas-winwing/src/lib.rs[4-21]
- crates/flight-hotas-winwing/src/f16ex_stick.rs[4-23]
- crates/flight-hotas-winwing/src/profiles.rs[254-265]

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

Copy link

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.

Pull request overview

Adds higher-level WinWing device support to flight-hotas-winwing by introducing PID-based device identification, batch-oriented LED/display feature-report builders, and a magnetic detent “snap” model for throttles.

Changes:

  • Add DeviceType + WinwingProtocol for PID-based identification and capability querying.
  • Introduce led_control batch APIs to build backlight/display feature reports from high-level commands.
  • Add detent_system with configurable magnetic detents and detection/snap behavior (with presets + tests).

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 7 comments.

File Description
crates/flight-hotas-winwing/src/protocol.rs Adds device-type detection/capabilities and a protocol wrapper; extends tests.
crates/flight-hotas-winwing/src/lib.rs Wires new modules and re-exports new detent/LED/protocol APIs.
crates/flight-hotas-winwing/src/led_control.rs New batch-oriented LED/display command API + tests.
crates/flight-hotas-winwing/src/detent_system.rs New magnetic detent configuration/detection logic + presets + tests.

Comment on lines +82 to +84
pub struct WinwingDetentConfig {
detents: Vec<MagneticDetent>,
}
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

WinwingDetentConfig naming is inconsistent with the crate’s existing WinWing* public types. Consider renaming to WinWingDetentConfig (and updating exports) to keep the public API consistent.

Copilot uses AI. Check for mistakes.
Comment on lines +44 to +57
pub fn contains(&self, value: f32) -> bool {
(value - self.centre).abs() <= self.snap_radius
}

/// Apply the magnetic detent effect to `value`.
///
/// If `value` is within the snap zone, it is pulled toward `centre`
/// by `strength`. If outside the zone, `value` is returned unchanged.
pub fn apply(&self, value: f32) -> f32 {
if !self.contains(value) {
return value;
}
let delta = self.centre - value;
value + delta * self.strength
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

MagneticDetent::contains will treat values outside the documented normalized range [0.0, 1.0] as inside the detent zone (e.g., negative values near an idle detent). That can lead to apply() producing out-of-range snapped values. Consider clamping value to [0.0, 1.0] (and possibly clamping the output of apply()), or updating the docs/tests to explicitly allow out-of-range inputs.

Suggested change
pub fn contains(&self, value: f32) -> bool {
(value - self.centre).abs() <= self.snap_radius
}
/// Apply the magnetic detent effect to `value`.
///
/// If `value` is within the snap zone, it is pulled toward `centre`
/// by `strength`. If outside the zone, `value` is returned unchanged.
pub fn apply(&self, value: f32) -> f32 {
if !self.contains(value) {
return value;
}
let delta = self.centre - value;
value + delta * self.strength
///
/// The input is clamped to the normalised `[0.0, 1.0]` range before
/// the containment check, so callers do not need to pre-clamp.
pub fn contains(&self, value: f32) -> bool {
let v = value.clamp(0.0, 1.0);
(v - self.centre).abs() <= self.snap_radius
}
/// Apply the magnetic detent effect to `value`.
///
/// If `value` is within the snap zone, it is pulled toward `centre`
/// by `strength`. If outside the zone, the (clamped) input is
/// returned unchanged. Both input and output are clamped to the
/// normalised `[0.0, 1.0]` range.
pub fn apply(&self, value: f32) -> f32 {
let clamped_in = value.clamp(0.0, 1.0);
if !self.contains(clamped_in) {
return clamped_in;
}
let delta = self.centre - clamped_in;
let snapped = clamped_in + delta * self.strength;
snapped.clamp(0.0, 1.0)

Copilot uses AI. Check for mistakes.
Comment on lines +49 to +55
pub fn build_led_report(commands: &[LedCommand]) -> Result<Vec<Vec<u8>>, ProtocolError> {
let mut reports = Vec::with_capacity(commands.len());
for cmd in commands {
let frame = match cmd {
LedCommand::SetIntensity {
panel_id,
button_index,
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

build_led_report re-encodes payload layouts that already exist as helpers in crate::protocol (e.g., build_backlight_single_command, build_backlight_all_rgb_command). Duplicating the encoding logic increases the chance of protocol drift; consider delegating to those existing builders and only handling the batch-to-Vec<Vec> conversion here.

Copilot uses AI. Check for mistakes.
Comment on lines +131 to +139
let truncated = if text.len() > 16 {
&text[..16]
} else {
text.as_str()
};
let mut payload = Vec::with_capacity(2 + truncated.len());
payload.push(*panel_id);
payload.push(*field_index);
payload.extend_from_slice(truncated.as_bytes());
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

&text[..16] slices by byte index on a String and will panic if text contains non-ASCII/multi-byte UTF-8 (even though the docs say ASCII). To avoid panics, truncate using text.as_bytes() (or validate text.is_ascii() and handle invalid input explicitly) rather than slicing the String by a hard-coded index.

Suggested change
let truncated = if text.len() > 16 {
&text[..16]
} else {
text.as_str()
};
let mut payload = Vec::with_capacity(2 + truncated.len());
payload.push(*panel_id);
payload.push(*field_index);
payload.extend_from_slice(truncated.as_bytes());
let bytes = text.as_bytes();
let truncated_bytes = if bytes.len() > 16 {
&bytes[..16]
} else {
bytes
};
let mut payload = Vec::with_capacity(2 + truncated_bytes.len());
payload.push(*panel_id);
payload.push(*field_index);
payload.extend_from_slice(truncated_bytes);

Copilot uses AI. Check for mistakes.
// ── Device identification ─────────────────────────────────────────────────────

/// WinWing USB Vendor ID (shared across all products).
pub const WINWING_VID: u16 = 0x4098;
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

WINWING_VID is now defined in this module, but the crate already defines WINWING_VID in src/lib.rs and WINWING_VENDOR_ID in src/input.rs (all 0x4098). Having multiple public constants for the same VID is likely to drift; consider removing this one and re-exporting/using the single canonical constant instead.

Suggested change
pub const WINWING_VID: u16 = 0x4098;
pub use crate::WINWING_VID;

Copilot uses AI. Check for mistakes.
Comment on lines +559 to +563
0xBD64 => Some(Self::SuperTaurus),
0xBEDE => Some(Self::F18Panel),
0xBEA8 => Some(Self::F16Panel),
0xBE64 => Some(Self::TfrpRudder),
0xBEF0 => Some(Self::SkywalkerRudder),
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

PID 0xBEA8 is mapped to DeviceType::F16Panel, and has_display() returns true for that type. Elsewhere in this crate 0xBEA8 is documented/parsed as the F-16EX Grip (10-byte report, no display), so this mapping/capability set appears incorrect and could misroute device handling. Consider renaming the variant and/or adjusting the PID mapping and has_display/has_leds capability flags to match the existing f16ex_stick device.

Copilot uses AI. Check for mistakes.
Comment on lines +628 to +633
pub struct WinwingProtocol {
device: DeviceType,
pid: u16,
}

impl WinwingProtocol {
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

Type name WinwingProtocol is inconsistent with the existing public API style in this crate (WinWingError, WinWingDevice, etc.). Consider renaming to WinWingProtocol for consistency before this becomes a stabilized public API.

Suggested change
pub struct WinwingProtocol {
device: DeviceType,
pid: u16,
}
impl WinwingProtocol {
pub struct WinWingProtocol {
device: DeviceType,
pid: u16,
}
impl WinWingProtocol {

Copilot uses AI. Check for mistakes.
EffortlessSteven and others added 2 commits March 1, 2026 00:05
- Fix PID 0xBEA8 mapping from F16Panel to F16ExGrip
- Clamp MagneticDetent inputs to [0.0, 1.0] range
- Fix text slicing panic on non-ASCII via as_bytes()
- Rename WinwingDetentConfig → WinWingDetentConfig
- Rename WinwingProtocol → WinWingProtocol
- Remove duplicate WINWING_VID constant
- Delegate LED encoding to protocol builders

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

CI Feedback 🧐

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

Action: Test Suite (windows-latest, stable)

Failed stage: Run tests [❌]

Failed test name: snapshot_alpha_yoke_full_right_roll

Failure summary:

The GitHub Action failed during cargo test --all-features --workspace --lib --tests --exclude
flight-hub-examples because an Insta snapshot test failed in the flight-hotas-honeycomb crate.

The specific failure was:
- Test snapshot_alpha_yoke_full_right_roll failed in
crates/flight-hotas-honeycomb/tests/snapshot_tests.rs:64 with an Insta snapshot mismatch for
snapshot alpha_yoke_full_right_roll.
- The snapshot diff shows the roll value changed from 1.0
(stored snapshot) to 0.9995117 (new result), causing the assertion to fail.
- The panic originates
from insta (insta-1.46.3/src/runtime.rs:719:13), and the overall test run exited with code 101.

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

170:  RUST_BACKTRACE: 1
171:  targets: 
172:  components: rustfmt, clippy
173:  ##[endgroup]
174:  ##[group]Run : set $CARGO_HOME
175:  �[36;1m: set $CARGO_HOME�[0m
176:  �[36;1mecho CARGO_HOME=${CARGO_HOME:-"$USERPROFILE\.cargo"} >> $GITHUB_ENV�[0m
177:  shell: C:\Program Files\Git\bin\bash.EXE --noprofile --norc -e -o pipefail {0}
178:  env:
179:  CARGO_TERM_COLOR: always
180:  RUST_BACKTRACE: 1
181:  ##[endgroup]
182:  ##[group]Run : install rustup if needed on windows
183:  �[36;1m: install rustup if needed on windows�[0m
184:  �[36;1mif ! command -v rustup &>/dev/null; then�[0m
185:  �[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
186:  �[36;1m  'D:\a\_temp\rustup-init.exe' --default-toolchain none --no-modify-path -y�[0m
...

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

443:  - D:\a\OpenFlight\OpenFlight\examples\Cargo.toml
444:  - D:\a\OpenFlight\OpenFlight\installer\Cargo.toml
445:  - D:\a\OpenFlight\OpenFlight\specs\Cargo.toml
446:  - D:\a\OpenFlight\OpenFlight\xtask\Cargo.toml
447:  ##[endgroup]
448:  ... Restoring cache ...
449:  No cache found.
450:  ##[group]Run cargo fmt --all -- --check
451:  �[36;1mcargo fmt --all -- --check�[0m
452:  shell: C:\Program Files\Git\bin\bash.EXE --noprofile --norc -e -o pipefail {0}
453:  env:
454:  CARGO_TERM_COLOR: always
455:  RUST_BACKTRACE: 1
456:  CARGO_HOME: C:\Users\runneradmin\.cargo
457:  CARGO_INCREMENTAL: 0
458:  CACHE_ON_FAILURE: false
459:  ##[endgroup]
460:  ##[group]Run cargo clippy --workspace --all-features --lib --tests --exclude flight-hub-examples
461:  �[36;1mcargo clippy --workspace --all-features --lib --tests --exclude flight-hub-examples�[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]
...

556:  �[1m�[92m  Downloaded�[0m unicase v2.9.0
557:  �[1m�[92m  Downloaded�[0m typetag v0.2.21
558:  �[1m�[92m  Downloaded�[0m typed-builder-macro v0.23.2
559:  �[1m�[92m  Downloaded�[0m typed-builder v0.23.2
560:  �[1m�[92m  Downloaded�[0m toml v0.9.12+spec-1.1.0
561:  �[1m�[92m  Downloaded�[0m toml v0.8.23
562:  �[1m�[92m  Downloaded�[0m tempfile v3.26.0
563:  �[1m�[92m  Downloaded�[0m synthez-core v0.4.0
564:  �[1m�[92m  Downloaded�[0m synstructure v0.13.2
565:  �[1m�[92m  Downloaded�[0m sync_wrapper v1.0.2
566:  �[1m�[92m  Downloaded�[0m spki v0.7.3
567:  �[1m�[92m  Downloaded�[0m smallvec v1.15.1
568:  �[1m�[92m  Downloaded�[0m slab v0.4.12
569:  �[1m�[92m  Downloaded�[0m simd-adler32 v0.3.8
570:  �[1m�[92m  Downloaded�[0m shlex v1.3.0
571:  �[1m�[92m  Downloaded�[0m serde_path_to_error v0.1.20
572:  �[1m�[92m  Downloaded�[0m semver v1.0.27
...

591:  �[1m�[92m  Downloaded�[0m typeid v1.0.3
592:  �[1m�[92m  Downloaded�[0m try-lock v0.2.5
593:  �[1m�[92m  Downloaded�[0m tower-service v0.3.3
594:  �[1m�[92m  Downloaded�[0m tonic-prost-build v0.14.5
595:  �[1m�[92m  Downloaded�[0m toml_write v0.1.2
596:  �[1m�[92m  Downloaded�[0m toml_parser v1.0.9+spec-1.1.0
597:  �[1m�[92m  Downloaded�[0m toml_datetime v0.7.5+spec-1.1.0
598:  �[1m�[92m  Downloaded�[0m toml_datetime v0.6.11
599:  �[1m�[92m  Downloaded�[0m tokio-stream v0.1.18
600:  �[1m�[92m  Downloaded�[0m tokio-rustls v0.26.4
601:  �[1m�[92m  Downloaded�[0m tinyvec v1.10.0
602:  �[1m�[92m  Downloaded�[0m tinytemplate v1.2.1
603:  �[1m�[92m  Downloaded�[0m time-macros v0.2.27
604:  �[1m�[92m  Downloaded�[0m time-core v0.1.8
605:  �[1m�[92m  Downloaded�[0m thread_local v1.1.9
606:  �[1m�[92m  Downloaded�[0m thiserror-impl v2.0.18
607:  �[1m�[92m  Downloaded�[0m thiserror v2.0.18
608:  �[1m�[92m  Downloaded�[0m terminal_size v0.4.3
...

631:  �[1m�[92m  Downloaded�[0m tokio-tungstenite v0.28.0
632:  �[1m�[92m  Downloaded�[0m tokio-test v0.4.5
633:  �[1m�[92m  Downloaded�[0m windows-sys v0.61.2
634:  �[1m�[92m  Downloaded�[0m windows-sys v0.60.2
635:  �[1m�[92m  Downloaded�[0m tinyvec_macros v0.1.1
636:  �[1m�[92m  Downloaded�[0m tinystr v0.8.2
637:  �[1m�[92m  Downloaded�[0m same-file v1.0.6
638:  �[1m�[92m  Downloaded�[0m ryu v1.0.23
639:  �[1m�[92m  Downloaded�[0m rusty-fork v0.3.1
640:  �[1m�[92m  Downloaded�[0m rustls-native-certs v0.8.3
641:  �[1m�[92m  Downloaded�[0m rustc_version v0.4.1
642:  �[1m�[92m  Downloaded�[0m rustc-hash v2.1.1
643:  �[1m�[92m  Downloaded�[0m rust-multipart-rfc7578_2 v0.8.0
644:  �[1m�[92m  Downloaded�[0m ring v0.17.14
645:  �[1m�[92m  Downloaded�[0m rand_core v0.9.5
646:  �[1m�[92m  Downloaded�[0m quick-error v1.2.3
647:  �[1m�[92m  Downloaded�[0m protoc-bin-vendored v3.2.0
...

881:  �[1m�[92m  Downloaded�[0m futures-core v0.3.32
882:  �[1m�[92m  Downloaded�[0m displaydoc v0.2.5
883:  �[1m�[92m  Downloaded�[0m borrow-or-share v0.2.4
884:  �[1m�[92m  Downloaded�[0m atomic_enum v0.3.0
885:  �[1m�[92m  Downloaded�[0m approx v0.5.1
886:  �[1m�[92m  Downloaded�[0m anyhow v1.0.102
887:  �[1m�[92m  Downloaded�[0m anstyle v1.0.13
888:  �[1m�[92m  Downloaded�[0m windows v0.62.2
889:  �[1m�[92m Downloading�[0m crates ...
890:  �[1m�[92m  Downloaded�[0m nix v0.31.2
891:  �[1m�[92m   Compiling�[0m proc-macro2 v1.0.106
892:  �[1m�[92m   Compiling�[0m quote v1.0.44
893:  �[1m�[92m   Compiling�[0m unicode-ident v1.0.24
894:  �[1m�[92m   Compiling�[0m serde_core v1.0.228
895:  �[1m�[92m   Compiling�[0m serde v1.0.228
896:  �[1m�[92m   Compiling�[0m thiserror v2.0.18
897:  �[1m�[92m   Compiling�[0m getrandom v0.3.4
...

911:  �[1m�[92m    Checking�[0m pin-project-lite v0.2.17
912:  �[1m�[92m   Compiling�[0m version_check v0.9.5
913:  �[1m�[92m    Checking�[0m log v0.4.29
914:  �[1m�[92m    Checking�[0m tracing-core v0.1.36
915:  �[1m�[92m   Compiling�[0m typenum v1.19.0
916:  �[1m�[92m   Compiling�[0m generic-array v0.14.7
917:  �[1m�[92m    Checking�[0m fnv v1.0.7
918:  �[1m�[92m    Checking�[0m regex-syntax v0.8.10
919:  �[1m�[92m    Checking�[0m rand_core v0.9.5
920:  �[1m�[92m    Checking�[0m fastrand v2.3.0
921:  �[1m�[92m    Checking�[0m bitflags v2.11.0
922:  �[1m�[92m    Checking�[0m memchr v2.8.0
923:  �[1m�[92m    Checking�[0m bit-vec v0.8.0
924:  �[1m�[92m    Checking�[0m wait-timeout v0.2.1
925:  �[1m�[92m    Checking�[0m bit-set v0.8.0
926:  �[1m�[92m    Checking�[0m quick-error v1.2.3
927:  �[1m�[92m    Checking�[0m rand_xorshift v0.4.0
928:  �[1m�[92m    Checking�[0m unarray v0.1.4
929:  �[1m�[92m    Checking�[0m itoa v1.0.17
930:  �[1m�[92m   Compiling�[0m anyhow v1.0.102
931:  �[1m�[92m   Compiling�[0m crossbeam-utils v0.8.21
932:  �[1m�[92m    Checking�[0m windows-targets v0.53.5
933:  �[1m�[92m    Checking�[0m windows-sys v0.60.2
934:  �[1m�[92m   Compiling�[0m semver v1.0.27
935:  �[1m�[92m   Compiling�[0m rustc_version v0.4.1
936:  �[1m�[92m    Checking�[0m tempfile v3.26.0
937:  �[1m�[92m    Checking�[0m bytes v1.11.1
938:  �[1m�[92m   Compiling�[0m serde_derive v1.0.228
939:  �[1m�[92m   Compiling�[0m thiserror-impl v2.0.18
940:  �[1m�[92m   Compiling�[0m tracing-attributes v0.1.31
...

1174:  �[1m�[92m   Compiling�[0m protoc-bin-vendored-linux-x86_32 v3.2.0
1175:  �[1m�[92m   Compiling�[0m protoc-bin-vendored-linux-x86_64 v3.2.0
1176:  �[1m�[92m   Compiling�[0m protoc-bin-vendored-macos-x86_64 v3.2.0
1177:  �[1m�[92m   Compiling�[0m protoc-bin-vendored-win32 v3.2.0
1178:  �[1m�[92m   Compiling�[0m protoc-bin-vendored-linux-aarch_64 v3.2.0
1179:  �[1m�[92m   Compiling�[0m protoc-bin-vendored-linux-s390_64 v3.2.0
1180:  �[1m�[92m   Compiling�[0m protoc-bin-vendored-linux-ppcle_64 v3.2.0
1181:  �[1m�[92m   Compiling�[0m protoc-bin-vendored-macos-aarch_64 v3.2.0
1182:  �[1m�[92m   Compiling�[0m protoc-bin-vendored v3.2.0
1183:  �[1m�[92m    Checking�[0m tracing-subscriber v0.3.22
1184:  �[1m�[92m   Compiling�[0m tonic-prost-build v0.14.5
1185:  �[1m�[92m    Checking�[0m tokio-tungstenite v0.28.0
1186:  �[1m�[92m    Checking�[0m axum-core v0.5.6
1187:  �[1m�[92m    Checking�[0m serde_urlencoded v0.7.1
1188:  �[1m�[92m    Checking�[0m futures-executor v0.3.32
1189:  �[1m�[92m    Checking�[0m serde_path_to_error v0.1.20
1190:  �[1m�[92m    Checking�[0m matchit v0.8.4
...

1462:  �[1m�[96m--> �[0mcrates\flight-watchdog\src\lib.rs:1134:9
1463:  �[1m�[96m|�[0m
1464:  �[1m�[96m1134�[0m �[1m�[96m|�[0m         config.enable_nan_guards = true;
1465:  �[1m�[96m|�[0m         �[1m�[93m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^�[0m
1466:  �[1m�[96m|�[0m
1467:  �[1m�[92mnote�[0m: consider initializing the variable with `WatchdogConfig { enable_nan_guards: true, ..Default::default() }` and removing relevant reassignments
1468:  �[1m�[96m--> �[0mcrates\flight-watchdog\src\lib.rs:1133:9
1469:  �[1m�[96m|�[0m
1470:  �[1m�[96m1133�[0m �[1m�[96m|�[0m         let mut config = WatchdogConfig::default();
1471:  �[1m�[96m|�[0m         �[1m�[92m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^�[0m
1472:  �[1m�[96m= �[0m�[1m�[97mhelp�[0m: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#field_reassign_with_default
1473:  �[1m�[96m= �[0m�[1m�[97mnote�[0m: `#[warn(clippy::field_reassign_with_default)]` on by default
1474:  �[1m�[93mwarning�[0m�[1m�[97m: field assignment outside of initializer for an instance created with Default::default()�[0m
1475:  �[1m�[96m--> �[0mcrates\flight-watchdog\src\lib.rs:1158:9
1476:  �[1m�[96m|�[0m
1477:  �[1m�[96m1158�[0m �[1m�[96m|�[0m         config.max_consecutive_failures = 2; // Lower threshold for testing
1478:  �[1m�[96m|�[0m         �[1m�[93m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^�[0m
1479:  �[1m�[96m|�[0m
1480:  �[1m�[92mnote�[0m: consider initializing the variable with `WatchdogConfig { max_consecutive_failures: 2, ..Default::default() }` and removing relevant reassignments
1481:  �[1m�[96m--> �[0mcrates\flight-watchdog\src\lib.rs:1157:9
...

1599:  �[1m�[93mwarning�[0m: `flight-axis` (test "detent_integration") generated 9 warnings
1600:  �[1m�[93mwarning[E0133]�[0m�[1m�[97m: call to unsafe function `flight_axis::Node::step_soa` is unsafe and requires unsafe block�[0m
1601:  �[1m�[96m--> �[0mcrates\flight-axis\tests\detent_tests.rs:25:5
1602:  �[1m�[96m|�[0m
1603:  �[1m�[96m25�[0m �[1m�[96m|�[0m     node.step_soa(frame, state_ptr);
1604:  �[1m�[96m|�[0m     �[1m�[93m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^�[0m �[1m�[93mcall to unsafe function�[0m
1605:  �[1m�[96m|�[0m
1606:  �[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>
1607:  �[1m�[96m= �[0m�[1m�[97mnote�[0m: consult the function's documentation for information on how to avoid undefined behavior
1608:  �[1m�[92mnote�[0m: an unsafe function restricts its caller, but its body is safe by default
1609:  �[1m�[96m--> �[0mcrates\flight-axis\tests\detent_tests.rs:23:1
1610:  �[1m�[96m|�[0m
1611:  �[1m�[96m23�[0m �[1m�[96m|�[0m unsafe fn process_frame_soa(node: &DetentNode, frame: &mut AxisFrame, state: &mut DetentState) {
1612:  �[1m�[96m|�[0m �[1m�[92m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^�[0m
1613:  �[1m�[96m= �[0m�[1m�[97mnote�[0m: `#[warn(unsafe_op_in_unsafe_fn)]` (part of `#[warn(rust_2024_compatibility)]`) on by default
1614:  �[1m�[97mFor more information about this error, try `rustc --explain E0133`.�[0m
1615:  �[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)
...

1809:  �[1m�[96m--> �[0mcrates\flight-core\src\lib.rs:131:30
1810:  �[1m�[96m|�[0m
1811:  �[1m�[96m131�[0m �[1m�[96m|�[0m         let r: Result<u32> = Ok(42);
1812:  �[1m�[96m|�[0m                              �[1m�[96m^^^^^^�[0m
1813:  �[1m�[96m= �[0m�[1m�[97mhelp�[0m: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.93.0/index.html#unnecessary_literal_unwrap
1814:  �[1m�[96m= �[0m�[1m�[97mnote�[0m: `#[warn(clippy::unnecessary_literal_unwrap)]` on by default
1815:  �[1m�[93mwarning�[0m�[1m�[97m: used `unwrap_err()` on `Err` value�[0m
1816:  �[1m�[96m--> �[0mcrates\flight-core\src\lib.rs:136:17
1817:  �[1m�[96m|�[0m
1818:  �[1m�[96m136�[0m �[1m�[96m|�[0m         assert!(e.unwrap_err().to_string().contains("Rules validation"));
1819:  �[1m�[96m|�[0m                 �[1m�[93m^^^^^^^^^^^^^^�[0m
1820:  �[1m�[96m|�[0m
1821:  �[1m�[96mhelp�[0m: remove the `Err` and `unwrap_err()`
1822:  �[1m�[96m--> �[0mcrates\flight-core\src\lib.rs:134:30
1823:  �[1m�[96m|�[0m
1824:  �[1m�[96m134�[0m �[1m�[96m|�[0m         let e: Result<u32> = Err(FlightError::RulesValidation("bad rule".to_string()));
1825:  �[1m�[96m|�[0m                              �[1m�[96m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^�[0m
...

2179:  �[36;1m# Apply strict warnings to core crates that must maintain high quality�[0m
2180:  �[36;1mcargo clippy -p flight-core --lib -- $STRICT_FLAGS�[0m
2181:  �[36;1mcargo clippy -p flight-axis --lib -- $STRICT_FLAGS�[0m
2182:  �[36;1mcargo clippy -p flight-bus --lib -- $STRICT_FLAGS�[0m
2183:  �[36;1mcargo clippy -p flight-hid --lib -- $STRICT_FLAGS�[0m
2184:  �[36;1mcargo clippy -p flight-ipc --lib -- $STRICT_FLAGS�[0m
2185:  �[36;1mcargo clippy -p flight-service --lib -- $STRICT_FLAGS�[0m
2186:  �[36;1mcargo clippy -p flight-simconnect --lib -- $STRICT_FLAGS�[0m
2187:  �[36;1mcargo clippy -p flight-panels --lib -- $STRICT_FLAGS�[0m
2188:  shell: C:\Program Files\Git\bin\bash.EXE --noprofile --norc -e -o pipefail {0}
2189:  env:
2190:  CARGO_TERM_COLOR: always
2191:  RUST_BACKTRACE: 1
2192:  CARGO_HOME: C:\Users\runneradmin\.cargo
2193:  CARGO_INCREMENTAL: 0
2194:  CACHE_ON_FAILURE: false
2195:  ##[endgroup]
...

2203:  �[1m�[92m   Compiling�[0m num-traits v0.2.19
2204:  �[1m�[92m    Checking�[0m crossbeam-epoch v0.9.18
2205:  �[1m�[92m    Checking�[0m aho-corasick v1.1.4
2206:  �[1m�[92m    Checking�[0m mio v1.1.1
2207:  �[1m�[92m    Checking�[0m hashbrown v0.16.1
2208:  �[1m�[92m    Checking�[0m regex-automata v0.4.14
2209:  �[1m�[92m    Checking�[0m indexmap v2.13.0
2210:  �[1m�[92m    Checking�[0m crossbeam-deque v0.8.6
2211:  �[1m�[92m    Checking�[0m crossbeam-channel v0.5.15
2212:  �[1m�[92m    Checking�[0m crossbeam-queue v0.3.12
2213:  �[1m�[92m    Checking�[0m tempfile v3.26.0
2214:  �[1m�[92m    Checking�[0m crossbeam v0.8.4
2215:  �[1m�[92m    Checking�[0m flight-metrics v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-metrics)
2216:  �[1m�[92m    Checking�[0m regex v1.12.3
2217:  �[1m�[92m   Compiling�[0m serde_derive v1.0.228
2218:  �[1m�[92m   Compiling�[0m thiserror-impl v2.0.18
2219:  �[1m�[92m   Compiling�[0m tracing-attributes v0.1.31
2220:  �[1m�[92m   Compiling�[0m windows-interface v0.59.3
2221:  �[1m�[92m   Compiling�[0m windows-implement v0.60.2
2222:  �[1m�[92m    Checking�[0m thiserror v2.0.18
2223:  �[1m�[92m    Checking�[0m tracing v0.1.44
...

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

2532:  �[1m�[92m   Compiling�[0m chrono v0.4.44
2533:  �[1m�[92m   Compiling�[0m flight-process-detection v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-process-detection)
2534:  �[1m�[92m   Compiling�[0m flight-profile v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-profile)
2535:  �[1m�[92m   Compiling�[0m hex v0.4.3
2536:  �[1m�[92m   Compiling�[0m flight-security v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-security)
2537:  �[1m�[92m   Compiling�[0m ppv-lite86 v0.2.21
2538:  �[1m�[92m   Compiling�[0m flight-session v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-session)
2539:  �[1m�[92m   Compiling�[0m toml v0.8.23
2540:  �[1m�[92m   Compiling�[0m flight-blackbox v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-blackbox)
2541:  �[1m�[92m   Compiling�[0m flight-writers v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-writers)
2542:  �[1m�[92m   Compiling�[0m windows-sys v0.59.0
2543:  �[1m�[92m   Compiling�[0m flight-watchdog v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-watchdog)
2544:  �[1m�[92m   Compiling�[0m flight-rules v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-rules)
2545:  �[1m�[92m   Compiling�[0m flight-units v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-units)
2546:  �[1m�[92m   Compiling�[0m bit-vec v0.8.0
2547:  �[1m�[92m   Compiling�[0m quick-error v1.2.3
2548:  �[1m�[92m   Compiling�[0m wait-timeout v0.2.1
...

2558:  �[1m�[92m   Compiling�[0m hidapi v2.6.5
2559:  �[1m�[92m   Compiling�[0m rand_chacha v0.9.0
2560:  �[1m�[92m   Compiling�[0m rand_xorshift v0.4.0
2561:  �[1m�[92m   Compiling�[0m rand v0.9.2
2562:  �[1m�[92m   Compiling�[0m similar v2.7.0
2563:  �[1m�[92m   Compiling�[0m unarray v0.1.4
2564:  �[1m�[92m   Compiling�[0m bitflags v2.11.0
2565:  �[1m�[92m   Compiling�[0m flight-hid v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-hid)
2566:  �[1m�[92m   Compiling�[0m proptest v1.10.0
2567:  �[1m�[92m   Compiling�[0m insta v1.46.3
2568:  �[1m�[92m    Finished�[0m `test` profile [unoptimized + debuginfo] target(s) in 57.00s
2569:  �[1m�[92m     Running�[0m unittests src\lib.rs (target\debug\deps\flight_hid-792612c870e3f2a7.exe)
2570:  running 2 tests
2571:  test fd_safety_tests::clippy_config::test_fd_usage_examples ... ok
2572:  test fd_safety_tests::windows_tests::test_typed_handle_usage ... ok
2573:  test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 200 filtered out; finished in 0.00s
2574:  �[1m�[92m     Running�[0m tests\integration.rs (target\debug\deps\integration-ceeb865f425a7849.exe)
2575:  running 0 tests
2576:  test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 14 filtered out; finished in 0.00s
2577:  �[1m�[92m     Running�[0m tests\proptest_axis_calibration.rs (target\debug\deps\proptest_axis_calibration-d622df6fe5b9260f.exe)
2578:  running 0 tests
2579:  test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 13 filtered out; finished in 0.00s
2580:  �[1m�[92m     Running�[0m tests\snapshots.rs (target\debug\deps\snapshots-0e50c6c6cba33881.exe)
2581:  running 0 tests
2582:  test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 5 filtered out; finished in 0.00s
2583:  �[1m�[92m   Compiling�[0m windows-sys v0.61.2
...

2702:  �[1m�[92m   Compiling�[0m plotters v0.3.7
2703:  �[1m�[92m   Compiling�[0m matchers v0.2.0
2704:  �[1m�[92m   Compiling�[0m tinytemplate v1.2.1
2705:  �[1m�[92m   Compiling�[0m thread_local v1.1.9
2706:  �[1m�[92m   Compiling�[0m oorandom v11.1.5
2707:  �[1m�[92m   Compiling�[0m anes v0.1.6
2708:  �[1m�[92m   Compiling�[0m proptest v1.10.0
2709:  �[1m�[92m   Compiling�[0m tracing-subscriber v0.3.22
2710:  �[1m�[92m   Compiling�[0m criterion v0.8.2
2711:  �[1m�[92m   Compiling�[0m tokio-test v0.4.5
2712:  �[1m�[92m    Finished�[0m `test` profile [unoptimized + debuginfo] target(s) in 1m 18s
2713:  �[1m�[92m     Running�[0m unittests src\lib.rs (target\debug\deps\flight_ipc-74ce1c29e103cca3.exe)
2714:  running 2 tests
2715:  test fd_safety_tests::fd_usage_examples::test_ipc_fd_usage_examples ... ok
2716:  test fd_safety_tests::windows_tests::test_typed_handle_usage_ipc ... ok
2717:  test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 171 filtered out; finished in 0.00s
2718:  �[1m�[92m     Running�[0m tests\grpc_tests.rs (target\debug\deps\grpc_tests-266f830c155c7b5c.exe)
2719:  running 0 tests
2720:  test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 21 filtered out; finished in 0.00s
2721:  �[1m�[92m     Running�[0m tests\ipc_fuzz_tests.rs (target\debug\deps\ipc_fuzz_tests-ecd20f41a7f303f9.exe)
2722:  running 0 tests
2723:  test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 5 filtered out; finished in 0.00s
2724:  �[1m�[92m     Running�[0m tests\proto_tests.rs (target\debug\deps\proto_tests-63614f4c2286312e.exe)
2725:  running 0 tests
2726:  test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 25 filtered out; finished in 0.00s
2727:  �[1m�[92m   Compiling�[0m windows-link v0.2.1
...

2730:  �[1m�[92m   Compiling�[0m serde v1.0.228
2731:  �[1m�[92m   Compiling�[0m windows-sys v0.61.2
2732:  �[1m�[92m   Compiling�[0m cc v1.2.56
2733:  �[1m�[92m   Compiling�[0m pin-project-lite v0.2.17
2734:  �[1m�[92m   Compiling�[0m serde_core v1.0.228
2735:  �[1m�[92m   Compiling�[0m num-traits v0.2.19
2736:  �[1m�[92m   Compiling�[0m once_cell v1.21.3
2737:  �[1m�[92m   Compiling�[0m memchr v2.8.0
2738:  �[1m�[92m   Compiling�[0m bytes v1.11.1
2739:  �[1m�[92m   Compiling�[0m itoa v1.0.17
2740:  �[1m�[92m   Compiling�[0m tracing v0.1.44
2741:  �[1m�[92m   Compiling�[0m windows_x86_64_msvc v0.53.1
2742:  �[1m�[92m   Compiling�[0m windows-targets v0.53.5
2743:  �[1m�[92m   Compiling�[0m tracing-core v0.1.36
2744:  �[1m�[92m   Compiling�[0m windows-sys v0.60.2
2745:  �[1m�[92m   Compiling�[0m thiserror v2.0.18
2746:  �[1m�[92m   Compiling�[0m stable_deref_trait v1.2.1
...

2862:  �[1m�[92m   Compiling�[0m icu_properties_data v2.1.2
2863:  �[1m�[92m   Compiling�[0m icu_normalizer_data v2.1.1
2864:  �[1m�[92m   Compiling�[0m flight-simconnect-sys v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-simconnect-sys)
2865:  �[1m�[92m   Compiling�[0m ryu v1.0.23
2866:  �[1m�[92m   Compiling�[0m untrusted v0.9.0
2867:  �[1m�[92m   Compiling�[0m icu_normalizer v2.1.1
2868:  �[1m�[92m   Compiling�[0m icu_properties v2.1.2
2869:  �[1m�[92m   Compiling�[0m tonic-prost-build v0.14.5
2870:  �[1m�[92m   Compiling�[0m http-body-util v0.1.3
2871:  �[1m�[92m   Compiling�[0m subtle v2.6.1
2872:  �[1m�[92m   Compiling�[0m flight-ipc v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-ipc)
2873:  �[1m�[92m   Compiling�[0m idna_adapter v1.2.1
2874:  �[1m�[92m   Compiling�[0m axum-core v0.5.6
2875:  �[1m�[92m   Compiling�[0m serde_urlencoded v0.7.1
2876:  �[1m�[92m   Compiling�[0m num-integer v0.1.46
2877:  �[1m�[92m   Compiling�[0m serde_path_to_error v0.1.20
2878:  �[1m�[92m   Compiling�[0m utf8_iter v1.0.4
...

2954:  �[1m�[92m   Compiling�[0m flight-hotas-vkb v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-hotas-vkb)
2955:  �[1m�[92m   Compiling�[0m matchers v0.2.0
2956:  �[1m�[92m   Compiling�[0m thread_local v1.1.9
2957:  �[1m�[92m   Compiling�[0m reserve-port v2.3.0
2958:  �[1m�[92m   Compiling�[0m bytesize v2.3.1
2959:  �[1m�[92m   Compiling�[0m unsafe-libyaml v0.2.11
2960:  �[1m�[92m   Compiling�[0m axum-test v18.7.0
2961:  �[1m�[92m   Compiling�[0m serde_yaml_ng v0.10.0
2962:  �[1m�[92m   Compiling�[0m tokio-test v0.4.5
2963:  �[1m�[92m   Compiling�[0m flight-service v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-service)
2964:  �[1m�[92m    Finished�[0m `test` profile [unoptimized + debuginfo] target(s) in 3m 22s
2965:  �[1m�[92m     Running�[0m unittests src\lib.rs (target\debug\deps\flight_service-4ab2f4b8e4e41e8c.exe)
2966:  running 2 tests
2967:  test fd_safety_tests::fd_usage_examples::test_service_fd_usage_examples ... ok
2968:  test fd_safety_tests::windows_tests::test_service_system_handle_safety ... ok
2969:  test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 408 filtered out; finished in 0.00s
2970:  �[1m�[92m     Running�[0m unittests src\main.rs (target\debug\deps\flightd-f11122a588484984.exe)
2971:  running 0 tests
2972:  test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
2973:  �[1m�[92m     Running�[0m tests\service_integration.rs (target\debug\deps\service_integration-3c0df996be52184c.exe)
2974:  running 0 tests
2975:  test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 9 filtered out; finished in 0.00s
2976:  �[1m�[92m     Running�[0m tests\service_integration_tests.rs (target\debug\deps\service_integration_tests-c9478996da6b3000.exe)
2977:  running 0 tests
2978:  test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 11 filtered out; finished in 0.00s
2979:  ##[group]Run echo "🔍 Verifying critical patterns are fixed..."
...

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

3158:  �[1m�[92m   Compiling�[0m flight-hotas-ch v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-hotas-ch)
3159:  �[1m�[92m   Compiling�[0m flight-hotas-logitech v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-hotas-logitech)
3160:  �[1m�[92m   Compiling�[0m flight-hotas-virpil v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-hotas-virpil)
3161:  �[1m�[92m   Compiling�[0m flight-hotas-honeycomb v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-hotas-honeycomb)
3162:  �[1m�[92m   Compiling�[0m flight-hotas-vpforce v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-hotas-vpforce)
3163:  �[1m�[92m   Compiling�[0m flight-hotas-saitek v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-hotas-saitek)
3164:  �[1m�[92m   Compiling�[0m flight-hotas-brunner v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-hotas-brunner)
3165:  �[1m�[92m   Compiling�[0m crossbeam-utils v0.8.21
3166:  �[1m�[92m   Compiling�[0m flight-integration-tests v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-integration-tests)
3167:  �[1m�[92m   Compiling�[0m num-integer v0.1.46
3168:  �[1m�[92m   Compiling�[0m crossbeam-epoch v0.9.18
3169:  �[1m�[92m   Compiling�[0m crossbeam-deque v0.8.6
3170:  �[1m�[92m   Compiling�[0m num-bigint v0.4.6
3171:  �[1m�[92m   Compiling�[0m crossbeam-channel v0.5.15
3172:  �[1m�[92m   Compiling�[0m crossbeam-queue v0.3.12
3173:  �[1m�[92m   Compiling�[0m quick-error v1.2.3
3174:  �[1m�[92m   Compiling�[0m wait-timeout v0.2.1
...

3390:  �[1m�[93mwarning[E0133]�[0m�[1m�[97m: call to unsafe function `flight_axis::Node::step_soa` is unsafe and requires unsafe block�[0m
3391:  �[1m�[96m--> �[0mcrates\flight-axis\tests\detent_tests.rs:25:5
3392:  �[1m�[96m|�[0m
3393:  �[1m�[96m25�[0m �[1m�[96m|�[0m     node.step_soa(frame, state_ptr);
3394:  �[1m�[96m|�[0m     �[1m�[93m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^�[0m �[1m�[93mcall to unsafe function�[0m
3395:  �[1m�[96m|�[0m
3396:  �[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>
3397:  �[1m�[96m= �[0m�[1m�[97mnote�[0m: consult the function's documentation for information on how to avoid undefined behavior
3398:  �[1m�[92mnote�[0m: an unsafe function restricts its caller, but its body is safe by default
3399:  �[1m�[96m--> �[0mcrates\flight-axis\tests\detent_tests.rs:23:1
3400:  �[1m�[96m|�[0m
3401:  �[1m�[96m23�[0m �[1m�[96m|�[0m unsafe fn process_frame_soa(node: &DetentNode, frame: &mut AxisFrame, state: &mut DetentState) {
3402:  �[1m�[96m|�[0m �[1m�[92m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^�[0m
3403:  �[1m�[96m= �[0m�[1m�[97mnote�[0m: `#[warn(unsafe_op_in_unsafe_fn)]` (part of `#[warn(rust_2024_compatibility)]`) on by default
3404:  �[1m�[92m   Compiling�[0m flight-elite v0.1.0 (D:\a\OpenFlight\OpenFlight\crates\flight-elite)
3405:  �[1m�[97mFor more information about this error, try `rustc --explain E0133`.�[0m
3406:  �[1m�[93mwarning�[0m: `flight-axis` (test "detent_tests") generated 1 warning (run `cargo fix --test "detent_tests" -p flight-axis` to apply 1 suggestion)
...

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

3570:  test accumulator::tests::test_reset_to_zero ... ok
3571:  test accumulator::tests::test_scale_factor ... ok
3572:  test accumulator::tests::test_wrap_negative ... ok
3573:  test accumulator::tests::test_wrap_positive ... ok
3574:  test blackbox::tests::test_annotator_creation ... ok
3575:  test blackbox::tests::test_conflict_data_conversion ... ok
3576:  test blackbox::tests::test_disabled_annotation ... ok
3577:  test blackbox::tests::test_buffer_flush ... ok
3578:  test blackbox::tests::test_conflict_annotation ... ok
3579:  test blackbox::tests::test_disabled_annotator ... ok
3580:  test blackbox::tests::test_resolution_annotation ... ok
3581:  test buttons::tests::test_axis_offset_action ... ok
3582:  test buttons::tests::test_axis_set_action ... ok
3583:  test buttons::tests::test_chord_partial_press_no_fire ... ok
3584:  test buttons::tests::test_chord_requires_all_buttons ... ok
3585:  test buttons::tests::test_chord_too_many_buttons_error ... ok
3586:  test buttons::tests::test_clear_removes_all_macros ... ok
3587:  test buttons::tests::test_duplicate_button_error ... ok
3588:  test buttons::tests::test_empty_chord_error ... ok
3589:  test buttons::tests::test_hold_repeats_at_interval ... ok
...

3612:  test calibration::tests::test_calbank_insert_and_get ... ok
3613:  test calibration::tests::test_calbank_unknown_axis_uses_default ... ok
3614:  test buttons::tests::proptest_output_count_never_exceeds_8 ... ok
3615:  test calibration::tests::test_normalize_8bit ... ok
3616:  test calibration::tests::test_normalize_above_deadband ... ok
3617:  test calibration::tests::test_normalize_center_is_zero ... ok
3618:  test calibration::tests::test_normalize_clamped_above_max ... ok
3619:  test calibration::tests::test_normalize_clamped_below_min ... ok
3620:  test calibration::tests::test_normalize_deadband_near_center ... ok
3621:  test calibration::tests::test_normalize_max_is_one ... ok
3622:  test calibration::tests::test_normalize_midpoint_above_center ... ok
3623:  test calibration::tests::test_normalize_midpoint_below_center ... ok
3624:  test calibration::tests::test_normalize_min_equals_max ... ok
3625:  test calibration::tests::test_normalize_virpil_14bit ... ok
3626:  test calibration::tests::test_normalize_min_is_neg_one ... ok
3627:  test calibration_wizard::tests::center_detection_noisy_fails ... ok
3628:  test calibration_wizard::tests::center_detection_stable_succeeds ... ok
3629:  test calibration_wizard::tests::complete_produces_result ... ok
3630:  test calibration_wizard::tests::deadzone_recommends_value ... ok
3631:  test calibration_wizard::tests::initial_state_is_not_started ... ok
3632:  test calibration_wizard::tests::progress_increases_through_steps ... ok
3633:  test calibration_wizard::tests::reset_returns_to_not_started ... ok
3634:  test calibration_wizard::tests::samples_ignored_in_terminal_states ... ok
3635:  test calibration_wizard::tests::start_transitions_to_center_detection ... ok
3636:  test calibration_wizard::tests::sweep_detects_full_range ... ok
3637:  test calibration_wizard::tests::sweep_insufficient_range_fails ... ok
3638:  test calibration_wizard::tests::timeout_fails_center_detection ... ok
3639:  test calibration_wizard::tests::verification_fails_non_monotonic ... ok
3640:  test calibration_wizard::tests::verification_passes_linear ... ok
...

3729:  test curve::tests::test_expo_negative_increases_center_sensitivity ... ok
3730:  test curve::tests::test_expo_one_input_maps_to_one ... ok
3731:  test curve::tests::test_expo_positive_reduces_center_sensitivity ... ok
3732:  test curve::tests::test_expo_zero_input_maps_to_zero ... ok
3733:  test curve::tests::test_expo_zero_is_linear ... ok
3734:  test curve::tests::test_is_monotone_identity ... ok
3735:  test curve::tests::test_linear_identity_constructor ... ok
3736:  test curve::tests::test_linear_identity_evaluates_x ... ok
3737:  test curve::tests::prop_output_always_in_range ... ok
3738:  test curve::tests::test_linear_identity_one ... ok
3739:  test curve::tests::test_linear_identity_zero ... ok
3740:  test curve::tests::test_linear_interpolation_midpoint ... ok
3741:  test curve::tests::test_monotone_cubic_identity ... ok
3742:  test curve::tests::test_monotone_cubic_preserves_monotone ... ok
3743:  test curve::tests::test_standard_deadzone_expo_curve ... ok
3744:  test curve::tests::test_too_few_points_error ... ok
3745:  test curve::tests::test_unsorted_points_error ... ok
3746:  test deadzone::tests::prop_antisymmetric ... ok
...

3752:  test deadzone::tests::test_asymmetric_negative_deadzone ... ok
3753:  test deadzone::tests::test_asymmetric_positive_deadzone ... ok
3754:  test deadzone::tests::test_asymmetric_symmetric_matches_center_only ... ok
3755:  test deadzone::tests::test_asymmetric_zero_positive_passes_positive ... ok
3756:  test deadzone::tests::test_bank_apply ... ok
3757:  test deadzone::tests::test_bank_set_config ... ok
3758:  test deadzone::tests::test_center_deadzone_full_deflection ... ok
3759:  test deadzone::tests::test_center_deadzone_negative ... ok
3760:  test deadzone::tests::test_center_deadzone_outside_zone ... ok
3761:  test deadzone::tests::test_center_deadzone_within_zone ... ok
3762:  test deadzone::tests::test_clamp_above_one ... ok
3763:  test deadzone::tests::test_clamp_below_neg_one ... ok
3764:  test deadzone::tests::test_combined_center_and_edge ... ok
3765:  test deadzone::tests::test_edge_deadzone_below ... ok
3766:  test deadzone::tests::test_edge_deadzone_saturation ... ok
3767:  test deadzone::tests::test_invalid_center_error ... ok
3768:  test deadzone::tests::test_overlap_error ... ok
3769:  test deadzone::tests::test_zero_deadzone_passthrough ... ok
...

3891:  test invert::tests::test_invert_disabled_passthrough ... ok
3892:  test invert::tests::test_invert_enabled_negates ... ok
3893:  test invert::tests::test_invert_negative_one ... ok
3894:  test invert::tests::test_invert_positive_one ... ok
3895:  test invert::tests::test_invert_toggle ... ok
3896:  test invert::tests::test_invert_zero_unchanged ... ok
3897:  test lag_compensator::tests::first_sample_passes_through ... ok
3898:  test lag_compensator::tests::max_prediction_clamped ... ok
3899:  test lag_compensator::tests::moving_axis_is_predicted_ahead ... ok
3900:  test lag_compensator::tests::nan_passes_through_unchanged ... ok
3901:  test lag_compensator::tests::negative_movement_predicts_backward ... ok
3902:  test lag_compensator::tests::output_is_clamped_to_valid_range ... ok
3903:  test lag_compensator::tests::reset_clears_initialized ... ok
3904:  test lag_compensator::tests::static_axis_unchanged ... ok
3905:  test lag_compensator::tests::zero_dt_uses_last_dt ... ok
3906:  test mixer::tests::add_input_beyond_max_fails ... ok
3907:  test mixer::tests::add_input_increments_count ... ok
...

3983:  test pid::tests::test_pid_bank_reset_not_needed ... ok
3984:  test pid::tests::test_pid_bank_update_known_axis ... ok
3985:  test pid::tests::test_pid_bank_update_unknown_axis ... ok
3986:  test pid::tests::test_pid_converges_step_response ... ok
3987:  test pid::tests::test_pid_derivative_on_step ... ok
3988:  test pid::tests::test_pid_derivative_zero_first_tick ... ok
3989:  test pid::tests::test_pid_integral_accumulates ... ok
3990:  test pid::tests::test_pid_integral_windup_limited ... ok
3991:  test pid::tests::test_pid_output_clamped_to_1 ... ok
3992:  test pid::tests::test_pid_output_clamped_to_neg1 ... ok
3993:  test pid::tests::test_pid_proportional_only ... ok
3994:  test pid::tests::test_pid_reset_clears_state ... ok
3995:  test pid::tests::test_pid_set_integral_clamped ... ok
3996:  test pid::tests::test_pid_setpoint_above_pv ... ok
3997:  test pid::tests::test_pid_setpoint_below_pv ... ok
3998:  test pid::tests::test_pid_zero_error ... ok
3999:  test pipeline::tests::test_alignment ... ok
4000:  test pid::tests::proptest_zero_error_zero_output ... ok
4001:  test pipeline::tests::test_bypass_out_of_bounds ... ok
...

4099:  test recording::tests::test_playback_is_finished_at_end ... ok
4100:  test recording::tests::test_playback_looping_wraps_around ... ok
4101:  test recording::tests::test_playback_rewind ... ok
4102:  test recording::tests::test_record_multiple_samples ... ok
4103:  test recording::tests::test_record_single_sample ... ok
4104:  test recording::tests::test_recording_duration ... ok
4105:  test recording::tests::test_recording_empty_by_default ... ok
4106:  test recording::tests::test_samples_in_range ... ok
4107:  test rate_limit::tests::proptest_unlimited_passthrough ... ok
4108:  test scale::tests::test_bank_apply ... ok
4109:  test scale::tests::test_bank_set_scale ... ok
4110:  test scale::tests::test_scale_clamp_max ... ok
4111:  test scale::tests::test_scale_clamp_min ... ok
4112:  test scale::tests::test_scale_default_passthrough ... ok
4113:  test scale::tests::test_scale_factor_half ... ok
4114:  test scale::tests::test_scale_invalid_range_error ... ok
4115:  test scale::tests::test_scale_nan_factor_error ... ok
4116:  test scale::tests::test_scale_negative_factor ... ok
...

4235:  test stages::tests::very_large_values_handled ... ok
4236:  test throttle_zone::tests::prop_event_count_never_exceeds_4 ... ok
4237:  test throttle_zone::tests::test_afterburner_zone_event ... ok
4238:  test throttle_zone::tests::test_builder_pattern ... ok
4239:  test throttle_zone::tests::test_combined_cut_and_milpower ... ok
4240:  test throttle_zone::tests::prop_output_always_in_range ... ok
4241:  test throttle_zone::tests::test_cut_zone_above_threshold ... ok
4242:  test throttle_zone::tests::test_cut_zone_at_threshold ... ok
4243:  test throttle_zone::tests::test_cut_zone_below_threshold ... ok
4244:  test throttle_zone::tests::test_max_zone_below_threshold ... ok
4245:  test throttle_zone::tests::test_max_zone_saturation ... ok
4246:  test throttle_zone::tests::test_milpower_zone_event_on_entry ... ok
4247:  test throttle_zone::tests::test_milpower_zone_event_on_exit ... ok
4248:  test throttle_zone::tests::test_no_zones_passthrough ... ok
4249:  test throttle_zone::tests::test_process_clamped_input_above_one ... ok
4250:  test throttle_zone::tests::test_validate_cut_above_max_error ... ok
4251:  test throttle_zone::tests::test_validate_invalid_cut_threshold ... ok
...

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

4345:  test test_deadzone_node_asymmetric ... ok
4346:  test test_deterministic_processing ... ok
4347:  test test_end_to_end_pipeline_processing ... ok
4348:  test test_node_state_sizes ... ok
4349:  test test_node_type_identification ... ok
4350:  test test_performance_snapshot ... ok
4351:  test test_pipeline_builder ... ok
4352:  test test_pipeline_state_validation ... ok
4353:  test test_runtime_counters ... ok
4354:  test test_runtime_counters_averaging ... ok
4355:  test test_slew_node_rate_limiting ... ok
4356:  test test_zero_allocation_constraint_validation ... ok
4357:  test test_zero_allocation_guarantee ... ok
4358:  test test_processing_performance ... ok
4359:  test test_performance_under_load ... ok
4360:  test result: ok. 26 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.79s
4361:  �[1m�[92m     Running�[0m tests\mixer_tests.rs (target\debug\deps\mixer_tests-bb55e39fdf9e6753.exe)
...

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

4453:  test test_combined_deadzone_expo_zeroes_inside_zone ... ok
4454:  test test_curve_expo_one_max_curvature ... ok
4455:  test test_curve_scurve_reduces_centre_gain ... ok
4456:  test test_curve_expo_zero_is_linear ... ok
4457:  test test_deadzone_negative_boundary ... ok
4458:  test test_deadzone_value_at_exact_threshold ... ok
4459:  test test_deadzone_value_just_outside_is_nonzero ... ok
4460:  test test_deadzone_value_inside_is_zero ... ok
4461:  test test_range_clamp_at_limits ... ok
4462:  test test_split_bipolar_half_positive ... ok
4463:  test test_split_bipolar_negative_one ... ok
4464:  test test_split_bipolar_positive_one ... ok
4465:  test test_split_bipolar_zero ... ok
4466:  test prop_split_bipolar_sum_equals_abs ... ok
4467:  test prop_combine_differential_bounded ... ok
4468:  test result: ok. 24 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
4469:  �[1m�[92m     Running�[0m tests\rt_timing_test.rs (target\debug\deps\rt_timing_test-3d8c4cf99cfac491.exe)
4470:  running 2 tests
4471:  test axis_pipeline_p99_within_4ms_budget ... ok
4472:  test axis_pipeline_fits_in_rt_budget ... ok
4473:  test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.08s
4474:  �[1m�[92m     Running�[0m tests\snapshot_tests.rs (target\debug\deps\snapshot_tests-8a7bcb41bf8d3985.exe)
4475:  running 3 tests
4476:  test snapshot_deadzone_expo_pipeline_output_values ... ok
4477:  test snapshot_deadzone_expo_pipeline_metadata ... ok
4478:  test snapshot_curve_node_expo_0_4_outputs ... ok
4479:  test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.16s
4480:  �[1m�[92m     Running�[0m unittests src\lib.rs (target\debug\deps\flight_bdd_metrics-2f4bbbb43d341ee8.exe)
4481:  running 14 tests
4482:  test tests::bdd_traceability_row_coverage_methods ... ok
4483:  test tests::coverage_percent_full_coverage ... ok
4484:  test tests::coverage_percent_zero_denominator_returns_zero ... ok
4485:  test tests::bdd_scenario_ac_tags_filters_non_ac_tags ... ok
4486:  test tests::coverage_status_compute_all_branches ... ok
4487:  test tests::extract_crates_from_command_parses_p_flag ... ok
4488:  test tests::extract_crates_from_reference_cmd_prefix ... ok
4489:  test tests::is_crate_name_candidate_valid_and_invalid ... ok
4490:  test tests::extract_crates_from_reference_double_colon_notation ... ok
4491:  test tests::is_scenario_header_recognises_scenario_types ... ok
4492:  test tests::normalize_crate_name_strips_quotes_and_underscores ... ok
4493:  test tests::parse_tags_from_line_extracts_tags ... ok
4494:  test tests::with_workspace_crates_filters_non_workspace_rows ... ok
4495:  test tests::with_workspace_crates_preserves_unmapped_row ... ok
4496:  test result: ok. 14 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
4497:  �[1m�[92m     Running�[0m unittests src\lib.rs (target\debug\deps\flight_blackbox-98b7135a86926b25.exe)
...

4522:  test recorder::tests::iterator_exact_size ... ok
4523:  test recorder::tests::mixed_record_types_in_buffer ... ok
4524:  test export::tests::json_csv_agree_on_axis_count ... ok
4525:  test recorder::tests::new_recorder_is_empty ... ok
4526:  test recorder::tests::record_and_retrieve_axis ... ok
4527:  test recorder::tests::record_event_stores_correctly ... ok
4528:  test recorder::tests::large_overflow_preserves_newest ... ok
4529:  test recorder::tests::record_ffb_stores_correctly ... ok
4530:  test recorder::tests::record_telemetry_stores_correctly ... ok
4531:  test recorder::tests::ring_buffer_exact_capacity_fill ... ok
4532:  test recorder::tests::ring_buffer_overflow_drops_oldest ... ok
4533:  test recorder::tests::zero_alloc_on_hot_path ... ok
4534:  test recorder::tests::zero_capacity_clamped_to_one ... ok
4535:  test tests::blackbox_config_defaults ... ok
4536:  test tests::blackbox_writer_starts_not_running ... ok
4537:  test tests::double_start_returns_error ... ok
4538:  test tests::blackbox_write_read_roundtrip ... ok
...

4540:  test tests::prop_blackbox_footer_roundtrip ... ok
4541:  test tests::record_queue_capacity_clamps_to_max ... ok
4542:  test tests::record_queue_capacity_clamps_to_min ... ok
4543:  test tests::stream_type_to_index ... ok
4544:  test time::tests::elapsed_to_ns_one_second ... ok
4545:  test time::tests::elapsed_to_ns_saturates_on_overflow ... ok
4546:  test time::tests::elapsed_to_ns_zero_duration ... ok
4547:  test tests::prop_index_entry_roundtrip ... ok
4548:  test time::tests::monotonic_now_ns_is_non_negative ... ok
4549:  test time::tests::to_ns_from_ms_basic ... ok
4550:  test time::tests::monotonic_now_ns_increases_over_time ... ok
4551:  test time::tests::to_ns_from_ms_saturates_on_overflow ... ok
4552:  test time::tests::unix_now_ns_is_after_epoch ... ok
4553:  test tests::prop_blackbox_header_roundtrip ... ok
4554:  test tests::export_doc_is_json_serializable ... ok
4555:  test result: ok. 56 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.02s
4556:  �[1m�[92m     Running�[0m unittests src\lib.rs (target\debug\deps\flight_bus-79691120ff409494.exe)
...

4579:  test adapters::tests::msfs_tests::test_msfs_percentage_conversion ... ok
4580:  test adapters::tests::msfs_tests::test_msfs_rpm_conversion ... ok
4581:  test adapters::tests::msfs_tests::test_msfs_speed_conversion ... ok
4582:  test a...

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