Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,14 @@ validation and acceptance are reused. The profile is read back by the existing
host owner; no new frontend configuration store or hidden default is added.
Preflight reports an unpinned/unsupported configuration as unavailable. A valid
argv is still runtime-unverified, not proof that a host or an operation ran.
The typed operation transport readback lists `supported_hosts` and
`supported_sandboxes`. An unsupported host returns
`select_supported_operation_host`; an unsupported sandbox returns
`select_supported_operation_sandbox`; missing model/effort returns
`correct_execution_profile`. Transport refusals do not suggest model-credential
environment variables. These are explicit recovery choices, not automatic host
selection or an execution grant. Ordinary host availability remains independent:
a launchable DSH model does not qualify the Codex-only operation connection.
Use `workspace-write` only when the existing work grant requires it;
`danger-full-access` is not accepted by this transport.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,13 @@ Goal instance,不改变 provider 权威,也不把旧操作移植到另一运
相同选项可用于 `turn run-once`。复用既有 delegation inspect/preflight、start、
准入、租约、session 续接、结果验证和验收。原 host owner 读回 profile;
不新增前端配置存储或隐藏默认。不固定或不受支持的配置在预检中标为 unavailable;
有效 argv 仍是 runtime-unverified,不能证明宿主或操作已运行。仅在现有工作授权
有效 argv 仍是 runtime-unverified,不能证明宿主或操作已运行。
typed operation transport 读回列出 `supported_hosts` 和 `supported_sandboxes`。
不支持的宿主返回 `select_supported_operation_host`,不支持的 sandbox 返回
`select_supported_operation_sandbox`,缺失模型/effort 返回
`correct_execution_profile`。传输拒绝不再建议配置模型凭据环境变量。
这些是显式恢复选项,不自动选择宿主或授予执行权限。普通宿主可用性独立保持:
DSH 模型可启动不能证明它拥有当前仅支持 Codex 的操作连接。仅在现有工作授权
确需时使用 `workspace-write`;此传输不接受 `danger-full-access`。

已准入宿主复用 `CodexChatAgentSession` app-server adapter,将不透明线程保存于
Expand Down
10 changes: 8 additions & 2 deletions loopx/control_plane/turn_driver/host_binding.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ def _with_operation_transport(
if observed["reason"]:
binding["available"] = False
binding["unavailable_reason"] = observed["reason"]
binding["unavailable_remediation"] = [REMEDY_CORRECT_EXECUTION_PROFILE]
binding["unavailable_remediation"] = observed["remediation"]
return binding


Expand Down Expand Up @@ -422,7 +422,13 @@ def managed_executor_unavailable_payload(
if str(code)
],
"remediation_host": INDIVIDUAL_TURN_HOST,
"remediation_env_vars": list(OPERATOR_CREDENTIAL_ENV_VARS),
# An operation transport refusal is not an instruction to configure
# model credentials. The existing typed transport owner supplies its
# remedies and supported hosts/sandboxes independently of launchability.
"remediation_env_vars": (
[] if "operation_transport" in binding
else list(OPERATOR_CREDENTIAL_ENV_VARS)
),
}


Expand Down
12 changes: 9 additions & 3 deletions loopx/control_plane/work_items/operation_agent_handoff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,20 @@ export function resolveOperationSourceRoute(input: JsonObject): JsonObject {
* Accept the CLI's provider-neutral effort vocabulary; actual model support
* remains a host qualification, not something this preflight can establish. */
export function projectManagedOperationTransport(input: JsonObject): JsonObject {
const reason = input.host !== "codex-cli" ? "operation_transport_host_unsupported"
: !["read-only", "workspace-write"].includes(String(input.sandbox)) ? "operation_transport_sandbox_unsupported"
const supportedHosts = ["codex-cli"];
const supportedSandboxes = ["read-only", "workspace-write"];
const reason = typeof input.host !== "string" || !supportedHosts.includes(input.host) ? "operation_transport_host_unsupported"
: typeof input.sandbox !== "string" || !supportedSandboxes.includes(input.sandbox) ? "operation_transport_sandbox_unsupported"
: typeof input.model !== "string" || !ID.test(input.model)
|| typeof input.reasoning_effort !== "string"
|| !["none", "minimal", "low", "medium", "high", "xhigh", "max", "ultra"].includes(input.reasoning_effort)
? "operation_transport_profile_required" : null;
return {reason, transport: {schema_version: "loopx_operation_transport_v0",
const remediation = reason === "operation_transport_host_unsupported" ? ["select_supported_operation_host"]
: reason === "operation_transport_sandbox_unsupported" ? ["select_supported_operation_sandbox"]
: reason === "operation_transport_profile_required" ? ["correct_execution_profile"] : [];
return {reason, remediation, transport: {schema_version: "loopx_operation_transport_v0",
kind: "owned_app_server", revision: "app-server-operation-tools-v0",
supported_hosts: supportedHosts, supported_sandboxes: supportedSandboxes,
configuration_valid: reason === null, runtime_qualified: false,
identity_source: "native_thread_turn_metadata", human_confirmation_required: true,
first_consumption_required: true, source_conversation_is_executor: false}};
Expand Down
100 changes: 100 additions & 0 deletions tests/control_plane/test_operation_transport_readback.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
"""The original delegation CLI distinguishes transport from model readiness."""

import json

import pytest

from test_delegation_cli import cli
from test_local_delegation import service as delegation_service

service = delegation_service


@pytest.mark.parametrize("host", [["codex-cli"], {"host": "codex-cli"}, None, True, 1])
def test_supported_host_readback_never_coerces_an_invalid_host(host):
from loopx.control_plane.effect_runtime import effect_runtime_result

result = effect_runtime_result("operation.managed_transport.project", {
"host": host, "sandbox": "read-only", "model": "test-model",
"reasoning_effort": "high",
})
assert result["reason"] == "operation_transport_host_unsupported"
assert result["remediation"] == ["select_supported_operation_host"]
assert result["transport"]["configuration_valid"] is False


@pytest.mark.parametrize("sandbox", [["read-only"], ["workspace-write"], {"sandbox": "read-only"}, None, True, 1])
def test_supported_sandbox_readback_never_coerces_an_invalid_sandbox(sandbox):
from loopx.control_plane.effect_runtime import effect_runtime_result

result = effect_runtime_result("operation.managed_transport.project", {
"host": "codex-cli", "sandbox": sandbox, "model": "test-model",
"reasoning_effort": "high",
})
assert result["reason"] == "operation_transport_sandbox_unsupported"
assert result["remediation"] == ["select_supported_operation_sandbox"]
assert result["transport"]["configuration_valid"] is False


@pytest.mark.parametrize(
("options", "reason", "remedy"),
[
(
["--host", "codex-cli", "--codex-model", "test-model",
"--codex-reasoning-effort", "high", "--codex-sandbox", "danger-full-access"],
"operation_transport_sandbox_unsupported", "select_supported_operation_sandbox",
),
(
["--host", "codex-cli"],
"operation_transport_profile_required", "correct_execution_profile",
),
],
)
def test_original_cli_inspection_returns_typed_transport_recovery_without_effects(
service, options, reason, remedy,
):
root, runner = service
config = json.loads(runner.config.read_text())
config["bindings"][0]["host_args"] = [*options, "--codex-operation-tools"]
runner.config.write_text(json.dumps(config))
before = runner.config.read_bytes(), runner.registry.read_bytes()

status, result = cli(runner, "inspect", "--binding-id", "analysis")

assert status == 0, result
assert result["executor"]["host"] == options[1]
assert result["executor"]["available"] is False
assert result["executor"]["reason"] == reason
assert result["executor"]["unavailable_remediation"] == [remedy]
transport = result["executor"]["operation_transport"]
assert transport["supported_hosts"] == ["codex-cli"]
assert transport["supported_sandboxes"] == ["read-only", "workspace-write"]
assert transport["configuration_valid"] is False
assert transport["runtime_qualified"] is False
assert transport["human_confirmation_required"] is True
assert transport["first_consumption_required"] is True
assert not any(result["effects"].values())
assert not (root / "host-started").exists()
assert before == (runner.config.read_bytes(), runner.registry.read_bytes())


def test_cli_does_not_repurpose_codex_operation_flag_for_a_dsh_executor(service):
root, runner = service
config = json.loads(runner.config.read_text())
config["bindings"][0]["host_args"] = [
"--host", "dsh", "--dsh-runner", "fixture-runner.py",
"--dsh-provider", "deepseek-official", "--dsh-model", "deepseek-flash",
"--dsh-reasoning-effort", "high", "--codex-operation-tools",
]
runner.config.write_text(json.dumps(config))
before = runner.config.read_bytes(), runner.registry.read_bytes()

status, result = cli(runner, "inspect", "--binding-id", "analysis")

# The original argv owner rejects this before executor projection. Keep
# that boundary; direct binding readback does not qualify a DSH CLI route.
assert status == 1
assert result["ok"] is False
assert "--codex-operation-tools requires the codex-cli host" in result["error"]
assert not (root / "host-started").exists()
assert before == (runner.config.read_bytes(), runner.registry.read_bytes())
42 changes: 42 additions & 0 deletions tests/test_turn_managed_executor_binding.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ def test_owned_operation_transport_is_opt_in_and_read_back_by_the_existing_host_
blocked = managed_executor_binding_from_host_args(options, environ={})
assert blocked["available"] is False
assert blocked["unavailable_reason"] == "operation_transport_profile_required"
assert blocked["unavailable_remediation"] == ["correct_execution_profile"]
pinned = managed_executor_binding_from_host_args(
[*options, "--codex-model", "test-model", "--codex-reasoning-effort", effort],
environ={},
Expand All @@ -136,10 +137,51 @@ def test_operation_transport_never_disappears_or_falls_back_on_another_host(host
)
assert observed["available"] is False
assert observed["unavailable_reason"] == "operation_transport_host_unsupported"
assert observed["executor"] == host
assert observed["unavailable_remediation"] == ["select_supported_operation_host"]
assert observed["operation_transport"]["supported_hosts"] == ["codex-cli"]
assert observed["operation_transport"]["supported_sandboxes"] == ["read-only", "workspace-write"]
assert observed["operation_transport"]["configuration_valid"] is False
assert observed["operation_transport"]["runtime_qualified"] is False


def test_operation_transport_sandbox_refusal_is_not_a_model_or_credential_remedy():
binding = managed_executor_binding(
"codex-cli", environ={}, codex_operation_tools=True,
codex_sandbox="danger-full-access", model="test-model", reasoning_effort="high",
)
assert binding["available"] is False
assert binding["unavailable_reason"] == "operation_transport_sandbox_unsupported"
assert binding["unavailable_remediation"] == ["select_supported_operation_sandbox"]
payload = managed_executor_unavailable_payload(
{"managed_executor": binding}, execute=True, host_projection={"kind": "codex-cli"},
)
assert payload["remediation"] == binding["unavailable_remediation"]
assert payload["remediation_env_vars"] == []


def test_configured_dsh_model_does_not_qualify_operation_transport_or_change_host():
kwargs = dict(
environ={"DEEPSEEK_API_KEY": "fixture-token"}, module_probe=_RUNTIME,
provider="deepseek-official", model="deepseek-flash", reasoning_effort="high",
)
ordinary = managed_executor_binding("dsh", **kwargs)
assert ordinary["available"] is True
assert "operation_transport" not in ordinary
blocked = managed_executor_binding("dsh", codex_operation_tools=True, **kwargs)
assert blocked["executor"] == ordinary["executor"] == "dsh"
assert blocked["execution_profile"] == ordinary["execution_profile"]
assert blocked["runtime_probe"] == ordinary["runtime_probe"]
assert blocked["unavailable_remediation"] == ["select_supported_operation_host"]
payload = managed_executor_unavailable_payload(
{"managed_executor": blocked}, execute=True, host_projection={"kind": "dsh"},
)
assert payload["status"] == "unavailable"
assert payload["host"] == {"kind": "dsh"}
assert payload["remediation_env_vars"] == []
assert "fixture-token" not in json.dumps([ordinary, blocked, payload])


def test_managed_executor_reports_the_operator_credential_and_endpoint():
binding = managed_executor_binding(
"dsh",
Expand Down
Loading