Skip to content
5 changes: 4 additions & 1 deletion loopx/cli_commands/turn_decision.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
scheduler_execution_context_for_turn,
)
from ..status import AUTONOMOUS_REPLAN_PERIODIC_LOOKBACK, collect_status
from ..paths import default_public_scan_root
from ..control_plane.effect_runtime import effect_runtime_result
from .lark_inbox import build_lark_operator_inbox_urgency_projector
from .turn_selection import turn_controller_advisory_primary
Expand Down Expand Up @@ -337,7 +338,9 @@ def current_heartbeat_host_launch_decision(
args = argparse.Namespace(
goal_id=goal_id, agent_id=agent_id, turn_instance_id=original_turn,
todo_id=None, codex_app=False, runtime_profile="generic_cli",
scan_path=[str(project)], scan_root=str(project), limit=0,
# Match heartbeat-prompt's default public scan. The execution workspace
# may be a private task with auth fixtures, rather than public LoopX code.
scan_path=[], scan_root=default_public_scan_root(), limit=0,
available_capabilities=["shell", "filesystem_write"],
)
selection = load_requested_quota_action_selection(
Expand Down
32 changes: 31 additions & 1 deletion tests/control_plane/test_benchmark_current_admission.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from __future__ import annotations

import json
from ipaddress import IPv4Address
from pathlib import Path
import sys
import time
Expand All @@ -11,9 +12,11 @@
from benchmark.runtime import worker
from benchmark.tests.test_shared_codex_runtime import worker_env
from loopx.configure_goal import configure_goal
from loopx.cli_commands import turn_decision
from loopx.control_plane.goals import activation_service
from loopx.control_plane.goals.first_party_host_admission import FirstPartyHostRuntimeRejected
from loopx.global_registry import sync_project_registry_to_global
from loopx.paths import default_public_scan_root
from tests.control_plane.canonical_authority_fixture import isolate_sqlite_runtime
from tests.control_plane.host_process_fixture import write_python_host_fixture
from tests.control_plane import test_quota_settlement_cli as fixture
Expand All @@ -39,6 +42,11 @@ def _environment(tmp_path, monkeypatch, provider, *, replan=False):
elif replan:
fixture._configure_autonomous_replan_fixture(project, runtime, source)
fixture._initialize_fixture_authority(project, runtime, provider=provider)
# A private task can contain synthetic private-network fixtures. It is not
# the public package tree selected by the heartbeat CLI's default scan.
(project / "task_network_fixture.py").write_text(
"endpoint = " + repr("http://" + str(IPv4Address(0x0A000001))) + "\n"
)
synced = sync_project_registry_to_global(
registry_path=source, runtime_root_override=str(runtime), goal_id=fixture.GOAL_ID,
)
Expand Down Expand Up @@ -70,7 +78,7 @@ def _environment(tmp_path, monkeypatch, provider, *, replan=False):
def _quota(registry, runtime, project):
code, result = fixture._run_cli(registry, runtime,
"quota", "should-run", "--goal-id", fixture.GOAL_ID, "--agent-id", fixture.AGENT_ID,
"--runtime-profile", "generic_cli", cwd=project)
"--runtime-profile", "generic_cli", "--scan-root", default_public_scan_root(), cwd=project)
assert code == 0 or code == 1 and result.get("status_health_ok") is False, result
return result

Expand Down Expand Up @@ -112,6 +120,7 @@ def after_session_selection(*arguments):
monkeypatch.setattr(worker, "native_command", after_session_selection)
bindings_before = _bindings(runtime)
rejected = None
result = None
try:
result = worker.run_once(env)
except FirstPartyHostRuntimeRejected as error:
Expand Down Expand Up @@ -166,3 +175,24 @@ def test_initial_benchmark_planner_can_launch_without_a_prior_heartbeat_receipt(
assert len(planned["todo_ids"]) == 1 and result["planning"]["todo_ids"] == planned["todo_ids"]
assert not fixture._heartbeat_receipt_events(runtime, result["turn_id"])
assert fixture._spend_run_count(runtime) == 0


@pytest.mark.parametrize("provider", ["file", "sqlite"])
def test_heartbeat_host_launch_retains_public_scan_refusal(tmp_path, monkeypatch, provider):
env, project, runtime, source, _state = _environment(tmp_path, monkeypatch, provider)
public = tmp_path / "selected-public"
public.mkdir()
(public / "unsafe_fixture.py").write_text(
"endpoint = " + repr("http://" + str(IPv4Address(0x0A000001))) + "\n"
)
code, original = fixture._run_cli(source, runtime,
"quota", "should-run", "--goal-id", fixture.GOAL_ID, "--agent-id", fixture.AGENT_ID,
"--scan-path", str(public), cwd=project)
assert code == 1 and original["status_health_ok"] is False and original["should_run"] is False
monkeypatch.setattr(turn_decision, "default_public_scan_root", lambda: str(public))
current = turn_decision.current_heartbeat_host_launch_decision(
registry_path=Path(env["LOOPX_REGISTRY"]), runtime_root=runtime, project=project,
goal_id=fixture.GOAL_ID, agent_id=fixture.AGENT_ID, turn_instance_id="public-scan-refusal",
)["current"]
assert current["status_health_ok"] is False and current["should_run"] is False
assert not (project / "native-starts").exists() and not (project / "model-starts").exists()
Loading