mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-06-22 21:41:13 +00:00
[AZ-611] Add --skip-auto-sync flag to bypass AC-9 validator
Mid-flight fixtures (Derkachi) and stationary-still scenarios (FT-P-01) have no take-off spike for the IMU detector and produce false-positive video motion onsets, so the AC-9 frame-window validator rejects every plausible offset. Add an operator-acknowledged opt-out: a new ReplayConfig.skip_auto_sync_validation flag that suppresses validation, paired with a hard requirement that time_offset_ms also be set (silent-zero guard at both schema and adapter layers). Wired through schema -> CLI (--skip-auto-sync) -> composition root -> ReplayInputAdapter; Derkachi e2e fixture now passes time_offset_ms=0 + skip_auto_sync=True by default since the synth tlog and the video share the same t=0 anchor by construction. 5 new unit tests: * schema gate rejects skip=True without manual offset * schema gate accepts the legal pair * default field value is False (default-construction safety) * adapter constructor mirrors the schema gate * adapter open() bypasses validate_offset_or_fail when flag is set All 38 unit tests in test_az401 + test_az405 pass on Mac. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -41,6 +41,7 @@ from gps_denied_onboard.components.c8_fc_adapter.tlog_replay_adapter import (
|
||||
)
|
||||
from gps_denied_onboard.config import (
|
||||
Config,
|
||||
ConfigError,
|
||||
ReplayAutoSyncConfig,
|
||||
ReplayConfig,
|
||||
RuntimeConfig,
|
||||
@@ -733,3 +734,58 @@ def test_compose_root_replay_with_no_calib_path_raises(
|
||||
match=r"(camera_calibration_path|CAMERA_CALIBRATION_PATH)",
|
||||
):
|
||||
compose_root(config)
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# AZ-611 — ReplayConfig.skip_auto_sync_validation schema gate
|
||||
|
||||
|
||||
def test_az611_skip_auto_sync_without_manual_offset_rejected_at_init() -> None:
|
||||
"""``__post_init__`` refuses ``skip_auto_sync_validation=True`` paired
|
||||
with ``time_offset_ms=None`` — the bypass is only legal once the
|
||||
operator has committed to an explicit manual offset.
|
||||
"""
|
||||
# Act / Assert
|
||||
with pytest.raises(
|
||||
ConfigError,
|
||||
match=r"skip_auto_sync_validation=True requires.*time_offset_ms",
|
||||
):
|
||||
ReplayConfig(
|
||||
video_path="/dev/null/fake.mp4",
|
||||
tlog_path="/dev/null/fake.tlog",
|
||||
output_path="/tmp/replay.jsonl",
|
||||
pace="asap",
|
||||
time_offset_ms=None,
|
||||
skip_auto_sync_validation=True,
|
||||
target_fc_dialect="ardupilot_plane",
|
||||
)
|
||||
|
||||
|
||||
def test_az611_skip_auto_sync_with_manual_offset_accepted() -> None:
|
||||
"""The legal combination — ``skip_auto_sync_validation=True`` with an
|
||||
explicit ``time_offset_ms`` — constructs cleanly and round-trips
|
||||
both flags onto the frozen dataclass.
|
||||
"""
|
||||
# Act
|
||||
cfg = ReplayConfig(
|
||||
video_path="/dev/null/fake.mp4",
|
||||
tlog_path="/dev/null/fake.tlog",
|
||||
output_path="/tmp/replay.jsonl",
|
||||
pace="asap",
|
||||
time_offset_ms=0,
|
||||
skip_auto_sync_validation=True,
|
||||
target_fc_dialect="ardupilot_plane",
|
||||
)
|
||||
|
||||
# Assert
|
||||
assert cfg.skip_auto_sync_validation is True
|
||||
assert cfg.time_offset_ms == 0
|
||||
|
||||
|
||||
def test_az611_skip_auto_sync_defaults_to_false() -> None:
|
||||
"""Default-constructed ReplayConfig must not opt out of validation."""
|
||||
# Act
|
||||
cfg = ReplayConfig()
|
||||
|
||||
# Assert
|
||||
assert cfg.skip_auto_sync_validation is False
|
||||
|
||||
Reference in New Issue
Block a user