fix(k1): harden live handoff and camera recovery

This commit is contained in:
DCCONSTRUCTIONS
2026-08-22 13:09:24 +03:00
parent eaad9deda1
commit 85035fa07b
26 changed files with 1478 additions and 170 deletions
+267
View File
@@ -19833,6 +19833,8 @@ def test_quick_connect_activates_the_device_ap_then_associates_the_host(
assert state["connection_mode"] == "quick-connect"
assert state["k1_ip"] == "192.168.56.1"
assert state["compatibility"]["attestation"]["topology"] == "device-ap"
assert state["last_operation"]["result"]["host_wifi_association_performed"] is True
assert state["last_operation"]["result"]["host_wifi_association_outcome"] == "associated"
quick_sessions = sorted(service.evidence_root.glob("*viewer_k1_ap_association*"))
assert len(quick_sessions) == 1
assert not (quick_sessions[0] / "provisioning.sensitive.json").exists()
@@ -19843,6 +19845,8 @@ def test_quick_connect_activates_the_device_ap_then_associates_the_host(
assert '"credentials_resolved_by_plugin": true' in redacted_manifest
assert "credential_provider_id" in redacted_manifest
assert "device_ap_activation_profile_id" in redacted_manifest
assert '"host_wifi_association_performed": true' in redacted_manifest
assert '"host_wifi_association_outcome": "associated"' in redacted_manifest
assert (quick_sessions[0] / "ap-activation.redacted.json").exists()
assert (
service._camera_target_for_session( # noqa: SLF001
@@ -29487,6 +29491,114 @@ _RECOVERY_ACQUISITION_ID = "acquisition-persisted-active-k1"
_RECOVERY_START_OPERATION_ID = "physical-start-persisted-active-k1"
def _persist_ambiguous_start_with_prepared_checkpoint(
service: XgridsK1CompatibilityService,
) -> None:
"""Persist the exact pre-crash shape: PREPARED token + ambiguous START."""
identity = PhysicalCommandIdentity(
vendor_device_id_sha256=_RECOVERY_VENDOR_HASH,
device_serial_sha256=_RECOVERY_SERIAL_HASH,
)
connection = PhysicalCommandConnectionBinding(
intent_id="ambiguous-start-intent",
transport_ref="test-ble-transport",
connection_mode="bridge",
target_ipv4="192.168.68.52",
target_port=facade_module.CONTROL_MQTT_PORT,
host_path_epoch=1,
control_session_id="ambiguous-start-control",
producer_generation=1,
)
observed_at_utc = datetime.now(UTC).isoformat(timespec="milliseconds").replace(
"+00:00",
"Z",
)
baseline = PhysicalCommandStatusEvidence(
source="live-control-session",
vendor_device_id_sha256=_RECOVERY_VENDOR_HASH,
device_serial_sha256=_RECOVERY_SERIAL_HASH,
control_session_id=connection.control_session_id,
host_path_epoch=connection.host_path_epoch,
producer_generation=connection.producer_generation,
session_state="ready",
session_state_code=300,
project_bound=False,
project_id_sha256=None,
init_ready=False,
status_message_sha256="1" * 64,
mqtt_retained=False,
observed_at_utc=observed_at_utc,
)
operation_id = "physical-start-persisted-ambiguous-k1"
acquisition_id = "acquisition-persisted-ambiguous-k1"
payload_sha256 = "2" * 64
ledger = service._physical_command_ledger # noqa: SLF001
ledger.prepare(
operation_id=operation_id,
parent_operation_id=None,
acquisition_id=acquisition_id,
action="start",
identity=identity,
connection=connection,
compatibility_profile_id=XGRIDS_K1_COMPATIBILITY_PROFILE_ID,
payload_sha256=payload_sha256,
baseline_status=baseline,
)
store = service._active_acquisition_checkpoint # noqa: SLF001
assert store is not None
store.prepare(
transition_id="prepare-persisted-ambiguous-start",
predecessor_revision=0,
acquisition_id=acquisition_id,
original_start_operation_id=operation_id,
start_payload_sha256=payload_sha256,
identity=ActiveAcquisitionRecoveryIdentity(
logical_device_id="known-k1",
vendor_device_id_sha256=_RECOVERY_VENDOR_HASH,
device_serial_sha256=_RECOVERY_SERIAL_HASH,
),
connection=ActiveAcquisitionRecoveryConnection(
transport_ref=connection.transport_ref,
connection_mode=connection.connection_mode,
target_ipv4=connection.target_ipv4,
target_port=connection.target_port,
),
compatibility_profile_id=XGRIDS_K1_COMPATIBILITY_PROFILE_ID,
project_name="AMBIGUOUS_RECOVERY",
project_name_wire_sha256=active_acquisition_project_name_sha256(
"AMBIGUOUS_RECOVERY"
),
original_evidence_session_id="evidence-before-crash",
duration_seconds=None,
requested_streams=("spatial.point-cloud.live", "camera.rgb.live"),
evidence_policy="required",
mount_type="handheld",
gnss_mode="none",
prepared_binding=ActiveAcquisitionRecoveryTransportBinding(
runtime_instance_id="runtime-before-crash",
intent_id=connection.intent_id,
transport_ref=connection.transport_ref,
connection_mode=connection.connection_mode,
target_ipv4=connection.target_ipv4,
target_port=connection.target_port,
host_path_epoch=connection.host_path_epoch,
control_session_id=connection.control_session_id,
producer_generation=connection.producer_generation,
logical_device_id="known-k1",
compatibility_profile_id=XGRIDS_K1_COMPATIBILITY_PROFILE_ID,
vendor_device_id_sha256=_RECOVERY_VENDOR_HASH,
device_serial_sha256=_RECOVERY_SERIAL_HASH,
),
)
ledger.mark_dispatching(operation_id)
ledger.mark_observing(
operation_id,
publish_call_returned=True,
packet_id=41,
)
def _persist_resolved_active_start_for_restart(
service: XgridsK1CompatibilityService,
) -> None:
@@ -30448,6 +30560,54 @@ def test_explicit_verify_reconciles_scanning_as_active_without_unblocking_mode_c
}
def test_explicit_verify_scanning_checkpoint_rehydrate_failure_keeps_stop_only(
monkeypatch: pytest.MonkeyPatch,
tmp_path: Path,
) -> None:
"""A rejected local checkpoint cannot erase proven physical STOP authority."""
service, runtime = service_with_fake_runtime(tmp_path)
coordinator = _VerifyPhysicalRecoveryCoordinator(
observed_session_state="scanning",
reconciliation_ready=True,
)
_install_synthetic_verify_recovery(service, coordinator)
rehydrate_calls: list[str] = []
async def reject_receiver_rehydration(**_: object) -> None:
rehydrate_calls.append("rejected")
raise facade_module.ActiveAcquisitionRecoveryCheckpointError(
"synthetic stale prepared checkpoint"
)
monkeypatch.setattr(
service,
"_rehydrate_active_acquisition_after_restart",
reject_receiver_rehydration,
)
operation_id = "op-00000000-0000-4000-8000-000000001217"
state = asyncio.run(
service.verify_connection(
_retained_physical_recovery_verify_request(operation_id=operation_id)
)
)
assert rehydrate_calls == ["rejected"]
assert state["last_operation"]["status"] == "succeeded"
assert state["physical_command"]["record"]["resolution"] == (
"physical-active-observed"
)
assert state["acquisition"]["acquisition_id"] == "acq-persisted-start"
assert state["acquisition"]["state"] == "failed"
assert state["acquisition"]["result"]["recovery_only"] is True
assert state["application_control_session"]["state"] == "scanning"
assert state["application_control_session"]["can_stop"] is True
assert state["connection_policy"]["actions"]["stop-acquisition"]["allowed"] is True
assert runtime.start_calls == []
assert runtime.stop_calls == 0
def test_explicit_verify_scanning_cleans_terminal_camera_residual_for_stop_only_shell(
monkeypatch: pytest.MonkeyPatch,
tmp_path: Path,
@@ -30934,6 +31094,113 @@ def test_active_reconciliation_survives_post_commit_adoption_failure_and_next_re
]["mode_selection"]
def test_prepared_ambiguous_start_active_then_ready_settles_checkpoint_without_command(
tmp_path: Path,
) -> None:
"""Fresh SCANNING then READY closes the pre-crash token without replay."""
service, runtime = service_with_fake_runtime(tmp_path)
_persist_ambiguous_start_with_prepared_checkpoint(service)
coordinator = service._physical_command_coordinator # noqa: SLF001
observed_base = datetime.now(UTC) + timedelta(seconds=1)
def bind_fresh_status(
*,
suffix: str,
generation: int,
session_state: str,
) -> None:
observed_at_utc = (
observed_base + timedelta(seconds=generation)
).isoformat(timespec="milliseconds").replace("+00:00", "Z")
coordinator.application_response(
ApplicationMqttResponseEvidence(
operation_key=f"bootstrap:{suffix}:DeviceInfoRequest",
response_topic="lixel/application/response/device_info",
payload_sha256=hashlib.sha256(
f"device-info:{suffix}".encode()
).hexdigest(),
modeling_action=None,
result_code=None,
success=None,
observed_at_utc=observed_at_utc,
)
)
coordinator.bind_control_session(
PhysicalCommandRuntimeBinding(
vendor_device_id_sha256=_RECOVERY_VENDOR_HASH,
device_serial_sha256=_RECOVERY_SERIAL_HASH,
compatibility_profile_id=XGRIDS_K1_COMPATIBILITY_PROFILE_ID,
intent_id=f"recovery-{suffix}-intent",
transport_ref="test-ble-transport",
connection_mode="bridge",
target_ipv4="192.168.68.52",
target_port=facade_module.CONTROL_MQTT_PORT,
host_path_epoch=generation,
control_session_id=f"recovery-{suffix}-control",
producer_generation=generation,
)
)
scanning = session_state == "scanning"
coordinator.device_status(
ApplicationMqttDeviceStatusEvidence(
vendor_device_id_sha256=_RECOVERY_VENDOR_HASH,
device_serial_sha256=_RECOVERY_SERIAL_HASH,
session_state=session_state, # type: ignore[arg-type]
session_state_code=MODELING_STATE_BASE + (302 if scanning else 300),
project_bound=scanning,
project_id_sha256=_RECOVERY_PROJECT_HASH if scanning else None,
init_ready=scanning,
status_message_sha256=hashlib.sha256(
f"status:{suffix}:{session_state}".encode()
).hexdigest(),
mqtt_retained=False,
observed_at_utc=observed_at_utc,
)
)
bind_fresh_status(suffix="active", generation=2, session_state="scanning")
active_record = coordinator.reconcile_unresolved(
reconciliation_id="reconcile-ambiguous-active"
)
assert active_record["resolution"] == "physical-active-observed"
token = service._validate_active_acquisition_checkpoint_lineage() # noqa: SLF001
assert token is not None and token.checkpoint_state == "prepared"
bind_fresh_status(suffix="ready", generation=3, session_state="ready")
standby_record = coordinator.reconcile_resolved_active(
reconciliation_id="reconcile-ambiguous-ready"
)
assert standby_record["resolution"] == "physical-standby-observed"
assert standby_record["reconciliations"][-1]["kind"] == (
"resolved-active-cessation"
)
settled = service._settle_restart_checkpoint_after_verified_standby( # noqa: SLF001
token=token,
reconciliation_id="reconcile-ambiguous-ready",
reconciled_record=standby_record,
)
assert settled is True
store = service._active_acquisition_checkpoint # noqa: SLF001
assert store is not None
checkpoint = store.snapshot().checkpoint
assert checkpoint is not None and checkpoint.state == "ceased"
assert checkpoint.active_project_id_sha256 == _RECOVERY_PROJECT_HASH
assert checkpoint.activated_at_utc is None
assert checkpoint.first_published_pcl_proof is None
assert checkpoint.reconciled_start_origin_proof is not None
assert checkpoint.reconciled_start_origin_proof.origin_kind == (
"ambiguous-reconciled"
)
assert checkpoint.reconciled_start_origin_proof.reconciled_active_project_id_sha256 == (
_RECOVERY_PROJECT_HASH
)
assert runtime.start_calls == []
assert runtime.stop_calls == 0
@pytest.mark.parametrize(
("proof_kind", "observed_session_state"),
[