# Retrospective — 2026-05-20 > Cycle-1 retrospective for GPS-Denied Onboard. Cycle 1 spans > 2026-05-11 → 2026-05-20 (Problem → Deploy → this retro). This is the > **first** retro for the project — no prior baseline. Generated by > `/autodev` greenfield Step 17 (Retrospective, cycle-end mode). ## Implementation Summary | Metric | Value | |--------|-------| | Total tasks (done) | 165 (product + test + hygiene + refactor) | | Total tasks (backlog) | 2 (AZ-592, AZ-593 — Tier-2 OKVIS2 / VINS-Mono validation) | | Total tasks (todo) | 0 | | Total batches | 97 (cycle 1) | | Cycle duration | 9 days (2026-05-11 → 2026-05-20) | | Avg tasks per batch | ≈ 1.7 | | Estimated total complexity points | ≈ 565 cp (sampled: 80 × 3 cp, 50 × 5 cp, 30 × 2 cp, plus a handful of 4 cp and 0 cp umbrella) | | Source LoC | 61,071 Python (src/) | | Components | 15 (C1, C2, C2.5, C3, C3.5, C4, C5, C6, C7, C8, C10, C11, C12, C13 + helpers/runtime_root) | | Binary tracks | 3 (airborne, research, operator-orchestrator) per ADR-002 + ADR-011 | ## Quality Metrics ### Product Implementation Completeness Gate (Step 7 → Step 8) Source: `_docs/03_implementation/implementation_completeness_cycle1_report.md` (revised 2026-05-19 addendum). | Verdict | Count | Percentage | |---------|-------|------------| | PASS | 114 | 98.3 % | | BLOCKED-with-named-Tier-2-handle | 4 | 3.4 % (overlaps; 2 share one hardware artifact) | | FAIL | 0 | 0 % | The 4 BLOCKED items are: **AZ-332** (OKVIS2 production-default VIO native binding → AZ-592 backlog), **AZ-333** (VINS-Mono research-only VIO → AZ-593 backlog), **AZ-624 AC-5** + **AZ-687 AC-687-3** (Jetson Tier-2 evidence file `_docs/03_implementation/jetson_runs/2026-05-19_az687_tier2_run.txt` pending). ### Code Review Verdicts (sampled across batches 50..97) The verdict field is consistently `**Verdict**:` in batches ≥ 53. Earlier batches (01–22) use a different convention and are captured in the consolidated `cumulative_review_batches_01-22_cycle1_report.md`. | Verdict | Approximate count (batches 53..97) | Notes | |---------|------------------------------------|-------| | PASS | ~24 | Includes single-task batches with inline self-review | | PASS_WITH_WARNINGS | ~30 | Includes 38 files matching the verdict phrase | | FAIL | 0 | No batch failed the in-loop review across the full cycle | | BLOCKED | 0 (at batch level; 4 at task level — see Completeness Gate above) | | Auto-fix loop never had to escalate to user intervention across cycle 1. ### Findings by Severity (latest 3 cumulative review windows: 70-72, 82-87, 88-92) | Severity | Count (rolling 3-window) | Trend | |----------|---------------------------|-------| | Critical | 0 | — | | High | 0 | — | | Medium | 2 (CR-F1 csv-helper, CR-F2 fixture-path-helper — both escalated and still OPEN at end of cycle 1) | Carried over from window 85-87 → 88-92 | | Low | ~5 (5 in batch 87, 3 in batch 85, 2 each in batches 83/84, 1 in batch 81) | Trending down across late batches | | Info | many — process notes, no action | — | ### Findings by Category (qualitative, since aggregate metrics across all 97 batches would need per-finding tagging that isn't uniform across early batches) | Category | Notable patterns | Top files | |----------|------------------|-----------| | Bug | Essentially none post Step 11 (Run Tests) — the iSAM2 ordering issue in AZ-625 was caught + fixed mid-batch | — | | Spec-Gap | AZ-595 dependency surfaced late (blocks 17 NFT scenarios); AZ-687 replay-mode guard emerged from AZ-624's Jetson run | `e2e/_unit_tests/helpers/`, `e2e/runner/helpers/` | | Security | OpenCV CVE pin replay condition tracked since 2026-05-11 (gtsam numpy<2 ABI block); per `_docs/05_security/dependency_scan.md` re-validated against current pin — no advisory exposure | `pyproject.toml` | | Performance | NFT-PERF Tier-2 baselines pending AZ-595 + AZ-592/AZ-593; cycle-1 Tier-1 probe completed 2026-05-19 | `_docs/06_metrics/perf_2026-05-19_workstation-tier1-probe.md` | | Maintainability | Two helper-duplication patterns surfaced (CR-F1, CR-F2) — 5 cp combined hygiene PBI proposed | `e2e/runner/helpers/csv_evidence_writer`, `e2e/runner/helpers/fixture_path` | | Style | Minimal — `ruff` is run pre-commit + in the e2e-runner; batch 91 opportunistically cleaned 12 pre-existing UP037 lints in `airborne_bootstrap.py` | `airborne_bootstrap.py` | | Scope | One mid-cycle scope correction — AZ-589/AZ-590 closed Won't Fix after post-mortem found the actual gap was cross-cutting (empty `_STRATEGY_REGISTRY`), not per-strategy C++ wiring. Re-decomposed into AZ-591 + AZ-592/AZ-593 backlog | `runtime_root/__init__.py` → `airborne_bootstrap.py` | ## Structural Metrics `_docs/02_document/architecture_compliance_baseline.md` does **not** exist — cumulative reviews could not emit `## Baseline Delta` sections through cycle 1. This is a known gap (see Improvement Action #3 below). | Metric | Value | Trend | |--------|-------|-------| | Component count | 15 | First-cycle baseline | | Source LoC (Python, src/) | 61,071 | First-cycle baseline | | Cycles in component import graph | 0 | Healthy — no back-edges in `runtime_root.airborne_bootstrap → {clock, fdr_client, runtime_root.*_factory, runtime_root.{storage,inference,errors,…}}` | | Cross-component edges | Concentrated in `runtime_root/` factories (composition root by design) | Healthy — single composition seam | | Contract files | `_docs/02_document/contracts/shared_*/` populated for FDR record schema (v1.3.0), log record schema (v1.0.0), C8 transport, post-landing upload, ingest (D-PROJ-2 placeholder) | First-cycle baseline; coverage % vs public-API symbols not computed (no inventory) | | Architecture violations net delta | n/a (no baseline) | Recommend establishing the baseline file in cycle 2 Step 6 | A structural snapshot for future delta comparison is recorded in `_docs/06_metrics/structure_2026-05-20.md` (next item in this retro). ## Efficiency | Metric | Value | |--------|-------| | Blocked tasks (cycle-1 close) | 4 (all Tier-2 hardware / evidence rooted) | | Tasks requiring fixes after review | ~5 (Medium/Low warnings landed as hygiene PBIs, not as in-cycle fixes) | | Auto-fix loop escalations to user | 0 | | Mid-cycle remediation post-mortems | 1 (AZ-589/AZ-590 → AZ-591) | | Mid-cycle scope rewinds | 1 (Step 11 Run Tests → Step 7 Implement, for AZ-618 cross-cutting umbrella with 12 builder signatures; surfaced as 2026-05-18 lessons entry already in LESSONS.md) | | Batch with most findings | Batch 87 (`PASS_WITH_WARNINGS — 0 Critical, 0 High, 0 Medium, 5 Low`) — late-cycle e2e helper polish | | Out-of-loop process leftover | D-CROSS-CVE-1 OpenCV pin deferred on upstream `gtsam` numpy<2 ABI; re-checked at every `/autodev` invocation per leftover protocol | ### Blocker Analysis | Blocker Type | Count | Prevention (carries to cycle 2) | |--------------|-------|----------------------------------| | Tier-2 hardware/evidence (Jetson Orin) | 4 | Allocate Tier-2 Jetson access for AZ-595 + AZ-624 AC-5 re-run + AZ-687 AC-687-3; AZ-592/AZ-593 unblocked only when CI build env + DBoW2 vocab + upstream choice are decided. | | Upstream library pin (D-CROSS-CVE-1) | 1 | Out-of-band — replay condition is `gtsam` numpy-2 wheels (or alternate SE(3) backend). Re-check is debounced ≤ 2 h per leftover entry; no action needed in dev cycle. | | Mid-cycle scope correction | 1 | The fix already informed the 2026-05-18 LESSONS entry. Cross-cutting registry/factory state should be probed before classifying a per-task FAIL. | ## Trend Comparison *Previous retrospective: N/A — first retro.* Cycle 1 establishes the baseline. From cycle 2 onward, this section will compare against: | Metric | Current (cycle-1 baseline) | Target (cycle-2) | |--------|-----------------------------|-------------------| | Code-review pass rate (PASS / total) | ≈ 44 % PASS, ≈ 55 % PASS_WITH_WARNINGS, 0 % FAIL | Maintain 0 % FAIL; lift PASS share by landing CR-F1 + CR-F2 hygiene PBIs early | | Avg findings per batch (Medium + Low) | ~0.2 (≈ 16 total Medium/Low across 97 batches, dominated by helper-duplication carryovers) | ≤ 0.15 | | Blocked tasks (cycle close) | 4 (all Tier-2 rooted) | ≤ 2; AZ-624 AC-5 + AZ-687 AC-687-3 close once the Tier-2 run lands | | Mid-cycle remediation post-mortems | 1 | 0 | | Structural baseline file present | No (gap) | Yes | ## Top 3 Improvement Actions 1. **Land the two open hygiene PBIs (CR-F1 + CR-F2) before any new NFT helper expansion in cycle 2.** - Impact: drops the only carried-over Medium findings; consolidates `csv_evidence_writer` + `fixture_path.resolve` into one canonical helper module under `e2e/runner/helpers/`; unblocks future NFT additions without duplication drift. - Effort: low (combined 5 cp; both already pre-decomposed in `cumulative_review_batches_88-92_cycle1_report.md`). 2. **Sequence AZ-595 (SITL observer + FDR replay fixture) as the first product task of cycle 2.** - Impact: closes 17 NFT scenarios in one PBI — every NFT-PERF / NFT-RES / NFT-SEC scenario that currently `sitl_replay_ready`-skips on the Tier-1 docker harness. Also unblocks the Tier-2 evidence files for AZ-624 AC-5 + AZ-687 AC-687-3 once Jetson hardware is available. - Effort: medium (5 cp, in scope of a single batch; depends only on already-done tasks). 3. **Create `_docs/02_document/architecture_compliance_baseline.md` as a Step 6 (Decompose) prerequisite.** - Impact: cumulative reviews can emit `## Baseline Delta` sections from cycle 2 onward, quantifying architecture violations carried over / resolved / newly introduced per cycle. Without it, structural regressions are invisible to the retro process. - Effort: low (small file: scrape ADR list + initial violation count = 0 for cycle 2; the structural snapshot in this retro can seed the baseline). Suggest landing it in cycle 2 Step 6 as a precondition. ## Suggested Rule/Skill Updates | File | Change | Rationale | |------|--------|-----------| | `.cursor/skills/decompose/SKILL.md` (Step 6 prerequisites) | Add a prerequisite check that `_docs/02_document/architecture_compliance_baseline.md` exists; create it with `0` baseline violations if missing | Closes the gap that cumulative reviews flagged repeatedly across cycle 1 ("`architecture_compliance_baseline.md` does NOT exist → no Baseline Delta section emitted") | | `.cursor/skills/implement/SKILL.md` (Step 15 Completeness Gate) | Before classifying any per-task FAIL, run a workspace grep for cross-cutting state the task depends on (e.g. central registries, factory dispatch tables); if the actual gap is cross-cutting, propose a single cross-cutting task instead of N per-task remediation tasks | AZ-589 + AZ-590 → AZ-591 post-mortem; saves a wasted remediation-task round-trip | | `.cursor/skills/decompose/SKILL.md` (or a new sub-step) | Identify the **fixture-builder dependency surface** explicitly during test-task decomposition: if N test tasks share a single un-built fixture, schedule the fixture builder ahead of the dependent tasks as a P0 prerequisite, not as a peer | AZ-595 surfaced as a late-cycle 17-scenario blocker — would have been a 1-task P0 if decompose had cross-referenced fixture references in each test spec | ## Process Leftovers (out of band) - **`_docs/_process_leftovers/2026-05-11_d_cross_cve_1_opencv_pin_deferred.md`** — still OPEN; replay condition unchanged (gtsam numpy<2). Re-checked at start of every `/autodev` invocation; last check 2026-05-20T05:51 UTC+3. End of cycle-1 retrospective.