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

102 lines
4.0 KiB
Markdown

---
phase: "01"
plan: "06"
subsystem: mavlink_io
tags: [refactor, hexagonal, mavlink, shim]
dependency_graph:
requires: [01-05]
provides: [components/mavlink_io]
affects: [core/mavlink.py]
tech_stack:
added: []
patterns: [shim-re-export, circular-import-avoidance-via-local-imports]
key_files:
created:
- src/gps_denied/components/mavlink_io/pymavlink_bridge.py
- src/gps_denied/components/mavlink_io/mock_mavlink.py
modified:
- src/gps_denied/components/mavlink_io/__init__.py
- src/gps_denied/core/mavlink.py
decisions:
- "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"
metrics:
duration: "~5 minutes"
completed: "2026-05-11"
tasks: 5
files: 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.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) 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