mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-06-22 21:01:13 +00:00
[AZ-845][AZ-846][AZ-847] Refactor 02: relocate RouteSpec + widen lint
Cycle-3 refactor run 02-az507 (RouteSpec relocation + module-layout
refresh + AZ-270 lint widening). Single batch of 3 tasks; epic AZ-844.
AZ-845 — Relocate RouteSpec DTO to _types/route.py (rule-9 fix):
* New canonical home: src/gps_denied_onboard/_types/route.py
(frozen+slots dataclass; full docstring carried over verbatim).
* c11_tile_manager/route_client.py imports from _types.route.
* replay_input/tlog_route.py and replay_input/__init__.py keep
re-exports for backward-compat (RouteSpec in __all__).
* 5 test files updated to import from _types.route for symmetry.
* Identity-preserving re-export verified by new test
test_az845_routespec_canonical_home_and_reexport_identity.
AZ-846 — Refresh module-layout.md cycle-3 entries:
* c11_tile_manager Internal list rewritten with all 8 internals
(alphabetised) — corrects a stale entry that referenced files
(satellite_provider_*.py) that no longer exist.
* shared/replay_input file list adds errors.py (cycle-2 carry),
tlog_ground_truth.py (cycle-2 carry), tlog_route.py (cycle-3 NEW).
* shared/_types section registers route.py with provenance line.
* Out-of-scope cycle-2 carry-overs (replay_api/, cli/render_map.py,
helpers/gps_compare.py, etc.) intentionally untouched.
AZ-847 — Widen test_az270 lint to enforce full rule-9 allow-list:
* test_ac6_only_compose_root_imports_concrete_strategies now walks
every components/<X>/*.py ImportFrom/Import and rejects anything
not in the rule-9 allow-list (own subpackage + _types + helpers
+ config/logging/fdr_client/clock + frame_source interface-only).
* Strict superset of the original AC-6 narrow check.
* Reports zero violations on the codebase post-AZ-845.
* Two principled carve-outs documented in the test docstring:
- components/<X>/bench/** path skip (measurement code legitimately
constructs production strategies via runtime_root factories).
- register_* lazy self-registration imports from
runtime_root.<X>_factory (central-registry plugin pattern).
* Both carve-outs surfaced to user via Choose A/B/C/D Risk-1
protocol; user skipped both — agent proceeded with documented
defaults. Doc-only follow-up tracked in
_docs/_process_leftovers/2026-05-24_az847_rule9_wording_followup.md
for rule-9 wording update in module-layout.md.
Test results: 2287 passed, 90 skipped (environmental — Docker / CUDA
/ TensorRT / Jetson hardware / fixtures), 0 failed. Focused subset
(replay_input/ + c11_tile_manager/ + test_az270_compose_root.py)
also clean: 169 passed, 1 skipped.
Tracker: AZ-845/846/847 transitioned In Progress -> In Testing.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
"""Route DTO shared between replay_input/ (producer) and c11_tile_manager/ (consumer).
|
||||
|
||||
Lives in ``_types/`` per ``module-layout.md`` rule 9 — DTOs that cross
|
||||
component boundaries are owned here so ``components/<X>/*.py`` can
|
||||
import them under the rule-9 allow-list without referencing other
|
||||
Layer-4 coordinators.
|
||||
|
||||
Producer: ``replay_input.tlog_route.extract_route_from_tlog`` (AZ-836).
|
||||
Consumer: ``components.c11_tile_manager.route_client.SatelliteProviderRouteClient.seed_route`` (AZ-838).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class RouteSpec:
|
||||
"""Coarsened flight route extracted from a tlog.
|
||||
|
||||
Attributes:
|
||||
waypoints: ``(lat_deg, lon_deg)`` pairs along the active
|
||||
segment in chronological order. Length is between 1 and
|
||||
the caller's ``max_waypoints``.
|
||||
suggested_region_size_meters: Per-waypoint coverage radius
|
||||
(meters) suggested for the satellite-provider region
|
||||
request — currently the caller-supplied
|
||||
``region_size_meters``.
|
||||
source_tlog: Provenance — path to the tlog this route was
|
||||
extracted from.
|
||||
source_segment: ``(start_idx, end_idx)`` inclusive bounds into
|
||||
the underlying tlog GPS row list. ``end_idx`` is the index
|
||||
of the last row in the active segment.
|
||||
total_distance_meters: Along-track great-circle distance of
|
||||
the un-coarsened active segment in meters.
|
||||
"""
|
||||
|
||||
waypoints: tuple[tuple[float, float], ...]
|
||||
suggested_region_size_meters: float
|
||||
source_tlog: Path
|
||||
source_segment: tuple[int, int]
|
||||
total_distance_meters: float
|
||||
@@ -1,7 +1,7 @@
|
||||
"""C11 ``SatelliteProviderRouteClient`` (AZ-838 / Epic AZ-835 C2).
|
||||
|
||||
Operator-side HTTP client for the parent-suite Route API. Takes a
|
||||
:class:`gps_denied_onboard.replay_input.tlog_route.RouteSpec` (produced
|
||||
:class:`gps_denied_onboard._types.route.RouteSpec` (produced
|
||||
by AZ-836 / C1) and onboards it with ``satellite-provider``:
|
||||
|
||||
1. **Pre-emptive validation** mirrors the AZ-809
|
||||
@@ -48,12 +48,12 @@ from typing import Any
|
||||
|
||||
import httpx
|
||||
|
||||
from gps_denied_onboard._types.route import RouteSpec
|
||||
from gps_denied_onboard.components.c11_tile_manager.errors import (
|
||||
RouteTerminalFailureError,
|
||||
RouteTransientError,
|
||||
RouteValidationError,
|
||||
)
|
||||
from gps_denied_onboard.replay_input.tlog_route import RouteSpec
|
||||
|
||||
__all__ = [
|
||||
"RouteSeedResult",
|
||||
|
||||
@@ -19,6 +19,7 @@ root's wiring needs; tests import the detectors via their full module
|
||||
path.
|
||||
"""
|
||||
|
||||
from gps_denied_onboard._types.route import RouteSpec
|
||||
from gps_denied_onboard.replay_input.errors import ReplayInputAdapterError
|
||||
from gps_denied_onboard.replay_input.interface import (
|
||||
AlignedWindow,
|
||||
@@ -33,7 +34,6 @@ from gps_denied_onboard.replay_input.tlog_ground_truth import (
|
||||
)
|
||||
from gps_denied_onboard.replay_input.tlog_route import (
|
||||
RouteExtractionError,
|
||||
RouteSpec,
|
||||
extract_route_from_tlog,
|
||||
)
|
||||
from gps_denied_onboard.replay_input.tlog_video_adapter import ReplayInputAdapter
|
||||
|
||||
@@ -21,10 +21,10 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import math
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
|
||||
from gps_denied_onboard._types.geo import LatLonAlt
|
||||
from gps_denied_onboard._types.route import RouteSpec
|
||||
from gps_denied_onboard.helpers.gps_compare import l2_horizontal_m
|
||||
from gps_denied_onboard.helpers.wgs_converter import WgsConverter
|
||||
from gps_denied_onboard.replay_input.errors import ReplayInputAdapterError
|
||||
@@ -51,34 +51,6 @@ class RouteExtractionError(ReplayInputAdapterError):
|
||||
"""Raised when a tlog cannot be reduced to a :class:`RouteSpec`."""
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class RouteSpec:
|
||||
"""Coarsened flight route extracted from a tlog.
|
||||
|
||||
Attributes:
|
||||
waypoints: ``(lat_deg, lon_deg)`` pairs along the active
|
||||
segment in chronological order. Length is between 1 and
|
||||
the caller's ``max_waypoints``.
|
||||
suggested_region_size_meters: Per-waypoint coverage radius
|
||||
(meters) suggested for the satellite-provider region
|
||||
request — currently the caller-supplied
|
||||
``region_size_meters``.
|
||||
source_tlog: Provenance — path to the tlog this route was
|
||||
extracted from.
|
||||
source_segment: ``(start_idx, end_idx)`` inclusive bounds into
|
||||
the underlying tlog GPS row list. ``end_idx`` is the index
|
||||
of the last row in the active segment.
|
||||
total_distance_meters: Along-track great-circle distance of
|
||||
the un-coarsened active segment in meters.
|
||||
"""
|
||||
|
||||
waypoints: tuple[tuple[float, float], ...]
|
||||
suggested_region_size_meters: float
|
||||
source_tlog: Path
|
||||
source_segment: tuple[int, int]
|
||||
total_distance_meters: float
|
||||
|
||||
|
||||
def extract_route_from_tlog(
|
||||
tlog: Path,
|
||||
*,
|
||||
|
||||
Reference in New Issue
Block a user