fix(perception): bound LAB replay to AI window

This commit is contained in:
DCCONSTRUCTIONS
2026-07-23 21:15:53 +03:00
parent 10019a454a
commit 082b7057da
7 changed files with 429 additions and 38 deletions
+9 -1
View File
@@ -199,6 +199,8 @@ def publish_e21_lab_instance(
store.data_dir,
source_session_id=reference.job.session_id,
lab_session_id=lab_session_id,
timeline_start_ns=round(validated.timeline_start_seconds * 1_000_000_000),
timeline_end_ns=round(validated.timeline_end_seconds * 1_000_000_000),
)
binding = store.publish_lab_instance(
session_id=lab_session_id,
@@ -210,9 +212,13 @@ def publish_e21_lab_instance(
source_result_id=str(e21_document["result_id"]),
config_sha256=str(e21_report["identity"]["profile_sha256"]),
run_created_at_utc=str(e21_report["created_at_utc"]),
duration_seconds=(
validated.timeline_end_seconds - validated.timeline_start_seconds
),
include_recorded_media=False,
provenance={
"schema_version": "missioncore.e21-lab-publication/v1",
"storage_mode": "hard-linked-source-and-bounded-derived-projection",
"storage_mode": "bounded-derived-replay-and-projection",
"e21_result_id": e21_document["result_id"],
"worker_result_id": worker_document["result_id"],
"semantic_reference_result_id": reference.result_id,
@@ -227,6 +233,8 @@ def publish_e21_lab_instance(
498,
],
"visual_frame_count": frame_count,
"timeline_start_seconds": validated.timeline_start_seconds,
"timeline_end_seconds": validated.timeline_end_seconds,
"source_payloads_mutated": False,
},
)
+248 -12
View File
@@ -5,7 +5,11 @@ from __future__ import annotations
import hashlib
import json
import os
import shutil
import stat
import subprocess
import sys
import tempfile
from pathlib import Path
from typing import Any
@@ -24,14 +28,35 @@ def publish_lab_replay_cache(
*,
source_session_id: str,
lab_session_id: str,
timeline_start_ns: int | None = None,
timeline_end_ns: int | None = None,
) -> None:
"""Hard-link a validated source RRD and clone its path-free sidecars.
"""Publish a validated source RRD and clone its path-free sidecars.
The RRD bytes are immutable and independent of the catalog id, so a hard
link gives every LAB instance a normal cache endpoint without consuming a
second copy of the multi-gigabyte recording.
Full-session LAB instances hard-link the immutable source bytes. Bounded
experiments materialize only their declared timeline window, so a short AI
run cannot silently hold its final frame over the rest of a long source
recording.
"""
bounded = timeline_start_ns is not None or timeline_end_ns is not None
if bounded and (
not isinstance(timeline_start_ns, int)
or isinstance(timeline_start_ns, bool)
or not isinstance(timeline_end_ns, int)
or isinstance(timeline_end_ns, bool)
or timeline_start_ns < 0
or timeline_end_ns <= timeline_start_ns
):
raise ValueError("LAB replay window is invalid")
window_start_ns = -1
window_end_ns = -1
if bounded:
assert isinstance(timeline_start_ns, int)
assert isinstance(timeline_end_ns, int)
window_start_ns = timeline_start_ns
window_end_ns = timeline_end_ns
root = data_dir.expanduser().resolve(strict=True)
recordings = (root / "recordings").resolve(strict=True)
source_root = recordings / source_session_id
@@ -52,10 +77,32 @@ def publish_lab_replay_cache(
raise SessionIntegrityError("LAB recording cache root is unsafe")
target_rrd = target_root / RECORDING_CACHE_FILENAME
if target_rrd.exists():
source_stat = _require_regular(source_rrd, source_root)
target_stat = _require_regular(target_rrd, target_root)
if (source_stat.st_dev, source_stat.st_ino) != (target_stat.st_dev, target_stat.st_ino):
raise SessionIntegrityError("LAB recording cache already contains different bytes")
if bounded:
_require_matching_bounded_cache(
target_rrd,
target_root / RECORDING_CACHE_SIDECAR_FILENAME,
lab_session_id=lab_session_id,
timeline_start_ns=window_start_ns,
timeline_end_ns=window_end_ns,
)
else:
source_stat = _require_regular(source_rrd, source_root)
target_stat = _require_regular(target_rrd, target_root)
if (source_stat.st_dev, source_stat.st_ino) != (
target_stat.st_dev,
target_stat.st_ino,
):
raise SessionIntegrityError(
"LAB recording cache already contains different bytes"
)
elif bounded:
_publish_bounded_rrd(
source_rrd,
target_rrd,
recording_id=lab_session_id,
timeline_start_ns=window_start_ns,
timeline_end_ns=window_end_ns,
)
else:
temporary = target_root / f".{RECORDING_CACHE_FILENAME}.{os.getpid()}.tmp"
try:
@@ -67,15 +114,196 @@ def publish_lab_replay_cache(
cloned = {
**document,
"session_id": lab_session_id,
"recording_byte_length": target_stat.st_size,
"recording_mtime_ns": target_stat.st_mtime_ns,
"recording_sha256": _sha256(target_rrd),
"timeline_start_ns": (
window_start_ns if bounded else document["timeline_start_ns"]
),
"timeline_end_ns": window_end_ns if bounded else document["timeline_end_ns"],
}
write_json_atomic(target_root / RECORDING_CACHE_SIDECAR_FILENAME, cloned)
os.chmod(target_root / RECORDING_CACHE_SIDECAR_FILENAME, 0o600)
_clone_recorded_media_sidecars(
root / "recorded-media-preparations",
source_session_id=source_session_id,
lab_session_id=lab_session_id,
if not bounded:
_clone_recorded_media_sidecars(
root / "recorded-media-preparations",
source_session_id=source_session_id,
lab_session_id=lab_session_id,
)
def _publish_bounded_rrd(
source_rrd: Path,
target_rrd: Path,
*,
recording_id: str,
timeline_start_ns: int,
timeline_end_ns: int,
) -> None:
rerun = _rerun_cli()
end_exclusive_ns = timeline_end_ns + 1
split_recording_prefix = f"{recording_id}-window-"
split_recording_id = f"{split_recording_prefix}1"
with tempfile.TemporaryDirectory(
prefix=".lab-window-",
dir=target_rrd.parent,
) as temporary_name:
temporary_root = Path(temporary_name)
split_root = temporary_root / "split"
split_root.mkdir()
_run_rerun(
rerun,
"rrd",
"split",
"--output-dir",
str(split_root),
"--timeline",
"session_time",
"--time",
str(timeline_start_ns),
"--time",
str(end_exclusive_ns),
"--recording-id",
split_recording_prefix,
str(source_rrd),
)
split_name = (
f"{source_rrd.stem}_{_rrd_duration(timeline_start_ns)}"
f"__{_rrd_duration(end_exclusive_ns)}.rrd"
)
split_path = split_root / split_name
_require_regular(split_path, split_root)
marker = temporary_root / "window.rrd"
_write_window_markers(
marker,
recording_id=split_recording_id,
timeline_start_ns=timeline_start_ns,
timeline_end_ns=timeline_end_ns,
)
merged = temporary_root / "bounded.rrd"
_run_rerun(
rerun,
"rrd",
"merge",
"--output",
str(merged),
str(split_path),
str(marker),
)
_run_rerun(rerun, "rrd", "verify", str(merged))
_require_regular(merged, temporary_root)
temporary_target = target_rrd.parent / f".{target_rrd.name}.{os.getpid()}.tmp"
try:
os.replace(merged, temporary_target)
os.chmod(temporary_target, 0o600)
os.replace(temporary_target, target_rrd)
finally:
temporary_target.unlink(missing_ok=True)
def _write_window_markers(
path: Path,
*,
recording_id: str,
timeline_start_ns: int,
timeline_end_ns: int,
) -> None:
import numpy as np
import rerun as rr
recording = rr.RecordingStream(
"nodedc_mission_core_recorded",
recording_id=recording_id,
)
stream = rr.binary_stream(recording)
try:
for timestamp, label in (
(timeline_start_ns, "LAB window start"),
(timeline_end_ns, "LAB window end"),
):
recording.set_time(
"session_time",
duration=np.timedelta64(timestamp, "ns"),
)
recording.log(
"/__mission_core/lab_window",
rr.TextDocument(label),
)
payload = stream.read(flush=True, flush_timeout_sec=5.0)
finally:
recording.disconnect()
if payload is None or not payload.startswith(b"RRF2"):
raise SessionIntegrityError("LAB replay window markers are invalid")
path.write_bytes(payload)
os.chmod(path, 0o600)
def _rerun_cli() -> Path:
adjacent = Path(sys.executable).with_name("rerun")
candidate = adjacent if adjacent.is_file() else None
if candidate is None:
resolved = shutil.which("rerun")
candidate = Path(resolved) if resolved is not None else None
if candidate is None or not candidate.is_file() or not os.access(candidate, os.X_OK):
raise SessionIntegrityError("Rerun CLI is unavailable for bounded LAB replay")
return candidate.resolve()
def _run_rerun(executable: Path, *arguments: str) -> None:
try:
completed = subprocess.run(
[str(executable), *arguments],
check=False,
capture_output=True,
text=True,
timeout=120,
)
except (OSError, subprocess.TimeoutExpired) as exc:
raise SessionIntegrityError("bounded LAB replay command failed") from exc
if completed.returncode != 0:
detail = completed.stderr.strip()[-1000:]
raise SessionIntegrityError(f"bounded LAB replay command failed: {detail}")
def _rrd_duration(value_ns: int) -> str:
for suffix, unit in (
("s", 1_000_000_000),
("ms", 1_000_000),
("us", 1_000),
("ns", 1),
):
if value_ns < unit:
continue
whole, remainder = divmod(value_ns, unit)
if remainder == 0:
return f"{whole}{suffix}"
digits = len(str(unit)) - 1
fraction = f"{remainder:0{digits}d}".rstrip("0")
return f"{whole}_{fraction}{suffix}"
return "0ns"
def _require_matching_bounded_cache(
target_rrd: Path,
target_sidecar: Path,
*,
lab_session_id: str,
timeline_start_ns: int,
timeline_end_ns: int,
) -> None:
target_root = target_rrd.parent
metadata = _require_regular(target_rrd, target_root)
_require_regular(target_sidecar, target_root)
document = _read_object(target_sidecar)
if (
document.get("session_id") != lab_session_id
or document.get("recording_byte_length") != metadata.st_size
or document.get("recording_mtime_ns") != metadata.st_mtime_ns
or document.get("recording_sha256") != _sha256(target_rrd)
or document.get("timeline_start_ns") != timeline_start_ns
or document.get("timeline_end_ns") != timeline_end_ns
):
raise SessionIntegrityError("LAB recording cache already contains different bytes")
def _clone_recorded_media_sidecars(
@@ -121,6 +349,14 @@ def _canonical_json(value: object) -> bytes:
).encode("utf-8")
def _sha256(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as stream:
for chunk in iter(lambda: stream.read(1024 * 1024), b""):
digest.update(chunk)
return digest.hexdigest()
def _read_object(path: Path) -> dict[str, Any]:
value = json.loads(path.read_text(encoding="utf-8"))
if not isinstance(value, dict):
+19 -5
View File
@@ -1,6 +1,7 @@
from __future__ import annotations
import json
import math
import os
import re
import shutil
@@ -333,6 +334,8 @@ class SessionStore:
source_result_id: str | None = None,
config_sha256: str | None = None,
provenance: dict[str, Any] | None = None,
duration_seconds: float | None = None,
include_recorded_media: bool = True,
) -> LabSessionBinding:
"""Append one immutable catalog projection over an existing source session.
@@ -357,6 +360,12 @@ class SessionStore:
if not 1 <= len(normalized_name) <= 160:
raise ValueError("LAB display name must contain 1..160 characters")
_require_utc_timestamp(run_created_at_utc, "LAB run creation time")
if duration_seconds is not None and (
isinstance(duration_seconds, bool)
or not math.isfinite(duration_seconds)
or duration_seconds <= 0
):
raise ValueError("LAB duration must be a positive finite value")
serialized_provenance = _serialize_provenance(provenance or {})
published_at = utc_now_iso()
@@ -428,7 +437,11 @@ class SessionStore:
source["status"],
run_created_at_utc,
run_created_at_utc,
source["duration_seconds"],
(
source["duration_seconds"]
if duration_seconds is None
else duration_seconds
),
source["modalities_json"],
source["replayable"],
LAB_ORIGIN,
@@ -449,8 +462,9 @@ class SessionStore:
"integrity_status, locator, replay_byte_length) "
"SELECT ?, artifact_id, kind, media_type, byte_length, sha256, "
"integrity_status, locator, replay_byte_length "
"FROM observation_session_artifacts WHERE session_id = ?",
(session_id, source_session_id),
"FROM observation_session_artifacts WHERE session_id = ? "
"AND (? OR kind <> 'recorded-video')",
(session_id, source_session_id, include_recorded_media),
)
connection.execute(
"INSERT INTO observation_session_sources "
@@ -458,8 +472,8 @@ class SessionStore:
"seekable, artifact_id) "
"SELECT ?, source_id, semantic_channel_id, modality, status, "
"seekable, artifact_id FROM observation_session_sources "
"WHERE session_id = ?",
(session_id, source_session_id),
"WHERE session_id = ? AND (? OR modality <> 'video')",
(session_id, source_session_id, include_recorded_media),
)
connection.execute(
"INSERT INTO observation_lab_instances "