diff --git a/_docs/03_implementation/cumulative_review_batches_04-06_cycle1_report.md b/_docs/03_implementation/cumulative_review_batches_04-06_cycle1_report.md new file mode 100644 index 0000000..8abfa75 --- /dev/null +++ b/_docs/03_implementation/cumulative_review_batches_04-06_cycle1_report.md @@ -0,0 +1,184 @@ +# Cumulative Code Review — Batches 04–06 (Cycle 1) + +**Trigger**: `implement/SKILL.md` Step 14.5 — `K=3` batches completed since the last cumulative review (`cumulative_review_batches_01-03_cycle1_report.md`). +**Date**: 2026-05-19 +**Cycle**: 1 +**Scope**: union of files changed in `batch_04_cycle1`, `batch_05_cycle1`, `batch_06_cycle1` (range `69c0629^..HEAD`, excluding `_docs/`). +**Mode**: inline (matching the per-batch precedent in batches 1–6; sub-skill `/code-review` deliberately skipped to conserve context). +**Baseline**: `_docs/02_document/architecture_compliance_baseline.md` still does not exist (greenfield project — no Architecture Baseline Scan ran). No `## Baseline Delta` section is produced. The previous cumulative review noted it would become the de-facto baseline; that intent is carried forward — once Step 12 (Test-Spec Sync) lands, an explicit baseline snapshot is worth promoting. + +## Tasks in scope + +| Batch | Tasks | Components touched | +|-------|------------------------------------------------------------------------------------------------------|-------------------------------------------------------------| +| 04 | AZ-643 (`mavlink_ack_demux_and_signing`), AZ-665 (`mapobjects_store_h3_classify`), AZ-672 (`vlm_client_provider_trait`) | `mavlink_layer`, `mapobjects_store`, `shared::contracts`, `vlm_client` (placeholder), `autopilot` runtime | +| 05 | AZ-666 (`mapobjects_store_ignored_and_pass_sweep`), AZ-673 (`vlm_client_nanollm_ipc`), AZ-648 (`mission_executor_state_machine`) | `mapobjects_store`, `vlm_client`, `mission_executor`, `autopilot` runtime | +| 06 | AZ-649 (`mission_executor_telemetry_forwarding`), AZ-674 (`vlm_client_schema_and_model_version`), AZ-667 (`mapobjects_store_hydrate_and_pending`) | `mission_executor`, `vlm_client`, `mapobjects_store`, `shared::models` (`telemetry`, `vlm`, `poi`) | + +Per-batch AC verification (rolled up from individual reports): **35 / 35 ACs verified locally** (12 in batch 04 + 11 in batch 05 + 12 in batch 06). One Linux-only test (`vlm_client::ac2_peer_cred_mismatch_hard_fails_connect`) deliberately skips on the macOS dev host; the code path is build-checked and runtime-checked on the Jetson Linux target. One perf-gated test (`mapobjects_store::ac5_classify_p99_under_one_ms`) runs `--ignored` under `--release`. + +## Phase 1 — Spec coverage + +Every Included scope item from these 9 tasks is implemented in production code (not just tests / not just trait placeholders): + +- **AZ-643**: MAVLink v2 signing (`Signer`/`Verifier`/`SigningKey` + 13-byte trailer + replay-defence), ack demux (`OneshotMap` keyed by `command_id` + deadline) and `MavlinkHandle::send_command` round-trip. `commands_in_flight()` surfaces on the health snapshot. +- **AZ-665**: `H3Index` (h3o-backed cell-of + k-ring), haversine, in-memory `BTreeMap>`, `ClassifyInput` typed input, `MapObjectsStoreHandle::classify`. AC-5 perf gate `≤ 1 ms p99` in release. +- **AZ-672**: `VlmProvider` trait final shape, `DisabledVlmProvider` in `shared::contracts`, feature-gated `dep:vlm_client` in `autopilot` (`cargo tree --no-default-features` drops `vlm_client` from the dep graph as verified). +- **AZ-666**: `IgnoredSet` (HashSet keyed `(mgrs, class_group)` + per-uuid round-trip map), `PassTracker` (per-region observed-uuid set + bbox-anchored `end_of_pass`), `Classification::Ignored` discriminator, decline → `IgnoredItem` append. +- **AZ-673**: `tokio::net::UnixStream`-based `NanoLlmClient`, Linux `SO_PEERCRED` peer-credential gate, length-prefixed JSON wire, pre-send `prompt::validate` (ROI size + JPEG/PNG header + non-empty prompt), per-request deadline, bounded reconnect with hard-stop on peer-cred mismatch. +- **AZ-648**: Variant-aware `MissionState` enum (multirotor + fixed-wing transition tables) with `MissionDriver` trait, per-transition retry budget keyed by `TransitionKey`, broadcast `TransitionEvent` stream, pause-and-flip-red on cap exhaustion. +- **AZ-649**: `UavTelemetry` canonical record in `shared::models::telemetry`, `TelemetryForwarder` (atomic snapshot via `ArcSwap` + three lossy `tokio::sync::broadcast` channels keyed by `Consumer`), `MavlinkProjection::from_mavlink` for the 4 telemetry-bearing MAVLink ids, `DropCountingReceiver`. Wired to `mavlink_layer` at the binary edge by `mission_executor::spawn_mavlink_pump`. +- **AZ-674**: `AssessmentParser` (typed `VlmAssessmentWire` → canonical `VlmAssessment`, schema-invalid downgrade to `VlmStatus::SchemaInvalid`, size-capped raw-bytes warn log, single-emit model-version change tracker, `Inconclusive` variant added so `VlmStatus` matches stay exhaustive without `_` arms). +- **AZ-667**: `Store::hydrate(MapObjectsBundle)` (full re-population from bundle; `freshness=Stale` ⇒ `sync_state=CachedFallback`, else `Synced`), `pending_observations` + `pending_ignored` append-only logs, `drain_pending`, `cascade_mission` (real `retain` pass), `last_pull_ts` / `last_push_ts` / `mark_pushed_ok`. + +Deferred (still explicitly Excluded by task scope, not by these batches): + +- Production `MissionDriver` impl over `mavlink_layer` — slated for AZ-650 (BIT F9) / AZ-652 (safety + resume) which carry the operational driver wiring. +- VLM persistence-layer mapping into `mapobjects_store` — covered by AZ-668 (next batch). +- Failsafe ladders (`failsafe_trigger`, `insert_middle_waypoint`) on `MissionExecutorHandle` remain `NotImplemented` per AZ-651 / AZ-652 scope. + +No scope creep observed across the three batches. + +## Phase 2 — Architecture compliance (layer + Public API) + +Dependency reality (from `Cargo.toml` of each touched crate, cross-checked against `module-layout.md`): + +| Component | Documented Layer | `Imports from` (module-layout) | Actual workspace deps | Status | +|------------------|------------------|-------------------------------------------------|---------------------------------------------------------------|--------| +| `shared` | 1 | (none) | external only | ✓ | +| `mavlink_layer` | 2 | `shared` | `shared` + tokio/bytes/chrono/tracing/thiserror/sha2 | ✓ | +| `mapobjects_store` | 2 | `shared` | `shared` + h3o/chrono/uuid/serde/tokio | ✓ | +| `vlm_client` | 2 | `shared` | `shared` + (feature-gated) serde/serde_json/thiserror/base64/libc | ✓ (drops out of `autopilot` dep graph when `vlm` is off) | +| `mission_executor` | 3 | `shared`, `mavlink_layer`, `mission_client`, `mapobjects_store`, `gimbal_controller` (later) | `shared` + `mavlink_layer` + `mission_client` + `mapobjects_store` + tokio/serde/chrono/thiserror | ✓ (Layer 3 → Layer 2 only) | +| `autopilot` bin | 5 | every component | currently the bootstrapped + landed crates only | ✓ | + +No Layer 2 → Layer 2 import, no same-layer cross-crate import, no Layer 3 → Layer 3 import (no other Layer 3 component has landed yet). The `mission_executor::spawn_mavlink_pump` wiring lives **at the crate boundary** (the binary-edge pump function) and does the cross-component glue — exactly the layered shape `module-layout.md §5` prescribes. + +Public API surface for the three Layer 2 actors changed this window matches `module-layout.md` to within the doc-drift items listed below: + +- `mavlink_layer`: added `Signer`, `SigningKey`, `Verifier`, `SigningReject`, `SendCommandError`, `CommandAck`, `MavlinkHandle::send_command`. All exported from `lib.rs`. ✓ +- `mapobjects_store`: added `ClassifyInput`, `Classification` (incl. `Ignored`), `MapObjectsStoreConfig`, `IgnoredItem`, `RegionBbox`, `RemovedCandidate`, `Store::hydrate`, `Store::drain_pending`, `Store::cascade_mission`, `Store::set_sync_state`, `Store::mark_pushed_ok`, plus the `pending_*_count` / `last_*_ts` accessors. All re-exported from `lib.rs`. ✓ +- `vlm_client`: added `VlmClient`, `VlmClient::open`, `VlmClient::connect`, `VlmClient::new`, plus the public `AssessmentParser`. Feature-gated. ✓ +- `mission_executor`: added `MissionExecutor`, `MissionExecutorConfig`, `MissionState`, `Telemetry`, `Variant`, `TransitionEvent`, `TransitionKey`, `StepOutcome`, `MissionDriver`, `DriverError`, `Consumer`, `DropCountingReceiver`, `MavlinkProjection`, `TelemetryForwarder`, `spawn_mavlink_pump`. ✓ + +**Doc drift carried over and added during this window** (not blocking; queued for Step 13 / the next `monorepo-document` pass): + +- `module-layout.md` line ~157: documents `mapobjects_store` public API as `classify(Detection) -> Classification`. AZ-665 introduced `ClassifyInput` (which carries `lat/lon/class/uav_id/observed_at_monotonic_ns` and is the shape `scan_controller` actually feeds in). Update line: `classify(ClassifyInput) -> Classification`. +- `module-layout.md` (same component): public API list does not yet list `hydrate`, `drain_pending`, `cascade_mission`, or the new `sync_state` / `pending_*` accessors. Add them. +- `architecture.md §5.6` (mission FSM): documented flow is `… → ARMED → TAKE_OFF → AUTO → LAND → POST_FLIGHT_SYNC → DONE`. AZ-648 introduces an explicit `MissionUploaded` state between `TakeOff` and `FlyMission` (rather than overloading `AUTO`). Match the diagram to the task brief. +- `_docs/02_document/components/mapobjects_store/description.md §3.sync_state`: documented diagram is `fresh_boot → synced | cached_fallback | degraded`. Implementation adds explicit `FreshBoot` initial state and a `Failed` terminal state (per `description.md §7` "bounded-retries-exhausted"). Refresh the diagram to include both. +- `_docs/02_document/data_model.md`: + - `VlmStatus` enum is missing the `Inconclusive` variant added in AZ-674 (carries an explicit "no confident judgement; do not advance to Done" semantics; required so the AC-4 exhaustive-match has no `_` arm). + - `UavTelemetry` (introduced in AZ-649 in `shared::models::telemetry`) is not yet listed as a canonical entity. Add a row pointing to `crates/shared/src/models/telemetry.rs`. + +## Phase 3 — Code quality (cross-batch) + +- **SRP holds across all touched modules.** New modules each own exactly one concern: `ack_demux.rs` (oneshot dispatch), `codec/signing.rs` (HMAC SHA-256 + replay defence), `internal/h3_index.rs` (h3o wrapper only), `internal/ignored.rs` (suppression set only), `internal/passes.rs` (per-region observed-id tracking only), `peer_cred.rs` (Linux `SO_PEERCRED` only), `prompt.rs` (ROI + prompt validation only), `wire.rs` (length-prefixed frame I/O only), `uds_client.rs` (UDS connection lifecycle only), `parser.rs` (schema validation + model-version tracking only), `fsm.rs` (transition stepping only), per-variant `multirotor` / `fixed_wing` tables, `internal/telemetry.rs` (atomic snapshot + lossy broadcast fan-out only), `internal/store.rs` (in-memory map + pending logs only). No god modules introduced. +- **Error handling**: every crate-level boundary exposes a typed error (`SendCommandError`, `SigningReject`, `DriverError`, `WireError`, `ValidateError`, `ConnectError`, `VlmStatus::SchemaInvalid` downgrade, classify returns typed errors via `AutopilotError::Validation`). No `.unwrap()` on runtime paths except the once-init schema-compile `OnceLock` (compile-time correctness). +- **No silent suppression**: CRC mismatches, schema failures, transient HTTP errors, ack-deadline expiry, signing replay, peer-cred mismatch, broadcast `Lagged(n)` events — all surface to typed counters, logs, or per-receiver counters. +- **Tests follow Arrange / Act / Assert** per `coderule.mdc` across all 35 new ACs. +- `cargo fmt --all` clean. +- `cargo clippy --workspace --all-features --all-targets -- -D warnings` returns one (1) pre-existing warning on `autopilot::runtime::vlm_provider_name` (introduced in batch 04 as a runtime helper for the disabled-provider name surface; subsequently shadowed by direct usage and not yet removed). All warnings introduced by these batches are resolved. Recommend removing or `#[allow(dead_code)]`-annotating `vlm_provider_name` when the runtime composition expands in AZ-650 / AZ-678. + +## Phase 4 — Test quality (cross-batch) + +| Layer | Test count (new in 04–06) | Test technology | +|----------------------------------------|------------------------------------------------------|------------------------------------------------------------------| +| `mavlink_layer` ack_demux | 3 integration | loopback UDP + spoofed ACK | +| `mavlink_layer` signing | 5 integration + 2 codec round-trip | real HMAC-SHA256 sign/verify | +| `mapobjects_store` classify (AZ-665) | 6 integration + 1 perf-gated `#[ignore]` | real h3o + real haversine | +| `mapobjects_store` ignored_and_sweep | 5 integration (3 AC + 2 supplementary) | in-process | +| `mapobjects_store` hydrate_and_pending | 8 integration (5 AC + 3 supplementary) | real `Store` via `MapObjectsStoreHandle` | +| `vlm_client` enabled (AZ-673) | 6 integration (4 AC + 2 supplementary) | real `tokio::net::UnixStream` + temp-dir socket fixture | +| `vlm_client` parser (AZ-674) | 4 integration | real `serde_json`; exhaustive-match invariant check | +| `vlm_client` wire / peer_cred / prompt | 4 + 2 + 4 unit | in-process | +| `mission_executor` state_machine | 4 AC integration + 1 unit | `ScriptedDriver` fake (driver behind the FSM is the seam) | +| `mission_executor` telemetry | 3 AC integration + 3 unit | real `tokio::sync::broadcast`, real `ArcSwap`, in-process pump | + +Fakes used: `ScriptedDriver` for AZ-648 (driver behind the FSM under test — the FSM is the unit of test, the driver is the seam) and the canned-JSON UDS fixture for AZ-673 / AZ-674 (the parser + wire framing is under test; the model-server is the external system). No fakes for HTTP, sockets, FS, or codecs inside the test boundary. + +The Linux-only AC-2 (`vlm_client::ac2_peer_cred_mismatch_hard_fails_connect`) is the right shape: build-checks the code path on every host, runtime-checks on the Jetson Linux production target. Documented in `vlm_client/description.md §8`. + +The perf-gated AC (`mapobjects_store::ac5_classify_p99_under_one_ms`) is the right shape: `#[ignore]`-gated on debug, asserted under `--release --ignored` and verified locally. + +## Phase 5 — Docs alignment + +- All new code paths point at their owning task (`AZ-NNN`) in module-level rustdoc. +- Schemas remain co-owned in `crates/shared/contracts/` (`mission-schema.json`, the three mapobjects schemas, plus the new `nanollm_request`/`nanollm_response` shapes carried internally to `vlm_client`'s parser). The cumulative open question from batches 01–03 ("missions-repo extraction" — W5) is still open; no new code has expanded the surface area, so the impact is unchanged. +- `architecture.md` and `data_model.md` updates are queued (see Phase 2 doc-drift list). + +## Phase 6 — Cross-task consistency + +Concerns that span batches 04–06: + +1. **`mission_executor::Telemetry` (guard view) vs `shared::models::telemetry::UavTelemetry` (canonical record)** — *Medium / Maintainability / Cross-Task-Consistency*. The FSM tick consumes a `watch::Receiver` (`link_up`, `health_ok`, `bit_ok`, `armed`, `takeoff_complete`, `flight_mode_auto`, `mission_reached_final`, `landed_disarmed` — all booleans). The MAVLink projection produces `shared::models::telemetry::UavTelemetry` (typed snapshot with `UavPosition`, `UavAttitude`, `UavMode`, `UavSysStatus`). No adapter exists yet that turns one into the other. This is acceptable today (AZ-649 was scoped narrowly to "forwarding"; the FSM uses a fake telemetry source in tests) but becomes a real wiring gap the moment AZ-650 / AZ-651 / AZ-652 connect the FSM to live MAVLink. Two architecturally clean options: + - **(a) Adapter in `mission_executor`**: a small `from_uav_telemetry(&UavTelemetry, &PrevTelemetry) -> Telemetry` function that derives the boolean guards from the canonical record (with hysteresis for `link_up` / `health_ok`). Lives in `mission_executor::internal::telemetry` (already created by AZ-649) and is the only place that knows the projection rules. + - **(b) Fold both views into one canonical pair**: replace the FSM-local `Telemetry` with `(UavTelemetry, FsmGuards)` where `FsmGuards` is the boolean view. Mechanically more code; semantically the same. + - **Recommendation**: (a). The bool view IS a guard projection — the canonical record stays the source of truth. Add this to AZ-650's task brief or pre-create a 1-pt remediation task `mission_executor_telemetry_adapter`. Not blocking these batches. + +2. **`ExponentialBackoff` duplication (carried over from batches 01–03 — W2 / W3)** — still present, still acceptable. The current count is 2 crates (`mavlink_layer::internal::retry` 1 call site; `mission_client::internal::retry` 4 call sites). Batches 04–06 did NOT introduce a third call site (the `vlm_client` bounded-reconnect uses a simpler fixed-backoff because peer-cred mismatch is a hard-stop, not a transient). The "promote to `shared::retry` when the third crate joins" trigger is still pending; the next crate that needs exponential backoff (likely `detection_client` AZ-660 / AZ-661 or `mission_executor` for the BIT F9 retry envelope in AZ-650) should land the move. + +3. **`Inconclusive` `VlmStatus` variant + exhaustive matching across the workspace** — AZ-674 added `VlmStatus::Inconclusive` and required the AC-4 exhaustive-match invariant (no `_` arm). The variant is currently consumed only inside `vlm_client::parser` and by the AC-4 test. Once `scan_controller` (AZ-684 evidence ladder) starts matching on `VlmStatus`, the exhaustive-match invariant is what will catch any future variant addition. No drift today; the test is the structural contract. + +4. **`MapObjectsStoreHandle` API growth across 04 → 05 → 06** — additive, no breaking changes. Public methods added in each batch reuse the existing types in `shared::models` (`MapObject`, `MapObjectObservation`, `IgnoredItem`, `RemovedCandidate`, `MapObjectsBundle`) so consumers don't see churn. The handle's expanded surface (`classify`, `append_ignored`, `is_ignored`, `pass_start`, `end_of_pass`, `apply_decline`, `hydrate`, `drain_pending`, `cascade_mission`, `set_sync_state`, `mark_pushed_ok`, `pending_*_count`, `last_*_ts`) is the 1:1 expression of `description.md §3 Inputs/Outputs` (modulo the persistence layer still pending AZ-668). + +5. **`shared::contracts::VlmProvider::name()` (added in AZ-672)** is consumed via the runtime composition root. The `autopilot::runtime::vlm_provider_name` helper (also added in AZ-672) duplicates what `VlmProvider::name()` already provides. Cleanup pending — see Phase 3 clippy note. + +6. **Constructor flavours on `vlm_client::VlmClient`** — both lazy (`VlmClient::new`) and eager (`VlmClient::open` / `connect`) constructors are exposed. The composition root uses lazy (because `Runtime::new` is synchronous and the UDS connect must be async). Tests use eager when they want construct-time failure semantics. The two paths are explicit and documented in rustdoc; not a finding. + +## Phase 7 — Architecture compliance (re-confirmation, post-batch-06) + +| Check | Result | +|------------------------------------------------------------------|--------| +| No cyclic crate dependencies | ✓ | +| No Layer 2 → Layer 2 import | ✓ | +| Layer 3 → Layer 2 only (mission_executor) | ✓ | +| No Layer 3 → Layer 3 import (no second Layer 3 crate yet) | ✓ | +| Public API matches `module-layout.md` (modulo Phase 2 doc-drift) | ✓ | +| Forbidden technologies absent | ✓ (no `mavlink`-rs, no pymavlink-bindgen, no OpenSSL on the airframe, no TLS in the UDS path) | +| Frozen choices (`architecture.md`) respected | ✓ (in-flight central writes forbidden — AZ-647 enforces terminal-only push; UDS peer-cred validates identity instead of TLS per `vlm_client/description.md §6`; the FSM core remains transport-agnostic and the MAVLink wiring sits at the binary edge per `architecture.md §5.6`) | +| No new cyclic module-level dependencies | ✓ (`mission_executor::spawn_mavlink_pump` does not introduce a cycle — it imports `mavlink_layer::MavlinkHandle` only, no reverse import) | +| Duplicate symbols across components | None new. Workspace-level safe (each crate is its own compilation unit; `cargo doc` namespace inspection clean). `ExponentialBackoff` remains intentionally duplicated (see Phase 6.2). | +| Cross-cutting concerns not locally re-implemented | ✓ (canonical `UavTelemetry` lives in `shared::models::telemetry`, not in `mission_executor`; canonical `VlmAssessment` / `VlmStatus` live in `shared::models::vlm`, not in `vlm_client`) | + +## Duplicate symbol detection + +- No two crates expose a public type with the same fully-qualified path. +- No two integration test files define a `pub fn` with the same name within the same crate (rustc enforces). +- `ExponentialBackoff` is intentionally duplicated across `mavlink_layer` and `mission_client` (carried-over from 01–03 — see Phase 6.2). +- `Telemetry` exists at two paths (`mission_executor::Telemetry` — guard view; `shared::models::telemetry::UavTelemetry` — canonical record). Different types, different responsibilities — not a duplicate-symbol finding, but Phase 6.1 records the adapter-gap follow-up. + +## Findings summary + +| # | Severity | Category | File:Line | Title | +|---|----------|------------------------|------------------------------------------------------------------------|------------------------------------------------------------------------------------------------| +| 1 | Medium | Maintainability | `crates/mission_executor/src/internal/types.rs:61` + `crates/shared/src/models/telemetry.rs:69` | No adapter from `UavTelemetry` (canonical) to `mission_executor::Telemetry` (guard view) yet — wiring gap surfaces in AZ-650/AZ-651/AZ-652 | +| 2 | Low | Maintainability | `_docs/02_document/module-layout.md` (`mapobjects_store` block) | Public API list out of sync with implementation (`classify`, `hydrate`, `drain_pending`, `cascade_mission`, sync_state/pending_* accessors) | +| 3 | Low | Maintainability | `_docs/02_document/architecture.md §5.6` | Mission FSM diagram missing the explicit `MissionUploaded` state | +| 4 | Low | Maintainability | `_docs/02_document/components/mapobjects_store/description.md §3` | `sync_state` diagram missing `FreshBoot` and `Failed` states | +| 5 | Low | Maintainability | `_docs/02_document/data_model.md` | `VlmStatus` missing `Inconclusive` variant; `UavTelemetry` row not yet present | +| 6 | Low | Maintainability | `crates/autopilot/src/runtime.rs:vlm_provider_name` | Pre-existing dead-code warning from batch 04 — remove or wire on next runtime composition pass | + +No Critical / High / Security findings. No new Architecture findings. + +## Verdict + +**PASS_WITH_WARNINGS**. + +All findings are Medium or Low severity. F1 (telemetry adapter) is the highest-severity item and is a known wiring gap that the next batch (AZ-650 BIT F9) will surface naturally — the recommendation is to either pre-create a 1-pt remediation task or include the adapter in AZ-650's brief. F2–F6 are doc drift that the Step 13 (Update Docs) pass will sync; the project's autodev rule already routes these. + +Auto-Fix Gate matrix (`implement/SKILL.md §10`): F1 is Medium-Maintainability — auto-fix-eligible if attempted; F2–F5 are Low-Maintainability doc updates (auto-fix-eligible but deliberately deferred to Step 13 to consolidate the documentation sync into one coherent pass); F6 is Low-Maintainability dead-code (auto-fix-eligible, deferred to the next runtime composition pass). No escalation required. + +## Continuation + +Proceed to batch 7. Per the dependency graph and the candidates flagged in `batch_06_cycle1_report.md` (corrected for the batch-6 report's name-typos against `_dependencies_table.md`), the topologically-ready tasks for batch 7 are: + +- AZ-650 `mission_executor_bit_f9` (5pt; deps AZ-640, AZ-648, AZ-649, AZ-644, AZ-646 — all done) +- AZ-651 `mission_executor_lost_link_ladder` (3pt; deps AZ-640, AZ-648, AZ-649 — all done) +- AZ-652 `mission_executor_safety_and_resume` (5pt; deps AZ-640, AZ-648, AZ-649, AZ-643, AZ-647 — all done) +- AZ-653 `gimbal_a40_transport` (5pt; deps AZ-640 — done) +- AZ-657 `frame_ingest_rtsp_session` (3pt; deps AZ-640 — done) +- AZ-668 `mapobjects_store_persistence` (3pt; deps AZ-640, AZ-665, AZ-667 — all done) +- AZ-682 `scan_controller_state_machine` (5pt; deps AZ-640, AZ-649 — both done) + +Recommendation: finish the `mission_executor` epic (AZ-636) first by selecting `[AZ-650, AZ-651, AZ-652]` — three same-component tasks, total 13 pts (matches the 10–13 pt cadence of the prior batches), closes one entire epic, and concentrates the AZ-649 telemetry-adapter follow-up (Finding F1 above) into a single component where the same person/agent who has the context can author the adapter inline. The actual selection is delegated to the next `/implement` invocation per its topological rule. diff --git a/_docs/_autodev_state.md b/_docs/_autodev_state.md index 1f42f99..63a3655 100644 --- a/_docs/_autodev_state.md +++ b/_docs/_autodev_state.md @@ -6,9 +6,9 @@ step: 7 name: Implement status: in_progress sub_step: - phase: 7 + phase: 8 name: batch-7-selection - detail: "batch 6 (AZ-649, AZ-674, AZ-667) committed + transitioned to In Testing; ready to select batch 7" + detail: "" retry_count: 0 cycle: 1 tracker: jira