Files
.pouch/tests/test_ack_launch_worker.py
T
2026-08-03 17:07:21 +08:00

1462 lines
51 KiB
Python

from __future__ import annotations
import contextlib
import io
import json
import os
import shlex
import stat
import subprocess
import sys
import tempfile
import unittest
from pathlib import Path
from unittest import mock
REPO_ROOT = Path(__file__).resolve().parents[1]
ACK_SCRIPTS = REPO_ROOT / "skills" / "ack" / "scripts"
sys.path.insert(0, str(ACK_SCRIPTS))
import launch_worker # noqa: E402
import validate_worker_command # noqa: E402
import worker_profiles # noqa: E402
def orchestration() -> dict:
return {
"profileVersion": 1,
"mode": "orca",
"allowedWorktrees": ["/repo/worktree"],
"modelAllowlist": {
"codex": {
"developer": {
"standard": ["gpt-5.6-terra"],
},
"test": {
"standard": ["gpt-5.6-luna"],
},
}
},
"profiles": {
"codex-dev-standard": {
"role": "developer",
"cli": "codex",
"tier": "standard",
"model": "gpt-5.6-terra",
"reasoningEffort": "medium",
"permissionMode": "workspace-write",
},
"codex-test-standard": {
"role": "test",
"cli": "codex",
"tier": "standard",
"model": "gpt-5.6-luna",
"reasoningEffort": "low",
"permissionMode": "workspace-write",
},
},
"defaults": {
"developer": "codex-dev-standard",
"test": "codex-test-standard",
},
}
def board(project_root: Path) -> dict:
return {
"version": 1,
"project": {
"name": "test-project",
"repoPath": str(project_root),
"orchestration": orchestration(),
},
"workerReceipts": [],
"tasks": [
{
"id": "TASK-001",
"title": "test task",
"status": "open",
}
],
}
def worktree_identity(path: Path) -> dict:
metadata = path.stat()
git_path = path / ".git"
git_metadata = git_path.stat() if git_path.exists() else metadata
return {
"path": str(path),
"device": metadata.st_dev,
"inode": metadata.st_ino,
"gitCommonDir": str(git_path if git_path.exists() else path),
"gitCommonDevice": git_metadata.st_dev,
"gitCommonInode": git_metadata.st_ino,
}
def plan_for(path: Path, executable: Path) -> dict:
profile = orchestration()["profiles"]["codex-dev-standard"]
task_board = board(path)
board_hash = worker_profiles.canonical_sha256(task_board)
identity = worktree_identity(path)
executable_metadata = executable.stat()
argv = worker_profiles.render_worker_argv(
profile,
str(executable),
str(path),
)
requested = {
"cli": "codex",
"tier": "standard",
"model": "gpt-5.6-terra",
"reasoningEffort": "medium",
"permissionMode": "workspace-write",
"executable": str(executable),
"executableDevice": executable_metadata.st_dev,
"executableInode": executable_metadata.st_ino,
"cliVersion": "codex-cli 1.0",
"argv": argv,
"argvHash": worker_profiles.canonical_sha256(argv),
"environmentPolicy": "per-cli-allowlist-v1",
}
created_for = {
"taskId": "TASK-001",
"attemptId": "TASK-001-A1",
"role": "developer",
}
profile_digest = worker_profiles.profile_hash(profile)
fingerprint = worker_profiles.canonical_sha256(
{
"protocolVersion": 1,
"backend": "orca",
"projectRoot": str(path),
"boardHash": board_hash,
"profileId": "codex-dev-standard",
"profileHash": profile_digest,
"createdFor": created_for,
"worktree": identity,
"requested": requested,
"slot": 1,
}
)
digest_short = fingerprint.split(":", 1)[1][:10]
return {
"protocolVersion": 1,
"backend": "orca",
"projectRoot": str(path),
"boardHash": board_hash,
"taskId": "TASK-001",
"attemptId": "TASK-001-A1",
"role": "developer",
"profileId": "codex-dev-standard",
"profileHash": profile_digest,
"launchFingerprint": fingerprint,
"worktree": identity,
"requested": requested,
"slot": 1,
"title": f"ACK-DEV-CODEX-STANDARD-{digest_short}-1",
}
@contextlib.contextmanager
def post_handle_failure_context(
*,
update_side_effect: object,
close_side_effect: object,
):
with tempfile.TemporaryDirectory() as temporary:
executable = Path(temporary) / "codex"
executable.write_text("#!/bin/sh\n", encoding="utf-8")
executable.chmod(0o700)
plan = plan_for(REPO_ROOT, executable)
close = mock.Mock()
if isinstance(close_side_effect, BaseException):
close.side_effect = close_side_effect
else:
close.return_value = close_side_effect
with (
mock.patch.object(
launch_worker.secrets,
"token_hex",
side_effect=["a" * 64, "b" * 64],
),
mock.patch.object(
launch_worker,
"create_record",
return_value=Path("/tmp/ack-record.json"),
),
mock.patch.object(
launch_worker,
"resolve_executable",
return_value=Path("/trusted/orca"),
),
mock.patch.object(
launch_worker,
"run_json",
side_effect=[
{"ok": True, "_meta": {"runtimeId": "runtime-1"}},
launch_worker.LaunchError("show failed"),
],
),
mock.patch.object(
launch_worker,
"run_orca_create",
return_value=(
{
"ok": True,
"result": {"terminal": {"handle": "term-1"}},
"_meta": {"runtimeId": "runtime-1"},
},
"term-1",
),
),
mock.patch.object(launch_worker, "assert_identity_current"),
mock.patch.object(launch_worker, "run_orca_close", new=close),
mock.patch.object(
launch_worker,
"update_record",
side_effect=update_side_effect,
) as update,
):
yield plan, close, update
class ArgumentBoundaryTests(unittest.TestCase):
def test_rejects_duplicate_separator_and_free_command_arguments(self) -> None:
cases = [
[
"profile-hash",
"--project-root",
"/repo",
"--project-root",
"/other",
"--profile-id",
"codex-dev-standard",
],
[
"profile-hash",
"--project-root",
"/repo",
"--profile-id",
"codex-dev-standard",
"--",
"forged",
],
[
"profile-hash",
"--project-root",
"/repo",
"--profile-id",
"codex-dev-standard",
"--command",
"codex; touch forged",
],
]
for arguments in cases:
with self.subTest(arguments=arguments), contextlib.redirect_stderr(
io.StringIO()
):
self.assertEqual(launch_worker.main(arguments), 2)
def test_legacy_free_command_path_always_fails_closed(self) -> None:
with (
contextlib.redirect_stderr(io.StringIO()),
contextlib.redirect_stdout(io.StringIO()),
):
self.assertEqual(
validate_worker_command.main(
[
"--role",
"developer",
"--command",
"codex; touch /tmp/forged",
]
),
2,
)
self.assertEqual(validate_worker_command.main(["--self-test"]), 0)
def test_launch_requires_reviewed_fingerprint_and_refuses_drift(self) -> None:
fake_plan = {"launchFingerprint": "sha256:" + "a" * 64}
arguments = [
"launch",
"--project-root",
"/repo",
"--task-id",
"TASK-001",
"--attempt-id",
"TASK-001-A1",
"--role",
"developer",
"--profile-id",
"codex-dev-standard",
"--worktree",
"/repo/worktree",
"--expected-launch-fingerprint",
"sha256:" + "b" * 64,
]
with (
mock.patch.object(launch_worker, "build_plan", return_value=fake_plan),
mock.patch.object(launch_worker, "launch_with_orca") as launch,
contextlib.redirect_stderr(io.StringIO()),
):
self.assertEqual(launch_worker.main(arguments), 1)
launch.assert_not_called()
class EnvironmentAndExecutableTests(unittest.TestCase):
def test_environment_splits_control_and_per_cli_credentials(self) -> None:
with tempfile.TemporaryDirectory() as temporary:
hostile_path = str(Path(temporary))
with mock.patch.dict(
os.environ,
{
"PATH": hostile_path,
"LD_AUDIT": "/tmp/evil.so",
"LD_PRELOAD": "/tmp/evil.so",
"NODE_OPTIONS": "--require=/tmp/evil.js",
"PYTHONPATH": "/tmp/evil",
"CODEX_HOME": "/tmp/evil-codex",
"GIT_SSH_COMMAND": "touch /tmp/evil",
"OPENAI_API_KEY": "test-token",
"AZURE_OPENAI_API_KEY": "azure-token",
"CURSOR_API_KEY": "cursor-token",
"ANTHROPIC_API_KEY": "anthropic-token",
"DBUS_SESSION_BUS_ADDRESS": "unix:path=/tmp/dbus",
"DISPLAY": ":99",
"WAYLAND_DISPLAY": "wayland-99",
"XDG_RUNTIME_DIR": "/tmp/runtime",
"LANG": "C.UTF-8",
},
clear=True,
):
control = launch_worker.control_environment()
codex = launch_worker.worker_environment("codex")
cursor = launch_worker.worker_environment("cursor-agent")
for environment in (control, codex, cursor):
self.assertNotIn(hostile_path, environment["PATH"].split(os.pathsep))
self.assertEqual(environment["LANG"], "C.UTF-8")
self.assertNotIn("OPENAI_API_KEY", control)
self.assertNotIn("CURSOR_API_KEY", control)
self.assertEqual(codex["OPENAI_API_KEY"], "test-token")
self.assertEqual(codex["AZURE_OPENAI_API_KEY"], "azure-token")
self.assertNotIn("CURSOR_API_KEY", codex)
self.assertEqual(cursor["CURSOR_API_KEY"], "cursor-token")
self.assertNotIn("OPENAI_API_KEY", cursor)
for forbidden in (
"ANTHROPIC_API_KEY",
"DBUS_SESSION_BUS_ADDRESS",
"DISPLAY",
"LD_AUDIT",
"LD_PRELOAD",
"NODE_OPTIONS",
"PYTHONPATH",
"CODEX_HOME",
"GIT_SSH_COMMAND",
"WAYLAND_DISPLAY",
"XDG_RUNTIME_DIR",
):
for environment in (control, codex, cursor):
self.assertNotIn(forbidden, environment)
def test_executable_resolution_ignores_hostile_path(self) -> None:
with tempfile.TemporaryDirectory() as temporary:
fake = Path(temporary) / "git"
fake.write_text("#!/bin/sh\nexit 99\n", encoding="utf-8")
fake.chmod(0o755)
with mock.patch.dict(os.environ, {"PATH": temporary}):
resolved = launch_worker.resolve_executable("git")
self.assertEqual(resolved, Path("/usr/bin/git"))
class PlanTests(unittest.TestCase):
def test_authoritative_board_is_derived_from_project_root_without_repo_path(self) -> None:
with tempfile.TemporaryDirectory() as temporary:
project = Path(temporary).resolve()
ack_dir = project / "docs" / "ack"
ack_dir.mkdir(parents=True)
task_board = board(project)
del task_board["project"]["repoPath"]
(ack_dir / "tasks.yaml").write_text(
json.dumps(task_board),
encoding="utf-8",
)
loaded_root, loaded_board = launch_worker.load_authoritative_board(
str(project)
)
self.assertEqual(loaded_root, project)
self.assertEqual(loaded_board, task_board)
def test_authoritative_board_ignores_legacy_repo_path(self) -> None:
with tempfile.TemporaryDirectory() as temporary:
project = Path(temporary).resolve()
ack_dir = project / "docs" / "ack"
ack_dir.mkdir(parents=True)
task_board = board(project)
task_board["project"]["repoPath"] = "/legacy/other-worktree"
(ack_dir / "tasks.yaml").write_text(
json.dumps(task_board),
encoding="utf-8",
)
loaded_root, loaded_board = launch_worker.load_authoritative_board(
str(project)
)
self.assertEqual(loaded_root, project)
self.assertEqual(loaded_board, task_board)
def test_plan_uses_exact_renderer_and_binds_created_for(self) -> None:
with tempfile.TemporaryDirectory() as temporary:
project = Path(temporary).resolve()
executable = project / "codex"
executable.write_text("#!/bin/sh\n", encoding="utf-8")
executable.chmod(0o700)
identity = worktree_identity(project)
routing = orchestration()
routing["allowedWorktrees"] = [str(project)]
task_board = board(project)
task_board["project"]["orchestration"] = routing
with (
mock.patch.object(
launch_worker,
"load_authoritative_board",
return_value=(project, task_board),
),
mock.patch.object(
launch_worker,
"capture_worktree_identity",
return_value=identity,
),
mock.patch.object(
launch_worker,
"resolve_executable",
return_value=executable,
),
mock.patch.object(
launch_worker,
"run_text",
return_value="codex-cli 1.0",
),
):
plan = launch_worker.build_plan(
project_root_value=str(project),
task_id="TASK-001",
attempt_id="TASK-001-A1",
role="developer",
profile_id="codex-dev-standard",
worktree_value=str(project),
slot=1,
)
expected_fingerprint = worker_profiles.canonical_sha256(
{
"protocolVersion": 1,
"backend": "orca",
"projectRoot": str(project),
"boardHash": worker_profiles.canonical_sha256(task_board),
"profileId": plan["profileId"],
"profileHash": plan["profileHash"],
"createdFor": {
"taskId": "TASK-001",
"attemptId": "TASK-001-A1",
"role": "developer",
},
"worktree": plan["worktree"],
"requested": plan["requested"],
"slot": 1,
}
)
self.assertEqual(plan["launchFingerprint"], expected_fingerprint)
self.assertNotIn("--dangerously-bypass-approvals-and-sandbox", plan["requested"]["argv"])
self.assertNotIn("--yolo", plan["requested"]["argv"])
def test_plan_fingerprint_binds_slot(self) -> None:
with tempfile.TemporaryDirectory() as temporary:
project = Path(temporary).resolve()
executable = project / "codex"
executable.write_text("#!/bin/sh\n", encoding="utf-8")
executable.chmod(0o700)
identity = worktree_identity(project)
routing = orchestration()
routing["allowedWorktrees"] = [str(project)]
task_board = board(project)
task_board["project"]["orchestration"] = routing
with (
mock.patch.object(
launch_worker,
"load_authoritative_board",
return_value=(project, task_board),
),
mock.patch.object(
launch_worker,
"capture_worktree_identity",
return_value=identity,
),
mock.patch.object(
launch_worker,
"resolve_executable",
return_value=executable,
),
mock.patch.object(
launch_worker,
"run_text",
return_value="codex-cli 1.0",
),
):
first = launch_worker.build_plan(
project_root_value=str(project),
task_id="TASK-001",
attempt_id="TASK-001-A1",
role="developer",
profile_id="codex-dev-standard",
worktree_value=str(project),
slot=1,
)
second = launch_worker.build_plan(
project_root_value=str(project),
task_id="TASK-001",
attempt_id="TASK-001-A1",
role="developer",
profile_id="codex-dev-standard",
worktree_value=str(project),
slot=2,
)
self.assertNotEqual(first["launchFingerprint"], second["launchFingerprint"])
self.assertNotEqual(first["title"], second["title"])
class GitIdentityTests(unittest.TestCase):
def test_registered_worktree_passes_and_git_symlink_impostor_fails(self) -> None:
with tempfile.TemporaryDirectory() as temporary:
base = Path(temporary).resolve()
project = base / "project"
project.mkdir()
subprocess.run(
["/usr/bin/git", "init", "-q", str(project)],
check=True,
)
identity = launch_worker.capture_worktree_identity(
project,
str(project),
[str(project)],
)
self.assertEqual(identity["path"], str(project))
impostor = base / "impostor"
impostor.mkdir()
(impostor / ".git").symlink_to(project / ".git")
with self.assertRaisesRegex(launch_worker.LaunchError, "symlink"):
launch_worker.capture_worktree_identity(
project,
str(impostor),
[str(impostor)],
)
class BootstrapProtocolTests(unittest.TestCase):
def test_launcher_uses_shared_protocol_version(self) -> None:
self.assertEqual(
launch_worker.PROTOCOL_VERSION,
worker_profiles.LAUNCH_PROTOCOL_VERSION,
)
def test_orca_command_contains_only_fixed_bootstrap_and_opaque_id(self) -> None:
first_id = "a" * 64
second_id = "b" * 64
first = shlex.split(launch_worker.build_bootstrap_command(first_id))
second = shlex.split(launch_worker.build_bootstrap_command(second_id))
self.assertEqual(first[0], "exec")
self.assertEqual(first[2], "-I")
self.assertEqual(first[4:6], ["_bootstrap", "--launch-id"])
self.assertEqual(first[-1], first_id)
self.assertEqual(first[:-1], second[:-1])
self.assertEqual(second[-1], second_id)
def test_bootstrap_proof_is_nonce_and_plan_bound(self) -> None:
launch_id = "a" * 64
fingerprint = "sha256:" + "b" * 64
nonce = "c" * 64
proof = launch_worker.bootstrap_ready_proof(
launch_id,
fingerprint,
nonce,
)
self.assertRegex(proof, r"^sha256:[0-9a-f]{64}$")
self.assertNotEqual(
proof,
launch_worker.bootstrap_ready_proof(
launch_id,
fingerprint,
"d" * 64,
),
)
self.assertNotEqual(
proof,
launch_worker.bootstrap_ready_proof(
launch_id,
"sha256:" + "e" * 64,
nonce,
),
)
def test_spoofed_ready_state_without_proof_is_rejected(self) -> None:
with (
mock.patch.object(
launch_worker,
"read_record",
return_value={"state": "bootstrap-ready", "bootstrapProof": "forged"},
),
self.assertRaisesRegex(launch_worker.LaunchError, "proof"),
):
launch_worker.wait_for_bootstrap(
"a" * 64,
"sha256:" + "b" * 64,
)
def test_bootstrap_executes_exact_argv_without_shell_after_authorization(self) -> None:
launch_id = "a" * 64
nonce = "b" * 64
project = REPO_ROOT
temporary = tempfile.TemporaryDirectory()
self.addCleanup(temporary.cleanup)
executable = Path(temporary.name) / "codex"
executable.write_text("#!/bin/sh\n", encoding="utf-8")
executable.chmod(0o700)
plan = plan_for(project, executable)
record = {
"state": "prepared",
"expiresAt": launch_worker.format_timestamp(
launch_worker.utc_now()
+ launch_worker.timedelta(seconds=30)
),
"plan": plan,
"authorizationHash": launch_worker.bootstrap_authorization_hash(
launch_id,
plan["launchFingerprint"],
nonce,
),
}
@contextlib.contextmanager
def fake_locked_record(_launch_id: str):
yield record
process = mock.Mock(pid=1234)
process.wait.return_value = 0
fake_stdin = io.StringIO(nonce + "\n")
with (
mock.patch.object(launch_worker, "locked_record", fake_locked_record),
mock.patch.object(launch_worker, "build_plan", return_value=plan),
mock.patch.object(launch_worker, "assert_identity_current"),
mock.patch.object(
launch_worker.select,
"select",
return_value=([fake_stdin], [], []),
),
mock.patch.object(launch_worker.sys, "stdin", fake_stdin),
mock.patch.object(launch_worker.subprocess, "Popen", return_value=process) as popen,
):
self.assertEqual(launch_worker.bootstrap_worker(launch_id), 0)
popen.assert_called_once_with(
plan["requested"]["argv"],
shell=False,
cwd=plan["worktree"]["path"],
env=mock.ANY,
)
self.assertEqual(
record["bootstrapProof"],
launch_worker.bootstrap_ready_proof(
launch_id,
plan["launchFingerprint"],
nonce,
),
)
self.assertEqual(record["state"], "closed")
def test_bootstrap_cleanup_wins_before_agent_spawn(self) -> None:
launch_id = "a" * 64
nonce = "b" * 64
temporary = tempfile.TemporaryDirectory()
self.addCleanup(temporary.cleanup)
executable = Path(temporary.name) / "codex"
executable.write_text("#!/bin/sh\n", encoding="utf-8")
executable.chmod(0o700)
plan = plan_for(REPO_ROOT, executable)
record = {
"state": "prepared",
"expiresAt": launch_worker.format_timestamp(
launch_worker.utc_now()
+ launch_worker.timedelta(seconds=30)
),
"plan": plan,
"authorizationHash": launch_worker.bootstrap_authorization_hash(
launch_id,
plan["launchFingerprint"],
nonce,
),
}
@contextlib.contextmanager
def fake_locked_record(_launch_id: str):
yield record
fake_stdin = io.StringIO(nonce + "\n")
def parent_marks_cleanup(*_args, **_kwargs):
record.update(
state="indeterminate",
error="parent requested cleanup",
cleanup={
"confirmed": False,
"reconcileRequired": True,
},
)
return ([fake_stdin], [], [])
with (
mock.patch.object(launch_worker, "locked_record", fake_locked_record),
mock.patch.object(launch_worker, "build_plan", return_value=plan),
mock.patch.object(launch_worker, "assert_identity_current"),
mock.patch.object(
launch_worker.select,
"select",
side_effect=parent_marks_cleanup,
),
mock.patch.object(launch_worker.sys, "stdin", fake_stdin),
mock.patch.object(launch_worker.subprocess, "Popen") as popen,
contextlib.redirect_stderr(io.StringIO()),
):
self.assertEqual(launch_worker.bootstrap_worker(launch_id), 1)
popen.assert_not_called()
self.assertEqual(record["state"], "indeterminate")
self.assertTrue(record["cleanup"]["reconcileRequired"])
class OrcaCreateTests(unittest.TestCase):
def test_orca_control_json_requires_explicit_ok_true(self) -> None:
valid = json.dumps({"ok": True, "result": {}})
with mock.patch.object(launch_worker, "run_text", return_value=valid):
self.assertTrue(
launch_worker.run_json(["orca", "status", "--json"], "orca status")[
"ok"
]
)
unsafe = [
json.dumps({"result": {}}),
json.dumps({"ok": None, "result": {}}),
json.dumps({"ok": 1, "result": {}}),
]
for output in unsafe:
with (
self.subTest(output=output),
mock.patch.object(launch_worker, "run_text", return_value=output),
self.assertRaisesRegex(launch_worker.LaunchError, "ok=true"),
):
launch_worker.run_json(
["orca", "status", "--json"],
"orca status",
)
def test_create_response_must_have_certain_handle(self) -> None:
valid = subprocess.CompletedProcess(
["orca"],
0,
stdout=json.dumps(
{
"ok": True,
"result": {"terminal": {"handle": "term-1"}},
"_meta": {"runtimeId": "runtime-1"},
}
),
stderr="",
)
with mock.patch.object(launch_worker, "run_process", return_value=valid):
response, handle = launch_worker.run_orca_create(["orca"])
self.assertEqual(handle, "term-1")
self.assertTrue(response["ok"])
unsafe_results = [
subprocess.CompletedProcess(["orca"], 1, stdout="", stderr="failed"),
subprocess.CompletedProcess(["orca"], 0, stdout="{", stderr=""),
subprocess.CompletedProcess(
["orca"],
0,
stdout=json.dumps({"ok": True, "result": {}}),
stderr="",
),
subprocess.CompletedProcess(
["orca"],
0,
stdout=json.dumps(
{"result": {"terminal": {"handle": "term-1"}}}
),
stderr="",
),
]
for completed in unsafe_results:
with (
self.subTest(completed=completed),
mock.patch.object(
launch_worker,
"run_process",
return_value=completed,
),
self.assertRaises(launch_worker.IndeterminateLaunch),
):
launch_worker.run_orca_create(["orca"])
def test_create_transport_and_decode_failures_are_indeterminate(self) -> None:
failures = (
UnicodeDecodeError("utf-8", b"\xff", 0, 1, "invalid start byte"),
subprocess.SubprocessError("transport failed"),
KeyboardInterrupt(),
RecursionError("response nesting too deep"),
)
for failure in failures:
with (
self.subTest(failure=type(failure).__name__),
mock.patch.object(
launch_worker,
"run_process",
side_effect=failure,
),
self.assertRaisesRegex(
launch_worker.IndeterminateLaunch,
"可能已创建终端",
),
):
launch_worker.run_orca_create(["orca"])
def test_indeterminate_create_records_identity_and_does_not_retry(self) -> None:
temporary = tempfile.TemporaryDirectory()
self.addCleanup(temporary.cleanup)
executable = Path(temporary.name) / "codex"
executable.write_text("#!/bin/sh\n", encoding="utf-8")
executable.chmod(0o700)
plan = plan_for(REPO_ROOT, executable)
updates: list[tuple[str, dict]] = []
def capture_update(launch_id: str, **changes):
updates.append((launch_id, changes))
return changes
with (
mock.patch.object(
launch_worker.secrets,
"token_hex",
side_effect=["a" * 64, "b" * 64],
),
mock.patch.object(
launch_worker,
"create_record",
return_value=Path("/tmp/ack-record.json"),
),
mock.patch.object(
launch_worker,
"resolve_executable",
return_value=Path("/trusted/orca"),
),
mock.patch.object(
launch_worker,
"run_json",
return_value={"ok": True, "_meta": {"runtimeId": "runtime-1"}},
),
mock.patch.object(
launch_worker,
"run_orca_create",
side_effect=launch_worker.IndeterminateLaunch("lost response"),
) as create,
mock.patch.object(launch_worker, "assert_identity_current"),
mock.patch.object(launch_worker, "update_record", side_effect=capture_update),
):
with self.assertRaisesRegex(
launch_worker.IndeterminateLaunch,
"launchId=" + "a" * 64,
):
launch_worker.launch_with_orca(plan)
self.assertEqual(create.call_count, 1)
self.assertTrue(
any(change.get("state") == "indeterminate" for _, change in updates)
)
def test_indeterminate_create_record_failure_does_not_mask_reconcile(self) -> None:
temporary = tempfile.TemporaryDirectory()
self.addCleanup(temporary.cleanup)
executable = Path(temporary.name) / "codex"
executable.write_text("#!/bin/sh\n", encoding="utf-8")
executable.chmod(0o700)
plan = plan_for(REPO_ROOT, executable)
with (
mock.patch.object(
launch_worker.secrets,
"token_hex",
side_effect=["a" * 64, "b" * 64],
),
mock.patch.object(
launch_worker,
"create_record",
return_value=Path("/tmp/ack-record.json"),
),
mock.patch.object(
launch_worker,
"resolve_executable",
return_value=Path("/trusted/orca"),
),
mock.patch.object(
launch_worker,
"run_json",
return_value={"ok": True, "_meta": {"runtimeId": "runtime-1"}},
),
mock.patch.object(
launch_worker,
"run_orca_create",
side_effect=launch_worker.IndeterminateLaunch("lost response"),
),
mock.patch.object(launch_worker, "assert_identity_current"),
mock.patch.object(
launch_worker,
"update_record",
side_effect=PermissionError("record denied"),
),
self.assertRaisesRegex(
launch_worker.IndeterminateLaunch,
"reconcile required",
) as raised,
):
launch_worker.launch_with_orca(plan)
detail = str(raised.exception)
self.assertIn("launchId=" + "a" * 64, detail)
self.assertIn("record=/tmp/ack-record.json", detail)
self.assertIn("record denied", detail)
def test_close_requires_durable_structured_confirmation(self) -> None:
valid = subprocess.CompletedProcess(
["orca"],
0,
stdout=json.dumps(
{
"ok": True,
"result": {
"close": {
"handle": "term-1",
"tabId": "tab-1",
"closeMode": "tab",
}
},
"_meta": {"runtimeId": "runtime-1"},
}
),
stderr="",
)
with mock.patch.object(
launch_worker,
"run_process",
return_value=valid,
) as run_process:
confirmation = launch_worker.run_orca_close(
Path("/trusted/orca"),
"term-1",
"runtime-1",
)
self.assertEqual(
confirmation,
{
"runtimeId": "runtime-1",
"handle": "term-1",
"tabId": "tab-1",
"closeMode": "tab",
},
)
close_argv = run_process.call_args.args[0]
self.assertEqual(
close_argv,
[
"/trusted/orca",
"terminal",
"close",
"--terminal",
"term-1",
"--tab",
"--json",
],
)
unsafe_results = [
subprocess.CompletedProcess(
["orca"],
1,
stdout="",
stderr="close rejected",
),
subprocess.CompletedProcess(
["orca"],
0,
stdout="{",
stderr="",
),
subprocess.CompletedProcess(
["orca"],
0,
stdout=json.dumps(
{
"ok": True,
"result": {"close": {"handle": "term-1"}},
"_meta": {"runtimeId": "runtime-1"},
}
),
stderr="",
),
subprocess.CompletedProcess(
["orca"],
0,
stdout=json.dumps(
{
"ok": True,
"result": {
"close": {
"handle": "term-other",
"tabId": "tab-1",
"closeMode": "tab",
}
},
"_meta": {"runtimeId": "runtime-1"},
}
),
stderr="",
),
subprocess.CompletedProcess(
["orca"],
0,
stdout=json.dumps(
{
"ok": True,
"result": {
"close": {
"handle": "term-1",
"tabId": "tab-1",
"closeMode": "tab",
}
},
"_meta": {"runtimeId": "runtime-other"},
}
),
stderr="",
),
]
for completed in unsafe_results:
with (
self.subTest(completed=completed),
mock.patch.object(
launch_worker,
"run_process",
return_value=completed,
),
self.assertRaises(launch_worker.IndeterminateLaunch),
):
launch_worker.run_orca_close(
Path("/trusted/orca"),
"term-1",
"runtime-1",
)
def test_post_handle_failure_keeps_original_error_when_close_is_confirmed(
self,
) -> None:
temporary = tempfile.TemporaryDirectory()
self.addCleanup(temporary.cleanup)
executable = Path(temporary.name) / "codex"
executable.write_text("#!/bin/sh\n", encoding="utf-8")
executable.chmod(0o700)
plan = plan_for(REPO_ROOT, executable)
updates: list[tuple[str, dict]] = []
def capture_update(launch_id: str, **changes):
updates.append((launch_id, changes))
return changes
with (
mock.patch.object(
launch_worker.secrets,
"token_hex",
side_effect=["a" * 64, "b" * 64],
),
mock.patch.object(
launch_worker,
"create_record",
return_value=Path("/tmp/ack-record.json"),
),
mock.patch.object(
launch_worker,
"resolve_executable",
return_value=Path("/trusted/orca"),
),
mock.patch.object(
launch_worker,
"run_json",
side_effect=[
{"ok": True, "_meta": {"runtimeId": "runtime-1"}},
launch_worker.LaunchError("show failed"),
],
),
mock.patch.object(
launch_worker,
"run_orca_create",
return_value=(
{
"ok": True,
"result": {"terminal": {"handle": "term-1"}},
"_meta": {"runtimeId": "runtime-1"},
},
"term-1",
),
),
mock.patch.object(launch_worker, "assert_identity_current"),
mock.patch.object(
launch_worker,
"run_orca_close",
return_value={
"runtimeId": "runtime-1",
"handle": "term-1",
"tabId": "tab-1",
"closeMode": "tab",
},
) as close,
mock.patch.object(
launch_worker,
"update_record",
side_effect=capture_update,
),
self.assertRaisesRegex(launch_worker.LaunchError, "show failed"),
):
launch_worker.launch_with_orca(plan)
close.assert_called_once_with(
Path("/trusted/orca"),
"term-1",
"runtime-1",
)
self.assertEqual(updates[-1][1]["state"], "failed")
self.assertEqual(updates[-1][1]["error"], "show failed")
self.assertTrue(updates[-1][1]["cleanup"]["confirmed"])
def test_post_handle_close_failure_is_indeterminate_and_requires_reconcile(
self,
) -> None:
temporary = tempfile.TemporaryDirectory()
self.addCleanup(temporary.cleanup)
executable = Path(temporary.name) / "codex"
executable.write_text("#!/bin/sh\n", encoding="utf-8")
executable.chmod(0o700)
plan = plan_for(REPO_ROOT, executable)
updates: list[tuple[str, dict]] = []
def capture_update(launch_id: str, **changes):
updates.append((launch_id, changes))
return changes
with (
mock.patch.object(
launch_worker.secrets,
"token_hex",
side_effect=["a" * 64, "b" * 64],
),
mock.patch.object(
launch_worker,
"create_record",
return_value=Path("/tmp/ack-record.json"),
),
mock.patch.object(
launch_worker,
"resolve_executable",
return_value=Path("/trusted/orca"),
),
mock.patch.object(
launch_worker,
"run_json",
side_effect=[
{"ok": True, "_meta": {"runtimeId": "runtime-1"}},
launch_worker.LaunchError("show failed"),
],
),
mock.patch.object(
launch_worker,
"run_orca_create",
return_value=(
{
"ok": True,
"result": {"terminal": {"handle": "term-1"}},
"_meta": {"runtimeId": "runtime-1"},
},
"term-1",
),
),
mock.patch.object(launch_worker, "assert_identity_current"),
mock.patch.object(
launch_worker,
"run_orca_close",
side_effect=launch_worker.IndeterminateLaunch("close timeout"),
),
mock.patch.object(
launch_worker,
"update_record",
side_effect=capture_update,
),
self.assertRaisesRegex(
launch_worker.IndeterminateLaunch,
"reconcile required",
),
):
launch_worker.launch_with_orca(plan)
self.assertEqual(updates[-1][1]["state"], "indeterminate")
self.assertTrue(updates[-1][1]["cleanup"]["reconcileRequired"])
self.assertIn("show failed", updates[-1][1]["error"])
self.assertIn("close timeout", updates[-1][1]["error"])
def test_pending_record_failure_does_not_skip_post_handle_close(self) -> None:
updates: list[dict] = []
def fail_pending(_launch_id: str, **changes):
updates.append(changes)
if len(updates) == 1:
raise PermissionError("pending denied")
return changes
close_confirmation = {
"runtimeId": "runtime-1",
"handle": "term-1",
"tabId": "tab-1",
"closeMode": "tab",
}
with post_handle_failure_context(
update_side_effect=fail_pending,
close_side_effect=close_confirmation,
) as (plan, close, _update):
with self.assertRaisesRegex(launch_worker.LaunchError, "show failed"):
launch_worker.launch_with_orca(plan)
close.assert_called_once_with(
Path("/trusted/orca"),
"term-1",
"runtime-1",
)
self.assertEqual(len(updates), 2)
self.assertEqual(updates[-1]["state"], "failed")
def test_close_and_reconcile_record_failures_stay_indeterminate(self) -> None:
updates: list[dict] = []
def fail_reconcile(_launch_id: str, **changes):
updates.append(changes)
if len(updates) == 2:
raise OSError("reconcile write failed")
return changes
with post_handle_failure_context(
update_side_effect=fail_reconcile,
close_side_effect=launch_worker.IndeterminateLaunch("close timeout"),
) as (plan, close, _update):
with self.assertRaisesRegex(
launch_worker.IndeterminateLaunch,
"reconcile required",
) as raised:
launch_worker.launch_with_orca(plan)
close.assert_called_once()
detail = str(raised.exception)
self.assertIn("close timeout", detail)
self.assertIn("reconcile write failed", detail)
self.assertIn("launchId=" + "a" * 64, detail)
self.assertIn("record=/tmp/ack-record.json", detail)
def test_confirmed_close_with_failed_state_write_is_indeterminate(self) -> None:
updates: list[dict] = []
def fail_final(_launch_id: str, **changes):
updates.append(changes)
if len(updates) == 2:
raise PermissionError("final write denied")
return changes
close_confirmation = {
"runtimeId": "runtime-1",
"handle": "term-1",
"tabId": "tab-1",
"closeMode": "tab",
}
with post_handle_failure_context(
update_side_effect=fail_final,
close_side_effect=close_confirmation,
) as (plan, close, _update):
with self.assertRaisesRegex(
launch_worker.IndeterminateLaunch,
"reconcile required",
) as raised:
launch_worker.launch_with_orca(plan)
close.assert_called_once()
detail = str(raised.exception)
self.assertIn("close confirmed", detail)
self.assertIn("final write denied", detail)
self.assertIn("launchId=" + "a" * 64, detail)
self.assertIn("record=/tmp/ack-record.json", detail)
def test_successful_launch_binds_terminal_before_nonce_and_receipt(self) -> None:
temporary = tempfile.TemporaryDirectory()
self.addCleanup(temporary.cleanup)
executable = Path(temporary.name) / "codex"
executable.write_text("#!/bin/sh\n", encoding="utf-8")
executable.chmod(0o700)
plan = plan_for(REPO_ROOT, executable)
launch_id = "a" * 64
nonce = "b" * 64
metadata = {
"handle": "term-1",
"incarnationId": "incarnation-1",
"worktreePath": str(REPO_ROOT),
"connected": True,
"writable": True,
}
def fake_run_json(argv: list[str], _label: str) -> dict:
if argv[1] == "status":
return {"ok": True, "_meta": {"runtimeId": "runtime-1"}}
if argv[1:3] == ["terminal", "show"]:
return {
"ok": True,
"result": {"terminal": metadata},
"_meta": {"runtimeId": "runtime-1"},
}
if argv[1:3] == ["terminal", "send"]:
self.assertEqual(argv[argv.index("--text") + 1], nonce)
return {"ok": True, "_meta": {"runtimeId": "runtime-1"}}
self.fail(f"unexpected Orca call: {argv}")
with (
mock.patch.object(
launch_worker.secrets,
"token_hex",
side_effect=[launch_id, nonce],
),
mock.patch.object(
launch_worker,
"create_record",
return_value=Path("/tmp/ack-record.json"),
),
mock.patch.object(
launch_worker,
"resolve_executable",
return_value=Path("/trusted/orca"),
),
mock.patch.object(launch_worker, "run_json", side_effect=fake_run_json),
mock.patch.object(
launch_worker,
"run_orca_create",
return_value=(
{
"ok": True,
"result": {"terminal": {"handle": "term-1"}},
"_meta": {"runtimeId": "runtime-1"},
},
"term-1",
),
) as create,
mock.patch.object(launch_worker, "assert_identity_current"),
mock.patch.object(launch_worker, "update_record"),
mock.patch.object(launch_worker, "wait_for_bootstrap") as wait,
):
receipt = launch_worker.launch_with_orca(plan)
expected_proof = launch_worker.bootstrap_ready_proof(
launch_id,
plan["launchFingerprint"],
nonce,
)
wait.assert_called_once_with(launch_id, expected_proof)
create_argv = create.call_args.args[0]
command = create_argv[create_argv.index("--command") + 1]
command_tokens = shlex.split(command)
self.assertEqual(command_tokens[-1], launch_id)
self.assertNotIn(plan["requested"]["model"], command_tokens)
self.assertNotIn(plan["taskId"], command_tokens)
self.assertEqual(receipt["binding"]["handle"], "term-1")
self.assertEqual(
receipt["receiptHash"],
worker_profiles.receipt_hash(receipt),
)
class RecordSecurityTests(unittest.TestCase):
def test_bootstrap_update_cannot_overwrite_cleanup_reconciliation(self) -> None:
record = {
"state": "indeterminate",
"error": "reconcile required",
"cleanup": {
"confirmed": False,
"reconcileRequired": True,
},
}
@contextlib.contextmanager
def fake_locked_record(_launch_id: str):
yield record
with mock.patch.object(
launch_worker,
"locked_record",
fake_locked_record,
):
result = launch_worker.update_record(
"a" * 64,
preserve_cleanup_state=True,
state="closed",
error=None,
)
self.assertEqual(result["state"], "indeterminate")
self.assertEqual(result["error"], "reconcile required")
self.assertTrue(result["cleanup"]["reconcileRequired"])
def test_record_requires_exact_private_mode_and_single_link(self) -> None:
with tempfile.TemporaryDirectory() as temporary:
root = Path(temporary)
launch_id = "a" * 64
record = root / f"{launch_id}.json"
record.write_text(
json.dumps({"launchId": launch_id}),
encoding="utf-8",
)
record.chmod(0o644)
with self.assertRaisesRegex(launch_worker.LaunchError, "0600"):
launch_worker._read_record_file(record)
record.chmod(0o600)
hardlink = root / "hardlink.json"
os.link(record, hardlink)
with self.assertRaisesRegex(launch_worker.LaunchError, "hard link"):
launch_worker._read_record_file(record)
if __name__ == "__main__":
unittest.main()