feat(observatory): add portable calculation profiles

This commit is contained in:
DCCONSTRUCTIONS
2026-08-31 15:42:56 +03:00
parent d1b75efcea
commit 9beb534108
75 changed files with 24419 additions and 348 deletions
+204 -31
View File
@@ -47,20 +47,38 @@ from k1link.observatory.m49_queue_binding import (
M49QueueBindingError,
M49RecordedQueueBindingService,
)
from k1link.observatory.portable_queue_binding import (
PortableQueueBindingError,
PortableRecordedQueueBindingService,
)
from k1link.observatory.portable_result_contract import (
PortableCalculationProfileRegistry,
PortableResultContractValidatorRegistry,
)
from k1link.observatory.portable_result_publisher import (
resolve_published_portable_calculation_profile,
)
from k1link.observatory.portable_run_definitions import (
PortableRunDefinitionRegistry,
PortableRunDefinitionRegistryError,
)
from k1link.observatory.portable_setup_projection import (
PORTABLE_LAB_V1_SETUP_ID,
PortableLabV1SetupProjector,
PortableSetupProjectionError,
PortableSetupProjector,
portable_calculation_profile_registry,
)
from k1link.observatory.portable_worker_integration import (
PortableObservatoryWorkerIntegration,
PortableWorkerIntegrationError,
PortableWorkerStorageRoots,
build_portable_observatory_worker_integration,
portable_result_validator_registry,
)
from k1link.observatory.recorded_jobs import (
ObservatoryRecordedJobQueue,
ObservatoryRecordedQueueError,
RecordedRunDefinitionRegistry,
)
from k1link.observatory.source_admission import RecordedK1SourceAdmissionService
from k1link.sessions import (
MaterializedRecording,
RecordedCameraFrameService,
@@ -73,6 +91,7 @@ from k1link.sessions import (
SessionRecordingPreparationManager,
SessionStore,
)
from k1link.sessions.models import SessionSummary
from k1link.simulation.projects import SimulationProjectService, SimulationProjectStore
from k1link.web.advanced_laboratory_api import build_advanced_laboratory_router
from k1link.web.artifact_health_api import build_artifact_health_router
@@ -261,6 +280,55 @@ plugin_catalog: DevicePluginCatalog = plugin_environment.catalog
plugin_dispatcher: DevicePluginDispatcher = plugin_environment.dispatcher
session_store = SessionStore(REPOSITORY_ROOT)
OBSERVATORY_PORTABLE_DEFINITION_REGISTRY: PortableRunDefinitionRegistry | None
OBSERVATORY_PORTABLE_DEFINITION_REGISTRY_ERROR: str | None
OBSERVATORY_PORTABLE_CALCULATION_PROFILES: PortableCalculationProfileRegistry | None
OBSERVATORY_PORTABLE_RESULT_VALIDATORS: PortableResultContractValidatorRegistry | None
try:
OBSERVATORY_PORTABLE_DEFINITION_REGISTRY = PortableRunDefinitionRegistry.from_file(
REPOSITORY_ROOT / "config" / "observatory-portable-run-definitions.json"
)
OBSERVATORY_PORTABLE_CALCULATION_PROFILES = portable_calculation_profile_registry(
OBSERVATORY_PORTABLE_DEFINITION_REGISTRY
)
OBSERVATORY_PORTABLE_RESULT_VALIDATORS = portable_result_validator_registry(
OBSERVATORY_PORTABLE_DEFINITION_REGISTRY
)
OBSERVATORY_PORTABLE_DEFINITION_REGISTRY_ERROR = None
except (
PortableRunDefinitionRegistryError,
PortableWorkerIntegrationError,
OSError,
ValueError,
) as exc:
# Portable definitions are an optional observation-only slice. Registry
# drift cannot affect K1, Simulation, legacy LAB, or the exact M49 binding.
OBSERVATORY_PORTABLE_DEFINITION_REGISTRY = None
OBSERVATORY_PORTABLE_CALCULATION_PROFILES = None
OBSERVATORY_PORTABLE_RESULT_VALIDATORS = None
OBSERVATORY_PORTABLE_DEFINITION_REGISTRY_ERROR = str(exc)
def _resolve_observatory_calculation_profile(
summary: SessionSummary,
) -> dict[str, object] | None:
if OBSERVATORY_LABORATORY_SETUP_REGISTRY is not None:
legacy = OBSERVATORY_LABORATORY_SETUP_REGISTRY.observatory_calculation_profile(
summary
)
if legacy is not None:
return legacy
if (
OBSERVATORY_PORTABLE_DEFINITION_REGISTRY is None
or OBSERVATORY_PORTABLE_CALCULATION_PROFILES is None
):
return None
return resolve_published_portable_calculation_profile(
summary,
definitions=OBSERVATORY_PORTABLE_DEFINITION_REGISTRY,
calculation_profiles=OBSERVATORY_PORTABLE_CALCULATION_PROFILES,
)
def _load_optional_observatory_worker_authentication(
recorded_job_queue: ObservatoryRecordedJobQueue | None,
@@ -299,9 +367,14 @@ try:
REPOSITORY_ROOT / "config" / "observatory-m49-recorded-queue-binding.json"
),
)
recorded_definitions = list(OBSERVATORY_RECORDED_BINDING_SERVICE.definitions.definitions)
if OBSERVATORY_PORTABLE_DEFINITION_REGISTRY is not None:
recorded_definitions.extend(
OBSERVATORY_PORTABLE_DEFINITION_REGISTRY.ready_recorded_definitions()
)
OBSERVATORY_RECORDED_JOB_QUEUE = ObservatoryRecordedJobQueue(
session_store.data_dir,
definitions=OBSERVATORY_RECORDED_BINDING_SERVICE.definitions,
definitions=RecordedRunDefinitionRegistry(tuple(recorded_definitions)),
)
OBSERVATORY_RECORDED_JOB_QUEUE_ERROR = None
except (M49QueueBindingError, ObservatoryRecordedQueueError, OSError, ValueError) as exc:
@@ -316,11 +389,14 @@ OBSERVATORY_WORKER_CLAIM_LEASE_READY = False
OBSERVATORY_WORKER_VERIFIED_RESULT_PUBLISHER_READY = False
OBSERVATORY_WORKER_PRODUCTION_API_ENABLED = False
OBSERVATORY_WORKER_AUTHENTICATION: ObservatoryWorkerAuthentication | None
OBSERVATORY_WORKER_AUTHENTICATION_ERROR: str | None
OBSERVATORY_WORKER_API_ERROR: str | None
OBSERVATORY_WORKER_AUTHENTICATION = None
OBSERVATORY_WORKER_API_ERROR = (
"Worker pull API is hard-disabled until claim leases and a verified "
"Observatory result publisher are implemented and accepted"
(
OBSERVATORY_WORKER_AUTHENTICATION,
OBSERVATORY_WORKER_AUTHENTICATION_ERROR,
) = _load_optional_observatory_worker_authentication(
OBSERVATORY_RECORDED_JOB_QUEUE,
token_path=OBSERVATORY_WORKER_TOKEN_PATH,
)
simulation_project_store = SimulationProjectStore(session_store.data_dir)
simulation_project_service = SimulationProjectService(simulation_project_store)
@@ -336,37 +412,122 @@ session_recording_materializer = SessionRecordingMaterializer(
session_recorded_media_inspector = RecordedMediaInspector(
session_store.data_dir / "recorded-media-preparations"
)
OBSERVATORY_PORTABLE_SETUP_PROJECTOR: PortableLabV1SetupProjector | None
OBSERVATORY_PORTABLE_WORKER_INTEGRATION: PortableObservatoryWorkerIntegration | None
OBSERVATORY_PORTABLE_WORKER_INTEGRATION_ERROR: str | None
OBSERVATORY_PORTABLE_WORKER_STORAGE_ROOTS: PortableWorkerStorageRoots | None = None
try:
if OBSERVATORY_PORTABLE_DEFINITION_REGISTRY is None:
raise PortableWorkerIntegrationError(
OBSERVATORY_PORTABLE_DEFINITION_REGISTRY_ERROR
or "portable definition registry is unavailable"
)
if OBSERVATORY_PORTABLE_CALCULATION_PROFILES is None:
raise PortableWorkerIntegrationError(
"portable calculation profile registry is unavailable"
)
if OBSERVATORY_PORTABLE_RESULT_VALIDATORS is None:
raise PortableWorkerIntegrationError(
"portable result validator registry is unavailable"
)
if OBSERVATORY_RECORDED_JOB_QUEUE is None:
raise PortableWorkerIntegrationError(
OBSERVATORY_RECORDED_JOB_QUEUE_ERROR
or "Observatory recorded-job queue is unavailable"
)
if session_artifact_gateway is None:
raise PortableWorkerIntegrationError(
"central artifact store is not configured"
)
if session_artifact_gateway.status().central_status != "ready":
raise PortableWorkerIntegrationError(
"central artifact store is unavailable"
)
OBSERVATORY_PORTABLE_WORKER_STORAGE_ROOTS = (
PortableWorkerStorageRoots.from_environment(
artifact_store_root=session_artifact_gateway.store.root,
)
)
OBSERVATORY_PORTABLE_WORKER_INTEGRATION = (
build_portable_observatory_worker_integration(
queue=OBSERVATORY_RECORDED_JOB_QUEUE,
session_store=session_store,
media_inspector=session_recorded_media_inspector,
definitions=OBSERVATORY_PORTABLE_DEFINITION_REGISTRY,
artifact_store=session_artifact_gateway.store,
calculation_profiles=OBSERVATORY_PORTABLE_CALCULATION_PROFILES,
validators=OBSERVATORY_PORTABLE_RESULT_VALIDATORS,
source_cas_root=(
OBSERVATORY_PORTABLE_WORKER_STORAGE_ROOTS.source_cas_root
),
result_staging_root=(
OBSERVATORY_PORTABLE_WORKER_STORAGE_ROOTS.result_staging_root
),
)
)
OBSERVATORY_PORTABLE_WORKER_INTEGRATION_ERROR = None
except (PortableWorkerIntegrationError, OSError, ValueError) as exc:
# Constructing this dormant foundation does not enable the Worker router.
# Failure remains isolated from K1, Simulation and legacy LAB.
OBSERVATORY_PORTABLE_WORKER_INTEGRATION = None
OBSERVATORY_PORTABLE_WORKER_INTEGRATION_ERROR = str(exc)
OBSERVATORY_WORKER_API_ERROR = (
"Worker pull API is hard-disabled pending sealed installed executors, "
"a configured Worker credential, explicit integration acceptance and the "
"production gate"
+ (
""
if OBSERVATORY_WORKER_AUTHENTICATION_ERROR is None
else (
"; authentication unavailable: "
f"{OBSERVATORY_WORKER_AUTHENTICATION_ERROR}"
)
)
+ (
""
if OBSERVATORY_PORTABLE_WORKER_INTEGRATION_ERROR is None
else f"; integration unavailable: {OBSERVATORY_PORTABLE_WORKER_INTEGRATION_ERROR}"
)
)
OBSERVATORY_WORKER_DISPATCH_READY = (
OBSERVATORY_WORKER_PRODUCTION_API_ENABLED
and OBSERVATORY_WORKER_CLAIM_LEASE_READY
and OBSERVATORY_WORKER_VERIFIED_RESULT_PUBLISHER_READY
and OBSERVATORY_RECORDED_JOB_QUEUE is not None
and OBSERVATORY_WORKER_AUTHENTICATION is not None
and OBSERVATORY_PORTABLE_WORKER_INTEGRATION is not None
)
OBSERVATORY_PORTABLE_BINDING_SERVICE: PortableRecordedQueueBindingService | None
OBSERVATORY_PORTABLE_SETUP_PROJECTOR: PortableSetupProjector | None
OBSERVATORY_PORTABLE_SETUP_PROJECTOR_ERROR: str | None
try:
portable_definition_registry = PortableRunDefinitionRegistry.from_file(
REPOSITORY_ROOT / "config" / "observatory-portable-run-definitions.json"
)
portable_lab_v1_definition = next(
definition
for definition in portable_definition_registry.definitions
if definition.setup_id == PORTABLE_LAB_V1_SETUP_ID
)
portable_source_capability_service = RecordedK1SourceAdmissionService(
if OBSERVATORY_PORTABLE_DEFINITION_REGISTRY is None:
raise PortableSetupProjectionError(
OBSERVATORY_PORTABLE_DEFINITION_REGISTRY_ERROR
or "portable definition registry is unavailable"
)
OBSERVATORY_PORTABLE_BINDING_SERVICE = PortableRecordedQueueBindingService(
data_dir=session_store.data_dir,
session_store=session_store,
media_inspector=session_recorded_media_inspector,
requirements=portable_lab_v1_definition.to_source_admission_requirements(),
definitions=OBSERVATORY_PORTABLE_DEFINITION_REGISTRY,
queue=OBSERVATORY_RECORDED_JOB_QUEUE,
)
OBSERVATORY_PORTABLE_SETUP_PROJECTOR = PortableLabV1SetupProjector(
registry=portable_definition_registry,
capability_probe=portable_source_capability_service,
OBSERVATORY_PORTABLE_SETUP_PROJECTOR = PortableSetupProjector(
registry=OBSERVATORY_PORTABLE_DEFINITION_REGISTRY,
capability_probe=OBSERVATORY_PORTABLE_BINDING_SERVICE,
dispatch_available=OBSERVATORY_WORKER_DISPATCH_READY,
)
OBSERVATORY_PORTABLE_SETUP_PROJECTOR_ERROR = None
except (
PortableQueueBindingError,
PortableRunDefinitionRegistryError,
PortableSetupProjectionError,
OSError,
StopIteration,
ValueError,
) as exc:
# Portable LAB V1 is an optional observation-only slice. A drifted
# Portable setup execution is an optional observation-only slice. A drifted
# registry cannot affect K1, Simulation, legacy LAB, or the exact M49 queue.
OBSERVATORY_PORTABLE_BINDING_SERVICE = None
OBSERVATORY_PORTABLE_SETUP_PROJECTOR = None
OBSERVATORY_PORTABLE_SETUP_PROJECTOR_ERROR = str(exc)
_ffmpeg = _resolve_media_tool("ffmpeg")
@@ -829,6 +990,14 @@ app.include_router(
perception_overlay_provider=session_perception_overlay_store,
perception_media_provider=session_perception_epoch_store,
point_color_renderers=plugin_environment.point_color_renderers,
lab_calculation_profile_resolver=(
None
if (
OBSERVATORY_LABORATORY_SETUP_REGISTRY is None
and OBSERVATORY_PORTABLE_DEFINITION_REGISTRY is None
)
else _resolve_observatory_calculation_profile
),
)
)
app.include_router(
@@ -843,19 +1012,23 @@ app.include_router(
recorded_job_queue_error=OBSERVATORY_RECORDED_JOB_QUEUE_ERROR,
portable_setup_projector=OBSERVATORY_PORTABLE_SETUP_PROJECTOR,
portable_setup_projector_error=OBSERVATORY_PORTABLE_SETUP_PROJECTOR_ERROR,
portable_binding_service=OBSERVATORY_PORTABLE_BINDING_SERVICE,
)
)
if (
OBSERVATORY_WORKER_PRODUCTION_API_ENABLED
and OBSERVATORY_WORKER_CLAIM_LEASE_READY
and OBSERVATORY_WORKER_VERIFIED_RESULT_PUBLISHER_READY
and OBSERVATORY_RECORDED_JOB_QUEUE is not None
and OBSERVATORY_WORKER_AUTHENTICATION is not None
):
if OBSERVATORY_WORKER_DISPATCH_READY:
assert OBSERVATORY_RECORDED_JOB_QUEUE is not None
assert OBSERVATORY_WORKER_AUTHENTICATION is not None
assert OBSERVATORY_PORTABLE_WORKER_INTEGRATION is not None
app.include_router(
build_observatory_worker_router(
OBSERVATORY_RECORDED_JOB_QUEUE,
authentication=OBSERVATORY_WORKER_AUTHENTICATION,
artifact_transport=(
OBSERVATORY_PORTABLE_WORKER_INTEGRATION.artifact_transport
),
result_publisher=(
OBSERVATORY_PORTABLE_WORKER_INTEGRATION.result_publisher
),
)
)
app.include_router(