Files
Oleksandr Bezdieniezhnykh 007aa36fbf [AZ-895] Deprecate replay auto-sync surface; file AZ-908 follow-up
Option A (minimum-deprecation, 2 SP) per user complexity-budget
decision. Auto-sync stays importable as a raising stub for one cycle
so external callers see a clean ReplayInputAdapterError instead of an
ImportError. Full physical removal is filed as AZ-908 (cycle-5+ backlog).

Production:
- auto_sync.py: 700+ LOC -> 56-line no-op stub raising
  "auto-sync removed; supply --imu CSV instead"
- tlog_video_adapter.py: 700+ LOC -> 105-line deprecated stub;
  ReplayInputAdapter.open() raises immediately, close() is a no-op
- _replay_branch.py: dropped legacy auto-sync branch +
  _build_auto_sync_config; _validate_replay_paths now requires
  imu_csv_path; replay_input_adapter_factory parameter removed
- cli/replay.py: --time-offset-ms / --skip-auto-sync / --auto-trim
  emit DeprecationWarning + stderr line; values ignored
- tlog_replay_adapter.py + tlog_ground_truth.py docstrings: AUDIT-ONLY

Tests:
- DELETED test_az405_auto_sync, test_az405_replay_input_adapter,
  test_az698_window_alignment (covered code no longer runs)
- ADDED test_az895_auto_sync_deprecated_stub (5 parametrised, pins AC-1)
- test_az402_replay_cli: deprecation warnings + ignored-value asserts
- test_az401_compose_root_replay: new imu_csv_path-required gate;
  deleted the calibration-loading test that relied on the removed
  replay_input_adapter_factory injection point
- test_derkachi_real_tlog: xfail reason refreshed to AZ-848 + AZ-883
  (AC-4 "AZ-848-scoped reason")

Docs:
- module-layout.md: replay_input file list flags deprecated modules,
  adds csv_ground_truth.py
- _dependencies_table.md: +AZ-908 row, preamble + totals updated
  (179 -> 180 tasks, 567 -> 570 SP)
- AZ-908 backlog spec added; AZ-895 spec moved todo -> done
- batch_03_cycle4_report.md written

Touched-module tests green (111 passed, 1 skipped). Full unit suite
green: 2287 passed, 85 skipped, 1 deselected (pre-existing flaky perf
test, unrelated).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 22:09:59 +03:00

12 KiB
Raw Permalink Blame History

Batch Report — cycle 4, batch 03

Batch: 03 Cycle: 4 Tasks: AZ-895 Total complexity: 2 SP Date: 2026-05-26 Commit: pending (this batch)

Task Selection

AZ-895 (deprecate auto_sync surface) ships solo. It is the natural follow-up to AZ-894 (CSV adapter, batch 02): now that the CSV-driven path is the primary replay surface, the legacy tlog auto-sync infrastructure can be retired. Per _dependencies_table.md, AZ-895 has a hard dependency on AZ-894 which closed in batch 02.

Complexity-budget user decision (Option A — minimum)

A naïve full removal of the auto-sync surface would have touched:

  • 4 production modules: auto_sync.py (delete), tlog_video_adapter.py (delete), interface.py (drop AutoSync DTOs + ReplayInputBundle field), _replay_branch.py (strip legacy branch + _build_auto_sync_config)
  • 3 config files: config/schema.py (drop ReplayConfig auto-sync fields + the ReplayAutoSyncConfig class), config/loader.py (drop REPLAY_TIME_OFFSET_MS env + auto_sync block handler), config/__init__.py (drop re-exports)
  • 1 CLI: drop the three deprecated flags entirely
  • 4 test files needing rewrite or deletion
  • Cascading docs in replay_protocol.md (AZ-842 sibling work)

Estimated at 45 SP, well over the ticket's 2 SP budget. Per meta-rule.mdc Complexity Budget Check, the user was offered four options and chose Option A — minimum:

"Minimum (~2 SP): no-op-stub auto_sync.py (raises documented error), strip tlog_video_adapter.open() to raise too, drop the unreachable legacy branch in _replay_branch.py, deprecate --time-offset-ms / --skip-auto-sync / --auto-trim CLI flags (emit warning + ignored), keep config fields, delete obsolete tests, update docstrings. File AZ-902 (cycle 5) for hard surface removal."

The follow-up ticket was filed as AZ-908 (Jira renumbered from the proposed AZ-902 because AZ-902AZ-907 were already taken). AZ-908 is in backlog/ and depends on AZ-895 + AZ-842.

Task Results

Task Status Files Modified Tests AC Coverage Issues
AZ-895_deprecate_auto_sync_surface Done 8 modified, 1 added (test) 3 unit-test files deleted; 1 new test added; 1 existing test file updated; 2,287 unit tests green 5/5 None

Files touched

Production (src/gps_denied_onboard/**):

  • REPLACED replay_input/auto_sync.py — was a 700+ LOC detector module; now a 56-line no-op stub whose every public callable raises ReplayInputAdapterError("auto-sync removed; supply --imu CSV instead"). __all__ preserved so any external import still resolves.
  • REPLACED replay_input/tlog_video_adapter.py — was a 700+ LOC coordinator; now a 105-line deprecated-stub that keeps the ReplayInputAdapter class signature for source-compat. open() raises ReplayInputAdapterError(...) immediately; close() is a no-op. Re-exports ReplayPace so _replay_branch.py can continue to import it from the same path (preserving the AZ-401 AC-8 import boundary).
  • MODIFIED runtime_root/_replay_branch.py — removed the legacy ReplayInputAdapter instantiation branch in _build_replay_input_bundle; deleted the _build_auto_sync_config helper; tightened _validate_replay_paths to require imu_csv_path (no more tlog fallback); dropped unused WgsConverter and AutoSyncConfig imports; removed the replay_input_adapter_factory test-injection parameter; updated module + function docstrings; cleaned auto_sync_used from the ready-log kv (always None now).
  • MODIFIED replay_input/__init__.py — docstring rewritten to flag the deprecation status of the tlog_video_adapter / auto_sync surfaces. Re-exports preserved.
  • MODIFIED cli/replay.py--time-offset-ms, --skip-auto-sync, --auto-trim help text replaced with DEPRECATED (AZ-895) notice; _print_startup_banner now emits a DeprecationWarning + stderr line when any of the three are non-default; _build_replay_config hard-codes the corresponding ReplayConfig fields to None / False so the deprecated values cannot influence composition.
  • MODIFIED components/c8_fc_adapter/tlog_replay_adapter.py — module docstring reframed as AUDIT-ONLY (AC-5). Code unchanged.
  • MODIFIED replay_input/tlog_ground_truth.py — module docstring reframed as AUDIT-ONLY (AC-5). Code unchanged.

Tests (tests/**):

  • DELETED tests/unit/replay_input/test_az405_auto_sync.py (386 LOC). Rationale: tested the AZ-405 detector algorithm + AC-9 validator which no longer execute. Per AC-3, the deprecation-stub test below replaces it.
  • DELETED tests/unit/replay_input/test_az405_replay_input_adapter.py (645 LOC). Rationale: tested the ReplayInputAdapter coordinator's six-step open() workflow which now raises immediately.
  • DELETED tests/unit/replay_input/test_az698_window_alignment.py (745 LOC). Rationale: tested the AZ-698 IMU↔optical-flow cross-correlation aligner which no longer executes.
  • ADDED tests/unit/replay_input/test_az895_auto_sync_deprecated_stub.py — 5 parametrised tests pinning the AC-1 contract: every public callable raises ReplayInputAdapterError with the documented message.
  • MODIFIED tests/unit/test_az402_replay_cli.py — renamed test_ac4_time_offset_forwardedtest_ac4_time_offset_ignored_after_az895 with asserts inverted (value now None regardless of flag); added test_az895_skip_auto_sync_ignored_and_warned, test_az895_auto_trim_ignored_and_warned, test_az895_no_deprecated_flags_no_warning; _argv helper grew skip_auto_sync and auto_trim overrides.
  • MODIFIED tests/unit/test_az401_compose_root_replay.py — renamed test_replay_branch_rejects_both_inputs_emptytest_replay_branch_rejects_missing_imu_csv_path with body updated to the new gate semantics; _make_replay_config helper now sets imu_csv_path by default; deleted test_replay_branch_loads_camera_calibration_from_runtime_path (only verified the now-removed replay_input_adapter_factory injection path; calibration loading is exercised indirectly by the full compose-root tests and by the e2e suite).
  • MODIFIED tests/e2e/replay/test_derkachi_real_tlog.py — xfail reason text refreshed to reference AZ-848 + AZ-883 (the live tlog-clock root cause) instead of the closed AZ-776 + AZ-777 (AC-4 literally specifies "AZ-848-scoped reason").

Docs (_docs/**):

  • MODIFIED _docs/02_document/module-layout.mdreplay_input file list flags tlog_video_adapter.py + auto_sync.py as DEPRECATED (AZ-895), adds csv_ground_truth.py, updates the package purpose to lead with the CSV path.
  • ADDED _docs/02_tasks/backlog/AZ-908_replay_auto_sync_hard_removal.md — cycle-5+ follow-up spec.
  • MODIFIED _docs/02_tasks/_dependencies_table.md — preamble + Total Tasks (179 → 180) + Total Complexity (567 → 570); AZ-908 row added under Cycle-4 / AZ-895 follow-up.

Tracker (Jira):

  • AZ-895 — transitioned To DoIn Progress (transition id 21).
  • AZ-908 — created (Replay: hard removal of deprecated auto-sync surface (AZ-895 follow-up)), 3 SP estimate, deps AZ-895 (hard) + AZ-842 (hard). Filed via createJiraIssue MCP.

File-Ownership Note

All touched paths are owned by the cycle-4 replay-input redesign envelope (replay_input/ + cli/replay.py + runtime_root/_replay_branch.py) plus the AC-5 audit-only docstring updates inside components/c8_fc_adapter/tlog_replay_adapter.py (the c8 owner already accepted the audit-only reframing in AZ-894). No out-of-scope edits.

AC Test Coverage

AC Coverage Test
AC-1 (auto_sync.py is deleted or made a no-op raising the documented error) Direct tests/unit/replay_input/test_az895_auto_sync_deprecated_stub.py::test_az895_public_callable_raises_with_documented_message[*] — 5 parametrised cases, one per public symbol (detect_tlog_takeoff, detect_video_motion_onset, compute_offset, validate_offset_or_fail, find_aligned_window); each asserts ReplayInputAdapterError("auto-sync removed; supply --imu CSV instead")
AC-2 (CLI flags removed or marked deprecated with one-cycle warning) Direct test_az402_replay_cli.py::test_ac4_time_offset_ignored_after_az895, ::test_az895_skip_auto_sync_ignored_and_warned, ::test_az895_auto_trim_ignored_and_warned, ::test_az895_no_deprecated_flags_no_warning — assert DeprecationWarning is emitted, the stderr banner contains the documented --flag is deprecated (AZ-895) text, the value is ignored on the ReplayConfig, and the no-flag baseline emits no warning
AC-3 (test_az405_auto_sync tests pass against the new behaviour or are deleted with rationale recorded in the batch report) Direct (rationale below) Deleted; rationale: the AZ-405 tests covered the detector algorithm + AC-9 validator which AZ-895 makes unreachable. Replaced by the AC-1 deprecation-stub test above
AC-4 (test_derkachi_real_tlog.py continues to @xfail with the AZ-848-scoped reason) Direct tests/e2e/replay/test_derkachi_real_tlog.py::test_az699_real_flight_validation_emits_verdict_and_report@pytest.mark.xfail decorator retained; reason text now names AZ-848 + AZ-883 as the live blocker
AC-5 (module docstrings of tlog_replay_adapter.py and tlog_ground_truth.py updated to call out their new audit-only roles) Direct Manual: both module docstrings now lead with AUDIT-ONLY (AZ-895) and explain the demotion; verified by inspection at the head of each file

Test-Run Summary

  • Touched-module focused suite: 111 passed, 1 skipped (RUN_REPLAY_E2E gate, expected).
  • Full unit suite: 2,287 passed, 85 skipped (hardware/Docker gates), 1 deselected (the timing-flaky perf test test_cli_console_script.py::TestConsoleScript::test_cold_start_under_1000ms_p99 — unrelated to this batch, pre-existing).

Open Items → AZ-908 (cycle-5+ backlog)

The deferred hard-removal surface (full spec in _docs/02_tasks/backlog/AZ-908_replay_auto_sync_hard_removal.md):

  • Delete replay_input/auto_sync.py + replay_input/tlog_video_adapter.py.
  • Drop AutoSyncConfig / AutoSyncDecision / AlignedWindow DTOs + ReplayInputBundle.auto_sync_result / aligned_window fields.
  • Drop the three deprecated CLI flags + their tests.
  • Drop ReplayConfig.time_offset_ms / .skip_auto_sync_validation / .auto_trim / .auto_sync + ReplayAutoSyncConfig class.
  • Drop BUILD_TLOG_REPLAY_ADAPTER build flag from REPLAY_BUILD_FLAGS.
  • Coordinate with AZ-842 to remove the auto-sync surface narrative from replay_protocol.md.

Lessons Captured

  • The user-decision Choose A/B/C/D flow worked exactly as designed: the agent surfaced the budget overrun before writing code, the user picked the minimum path with a clear follow-up ticket, and the batch shipped within its SP budget.
  • Keeping deprecated symbols as raising stubs (rather than deleting them outright in this cycle) gives operators one cycle of upgrade signal: they import the same name, get a clean ReplayInputAdapterError with a "supply --imu CSV instead" hint, and have a DeprecationWarning to silence in any test fixtures.
  • Architectural lint (test_ac8_replay_branch_imports_only_public_apis) caught a mid-batch attempt to import ReplayPace directly from the c8 internals — the lint forces the import to go through the documented re-export path (replay_input.tlog_video_adapter). Even though that re-export sits inside a deprecated module, the lint's allow-list is the architectural contract; routing around it would have been the wrong fix.