fix(replay): serve admitted AI overlays without revalidation
This commit is contained in:
@@ -55,6 +55,7 @@ JS_MAX_SAFE_INTEGER = (1 << 53) - 1
|
||||
RECORDED_VIEW_POINT_DECIMATION_THRESHOLD = 100_000
|
||||
RECORDED_VIEW_POINT_STRIDE = 4
|
||||
RECORDED_VIEW_POINT_FRAME_STRIDE = 5
|
||||
RECORDED_RRD_IDENTITY_VERSION = "missioncore.recorded-rrd/v1"
|
||||
|
||||
# Rerun keys viewer state by these IDs. Reusing them for every settings-only
|
||||
# blueprint update makes the update overwrite the existing scene instead of
|
||||
@@ -216,13 +217,26 @@ def export_k1mqtt_to_rrd(
|
||||
_validate_paths(source, destination)
|
||||
destination.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
recording_id = str(uuid4())
|
||||
temporary = destination.with_name(f".{destination.name}.{recording_id}.tmp")
|
||||
source_sha256 = _sha256_file(
|
||||
source,
|
||||
cancel_event=cancel_event,
|
||||
activity_callback=activity_callback,
|
||||
)
|
||||
capture_clock = _optional_capture_clock(source, capture_clock_path)
|
||||
capture_clock_origin = _optional_capture_clock_origin(
|
||||
source,
|
||||
capture_clock_origin_path,
|
||||
)
|
||||
# Rerun uses this identity to merge independently delivered base,
|
||||
# blueprint and perception streams. Bind it to immutable source evidence
|
||||
# so regenerating an unchanged recording does not invalidate every derived
|
||||
# overlay cache.
|
||||
recording_id = _stable_recording_id(
|
||||
source_sha256,
|
||||
capture_clock,
|
||||
capture_clock_origin,
|
||||
)
|
||||
temporary = destination.with_name(f".{destination.name}.{uuid4()}.tmp")
|
||||
settings = RerunSceneSettings()
|
||||
blueprint = _recorded_blueprint(settings)
|
||||
recording: rr.RecordingStream | None = None
|
||||
@@ -231,11 +245,6 @@ def export_k1mqtt_to_rrd(
|
||||
|
||||
counters = _ExportCounters()
|
||||
trajectory = _TrajectoryBuffer.empty()
|
||||
capture_clock = _optional_capture_clock(source, capture_clock_path)
|
||||
capture_clock_origin = _optional_capture_clock_origin(
|
||||
source,
|
||||
capture_clock_origin_path,
|
||||
)
|
||||
if (
|
||||
capture_clock is not None
|
||||
and capture_clock_origin is not None
|
||||
@@ -449,6 +458,31 @@ def _validate_paths(source: Path, destination: Path) -> None:
|
||||
raise RrdExportError("RRD export accepts only native K1MQTT captures")
|
||||
|
||||
|
||||
def _stable_recording_id(
|
||||
source_sha256: str,
|
||||
capture_clock: CaptureClockEnvelope | None,
|
||||
capture_clock_origin: CaptureClockOrigin | None,
|
||||
) -> str:
|
||||
identity = hashlib.sha256()
|
||||
for value in (
|
||||
RECORDED_RRD_IDENTITY_VERSION,
|
||||
source_sha256,
|
||||
str(capture_clock.started_at_epoch_ns) if capture_clock is not None else "-",
|
||||
str(capture_clock.started_monotonic_ns) if capture_clock is not None else "-",
|
||||
str(capture_clock.completed_at_epoch_ns) if capture_clock is not None else "-",
|
||||
str(capture_clock.completed_monotonic_ns) if capture_clock is not None else "-",
|
||||
str(capture_clock_origin.started_at_epoch_ns)
|
||||
if capture_clock_origin is not None
|
||||
else "-",
|
||||
str(capture_clock_origin.started_monotonic_ns)
|
||||
if capture_clock_origin is not None
|
||||
else "-",
|
||||
):
|
||||
identity.update(value.encode("ascii"))
|
||||
identity.update(b"\0")
|
||||
return f"k1-{identity.hexdigest()}"
|
||||
|
||||
|
||||
def _optional_capture_clock(
|
||||
source: Path,
|
||||
explicit_path: Path | None,
|
||||
|
||||
Reference in New Issue
Block a user