feat(ack): add grok workers and allow --always-approve
Grok is a first-class worker CLI. Launcher argv includes --always-approve so unattended tool calls are not blocked; sandbox stays required.
This commit is contained in:
@@ -30,6 +30,13 @@ def valid_orchestration() -> dict:
|
||||
"developer": {"standard": ["cursor-auto"]},
|
||||
"test": {"standard": ["cursor-auto"]},
|
||||
},
|
||||
"grok": {
|
||||
"developer": {
|
||||
"standard": ["grok-4.5"],
|
||||
"strong": ["grok-4.6"],
|
||||
},
|
||||
"test": {"standard": ["grok-4.5"]},
|
||||
},
|
||||
},
|
||||
"profiles": {
|
||||
"codex-dev-standard": {
|
||||
@@ -64,6 +71,30 @@ def valid_orchestration() -> dict:
|
||||
"reasoningEffort": None,
|
||||
"permissionMode": "workspace-write",
|
||||
},
|
||||
"grok-dev-standard": {
|
||||
"role": "developer",
|
||||
"cli": "grok",
|
||||
"tier": "standard",
|
||||
"model": "grok-4.5",
|
||||
"reasoningEffort": "medium",
|
||||
"permissionMode": "workspace-write",
|
||||
},
|
||||
"grok-dev-strong": {
|
||||
"role": "developer",
|
||||
"cli": "grok",
|
||||
"tier": "strong",
|
||||
"model": "grok-4.6",
|
||||
"reasoningEffort": "high",
|
||||
"permissionMode": "workspace-write",
|
||||
},
|
||||
"grok-test-readonly": {
|
||||
"role": "test",
|
||||
"cli": "grok",
|
||||
"tier": "standard",
|
||||
"model": "grok-4.5",
|
||||
"reasoningEffort": "low",
|
||||
"permissionMode": "read-only",
|
||||
},
|
||||
},
|
||||
"defaults": {
|
||||
"developer": "codex-dev-standard",
|
||||
@@ -278,12 +309,16 @@ class ProfileValidationTests(unittest.TestCase):
|
||||
codex["profiles"]["codex-dev-standard"]["reasoningEffort"] = None
|
||||
cursor = valid_orchestration()
|
||||
cursor["profiles"]["cursor-test-standard"]["reasoningEffort"] = "low"
|
||||
grok = valid_orchestration()
|
||||
grok["profiles"]["grok-dev-standard"]["reasoningEffort"] = None
|
||||
|
||||
codex_errors = worker_profiles.validate_orchestration(codex)
|
||||
cursor_errors = worker_profiles.validate_orchestration(cursor)
|
||||
grok_errors = worker_profiles.validate_orchestration(grok)
|
||||
|
||||
self.assertTrue(any("Codex requires" in error for error in codex_errors))
|
||||
self.assertTrue(any("Cursor requires null" in error for error in cursor_errors))
|
||||
self.assertTrue(any("Grok requires" in error for error in grok_errors))
|
||||
|
||||
def test_test_cannot_use_strong_tier(self) -> None:
|
||||
routing = valid_orchestration()
|
||||
@@ -444,6 +479,86 @@ class ArgvRendererTests(unittest.TestCase):
|
||||
self.assertNotIn("--yolo", argv)
|
||||
self.assertNotIn("--force", argv)
|
||||
|
||||
def test_grok_workspace_write_exact_safe_argv(self) -> None:
|
||||
profile = valid_orchestration()["profiles"]["grok-dev-standard"]
|
||||
|
||||
argv = worker_profiles.render_worker_argv(
|
||||
profile,
|
||||
"/usr/local/bin/grok",
|
||||
"/repo/demo",
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
argv,
|
||||
[
|
||||
"/usr/local/bin/grok",
|
||||
"--model",
|
||||
"grok-4.5",
|
||||
"--reasoning-effort",
|
||||
"medium",
|
||||
"--permission-mode",
|
||||
"acceptEdits",
|
||||
"--always-approve",
|
||||
"--sandbox",
|
||||
"workspace",
|
||||
"--cwd",
|
||||
"/repo/demo",
|
||||
],
|
||||
)
|
||||
for forbidden in (
|
||||
"--yolo",
|
||||
"bypassPermissions",
|
||||
"auto",
|
||||
"dontAsk",
|
||||
"off",
|
||||
):
|
||||
self.assertNotIn(forbidden, argv)
|
||||
|
||||
def test_grok_read_only_uses_plan_and_read_only_sandbox(self) -> None:
|
||||
profile = valid_orchestration()["profiles"]["grok-test-readonly"]
|
||||
|
||||
argv = worker_profiles.render_worker_argv(
|
||||
profile,
|
||||
"/usr/local/bin/grok",
|
||||
"/repo/demo",
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
argv,
|
||||
[
|
||||
"/usr/local/bin/grok",
|
||||
"--model",
|
||||
"grok-4.5",
|
||||
"--reasoning-effort",
|
||||
"low",
|
||||
"--permission-mode",
|
||||
"plan",
|
||||
"--always-approve",
|
||||
"--sandbox",
|
||||
"read-only",
|
||||
"--cwd",
|
||||
"/repo/demo",
|
||||
],
|
||||
)
|
||||
self.assertNotIn("--yolo", argv)
|
||||
self.assertNotIn("bypassPermissions", argv)
|
||||
|
||||
def test_grok_accepts_vendor_artifact_basename(self) -> None:
|
||||
profile = valid_orchestration()["profiles"]["grok-dev-standard"]
|
||||
artifact = "/home/ace/.grok/downloads/grok-linux-x86_64"
|
||||
|
||||
argv = worker_profiles.render_worker_argv(profile, artifact, "/repo/demo")
|
||||
|
||||
self.assertEqual(argv[0], artifact)
|
||||
self.assertTrue(
|
||||
worker_profiles.executable_basename_matches_cli(artifact, "grok")
|
||||
)
|
||||
self.assertFalse(
|
||||
worker_profiles.executable_basename_matches_cli(
|
||||
artifact, "cursor-agent"
|
||||
)
|
||||
)
|
||||
|
||||
def test_renderer_rejects_wrong_executable_or_unsafe_worktree(self) -> None:
|
||||
profile = valid_orchestration()["profiles"]["codex-dev-standard"]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user