feat(orc): centralize host-aware routing

This commit is contained in:
2026-08-01 20:04:55 +08:00
parent 34bbb97406
commit f5bf35c722
9 changed files with 499 additions and 275 deletions
+166 -42
View File
@@ -18,7 +18,7 @@ from unittest import mock
REPO_ROOT = Path(__file__).resolve().parents[1]
ORC_DIR = REPO_ROOT / "skills" / "orc"
SCRIPT = ORC_DIR / "scripts" / "resolve_profile.py"
CONFIG = ORC_DIR / "templates" / "config.template.yaml"
CONFIG = ORC_DIR / "config.yaml"
spec = importlib.util.spec_from_file_location("orc_resolve_profile", SCRIPT)
assert spec is not None and spec.loader is not None
@@ -36,7 +36,13 @@ class OrcSkillTests(unittest.TestCase):
self.assertIn("low", skill)
self.assertIn("mid", skill)
self.assertIn("high", skill)
self.assertIn("只支持 `cli: codex`", skill)
self.assertIn("`codex` 和 `cursor-agent`", skill)
self.assertIn("<orc-skill-dir>/config.yaml", skill)
self.assertIn("不得在项目中创建 `docs/orc/config.yaml`", skill)
self.assertIn("薄路由器", skill)
self.assertIn("不做领域判断", skill)
self.assertNotIn("用户未指定档位时采用以下判断", skill)
self.assertNotIn("若该档位不足以安全完成", skill)
for child in ("$ack", "$manage-release", "$deb-publisher", "$publish-docker-image"):
self.assertIn(child, routing)
@@ -64,12 +70,20 @@ class OrcSkillTests(unittest.TestCase):
self.assertIn("最多到", routing)
self.assertIn("review_ready", routing)
self.assertIn("当前 task 粒度无法安全表达", routing)
self.assertRegex(
routing,
r"不判断版本号、\s*实现方案、发布风险或产物策略",
)
def test_template_and_cli_validate(self) -> None:
def test_shared_config_and_cli_validate(self) -> None:
config = orc_profiles.load_config(CONFIG)
self.assertEqual(set(config["profiles"]), {"low", "mid", "high"})
self.assertEqual(config["version"], 2)
self.assertEqual(config["cliPolicy"], "current-host")
self.assertEqual(set(config["profiles"]), {"codex", "cursor-agent"})
for cli in ("codex", "cursor-agent"):
self.assertEqual(set(config["profiles"][cli]), {"low", "mid", "high"})
completed = subprocess.run(
[sys.executable, str(SCRIPT), "validate", str(CONFIG)],
[sys.executable, str(SCRIPT), "validate"],
text=True,
capture_output=True,
check=False,
@@ -77,8 +91,16 @@ class OrcSkillTests(unittest.TestCase):
self.assertEqual(completed.returncode, 0, completed.stderr)
self.assertIn('"ok": true', completed.stdout)
project_config_argument = subprocess.run(
[sys.executable, str(SCRIPT), "validate", str(CONFIG)],
text=True,
capture_output=True,
check=False,
)
self.assertEqual(project_config_argument.returncode, 2)
clean_python = subprocess.run(
[sys.executable, "-I", "-S", str(SCRIPT), "validate", str(CONFIG)],
[sys.executable, "-I", "-S", str(SCRIPT), "validate"],
text=True,
capture_output=True,
check=False,
@@ -88,24 +110,39 @@ class OrcSkillTests(unittest.TestCase):
def test_level_precedence_is_stage_then_global_then_config(self) -> None:
config = orc_profiles.load_config(CONFIG)
stage = orc_profiles.resolve_profile(
config, stage="docker", global_level="mid", stage_level="high"
config,
stage="docker",
host_cli="codex",
global_level="mid",
stage_level="high",
)
global_choice = orc_profiles.resolve_profile(
config, stage="docker", global_level="mid"
config, stage="docker", host_cli="codex", global_level="mid"
)
configured = orc_profiles.resolve_profile(
config, stage="docker", host_cli="codex"
)
configured = orc_profiles.resolve_profile(config, stage="docker")
fallback_config = copy.deepcopy(config)
del fallback_config["stageDefaults"]["docker"]
fallback = orc_profiles.resolve_profile(fallback_config, stage="docker")
fallback = orc_profiles.resolve_profile(
fallback_config, stage="docker", host_cli="codex"
)
self.assertEqual((stage["level"], stage["selectionSource"]), ("high", "request.stage"))
self.assertEqual((global_choice["level"], global_choice["selectionSource"]), ("mid", "request.global"))
self.assertEqual((configured["level"], configured["selectionSource"]), ("low", "config.stageDefaults.docker"))
self.assertEqual((fallback["level"], fallback["selectionSource"]), ("mid", "config.defaultLevel"))
self.assertEqual(configured["cli"], "codex")
self.assertEqual(configured["cliSelectionSource"], "runtime.host")
with self.assertRaisesRegex(orc_profiles.ConfigError, "host CLI is required"):
orc_profiles.resolve_profile(config, stage="docker")
def test_resolver_builds_fixed_worker_args_without_free_command_fields(self) -> None:
config = orc_profiles.load_config(CONFIG)
plan = orc_profiles.resolve_profile(config, stage="release")
plan = orc_profiles.resolve_profile(
config, stage="release", host_cli="codex"
)
self.assertEqual(plan["workerArgs"][:2], ["--model", "gpt-5.6-terra"])
self.assertIn("--strict-config", plan["workerArgs"])
@@ -113,6 +150,40 @@ class OrcSkillTests(unittest.TestCase):
self.assertNotIn("env", plan["profile"])
self.assertNotIn("command", plan["profile"])
cursor = orc_profiles.resolve_profile(
config,
stage="release",
host_cli="cursor-agent",
stage_level="low",
)
self.assertEqual(cursor["cli"], "cursor-agent")
self.assertEqual(cursor["cliSelectionSource"], "runtime.host")
self.assertEqual(cursor["modelAuth"], "cursor-login")
self.assertEqual(
cursor["workerArgs"],
[
"--model",
"auto",
"--auto-review",
"--sandbox",
"enabled",
],
)
with self.assertRaisesRegex(orc_profiles.ConfigError, "not valid for cursor-agent"):
orc_profiles.resolve_profile(
config,
stage="release",
host_cli="cursor-agent",
model_auth="openai",
)
with self.assertRaisesRegex(orc_profiles.ConfigError, "not valid for codex"):
orc_profiles.resolve_profile(
config,
stage="release",
host_cli="codex",
model_auth="cursor-api-key",
)
def test_worker_environment_selects_one_model_and_remote_auth(self) -> None:
ambient = {
"OPENAI_API_KEY": "openai-secret",
@@ -145,6 +216,19 @@ class OrcSkillTests(unittest.TestCase):
):
self.assertNotIn(rejected, environment)
cursor_ambient = {
"CURSOR_API_KEY": "cursor-secret",
"OPENAI_API_KEY": "openai-secret",
}
with mock.patch.dict(os.environ, cursor_ambient, clear=True):
cursor_environment = orc_profiles.worker_environment(
"release",
model_auth="cursor-api-key",
remote_auth="none",
)
self.assertEqual(cursor_environment["CURSOR_API_KEY"], "cursor-secret")
self.assertNotIn("OPENAI_API_KEY", cursor_environment)
with self.assertRaisesRegex(orc_profiles.ConfigError, "deb remote auth"):
orc_profiles.worker_environment(
"deb",
@@ -240,35 +324,60 @@ class OrcSkillTests(unittest.TestCase):
base = orc_profiles.load_config(CONFIG)
free_command = copy.deepcopy(base)
free_command["profiles"]["low"]["command"] = "codex --dangerously-bypass"
free_command["profiles"]["codex"]["low"]["command"] = "codex --dangerously-bypass"
with self.assertRaisesRegex(orc_profiles.ConfigError, "unknown fields"):
orc_profiles.validate_config(free_command)
full_access = copy.deepcopy(base)
full_access["profiles"]["high"]["permissionMode"] = "danger-full-access"
with self.assertRaisesRegex(orc_profiles.ConfigError, "workspace-write in ORC v1"):
full_access["profiles"]["codex"]["high"]["permissionMode"] = "danger-full-access"
with self.assertRaisesRegex(orc_profiles.ConfigError, "workspace-write in ORC v2"):
orc_profiles.validate_config(full_access)
read_only = copy.deepcopy(base)
read_only["profiles"]["low"]["permissionMode"] = "read-only"
with self.assertRaisesRegex(orc_profiles.ConfigError, "workspace-write in ORC v1"):
read_only["profiles"]["codex"]["low"]["permissionMode"] = "read-only"
with self.assertRaisesRegex(orc_profiles.ConfigError, "workspace-write in ORC v2"):
orc_profiles.validate_config(read_only)
missing_level = copy.deepcopy(base)
del missing_level["profiles"]["mid"]
del missing_level["profiles"]["cursor-agent"]["mid"]
with self.assertRaisesRegex(orc_profiles.ConfigError, "missing fields: mid"):
orc_profiles.validate_config(missing_level)
option_model = copy.deepcopy(base)
option_model["profiles"]["low"]["model"] = "--model"
option_model["profiles"]["codex"]["low"]["model"] = "--model"
with self.assertRaisesRegex(orc_profiles.ConfigError, "safe exact model ID"):
orc_profiles.validate_config(option_model)
list_policy = copy.deepcopy(base)
list_policy["profiles"]["low"]["approvalPolicy"] = ["never"]
list_policy["profiles"]["codex"]["low"]["approvalPolicy"] = ["never"]
with self.assertRaisesRegex(orc_profiles.ConfigError, "approvalPolicy"):
orc_profiles.validate_config(list_policy)
cursor_effort = copy.deepcopy(base)
cursor_effort["profiles"]["cursor-agent"]["low"]["reasoningEffort"] = "low"
with self.assertRaisesRegex(orc_profiles.ConfigError, "Cursor requires null"):
orc_profiles.validate_config(cursor_effort)
mislabeled_cursor = copy.deepcopy(base)
mislabeled_cursor["profiles"]["cursor-agent"]["low"]["model"] = (
"gpt-5.6-sol-high"
)
with self.assertRaisesRegex(orc_profiles.ConfigError, "encode the low"):
orc_profiles.validate_config(mislabeled_cursor)
project_specific = copy.deepcopy(base)
project_specific["worktreePolicy"] = ["."]
with self.assertRaisesRegex(
orc_profiles.ConfigError,
"registered-same-repository",
):
orc_profiles.validate_config(project_specific)
default_cli = copy.deepcopy(base)
default_cli["cliPolicy"] = "default-codex"
with self.assertRaisesRegex(orc_profiles.ConfigError, "current-host"):
orc_profiles.validate_config(default_cli)
def test_config_reader_rejects_symlinks_and_redacts_parser_input(self) -> None:
with tempfile.TemporaryDirectory() as temporary:
root = Path(temporary)
@@ -282,16 +391,11 @@ class OrcSkillTests(unittest.TestCase):
malformed = root / "malformed.yaml"
secret_marker = "PRIVATE_MATERIAL_MUST_NOT_APPEAR"
malformed.write_text(f"{secret_marker}: [unterminated\n", encoding="utf-8")
completed = subprocess.run(
[sys.executable, str(SCRIPT), "validate", str(malformed)],
text=True,
capture_output=True,
check=False,
)
self.assertEqual(completed.returncode, 1)
self.assertNotIn(secret_marker, completed.stderr)
with self.assertRaises(orc_profiles.ConfigError) as error:
orc_profiles.load_config(malformed)
self.assertNotIn(secret_marker, str(error.exception))
def test_bound_plan_enforces_registered_allowlisted_worktree(self) -> None:
def test_bound_plan_enforces_registered_same_repository_worktree(self) -> None:
git = shutil.which("git")
self.assertIsNotNone(git)
assert git is not None
@@ -306,13 +410,14 @@ class OrcSkillTests(unittest.TestCase):
check=True,
capture_output=True,
)
config_path = root / "docs" / "orc" / "config.yaml"
config_path.parent.mkdir(parents=True)
config_path.write_text(CONFIG.read_text(encoding="utf-8"), encoding="utf-8")
fake_codex = root / "trusted-codex" / "codex"
fake_codex.parent.mkdir()
fake_codex.write_text("#!/bin/sh\nexit 0\n", encoding="utf-8")
fake_codex.chmod(0o700)
fake_cursor = root / "trusted-cursor" / "cursor-agent"
fake_cursor.parent.mkdir()
fake_cursor.write_text("#!/bin/sh\nexit 0\n", encoding="utf-8")
fake_cursor.chmod(0o700)
fake_orca = root / "trusted-orca" / "orca"
fake_orca.parent.mkdir()
fake_orca.write_text("#!/bin/sh\nexit 0\n", encoding="utf-8")
@@ -322,9 +427,20 @@ class OrcSkillTests(unittest.TestCase):
return {
"git": git_path,
"codex": fake_codex,
"cursor-agent": fake_cursor,
"orca": fake_orca,
}[name]
def executable_facts(path: Path) -> dict[str, object]:
return {
"path": str(path),
"device": 1,
"inode": 2,
"size": 3,
"mtimeNs": 4,
"version": f"{path.name}-test 1",
}
with (
mock.patch.object(
orc_profiles,
@@ -339,25 +455,33 @@ class OrcSkillTests(unittest.TestCase):
mock.patch.object(
orc_profiles,
"_executable_facts",
return_value={
"path": str(fake_codex),
"device": 1,
"inode": 2,
"size": 3,
"mtimeNs": 4,
"version": "codex-test 1",
},
side_effect=executable_facts,
),
):
plan = orc_profiles.build_launch_plan(
config_path,
project_root=root,
worktree=root,
stage="code",
host_cli="codex",
stage_level="high",
)
cursor_plan = orc_profiles.build_launch_plan(
project_root=root,
worktree=root,
stage="release",
host_cli="cursor-agent",
stage_level="low",
)
self.assertEqual(plan["argv"][0], str(fake_codex))
self.assertEqual(plan["config"]["path"], str(CONFIG))
self.assertEqual(cursor_plan["argv"][0], str(fake_cursor))
self.assertEqual(cursor_plan["executable"]["path"], str(fake_cursor))
self.assertEqual(cursor_plan["argv"][1:3], ["--model", "auto"])
self.assertIn("--auto-review", cursor_plan["argv"])
self.assertEqual(cursor_plan["modelAuth"], "cursor-login")
self.assertIn("--host-cli", cursor_plan["launcherArgv"])
self.assertEqual(plan["terminalCreateArgv"][0], str(fake_orca))
self.assertEqual(plan["worktree"], str(root))
self.assertEqual(plan["selectionSource"], "request.stage")
@@ -392,10 +516,10 @@ class OrcSkillTests(unittest.TestCase):
):
with self.assertRaisesRegex(
orc_profiles.ConfigError,
"not in allowedWorktrees",
"not registered in the project repository",
):
orc_profiles.validate_worktree(
orc_profiles.load_config(config_path),
orc_profiles.load_config(CONFIG),
project_root_value=root,
worktree_value=outside,
)