7.1 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-hexagonal-refactor | 01-07 | core-restructure |
|
|
|
|
|
|
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
@abstractmethoddecorators; replacedpassbodies with... - Concrete classes continue to subclass the Protocol (valid Python)
pyproject.toml Changes
[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 ImageInputPipelinefrom gps_denied.core.results import ResultManager→from gps_denied.pipeline.result_manager import ResultManagerfrom 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
-
IFactorGraphOptimizerincore/factor_graph.py: The concrete classFactorGraphOptimizersubclasses the Protocol. Python allows this and it provides structural typing via@runtime_checkable. The existingisinstance(x, IFactorGraphOptimizer)calls in tests will work. -
Long method signatures in
factor_graph.py: TheE501ruff ignore was updated fromcore/graph.pytocore/factor_graph.py— signatures likeadd_relative_factor_to_chunk(...)with 6 parameters exceed 120 chars. -
chunk_manager.pyimport ofIFactorGraphOptimizer: Still imports fromgps_denied.core.graph(which shims tofactor_graph) — no change needed, backward-compat maintained. -
IImageMatcherinrotation.py: Used as a DI parameter type intry_rotation_sweep. Concrete implementations (e.g.,MetricRefinementfromcomponents/satellite_matcher) are not subclasses but satisfy the Protocol structurally. -
IModelManagerreturn typeInferenceEngine:InferenceEngineis 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