- Changed autodev state sub_step to reflect new phase and task details: updated phase from 7 to 2, renamed task to 'refactor-analysis-gate', and revised detail to indicate the creation of new tasks AZ-844, AZ-845, AZ-846, and AZ-847, awaiting Phase-2 gate. - Updated dependencies table with the latest task counts and complexity points, reflecting the addition of new tasks and the closure of AZ-777 in Jira. Total tasks now stand at 173 with 557 complexity points.
8.0 KiB
Baseline Metrics — Run 02-az507-routespec-relocation
Date: 2026-05-23
Run: _docs/04_refactoring/02-az507-routespec-relocation/
Mode: guided
Source: cycle-3 cumulative review (_docs/03_implementation/cumulative_review_batches_104-109_cycle3_report.md) — F1, F2, F3
Scope: mechanical relocation of cross-component DTO + module-layout doc refresh + AZ-270 lint scope expansion
Why a minimal baseline is appropriate for this run
The standard Phase-0 baseline metric grid (overall coverage, complexity, code smells, performance, dependencies, build time) is not the right instrument for this refactoring run. The work is a structural relocation of one frozen dataclass + a documentation refresh + a lint widening. Behaviour does not change; performance does not change; coverage does not change; dependency count does not change. A LOC-and-cyclomatic-complexity baseline would record near-zero deltas and would obscure the actual signal — whether the architectural rule (module-layout.md rule 9) is satisfied after the run.
What matters here, and is captured below, is:
- The structural baseline: one rule-9 violation today (F1).
- The test baseline: which tests cover the affected import paths and that they pass at HEAD (the safety net for Phase 4).
- The doc baseline: which artifacts are stale (F2) and what "complete" looks like.
- The lint baseline: what AZ-270 currently catches vs. what rule 9 says it should catch (F3).
Phases 5/6 verify that (a) the structural baseline goes from 1 → 0 rule-9 violations, (b) every test still passes, (c) the doc baseline is reconciled, and (d) the lint baseline is widened.
1. Structural baseline (rule-9 violations)
Source of truth: _docs/02_document/module-layout.md rule 9 (AZ-507 cross-component contract surface).
| # | File | Importer (Component) | Imported (Module) | Allow-listed for importer? |
|---|---|---|---|---|
| 1 | src/gps_denied_onboard/components/c11_tile_manager/route_client.py:56 |
c11_tile_manager |
gps_denied_onboard.replay_input.tlog_route (RouteSpec) |
NO — replay_input not in c11's allow-list |
Search method: rg "^from gps_denied_onboard\." src/gps_denied_onboard/components filtered against the allow-list (_types/*, _types.inference_errors, helpers/*, config, logging, fdr_client, clock, frame_source).
Target post-run: 0 violations.
2. Test baseline (safety net for Phase 4)
Files that import RouteSpec, SatelliteProviderRouteClient, or RouteSeedResult (i.e. the symbols the relocation touches):
Production source (must be updated):
src/gps_denied_onboard/components/c11_tile_manager/route_client.py— defines the import to be re-pointedsrc/gps_denied_onboard/components/c11_tile_manager/__init__.py— public API re-exports (no import path change)src/gps_denied_onboard/replay_input/tlog_route.py— definesRouteSpectoday (will lose the local definition, gain an import + alias)src/gps_denied_onboard/replay_input/__init__.py— public API re-exports (will re-export from_types.routeinstead oftlog_route)
Tests (verify still pass; update imports only if they reach into the pre-relocation internal path replay_input.tlog_route directly):
tests/unit/replay_input/test_tlog_route.py(14 tests; producer-side)tests/unit/c11_tile_manager/test_route_client.py(consumer-side unit tests)tests/integration/c11_tile_manager/test_route_client_e2e.py(integration)tests/e2e/replay/conftest.pytests/e2e/replay/_operator_pre_flight.pytests/e2e/replay/test_operator_pre_flight_driver.pytests/e2e/replay/test_operator_pre_flight_integration.pytests/e2e/replay/_e2e_orchestrator.pytests/e2e/replay/test_e2e_orchestrator_unit.pytests/fixtures/derkachi_c6/seed_route.py
HEAD test status (asserted, not measured here): per cycle-3 batch reports 104, 106, 107, 108, 108b, 109, every committed batch ended with passing tests at the per-batch full run. The cumulative review (FAIL on F1) is a static-analysis verdict, not a test-run verdict — no test failures are attributable to F1 today. Phase 4 will run the affected test files first; Phase 6 runs the project's full test gate per the existing-code flow's test policy.
3. Doc baseline (F2 surface area)
_docs/02_document/module-layout.md is stale relative to on-disk reality. The following entries diverge today:
c11_tile_manager — Internal list lists 2 files (satellite_provider_downloader.py, satellite_provider_uploader.py); on-disk has 8 internal files plus route_client.py (cycle-3 NEW). Missing entries: _types.py, config.py, errors.py, idempotent_retry.py, signing_key.py, tile_downloader.py, tile_uploader.py, route_client.py.
shared/replay_input file list lists __init__.py, interface.py, tlog_video_adapter.py, auto_sync.py, tests/; on-disk adds errors.py (cycle-2 carry), tlog_ground_truth.py (cycle-2 carry), tlog_route.py (cycle-3 NEW). After the relocation, tlog_route.py stays (it still owns extract_route_from_tlog); _types/route.py is added.
Cycle-2 carry-overs still unaddressed (out of this run's scope unless the user expands it; surfaced in F2 of the cumulative review):
replay_api/package (7 files; needs Per-Component Mapping entry).cli/render_map.py,cli/replay_api_entrypoint.py(need Shared section entries).helpers/gps_compare.py,helpers/accuracy_report.py(need Shared section entries).
Target post-run (in-scope): c11_tile_manager Internal list refreshed (route_client + the 7 long-standing internals); shared/replay_input file list refreshed (tlog_route + tlog_ground_truth + errors); new _types/route.py registered. Cycle-2 carry-overs are deferred to a separate doc-only task unless user expands scope.
4. Lint baseline (F3)
tests/unit/test_az270_compose_root.py:194-219 (test_ac6_only_compose_root_imports_concrete_strategies) walks src/gps_denied_onboard/components/**/*.py and flags only edges whose node.module starts with gps_denied_onboard.components. AND whose leaf-component is not the importer's component. The full rule-9 allow-list (8 prefixes plus frame_source interface-only restriction) is NOT enforced.
Concrete miss demonstrated by F1: the c11 → replay_input edge passes this lint silently because replay_input is not under components/.
Target post-run (in-scope): expand the lint to enforce rule 9's full allow-list. Remaining design choices (whether to allow frame_source non-interface modules, whether to treat runtime_root exception case-sensitively) are addressed in C03's task spec.
5. Functionality inventory
This run touches no public-feature surfaces. The DTO RouteSpec continues to be re-exported from gps_denied_onboard.replay_input (the public package), so consumers using from gps_denied_onboard.replay_input import RouteSpec see no change. Consumers reaching into replay_input.tlog_route directly (an internal-module path) will need their imports updated — this set is small and lives entirely under tests/. There is no operator-facing CLI / endpoint / config schema change.
Self-verification
- RUN_DIR created with auto-incremented prefix (
02-az507-routespec-relocation; previous:01-testability-refactoring) - All metric categories reasoned about — standard categories noted N/A with reason; relevant baselines (structural, test, doc, lint) captured
- Functionality inventory complete (no functionality change in scope)
- Measurements are reproducible (rg + glob commands documented)
BLOCKING — Phase 0 gate
Awaiting user confirmation of:
- The minimal-baseline rationale (no LOC/coverage/perf metrics for a mechanical relocation).
- The structural / test / doc / lint baseline above as the "before" state Phase 6 will compare against.
- The scope decision: cycle-2 doc carry-overs are OUT of this run unless explicitly expanded.
If confirmed, Phase 1 produces RUN_DIR/list-of-changes.md (already drafted alongside this file as the guided-mode input).