feat: wire physical K1 surface shadow

This commit is contained in:
DCCONSTRUCTIONS
2026-07-26 01:30:53 +03:00
parent e6d5411bdd
commit a1e2cb523f
14 changed files with 1444 additions and 41 deletions
@@ -136,11 +136,26 @@ if (
$live = Get-Content -LiteralPath $liveProfile -Raw | ConvertFrom-Json
if (
$live.schema_version -ne "missioncore.e15-shadow-inference-profile/v1" -or
$live.mode -ne "replay-shadow-gate" -or
$live.mode -notin @("replay-shadow-gate", "physical-shadow-gate") -or
[bool]$live.authority.commands_enabled -or
[bool]$live.authority.navigation_or_safety_accepted -or
$live.transport.pyav_version -ne "18.0.0"
) { throw "LAB E15 replay-shadow authority contract changed" }
) { throw "LAB E15/E28 shadow authority contract changed" }
if ($live.mode -eq "physical-shadow-gate") {
foreach ($relative in @(
"k1link\compute\lidar_local_surface_geometry.py",
"k1link\compute\lidar_local_surface_shadow.py",
"k1link\ground_segmentation.py"
)) {
if (-not (Test-Path -LiteralPath (Join-Path $package $relative) -PathType Leaf)) {
throw "LAB E28 worker package lacks local-surface runtime"
}
}
if (
-not [bool]$live.local_surface.enabled -or
$live.local_surface.profile_id -ne "k1-vendor-map-dynamic-local-surface/v1"
) { throw "LAB E28 local-surface profile contract changed" }
}
if ($stabilityProfile) {
$stability = Get-Content -LiteralPath $stabilityProfile -Raw | ConvertFrom-Json
if (
@@ -0,0 +1,71 @@
{
"schema_version": "missioncore.e15-shadow-inference-profile/v1",
"mode": "physical-shadow-gate",
"authority": {
"commands_enabled": false,
"navigation_or_safety_accepted": false
},
"source": {
"source_id": "sensor.camera.right",
"resolution": [
800,
600
],
"calibration_slot": "camera_1",
"calibration_sha256": "05f3ad9b38b3a4fc95388a8ec83da83c745e217709e51787b3d5aad0969f6fa9"
},
"transport": {
"wire_schema": "missioncore.live-perception-wire/v1",
"camera_media": "persistent-fmp4-pyav",
"pyav_version": "18.0.0",
"maximum_media_buffer_bytes": 8388608,
"camera_metadata_capacity": 16
},
"scheduling": {
"detector_queue_capacity": 2,
"semantic_queue_capacity": 1,
"semantic_sample_every_frames": 5,
"semantic_ttl_ms": 750.0,
"sensor_wait_ms": 90.0
},
"temporal": {
"binding": "nearest-recorded-host-arrival-best-effort",
"maximum_lidar_camera_delta_ms": 100.0,
"maximum_pose_point_delta_ms": 100.0,
"buffer_capacity_per_modality": 32,
"retention_seconds": 3.0,
"clock_qualification": "not-hardware-synchronized"
},
"local_surface": {
"enabled": true,
"profile_id": "k1-vendor-map-dynamic-local-surface/v1",
"profile_sha256": "7a59edc8404d0177a39175578743589bfb6b7822837170cded38ca2b6698cc26",
"point_queue_capacity": 2,
"pose_buffer_capacity": 16,
"future_pose_wait_ms": 25.0,
"retention_seconds": 3.0,
"result_capacity": 8,
"acceptance": {
"minimum_bound_frames": 100,
"maximum_pose_miss_fraction": 0.05,
"maximum_point_drop_fraction": 0.01,
"maximum_runtime_drop_fraction": 0.01,
"maximum_p95_result_age_ms": 80.0
}
},
"acceptance": {
"minimum_camera_frames": 140,
"detector_minimum_effective_fps": 9.5,
"detector_maximum_drop_fraction": 0.01,
"semantic_minimum_effective_fps": 1.8,
"semantic_maximum_drop_fraction": 0.05,
"semantic_maximum_p95_completion_age_ms": 400.0,
"minimum_fresh_semantic_coverage": 0.9,
"minimum_fused_fraction": 0.85,
"maximum_p95_decode_age_ms": 80.0,
"maximum_p95_world_state_age_ms": 200.0,
"require_zero_transport_gaps": true,
"require_zero_camera_sequence_gaps": true,
"require_zero_failures": true
}
}
@@ -176,6 +176,7 @@ def read_live_profile(path: Path) -> tuple[dict[str, Any], str]:
transport = profile.get("transport")
scheduling = profile.get("scheduling")
temporal = profile.get("temporal")
local_surface = profile.get("local_surface")
acceptance = profile.get("acceptance")
if (
profile.get("schema_version") != PROFILE_SCHEMA
@@ -212,6 +213,78 @@ def read_live_profile(path: Path) -> tuple[dict[str, Any], str]:
or not 1 <= float(temporal.get("maximum_pose_point_delta_ms", 0)) <= 1000
):
raise RuntimeError("LAB E15 bounded runtime contract is invalid")
if local_surface is not None:
from k1link.compute.lidar_local_surface_geometry import (
DEFAULT_K1_LOCAL_SURFACE_PROFILE,
)
local_acceptance = (
local_surface.get("acceptance")
if isinstance(local_surface, dict)
else None
)
expected_profile_sha256 = hashlib.sha256(
canonical_json(DEFAULT_K1_LOCAL_SURFACE_PROFILE.to_dict())
).hexdigest()
local_fractions = (
"maximum_pose_miss_fraction",
"maximum_point_drop_fraction",
"maximum_runtime_drop_fraction",
)
point_capacity = (
local_surface.get("point_queue_capacity")
if isinstance(local_surface, dict)
else None
)
pose_capacity = (
local_surface.get("pose_buffer_capacity")
if isinstance(local_surface, dict)
else None
)
result_capacity = (
local_surface.get("result_capacity")
if isinstance(local_surface, dict)
else None
)
if (
profile.get("mode") != "physical-shadow-gate"
or not isinstance(local_surface, dict)
or local_surface.get("enabled") is not True
or local_surface.get("profile_id")
!= DEFAULT_K1_LOCAL_SURFACE_PROFILE.profile_id
or local_surface.get("profile_sha256")
!= expected_profile_sha256
or not isinstance(point_capacity, int)
or isinstance(point_capacity, bool)
or point_capacity not in range(1, 9)
or not isinstance(pose_capacity, int)
or isinstance(pose_capacity, bool)
or pose_capacity not in range(2, 257)
or not isinstance(result_capacity, int)
or isinstance(result_capacity, bool)
or result_capacity not in range(1, 257)
or not 0
<= float(local_surface.get("future_pose_wait_ms", -1))
<= DEFAULT_K1_LOCAL_SURFACE_PROFILE.maximum_pose_binding_ms
or not 0.1
<= float(local_surface.get("retention_seconds", 0))
<= 30
or float(temporal.get("maximum_pose_point_delta_ms", 0))
!= DEFAULT_K1_LOCAL_SURFACE_PROFILE.maximum_pose_binding_ms
or not isinstance(local_acceptance, dict)
or int(local_acceptance.get("minimum_bound_frames", 0)) < 2
or any(
not 0 <= float(local_acceptance.get(key, -1)) <= 1
for key in local_fractions
)
or float(
local_acceptance.get("maximum_p95_result_age_ms", 0)
)
<= 0
):
raise RuntimeError(
"LAB E28 physical local-surface profile contract is invalid"
)
fractions = (
"detector_maximum_drop_fraction",
"semantic_maximum_drop_fraction",
@@ -244,6 +317,125 @@ def read_live_profile(path: Path) -> tuple[dict[str, Any], str]:
return profile, sha256(resolved)
def _local_surface_acceptance_checks(
snapshot: dict[str, object],
config: dict[str, Any],
) -> dict[str, bool]:
binder = snapshot.get("binder")
runtime = snapshot.get("runtime")
acceptance = config["acceptance"]
if not isinstance(binder, dict):
binder = {}
if not isinstance(runtime, dict):
runtime = {}
points = binder.get("points")
poses = binder.get("poses")
queue_state = runtime.get("queue")
results = runtime.get("results")
runtime_profile = runtime.get("profile")
result_age = results.get("result_age_ms") if isinstance(results, dict) else None
if not isinstance(points, dict):
points = {}
if not isinstance(poses, dict):
poses = {}
if not isinstance(queue_state, dict):
queue_state = {}
if not isinstance(results, dict):
results = {}
if not isinstance(runtime_profile, dict):
runtime_profile = {}
if not isinstance(result_age, dict):
result_age = {}
point_published = int(points.get("published", 0))
point_bound = int(points.get("bound", 0))
point_missed = int(points.get("missed", 0))
point_dropped = int(points.get("dropped_overflow", 0))
point_depth = int(points.get("depth", 0))
runtime_published = int(queue_state.get("published", 0))
runtime_consumed = int(queue_state.get("consumed", 0))
runtime_dropped = int(queue_state.get("dropped_overflow", 0))
runtime_depth = int(queue_state.get("depth", 0))
result_published = int(results.get("published", 0))
result_failed = int(results.get("failed", 0))
p95_result_age = result_age.get("p95")
return {
"local_surface_session_initialized": bool(runtime),
"local_surface_closed": snapshot.get("closed") is True
and runtime.get("closed") is True,
"local_surface_minimum_bound_frames": point_bound
>= int(acceptance["minimum_bound_frames"]),
"local_surface_binder_accounting": point_bound
+ point_missed
+ point_dropped
+ point_depth
== point_published,
"local_surface_binder_to_runtime_accounting": point_bound
== runtime_published,
"local_surface_point_buffer_bound": (
int(points.get("capacity", 0)) == int(config["point_queue_capacity"])
and int(points.get("maximum_depth", 0))
<= int(points.get("capacity", 0))
and point_depth == 0
),
"local_surface_pose_buffer_bound": (
int(poses.get("capacity", 0)) == int(config["pose_buffer_capacity"])
and int(poses.get("maximum_depth", 0))
<= int(poses.get("capacity", 0))
),
"local_surface_maximum_pose_miss_fraction": point_missed
/ max(1, point_published)
<= float(acceptance["maximum_pose_miss_fraction"]),
"local_surface_maximum_point_drop_fraction": point_dropped
/ max(1, point_published)
<= float(acceptance["maximum_point_drop_fraction"]),
"local_surface_runtime_accounting": runtime_consumed
+ runtime_dropped
+ runtime_depth
== runtime_published,
"local_surface_runtime_result_accounting": result_published
+ result_failed
== runtime_consumed,
"local_surface_runtime_queue_bound": (
int(queue_state.get("capacity", 0)) == int(config["point_queue_capacity"])
and int(queue_state.get("maximum_depth", 0))
<= int(queue_state.get("capacity", 0))
and runtime_depth == 0
),
"local_surface_maximum_runtime_drop_fraction": runtime_dropped
/ max(1, runtime_published)
<= float(acceptance["maximum_runtime_drop_fraction"]),
"local_surface_zero_runtime_failures": result_failed == 0,
"local_surface_maximum_p95_result_age_ms": (
isinstance(p95_result_age, (int, float))
and not isinstance(p95_result_age, bool)
and float(p95_result_age)
<= float(acceptance["maximum_p95_result_age_ms"])
),
"local_surface_profile_pinned": (
runtime_profile.get("profile_id") == config["profile_id"]
),
"local_surface_shadow_authority_only": (
snapshot.get("authority")
== {
"commands_enabled": False,
"navigation_or_safety_accepted": False,
}
and runtime.get("authority")
== {
"commands_enabled": False,
"navigation_or_safety_accepted": False,
}
),
"local_surface_unknown_never_free": runtime.get("occupancy_policy")
== {
"absence_of_points_means_free": False,
"unknown_is_traversable": False,
},
}
def read_projection_pack(
root: Path, expected_calibration_sha256: str
) -> tuple[ProjectionProfile, dict[str, Any]]:
@@ -312,7 +504,7 @@ def read_worker_package(root: Path) -> dict[str, Any]:
or manifest.get("package_id") != f"e15-worker-package-{identity_sha256}"
or resolved.name != manifest.get("package_id")
or not isinstance(artifacts, list)
or len(artifacts) != 12
or len(artifacts) not in {12, 15}
):
raise RuntimeError("LAB E15 worker package identity is invalid")
expected = set()
@@ -568,6 +760,7 @@ def _receiver(
max_duration_seconds: float,
decoder: PersistentFmp4Decoder,
synchronizer: LiveSensorSynchronizer,
local_surface: Any | None,
lidar_quality: LidarQualityMonitor,
state: _TransportState,
sensor_decode_ms: dict[str, list[float]],
@@ -646,6 +839,8 @@ def _receiver(
session_id = str(header["session_id"])
if state.session_id is None:
state.session_id = session_id
if local_surface is not None:
local_surface.begin_session(session_id)
elif state.session_id != session_id:
raise ShadowRuntimeError("shadow session identity changed")
modality = str(header["modality"])
@@ -698,8 +893,12 @@ def _receiver(
if modality == "lidar" and isinstance(normalized, DecodedPointCloudView):
lidar_quality.observe(normalized)
synchronizer.publish_point_cloud(normalized)
if local_surface is not None:
local_surface.publish_point_cloud(normalized)
elif modality == "pose" and isinstance(normalized, DecodedPoseView):
synchronizer.publish_pose(normalized)
if local_surface is not None:
local_surface.publish_pose(normalized)
else:
raise ShadowRuntimeError("known sensor modality did not normalize")
else:
@@ -709,6 +908,12 @@ def _receiver(
state.failures.append(exc)
finally:
decoder.finish_input()
if local_surface is not None:
try:
local_surface.close(timeout_seconds=30)
except BaseException as exc:
assert state.failures is not None
state.failures.append(exc)
sender_stop.set()
if sender_thread is not None:
sender_thread.join(timeout=5)
@@ -765,6 +970,21 @@ def _common(args: argparse.Namespace) -> dict[str, Any]:
if dependency["identity"]["profile_sha256"] != semantic_sha256:
raise RuntimeError("LAB E15 semantic dependency identity changed")
worker_package = read_worker_package(args.worker_package)
if live.get("local_surface") is not None:
worker_sources = {
str(item.get("path"))
for item in worker_package["identity"]["source_files"]
if isinstance(item, dict)
}
required_surface_sources = {
"k1link/compute/lidar_local_surface_geometry.py",
"k1link/compute/lidar_local_surface_shadow.py",
"k1link/ground_segmentation.py",
}
if not required_surface_sources <= worker_sources:
raise RuntimeError(
"LAB E28 worker package lacks local-surface runtime"
)
stability = None
stability_sha256 = None
if args.stability_profile is not None:
@@ -926,6 +1146,22 @@ def run(args: argparse.Namespace, loaded: _LoadedModels | None = None) -> int:
capacity_per_modality=int(temporal["buffer_capacity_per_modality"]),
retention_seconds=float(temporal["retention_seconds"]),
)
local_surface_config = live.get("local_surface")
local_surface = None
if isinstance(local_surface_config, dict):
from k1link.compute.lidar_local_surface_shadow import (
K1LocalSurfaceShadowCoordinator,
)
local_surface = K1LocalSurfaceShadowCoordinator(
point_capacity=int(local_surface_config["point_queue_capacity"]),
pose_capacity=int(local_surface_config["pose_buffer_capacity"]),
future_pose_wait_ms=float(
local_surface_config["future_pose_wait_ms"]
),
retention_seconds=float(local_surface_config["retention_seconds"]),
result_capacity=int(local_surface_config["result_capacity"]),
)
lidar_quality = LidarQualityMonitor(K1_LIVE_LIDAR_PROFILE)
first_camera_epoch_ns: list[int] = []
last_camera_epoch_ns: list[int] = []
@@ -1025,6 +1261,21 @@ def run(args: argparse.Namespace, loaded: _LoadedModels | None = None) -> int:
runtime_path = output / "runtime-telemetry.jsonl"
run_started = time.perf_counter()
process_cpu_started = time.process_time()
runtime_snapshotters = {
"detector": detector_queue.snapshot,
"semantic": semantic_queue.snapshot,
"decoder": decoder.snapshot,
"synchronizer": synchronizer.snapshot,
"lidar_quality": lidar_quality.snapshot,
"result": lambda: {
"capacity": result_queue.maxsize,
"depth": result_queue.qsize(),
"dropped_overflow": transport.results_dropped,
"published": transport.results_published,
},
}
if local_surface is not None:
runtime_snapshotters["local_surface"] = local_surface.snapshot
with (
semantic_path.open("x", encoding="utf-8", newline="\n") as semantic_stream,
@@ -1037,19 +1288,7 @@ def run(args: argparse.Namespace, loaded: _LoadedModels | None = None) -> int:
_RuntimeTelemetry(
runtime_stream,
interval_seconds=1.0,
snapshotters={
"detector": detector_queue.snapshot,
"semantic": semantic_queue.snapshot,
"decoder": decoder.snapshot,
"synchronizer": synchronizer.snapshot,
"lidar_quality": lidar_quality.snapshot,
"result": lambda: {
"capacity": result_queue.maxsize,
"depth": result_queue.qsize(),
"dropped_overflow": transport.results_dropped,
"published": transport.results_published,
},
},
snapshotters=runtime_snapshotters,
) as runtime_telemetry,
):
@@ -1111,6 +1350,7 @@ def run(args: argparse.Namespace, loaded: _LoadedModels | None = None) -> int:
"max_duration_seconds": args.max_duration_seconds,
"decoder": decoder,
"synchronizer": synchronizer,
"local_surface": local_surface,
"lidar_quality": lidar_quality,
"state": transport,
"sensor_decode_ms": sensor_decode_ms,
@@ -1400,6 +1640,9 @@ def run(args: argparse.Namespace, loaded: _LoadedModels | None = None) -> int:
temporal_semantic_summary = (
None if semantic_stabilizer is None else semantic_stabilizer.snapshot()
)
local_surface_snapshot = (
None if local_surface is None else local_surface.snapshot()
)
acceptance = live["acceptance"]
checks = {
"minimum_camera_frames": decoded_frame_count >= int(acceptance["minimum_camera_frames"]),
@@ -1454,6 +1697,14 @@ def run(args: argparse.Namespace, loaded: _LoadedModels | None = None) -> int:
"authority_remains_shadow_only": live["authority"]
== {"commands_enabled": False, "navigation_or_safety_accepted": False},
}
if isinstance(local_surface_config, dict):
assert local_surface_snapshot is not None
checks.update(
_local_surface_acceptance_checks(
local_surface_snapshot,
local_surface_config,
)
)
if stability is not None:
temporal_acceptance = stability["acceptance"]
assert temporal_track_summary is not None
@@ -1502,6 +1753,16 @@ def run(args: argparse.Namespace, loaded: _LoadedModels | None = None) -> int:
"identity_sha256": common["projection_manifest"]["identity_sha256"],
},
"lidar_evidence": lidar_readiness_document(K1_LIVE_LIDAR_PROFILE),
"local_surface": (
None
if local_surface_config is None
else {
"profile_id": local_surface_config["profile_id"],
"profile_sha256": local_surface_config["profile_sha256"],
"binder_schema": "missioncore.k1-local-surface-pose-binder/v1",
"runtime_schema": "missioncore.k1-local-surface-shadow-runtime/v1",
}
),
"worker_package": {
"id": common["worker_package"]["package_id"],
"identity_sha256": common["worker_package"]["identity_sha256"],
@@ -1566,6 +1827,7 @@ def run(args: argparse.Namespace, loaded: _LoadedModels | None = None) -> int:
"sensor_decode_ms": sensor_decode_summary,
},
"lidar_quality": lidar_quality.snapshot(),
"local_surface": local_surface_snapshot,
"latency_ms": latency_summary,
"temporal_stability": {
"enabled": stability is not None,
@@ -1616,6 +1878,16 @@ def run(args: argparse.Namespace, loaded: _LoadedModels | None = None) -> int:
"Camera/LiDAR matching uses recorded host arrival time, not a hardware clock.",
"K1 LiDAR is a vendor map increment, not an admitted raw sensor sweep.",
"K1 LiDAR has no admitted per-point time, ring, scan geometry or IMU stream.",
*(
[
"K1 local-surface pose binding uses bounded worker host-arrival "
"time, not hardware synchronization.",
"K1 local-surface outputs are diagnostic observed-surface evidence; "
"they do not infer free or traversable unknown space.",
]
if local_surface_snapshot is not None
else []
),
"Cross-host source epoch age is diagnostic and excluded from acceptance.",
"COCO and Cityscapes models are not forest-domain or safety validated.",
"Amodal cuboids infer unobserved volume from class priors.",