Update autodev state and dependencies table for Phase 2 progress
ci/woodpecker/push/02-build-push Pipeline failed

- 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.
This commit is contained in:
Oleksandr Bezdieniezhnykh
2026-05-23 17:11:50 +03:00
parent ade0c86f2b
commit 9dc04cc677
12 changed files with 758 additions and 6 deletions
File diff suppressed because one or more lines are too long
@@ -0,0 +1,69 @@
# Relocate RouteSpec DTO to _types/route.py (AZ-507 rule 9 fix)
**Task**: AZ-845_refactor_relocate_routespec
**Name**: Relocate `RouteSpec` from `replay_input/tlog_route.py` to `_types/route.py`
**Description**: Resolve cycle-3 cumulative review F1 (High Architecture). Move the `RouteSpec` cross-component DTO to `_types/route.py` so the `c11_tile_manager.route_client` import becomes rule-9 compliant. Producer-side keeps backward-compat re-export so test imports do not break.
**Complexity**: 2 SP
**Dependencies**: None (anchor task of refactor run 02-az507-routespec-relocation)
**Component**: `_types/` (new file `route.py`); `replay_input/` (`tlog_route.py`, `__init__.py` modify); `components/c11_tile_manager/` (`route_client.py` modify)
**Tracker**: AZ-845 (https://denyspopov.atlassian.net/browse/AZ-845)
**Parent Epic**: AZ-844 (Refactor 02 — RouteSpec relocation + module-layout refresh + AZ-270 lint widening)
Jira AZ-845 is the authoritative spec; this file is the in-workspace mirror.
## Problem
`src/gps_denied_onboard/components/c11_tile_manager/route_client.py:56` imports `RouteSpec` from `gps_denied_onboard.replay_input.tlog_route`, violating `module-layout.md` rule 9 (AZ-507 cross-component contract surface). Per the rule, `components/<X>/*.py` may only import from `_types/*`, `_types.inference_errors`, `helpers/*`, `config`, `logging`, `fdr_client`, `clock`, `frame_source` (interface only), and its own subpackage. `replay_input` is not in this allow-list. Every other cross-component DTO already lives under `_types/*` (`_types/geo.py`, `_types/tile.py`, `_types/inference.py`, etc.); `RouteSpec` is the asymmetric outlier.
## Outcome
- `RouteSpec` is defined in `src/gps_denied_onboard/_types/route.py` (frozen+slots dataclass; full docstring carried over verbatim).
- `c11_tile_manager/route_client.py:56` imports `RouteSpec` from `gps_denied_onboard._types.route`.
- `replay_input/tlog_route.py` continues to use `RouteSpec` internally (extractor return type) by importing from `_types.route`; keeps `RouteSpec` in `__all__` for backward-compat re-export.
- `replay_input/__init__.py` re-exports `RouteSpec` from `_types.route` directly.
- All existing tests pass at HEAD.
- Rule-9 audit reports zero violations after the move.
## Scope
### Included
- New file: `src/gps_denied_onboard/_types/route.py` with `RouteSpec` dataclass.
- Modify `src/gps_denied_onboard/replay_input/tlog_route.py` (remove local definition, add import).
- Modify `src/gps_denied_onboard/replay_input/__init__.py` (re-export from `_types.route`).
- Modify `src/gps_denied_onboard/components/c11_tile_manager/route_client.py:56` (the rule-9 fix) plus the docstring snippet at file-top that names the source module.
- Optional hygiene: update 5 test files that import `RouteSpec` from `replay_input.tlog_route` directly (`tests/unit/replay_input/test_tlog_route.py`, `tests/unit/c11_tile_manager/test_route_client.py`, `tests/e2e/replay/_operator_pre_flight.py`, `tests/e2e/replay/test_e2e_orchestrator_unit.py`, `tests/e2e/replay/test_operator_pre_flight_driver.py`) to import from `_types.route` for symmetry.
### Excluded
- `RouteExtractionError` does NOT relocate — it is a `replay_input/`-specific error not imported by any `components/<X>/*.py` file.
- `extract_route_from_tlog` does NOT relocate — extraction logic is a `replay_input/` concern; only the DTO moves.
- No contract document at `_docs/02_document/contracts/shared_types/route.md`.
- No behaviour, performance, or contract-shape changes.
## Acceptance Criteria
| # | Criterion |
|---|-----------|
| AC-1 | `_types/route.py` contains `RouteSpec` with `@dataclass(frozen=True, slots=True)`, identical fields to the original (`waypoints`, `suggested_region_size_meters`, `source_tlog`, `source_segment`, `total_distance_meters`), and the full original docstring. |
| AC-2 | `route_client.py:56` reads `from gps_denied_onboard._types.route import RouteSpec`; rule-9 audit reports zero violations across `components/**/*.py`. |
| AC-3 | `replay_input/tlog_route.py` imports `RouteSpec` from `_types.route`; `extract_route_from_tlog` returns `RouteSpec`; `RouteSpec` is in `__all__` so `from replay_input.tlog_route import RouteSpec` resolves via re-export. |
| AC-4 | `from gps_denied_onboard.replay_input import RouteSpec` resolves to the same class object as `_types.route.RouteSpec` (verified by `is` identity check in test). |
| AC-5 | `pytest tests/unit/replay_input/test_tlog_route.py tests/unit/c11_tile_manager/test_route_client.py` passes — no failures, no skipped tests beyond pre-existing skips. |
## Constraints
- `RouteSpec` MUST remain `frozen=True, slots=True` (AZ-355 AC-2).
- `RouteSpec.__module__` MAY change to `gps_denied_onboard._types.route` (intended observable change; no test asserts on it).
- `from gps_denied_onboard.replay_input import RouteSpec` MUST keep working.
## Risks & Mitigation
**Risk 1 — pickle / serialization break**: confirmed by grep — no `pickle.dumps(route)` exists in `src/` or `tests/`. Risk does not materialize.
**Risk 2 — hidden import grep missed**: producer-side keeps `RouteSpec` in its namespace via re-import + `__all__`; lazy importers using the old path resolve correctly.
## Implementation Notes
- This is the anchor of refactor run 02-az507-routespec-relocation. AZ-846 (module-layout refresh) and AZ-847 (lint widening) are blocked by this task (Jira "Blocks" links recorded).
- After this task lands, run the rule-9 audit script (the widened lint from AZ-847 once it lands) to confirm zero violations.
@@ -0,0 +1,60 @@
# Refresh module-layout.md cycle-3 entries (c11 + replay_input + _types/route)
**Task**: AZ-846_refactor_module_layout_cycle3
**Name**: Refresh `module-layout.md` for cycle-3 file additions and the new `_types/route.py`
**Description**: Resolve cycle-3 cumulative review F2 (Medium Architecture). Update the c11_tile_manager Internal list, the shared/replay_input file list, and the `_types/` section in `module-layout.md` so they match on-disk reality. Cycle-2 carry-overs OUTSIDE these three sections are explicitly out of scope (deferred to a separate doc task).
**Complexity**: 2 SP
**Dependencies**: AZ-845 (the new `_types/route.py` file must exist before this task can register it)
**Component**: `_docs/02_document/module-layout.md` (single file)
**Tracker**: AZ-846 (https://denyspopov.atlassian.net/browse/AZ-846)
**Parent Epic**: AZ-844 (Refactor 02 — RouteSpec relocation + module-layout refresh + AZ-270 lint widening)
Jira AZ-846 is the authoritative spec; this file is the in-workspace mirror.
## Problem
`module-layout.md` is stale. Cycle-3 cumulative review F2 documents:
- **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 from batch 107).
- **shared/replay_input file list** is missing `errors.py` (cycle-2 carry), `tlog_ground_truth.py` (cycle-2 carry), `tlog_route.py` (cycle-3 NEW from batch 106).
- **`_types/` file list** does not yet include `route.py` (added by AZ-845).
`/implement` Step 4 (File Ownership) treats `module-layout.md` as authoritative; staleness BLOCKS any future task touching unregistered areas. F2 is currently Medium; severity escalates to High if a fourth consecutive cycle leaves it stale.
## Outcome
- c11_tile_manager Internal list registers all 8 internals + `route_client.py`.
- shared/replay_input file list registers `errors.py`, `tlog_ground_truth.py`, `tlog_route.py`.
- `_types/` section registers `route.py` with a one-line description matching the convention of other `_types/*.py` entries.
- `git diff` shows additions only to those three sections — no other section, rule, or rule-text edit.
## Scope
### Included
- Append cycle-3 + relevant cycle-2-carry entries to the c11_tile_manager Internal list, the shared/replay_input file list, and the `_types/` section.
### Excluded
- **Cycle-2 carry-overs OUTSIDE these sections**: `replay_api/` Per-Component Mapping entry, `cli/render_map.py`, `cli/replay_api_entrypoint.py`, `helpers/gps_compare.py`, `helpers/accuracy_report.py`. These are recorded in the cycle-3 retrospective and require a separate follow-up doc task with its own AZ ID.
- No code changes.
- No changes to `module-layout.md` rule numbering or rule text. Only the per-section file inventories are updated.
## Acceptance Criteria
| # | Criterion |
|---|-----------|
| AC-1 | c11_tile_manager Internal list contains all 8 existing internals (`_types.py`, `config.py`, `errors.py`, `idempotent_retry.py`, `signing_key.py`, `tile_downloader.py`, `tile_uploader.py`) plus `route_client.py`, alphabetised. |
| AC-2 | shared/replay_input file list adds `errors.py`, `tlog_ground_truth.py`, `tlog_route.py` with one-line descriptions matching the existing convention. |
| AC-3 | `_types/` section includes `route.py` with a one-line description of `RouteSpec` (waypoints + region size + source tlog provenance), identifying its producer (`replay_input/tlog_route.py`) and consumer (`c11/route_client.py`). |
| AC-4 | Diff of `module-layout.md` shows edits to ONLY the three named sections; no edits to other sections, rule numbering, or rule text. |
## Constraints
- Single file modified: `_docs/02_document/module-layout.md`.
- No tests required — documentation update.
- Scope discipline: cycle-2 doc carry-overs outside the three sections remain deferred.
## Risks & Mitigation
**Risk 1 — scope creep into cycle-2 carry-overs**: the Excluded list is explicit; Phase-4 implementer reviews the diff against ACs and rejects entries outside the three named sections at review.
@@ -0,0 +1,61 @@
# Widen test_az270_compose_root lint to enforce full rule-9 allow-list
**Task**: AZ-847_refactor_az270_lint_widening
**Name**: Widen `test_ac6_only_compose_root_imports_concrete_strategies` to enforce the full rule-9 allow-list
**Description**: Resolve cycle-3 cumulative review F3 (Medium Maintainability). Replace the AZ-270 lint's narrow `components → components` check with a full rule-9 allow-list check, so any future cross-component drift is caught at lint time rather than at cumulative-review time. Strict superset of the existing AC-6 check.
**Complexity**: 2 SP
**Dependencies**: AZ-845 (the widened lint must see a clean codebase to pass; running it against pre-AZ-845 HEAD is what AC-4 demonstrates as a one-time verification)
**Component**: `tests/unit/test_az270_compose_root.py` (single file)
**Tracker**: AZ-847 (https://denyspopov.atlassian.net/browse/AZ-847)
**Parent Epic**: AZ-844 (Refactor 02 — RouteSpec relocation + module-layout refresh + AZ-270 lint widening)
Jira AZ-847 is the authoritative spec; this file is the in-workspace mirror.
## Problem
`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. Imports from `replay_input`, `replay_api`, `runtime_root`, `cli/*`, and `frame_source` non-interface modules pass silently. F1 of the cycle-3 cumulative review (the c11 → replay_input edge) is the concrete consequence.
`module-layout.md` rule 9 documents this lint as the enforcement mechanism for the rule. Reviewers reasonably assume the lint covers the documented allow-list; in practice it covers only one of the eight prefixes. The asymmetry is the F3 finding.
## Outcome
- `test_ac6_only_compose_root_imports_concrete_strategies` enforces the full rule-9 allow-list: a `components/<X>/*.py` ImportFrom node is allowed iff the imported module matches one of: `gps_denied_onboard.components.<X>.*` (own component), `gps_denied_onboard._types.*`, `gps_denied_onboard._types.inference_errors`, `gps_denied_onboard.helpers.*`, `gps_denied_onboard.config`, `gps_denied_onboard.logging`, `gps_denied_onboard.fdr_client`, `gps_denied_onboard.clock`, `gps_denied_onboard.frame_source` (interface-only — see Constraints).
- The widened lint is a strict superset of the existing AC-6 narrow check.
- After AZ-845 lands, the widened lint reports zero violations.
- The test docstring cites `module-layout.md` rule 9, not just AZ-270 AC-6.
## Scope
### Included
- Modify `tests/unit/test_az270_compose_root.py` — the `test_ac6_*` test and its docstring.
- Add a small allow-list constant at module scope (single source of truth).
- Verify by `pytest tests/unit/test_az270_compose_root.py` after AZ-845 lands.
### Excluded
- Changes to other tests in the same file.
- Changes to production code.
- The `frame_source` interface-only enforcement: if AST-level disambiguation between interface and non-interface modules within `frame_source/*` is not feasible, allow-list only the explicit interface module path and reject other `frame_source.*` paths. Document in the test docstring.
## Acceptance Criteria
| # | Criterion |
|---|-----------|
| AC-1 | The lint flags any ImportFrom in `components/**/*.py` whose `module` starts with `gps_denied_onboard.` and is NOT in the rule-9 allow-list. |
| AC-2 | Strict superset of the existing AC-6 narrow check — every cross-component edge previously flagged is still flagged. |
| AC-3 | After AZ-845 lands, the widened lint reports zero violations. |
| AC-4 | Against the codebase BEFORE AZ-845 (verified during implementation by running the new lint on a temp checkout of pre-relocation HEAD), the lint produces a failure naming the c11 → replay_input edge and citing rule 9. |
| AC-5 | The test docstring cites `module-layout.md` rule 9 (AZ-507 cross-component contract surface) and lists the allow-list. |
## Constraints
- `frame_source` interface-only requirement: if AST-level disambiguation is not feasible, allow-list only the explicit interface module path. Document the chosen disambiguation strategy in the test docstring. Surface to user if the documented intent and codebase reality disagree.
- The existing test name MAY remain (preserves AZ-270 audit trail) or be renamed; if renamed, update `module-layout.md` rule 9's enforcement-citation.
- Single file modified: `tests/unit/test_az270_compose_root.py`. No production source change.
## Risks & Mitigation
**Risk 1 — widening exposes another rule-9 violation**: STOP-and-surface protocol. The implement skill MUST stop and present the additional violation as a scope-decision Choose to the user, NOT auto-bundle into this task. Remediation of any newly-exposed violation is a separate AZ ticket.
**Risk 2 — false positive on `gps_denied_onboard.frame_source` non-interface module**: documented disambiguation strategy in the test docstring. If wrong, the failure surfaces as a deterministic test failure, not silent drift; surface to user.