mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-06-21 08:41:12 +00:00
docs(01-07): complete plan summary for hexagonal refactor plan 07
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
---
|
||||
phase: "01-hexagonal-refactor"
|
||||
plan: "01-07"
|
||||
subsystem: "core-restructure"
|
||||
tags: ["refactor", "protocol", "pipeline", "abc-to-protocol", "shim"]
|
||||
|
||||
dependency_graph:
|
||||
requires: ["01-05", "01-06"]
|
||||
provides: ["pipeline-package", "factor-graph-module", "testing-benchmark-module"]
|
||||
affects: ["core/graph.py", "core/processor.py", "core/pipeline.py", "core/results.py", "core/sse.py", "core/benchmark.py", "core/chunk_manager.py", "core/recovery.py", "core/models.py", "core/rotation.py"]
|
||||
|
||||
tech_stack:
|
||||
added: []
|
||||
patterns: ["typing.Protocol with @runtime_checkable", "shim re-export pattern", "package decomposition"]
|
||||
|
||||
key_files:
|
||||
created:
|
||||
- src/gps_denied/core/factor_graph.py
|
||||
- src/gps_denied/pipeline/__init__.py
|
||||
- src/gps_denied/pipeline/orchestrator.py
|
||||
- src/gps_denied/pipeline/image_input.py
|
||||
- src/gps_denied/pipeline/result_manager.py
|
||||
- src/gps_denied/pipeline/sse_streamer.py
|
||||
- src/gps_denied/testing/benchmark.py
|
||||
modified:
|
||||
- src/gps_denied/core/graph.py (shim)
|
||||
- src/gps_denied/core/processor.py (shim)
|
||||
- src/gps_denied/core/pipeline.py (shim)
|
||||
- src/gps_denied/core/results.py (shim)
|
||||
- src/gps_denied/core/sse.py (shim)
|
||||
- src/gps_denied/core/benchmark.py (shim)
|
||||
- src/gps_denied/core/chunk_manager.py (ABC→Protocol in-place)
|
||||
- src/gps_denied/core/recovery.py (ABC→Protocol in-place)
|
||||
- src/gps_denied/core/models.py (ABC→Protocol in-place)
|
||||
- src/gps_denied/core/rotation.py (ABC→Protocol in-place)
|
||||
- pyproject.toml (ruff per-file-ignores updated)
|
||||
|
||||
decisions:
|
||||
- "Protocol subclassing is valid Python — FactorGraphOptimizer(IFactorGraphOptimizer) kept as-is"
|
||||
- "pipeline/result_manager.py imports from pipeline/sse_streamer.py directly, avoiding shim chain"
|
||||
- "core/results.py and core/sse.py shims kept lean; no circular import issues"
|
||||
- "pipeline/orchestrator.py internal imports updated to new paths; test shims handle old paths"
|
||||
- "src/gps_denied/testing/harness.py and api/deps.py left using shim paths (backward-compat)"
|
||||
|
||||
metrics:
|
||||
duration: "~8 minutes"
|
||||
completed: "2026-05-11"
|
||||
tasks_completed: 6
|
||||
files_created: 7
|
||||
files_modified: 11
|
||||
---
|
||||
|
||||
# Phase 01-hexagonal-refactor Plan 07: Factor Graph, Pipeline Package, Benchmark, Protocol Conversions Summary
|
||||
|
||||
**One-liner:** Extracted pipeline orchestration into `pipeline/` package, moved factor graph to `core/factor_graph.py`, benchmarks to `testing/benchmark.py`, and converted 5 ABCs to `typing.Protocol` with `@runtime_checkable`.
|
||||
|
||||
## File Moves Performed
|
||||
|
||||
| Source | Target | Method |
|
||||
|--------|--------|--------|
|
||||
| `core/graph.py` (IFactorGraphOptimizer) | `core/factor_graph.py` | Copy + ABC→Protocol, shim left at source |
|
||||
| `core/processor.py` (FlightProcessor) | `pipeline/orchestrator.py` | Copy + internal imports updated, shim left at source |
|
||||
| `core/pipeline.py` (ImageInputPipeline) | `pipeline/image_input.py` | Copy verbatim, shim left at source |
|
||||
| `core/results.py` (ResultManager) | `pipeline/result_manager.py` | Copy + SSE import updated, shim left at source |
|
||||
| `core/sse.py` (SSEEventStreamer) | `pipeline/sse_streamer.py` | Copy verbatim, shim left at source |
|
||||
| `core/benchmark.py` (AccuracyBenchmark et al.) | `testing/benchmark.py` | Copy verbatim, shim left at source |
|
||||
|
||||
## ABCs Converted to Protocol (5 total)
|
||||
|
||||
| Interface | File | Method count |
|
||||
|-----------|------|-------------|
|
||||
| `IFactorGraphOptimizer` | `core/factor_graph.py` | 13 methods |
|
||||
| `IRouteChunkManager` | `core/chunk_manager.py` | 6 methods |
|
||||
| `IFailureRecoveryCoordinator` | `core/recovery.py` | 2 methods |
|
||||
| `IModelManager` | `core/models.py` | 5 methods |
|
||||
| `IImageMatcher` | `core/rotation.py` | 1 method |
|
||||
|
||||
**Pattern applied to each:**
|
||||
- Removed `from abc import ABC, abstractmethod`
|
||||
- Added `from typing import Protocol, runtime_checkable`
|
||||
- Replaced `class IXxx(ABC):` with `@runtime_checkable\nclass IXxx(Protocol):`
|
||||
- Dropped `@abstractmethod` decorators; replaced `pass` bodies with `...`
|
||||
- Concrete classes continue to subclass the Protocol (valid Python)
|
||||
|
||||
## pyproject.toml Changes
|
||||
|
||||
```diff
|
||||
[tool.ruff.lint.per-file-ignores]
|
||||
-"src/gps_denied/core/graph.py" = ["E501"]
|
||||
+"src/gps_denied/core/factor_graph.py" = ["E501"]
|
||||
-"src/gps_denied/core/metric.py" = ["E501"]
|
||||
+"src/gps_denied/components/satellite_matcher/metric_refinement.py" = ["E501"]
|
||||
"src/gps_denied/core/chunk_manager.py" = ["E501"]
|
||||
```
|
||||
|
||||
## Test Counts
|
||||
|
||||
| | Count |
|
||||
|--|--|
|
||||
| Baseline (before plan) | 216 passed, 8 skipped |
|
||||
| After plan | 216 passed, 8 skipped |
|
||||
| Regression floor met | YES |
|
||||
|
||||
## Internal Import Updates in Non-Test Source Files
|
||||
|
||||
`pipeline/orchestrator.py` (canonical location of `FlightProcessor`):
|
||||
- `from gps_denied.core.pipeline import ImageInputPipeline` → `from gps_denied.pipeline.image_input import ImageInputPipeline`
|
||||
- `from gps_denied.core.results import ResultManager` → `from gps_denied.pipeline.result_manager import ResultManager`
|
||||
- `from gps_denied.core.sse import SSEEventStreamer` → `from gps_denied.pipeline.sse_streamer import SSEEventStreamer`
|
||||
|
||||
`pipeline/result_manager.py` (canonical location of `ResultManager`):
|
||||
- `from gps_denied.core.sse import SSEEventStreamer` → `from gps_denied.pipeline.sse_streamer import SSEEventStreamer`
|
||||
|
||||
`src/gps_denied/testing/harness.py` and `src/gps_denied/api/deps.py`: left using legacy `core.*` shim paths — they continue to work transparently.
|
||||
|
||||
## Protocol Conversion Edge Cases
|
||||
|
||||
1. **`IFactorGraphOptimizer` in `core/factor_graph.py`**: The concrete class `FactorGraphOptimizer` subclasses the Protocol. Python allows this and it provides structural typing via `@runtime_checkable`. The existing `isinstance(x, IFactorGraphOptimizer)` calls in tests will work.
|
||||
|
||||
2. **Long method signatures in `factor_graph.py`**: The `E501` ruff ignore was updated from `core/graph.py` to `core/factor_graph.py` — signatures like `add_relative_factor_to_chunk(...)` with 6 parameters exceed 120 chars.
|
||||
|
||||
3. **`chunk_manager.py` import of `IFactorGraphOptimizer`**: Still imports from `gps_denied.core.graph` (which shims to `factor_graph`) — no change needed, backward-compat maintained.
|
||||
|
||||
4. **`IImageMatcher` in `rotation.py`**: Used as a DI parameter type in `try_rotation_sweep`. Concrete implementations (e.g., `MetricRefinement` from `components/satellite_matcher`) are not subclasses but satisfy the Protocol structurally.
|
||||
|
||||
5. **`IModelManager` return type `InferenceEngine`**: `InferenceEngine` is a Pydantic model, not changed. Protocol stub uses `...` which satisfies mypy for structural checks.
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
None — plan executed exactly as written.
|
||||
|
||||
## Known Stubs
|
||||
|
||||
None introduced by this plan. All moved code is functionally complete.
|
||||
|
||||
## Threat Flags
|
||||
|
||||
None. No new network endpoints, auth paths, or file access patterns introduced by these refactors.
|
||||
|
||||
## Self-Check: PASSED
|
||||
|
||||
Files created:
|
||||
- FOUND: src/gps_denied/core/factor_graph.py
|
||||
- FOUND: src/gps_denied/pipeline/__init__.py
|
||||
- FOUND: src/gps_denied/pipeline/orchestrator.py
|
||||
- FOUND: src/gps_denied/pipeline/image_input.py
|
||||
- FOUND: src/gps_denied/pipeline/result_manager.py
|
||||
- FOUND: src/gps_denied/pipeline/sse_streamer.py
|
||||
- FOUND: src/gps_denied/testing/benchmark.py
|
||||
|
||||
Commit: 5a60c1e — FOUND
|
||||
Regression: 216 passed >= 216 baseline — PASSED
|
||||
Reference in New Issue
Block a user