diff --git a/loopx/control_plane/runtime/runtime_projection_route.py b/loopx/control_plane/runtime/runtime_projection_route.py index 2e83d3d9d2..801bc8cd6c 100644 --- a/loopx/control_plane/runtime/runtime_projection_route.py +++ b/loopx/control_plane/runtime/runtime_projection_route.py @@ -58,27 +58,10 @@ def _registry_runtime_root( registry: dict[str, Any], *, registry_path: Path, - goal_id: str, ) -> Path: - runtime_root = resolve_runtime_root(registry, None).expanduser() - if not runtime_root.is_absolute(): - goal = next( - ( - item - for item in registry_goals(registry) - if str(item.get("id") or "") == goal_id - ), - None, - ) - repo = Path(str((goal or {}).get("repo") or "")).expanduser() - if not repo.is_absolute(): - repo = ( - registry_path.parent.parent - if registry_path.parent.name == ".loopx" - else registry_path.parent - ) - runtime_root = repo / runtime_root - return runtime_root.resolve() + return resolve_runtime_root( + registry, None, registry_path=registry_path, + ).expanduser().resolve() def _goal_source_route_packet( @@ -131,7 +114,6 @@ def resolve_goal_source_runtime_route( invoked_runtime = _registry_runtime_root( registry_payload, registry_path=invoked_registry, - goal_id=goal_id, ) if runtime_root_override: runtime_root = Path(runtime_root_override).expanduser().resolve() @@ -200,7 +182,6 @@ def resolve_goal_source_runtime_route( source_runtime = _registry_runtime_root( source_payload, registry_path=source_registry, - goal_id=goal_id, ) return _goal_source_route_packet( status="source_registry", diff --git a/tests/control_plane/test_explore_source_runtime_route.py b/tests/control_plane/test_explore_source_runtime_route.py index eaf5a07e32..8d28d4e5a5 100644 --- a/tests/control_plane/test_explore_source_runtime_route.py +++ b/tests/control_plane/test_explore_source_runtime_route.py @@ -105,6 +105,19 @@ def test_global_goal_route_uses_source_registry_relative_runtime( assert Path(route["source_runtime_root"]) == project / ".loopx" / "runtime" +def test_relative_runtime_belongs_to_registry_even_when_goal_repo_differs(tmp_path: Path) -> None: + for relative_registry in ("registry.json", ".loopx/registry.json"): + owner = tmp_path / relative_registry.replace("/", "-") + registry = owner / relative_registry + _write_registry(registry, runtime_root="runtime") + payload = json.loads(registry.read_text()) + payload["goals"][0]["repo"] = str(tmp_path / "separate-goal-checkout") + registry.write_text(json.dumps(payload)) + route = resolve_goal_source_runtime_route(registry_path=registry, goal_id=GOAL_ID) + assert Path(route["source_runtime_root"]) == owner / "runtime" + assert route["status"] == "project_registry" + + def test_feishu_sync_uses_source_rows_and_visual_marker(tmp_path: Path) -> None: project = tmp_path / "project" source_registry = project / ".loopx" / "registry.json"