Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4.0 KiB
phase, plan, subsystem, tags, dependency_graph, tech_stack, key_files, decisions, metrics
| phase | plan | subsystem | tags | dependency_graph | tech_stack | key_files | decisions | metrics | |||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 01 | 06 | mavlink_io |
|
|
|
|
|
|
Phase 01 Plan 06: MAVLink I/O Split Summary
Split core/mavlink.py (483 LOC) into component modules under components/mavlink_io/, replacing the original with a shim that re-exports all public and private names verbatim.
LOC Distribution
| File | LOC | Contents |
|---|---|---|
components/mavlink_io/pymavlink_bridge.py |
455 | MAVLinkBridge class + 3 module-level helpers + pymavlink conditional import |
components/mavlink_io/mock_mavlink.py |
30 | MockMAVConnection (no-op for dev/CI) |
core/mavlink.py (shim) |
29 | Re-export shim only |
components/mavlink_io/__init__.py |
20 | Package surface |
Original: 483 LOC → split across 4 files (514 total including shim and __init__.py).
Test Counts
| Test file | Result |
|---|---|
tests/test_mavlink.py |
32 passed |
tests/test_gps_input_encoding.py |
included in the 32 above |
Full regression (tests/) |
216 passed, 8 skipped |
Regression floor: 216 passed (baseline). Status: MAINTAINED.
Private Helper Verification
The three underscore names required by test_mavlink.py and test_gps_input_encoding.py resolve correctly via the shim:
python -c "from gps_denied.core.mavlink import _confidence_to_fix_type, _eskf_to_gps_input, _unix_to_gps_time; print('private helpers ok')"
# Output: private helpers ok
All three are exported from core/mavlink.py → components/mavlink_io/pymavlink_bridge.py → callable.
_PYMAVLINK_AVAILABLE on Dev Machine
_PYMAVLINK_AVAILABLE = True
pymavlink is installed on this development machine, so MAVLinkBridge._open_connection() will attempt a real connection before falling back to MockMAVConnection.
Deviations from Plan
Auto-fixed Issues
1. [Rule 3 - Blocking] Circular import between pymavlink_bridge and mock_mavlink
- Found during: Task 1 (design review before writing)
- Issue:
pymavlink_bridge.py(MAVLinkBridge) usesisinstance(self._conn, MockMAVConnection)checks. Ifmock_mavlink.pywere imported at module level inpymavlink_bridge.py, and__init__.pyimports both, a circular import chain would form. - Fix: Used local (deferred) imports of
MockMAVConnectioninside each method that references it (_send_gps_input,_recv_imu,_send_reloc_request,_send_telemetry,_open_connection). This matches the pattern used in similar hexagonal refactors in this codebase. - Files modified:
pymavlink_bridge.py - Commit:
f965ac7
Known Stubs
None. All data paths are wired: bridge reads from live ESKFState, writes to real or mock MAVLink connection.
Threat Flags
None. No new network endpoints or auth paths introduced. The MAVLink UART connection was already present in the original core/mavlink.py.
Self-Check: PASSED
src/gps_denied/components/mavlink_io/pymavlink_bridge.py— FOUNDsrc/gps_denied/components/mavlink_io/mock_mavlink.py— FOUNDsrc/gps_denied/components/mavlink_io/__init__.py— FOUND (updated)src/gps_denied/core/mavlink.py— FOUND (shim, 29 LOC)- Commit
f965ac7— FOUND - 216 tests passed — CONFIRMED