Files
gps-denied-onboard/.planning/phases/01-hexagonal-refactor/01-06-SUMMARY.md
T
2026-05-11 08:50:22 +03:00

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
refactor
hexagonal
mavlink
shim
requires provides affects
01-05
components/mavlink_io
core/mavlink.py
added patterns
shim-re-export
circular-import-avoidance-via-local-imports
created modified
src/gps_denied/components/mavlink_io/pymavlink_bridge.py
src/gps_denied/components/mavlink_io/mock_mavlink.py
src/gps_denied/components/mavlink_io/__init__.py
src/gps_denied/core/mavlink.py
Used local (deferred) imports of MockMAVConnection inside MAVLinkBridge methods to avoid circular import between pymavlink_bridge and mock_mavlink
Shim re-exports all seven names including three private helpers (_confidence_to_fix_type, _eskf_to_gps_input, _unix_to_gps_time) per CRITICAL warning
duration completed tasks files
~5 minutes 2026-05-11 5 4

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.pycomponents/mavlink_io/pymavlink_bridge.py → callable.

_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) uses isinstance(self._conn, MockMAVConnection) checks. If mock_mavlink.py were imported at module level in pymavlink_bridge.py, and __init__.py imports both, a circular import chain would form.
  • Fix: Used local (deferred) imports of MockMAVConnection inside 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 — FOUND
  • src/gps_denied/components/mavlink_io/mock_mavlink.py — FOUND
  • src/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