feat: ingest repository navigation projections
Some checks failed
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / pytest-smoke (push) Failing after 3s

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a0230c-b06c-7641-808a-e191b6d1da49
This commit is contained in:
tegwick 2026-08-22 00:35:47 +02:00
parent f9a0a6dd72
commit 3db8c9cd78
9 changed files with 933 additions and 4 deletions

View file

@ -19,6 +19,7 @@ from hub_core.runtime.models import (
Provenance,
RegistryRegistration,
)
from hub_core.runtime.repository_navigation import NavigationProjection
class PortStore(Protocol):
@ -44,6 +45,16 @@ class PortStore(Protocol):
async def query_projection(self, projection_id: str) -> PortRecord | None: ...
async def get_repository_navigation(self) -> NavigationProjection | None: ...
async def replace_repository_navigation(
self, projection: NavigationProjection
) -> None: ...
async def mark_repository_navigation_stale(
self, *, checked_at: datetime, diagnostic: Mapping[str, Any]
) -> None: ...
class InMemoryPortStore:
"""Deterministic ephemeral backend for local runtime and conformance tests.
@ -60,6 +71,7 @@ class InMemoryPortStore:
self._messages: list[dict[str, Any]] = []
self._progress_events: list[dict[str, Any]] = []
self._interaction_events: list[dict[str, Any]] = []
self._repository_navigation: NavigationProjection | None = None
async def readiness_checks(self) -> dict[str, str]:
return {"database": "not_applicable"}
@ -134,6 +146,34 @@ class InMemoryPortStore:
},
)
async def get_repository_navigation(self) -> NavigationProjection | None:
async with self._lock:
return deepcopy(self._repository_navigation)
async def replace_repository_navigation(
self, projection: NavigationProjection
) -> None:
async with self._lock:
self._repository_navigation = deepcopy(projection)
async def mark_repository_navigation_stale(
self, *, checked_at: datetime, diagnostic: Mapping[str, Any]
) -> None:
async with self._lock:
current = self._repository_navigation
if current is None:
return
self._repository_navigation = NavigationProjection(
projection_status="stale",
source_snapshot=deepcopy(current.source_snapshot),
source_checked_at=checked_at,
rebuilt_at=current.rebuilt_at,
content_hash=current.content_hash,
repositories=deepcopy(current.repositories),
facets=deepcopy(current.facets),
diagnostics=(deepcopy(dict(diagnostic)),),
)
async def _append_event(
self,
command: EventCommand,