#!/usr/bin/env python3 """Adapter and headless-runner behavior tests; fake CLIs never contact providers.""" import importlib.util import json import os import pathlib import sys import shutil import unittest import tempfile from unittest import mock ROOT = pathlib.Path(__file__).resolve().parents[1] REAL_WHICH = shutil.which def load_module(name, path): spec = importlib.util.spec_from_file_location(name, path) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) return module installer = load_module("dev_workflows_install", ROOT / "scripts" / "install.py") harness = load_module("dev_workflows_harness", ROOT / "scripts" / "harness_runner.py") class AdapterTest(unittest.TestCase): def test_omp_install_preserves_unowned_destination_and_skips_link(self): with tempfile.TemporaryDirectory() as temp: base = pathlib.Path(temp) / ".omp" dest = base / "plugins" / "dev-workflows" dest.mkdir(parents=True) (dest / "user-data").write_text("preserve", encoding="utf-8") runner = mock.Mock() with self.assertRaises(SystemExit): installer.install_omp(base=str(base), runner=runner) runner.assert_not_called() self.assertEqual((dest / "user-data").read_text(encoding="utf-8"), "preserve") def test_omp_install_keeps_package_for_recovery_if_link_fails(self): with tempfile.TemporaryDirectory() as temp: base = pathlib.Path(temp) / ".omp" runner = mock.Mock(return_value=mock.Mock(returncode=7)) with self.assertRaisesRegex(SystemExit, "falhou com código 7"): installer.install_omp(base=str(base), runner=runner) self.assertTrue((base / "plugins" / "dev-workflows" / ".dev-workflows-omp-package").is_file()) class HarnessRunnerTest(unittest.TestCase): def setUp(self): self.temp = tempfile.TemporaryDirectory() self.root = pathlib.Path(self.temp.name) self.cwd = self.root / "state" / "project" / "run" / "worktrees" / "iteration-001" self.cwd.mkdir(parents=True) gitdir = self.root / "project" / ".git" / "worktrees" / "iteration-001" gitdir.mkdir(parents=True) (self.cwd / ".git").write_text(f"gitdir: {gitdir}\n", encoding="utf-8") self.bin = self.root / "bin" self.bin.mkdir() self.trace = self.root / "calls.jsonl" self.cache = self.root / "catalog" self.cache.mkdir() self._fake_cli() def tearDown(self): self.temp.cleanup() def _fake_cli(self): executable = self.bin / "fake-cli" executable.write_text( "#!" + sys.executable + "\n" "import json, os, pathlib, sys\n" "name = pathlib.Path(sys.argv[0]).name\n" "args = sys.argv[1:]\n" "with open(os.environ['DW_TRACE'], 'a', encoding='utf-8') as out:\n" " out.write(json.dumps({'name': name, 'args': args, 'cwd': os.getcwd(), 'marker': os.getenv('DW_MARKER')}) + '\\n')\n" "if name == 'claude' and args[:3] == ['auth', 'status', '--json']:\n" " print(os.environ.get('DW_CLAUDE_AUTH', '{\\\"loggedIn\\\": true}'))\n" "elif name == 'opencode' and args[:1] == ['models']:\n" " print(os.environ.get('DW_MODELS', ''))\n" "elif name == 'omp' and args[:2] == ['models', args[1] if len(args) > 1 else '']:\n" " print(os.environ.get('DW_MODELS_JSON', '[]'))\n" "else:\n" " print('fake response')\n" " print('sk-secret-must-not-escape', file=sys.stderr)\n", encoding="utf-8", ) executable.chmod(0o755) for name in ("claude", "opencode", "omp"): (self.bin / name).symlink_to(executable) def _env(self, **extra): value = os.environ.copy() value.update({ "PATH": str(self.bin) + os.pathsep + value.get("PATH", ""), "DEV_WORKFLOWS_MODEL_CACHE": str(self.cache), "DW_TRACE": str(self.trace), "DW_MARKER": "test-env", }) value.update(extra) return value def _snapshot(self, tool, model_key, *, entitled=True, variant=None, provider=None, model_id=None): row = { "tool": tool, "model_key": model_key, "availability": { "local_listed": True, "authenticated": True, "entitled": entitled, "source": "manual_audited", "verified_at": "2026-09-25T12:00:00Z", }, } if variant is not None: row.update({"variant": variant, "provider": provider, "model_id": model_id}) (self.cache / f"catalog-{tool}.json").write_text( json.dumps({"schema_version": 1, "tool": tool, "models": [row]}), encoding="utf-8" ) def _calls(self): if not self.trace.exists(): return [] return [json.loads(line) for line in self.trace.read_text(encoding="utf-8").splitlines()] def _fake_bwrap(self): trace = self.root / "bwrap.jsonl" executable = self.bin / "bwrap" executable.write_text( "#!" + sys.executable + "\n" "import json, os, pathlib, sys\n" "args = sys.argv[1:]\n" "with open(os.environ['DW_BWRAP_TRACE'], 'a', encoding='utf-8') as out:\n" " out.write(json.dumps(args) + '\\n')\n" "command = args[args.index('--') + 1:]\n" "tool = pathlib.Path(command[0]).name\n" "if tool == 'omp' and 'models' in command:\n" " print(os.environ.get('DW_MODELS_JSON', '[]'))\n" "elif tool == 'opencode' and 'models' in command:\n" " print(os.environ.get('DW_MODELS', ''))\n" "elif tool == 'claude' and command[1:3] == ['auth', 'status']:\n" " print(os.environ.get('DW_CLAUDE_AUTH', '{\\\"loggedIn\\\": true}'))\n" "else:\n" " print('fake wrapped response')\n", encoding="utf-8", ) executable.chmod(0o755) return trace def _invoke_with_fake_bwrap(self, *args, **kwargs): def find_executable(name, path=None): if name == "bwrap": return str(self.bin / "bwrap") return REAL_WHICH(name, path=path) with mock.patch.object(harness.shutil, "which", side_effect=find_executable): return harness.invoke(*args, **kwargs) def test_claude_alias_and_dontask_preserve_default_permission_gate(self): result = harness.invoke("claude", "reviewer", "Review safely", str(self.cwd), "opus", env=self._env()) self.assertEqual(result["returncode"], 0) calls = self._calls() self.assertEqual(calls[0]["args"], ["auth", "status", "--json"]) call = calls[1] args = call["args"] self.assertIn("--permission-mode", args) self.assertEqual(args[args.index("--permission-mode") + 1], "dontAsk") self.assertIn("--agent", args) self.assertIn("reviewer", args) self.assertEqual(args[args.index("--model") + 1], "opus") self.assertNotIn("--dangerously-skip-permissions", args) self.assertEqual(call["cwd"], str(self.cwd)) self.assertEqual(call["marker"], "test-env") self.assertIsNone(result["usage"]) self.assertNotIn("sk-secret", result["output"]) def test_claude_inherit_keeps_role_alias_without_model_override(self): result = harness.invoke("claude", "explorer", "Map the project", str(self.cwd), "inherit", env=self._env()) self.assertEqual(result["returncode"], 0) calls = self._calls() self.assertEqual(calls[0]["args"], ["auth", "status", "--json"]) args = calls[1]["args"] self.assertIn("--agent", args) self.assertNotIn("--model", args) self.assertNotIn("--dangerously-skip-permissions", args) def test_sonnet_alias_is_passed_without_rewriting_the_plugin(self): harness.invoke("claude", "ui-critic", "Critique only", str(self.cwd), "sonnet", env=self._env()) calls = self._calls() args = calls[1]["args"] self.assertEqual(args[args.index("--model") + 1], "sonnet") self.assertEqual(args[args.index("--agent") + 1], "ui-critic") def test_claude_alias_is_blocked_when_local_auth_status_is_negative(self): with self.assertRaisesRegex(harness.HarnessError, "auth status"): harness.invoke( "claude", "reviewer", "Review", str(self.cwd), "opus", env=self._env(DW_CLAUDE_AUTH='{"loggedIn": false}'), ) calls = self._calls() self.assertEqual(len(calls), 1) self.assertEqual(calls[0]["args"], ["auth", "status", "--json"]) def test_opencode_uses_exact_variant_and_role_agent_without_auto_approval(self): model_key = "openai/gpt-6-luna#high" self._snapshot("opencode", model_key) result = harness.invoke( "opencode", "planner", "Plan only", str(self.cwd), model_key, env=self._env(DW_MODELS="gpt-6-luna"), ) self.assertEqual(result["returncode"], 0) calls = self._calls() self.assertEqual(calls[0]["args"], ["models", "openai"]) args = calls[1]["args"] self.assertEqual(args[:3], ["run", "--agent", "planner"]) self.assertEqual(args[args.index("--model") + 1], model_key) self.assertNotIn("--auto", args) self.assertEqual(calls[1]["cwd"], str(self.cwd)) self.assertIn("stderr omitido por segurança", result["output"]) self.assertNotIn("sk-secret", result["output"]) def test_omp_runs_with_exact_tools_and_always_ask(self): model_key = "openai/gpt-6-luna#high" self._snapshot("omp", model_key, variant="high", provider="openai", model_id="gpt-6-luna") result = harness.invoke( "omp", "explorer", "Inspect only", str(self.cwd), model_key, env=self._env(DW_MODELS_JSON=json.dumps([{"provider": "openai", "id": "gpt-6-luna", "thinking": ["low", "high"]}])), ) self.assertEqual(result["returncode"], 0) calls = self._calls() self.assertEqual(calls[0]["args"], ["models", "openai", "--json"]) args = calls[1]["args"] self.assertEqual(args[0], "-p") self.assertEqual(args[args.index("--model") + 1], "openai/gpt-6-luna") self.assertEqual(args[args.index("--thinking") + 1], "high") self.assertEqual(args[args.index("--approval-mode") + 1], "always-ask") self.assertNotIn("--auto-approve", args) self.assertEqual(args[args.index("--tools") + 1], "read,grep,glob") self.assertEqual(args[args.index("--cwd") + 1], str(self.cwd)) def test_omp_unknown_thinking_variant_is_rejected_before_listing_or_dispatch(self): model_key = "openai/model#unsupported" self._snapshot("omp", model_key, variant="unsupported", provider="openai", model_id="model") with self.assertRaisesRegex(harness.HarnessError, "variante"): harness.invoke("omp", "explorer", "Inspect", str(self.cwd), model_key, env=self._env()) self.assertEqual(self._calls(), []) def test_omp_rejects_thinking_not_supported_by_current_model_listing(self): model_key = "openai/gpt-6-luna#high" self._snapshot("omp", model_key, variant="high", provider="openai", model_id="gpt-6-luna") listed = {"models": [{"provider": "openai", "id": "gpt-6-luna", "thinking": ["low"]}]} with self.assertRaisesRegex(harness.HarnessError, "indisponível"): harness.invoke("omp", "explorer", "Inspect", str(self.cwd), model_key, env=self._env(DW_MODELS_JSON=json.dumps(listed))) self.assertEqual([call["args"] for call in self._calls()], [["models", "openai", "--json"]]) def test_omp_slash_model_id_keeps_provider_and_qualified_selector(self): model_key = "openrouter/anthropic/claude-sonnet-4.6" self._snapshot("omp", model_key) listed = {"models": [{"provider": "openrouter", "id": "anthropic/claude-sonnet-4.6", "selector": model_key, "thinking": None}]} result = harness.invoke("omp", "explorer", "Inspect", str(self.cwd), model_key, env=self._env(DW_MODELS_JSON=json.dumps(listed))) self.assertEqual(result["returncode"], 0) calls = self._calls() self.assertEqual(calls[0]["args"], ["models", "openrouter", "--json"]) self.assertEqual(calls[1]["args"][calls[1]["args"].index("--model") + 1], model_key) def test_autonomous_omp_uses_bwrap_and_bounded_tools_with_auto_approval(self): model_key = "openai/gpt-6-luna#high" self._snapshot("omp", model_key, variant="high", provider="openai", model_id="gpt-6-luna") trace = self._fake_bwrap() result = self._invoke_with_fake_bwrap( "omp", "implementer", "Inspect only", str(self.cwd), model_key, env=self._env( DEV_WORKFLOWS_AUTONOMOUS="1", DW_BWRAP_TRACE=str(trace), DW_MODELS_JSON=json.dumps([{"provider": "openai", "id": "gpt-6-luna", "thinking": ["low", "high"]}]), ), ) self.assertEqual(result["returncode"], 0) self.assertEqual(self._calls(), []) calls = [json.loads(line) for line in trace.read_text(encoding="utf-8").splitlines()] self.assertEqual(len(calls), 2) for args in calls: self.assertEqual(args[:6], ["--unshare-all", "--share-net", "--die-with-parent", "--ro-bind", "/", "/"]) binds = [args[index + 1:index + 3] for index, value in enumerate(args) if value == "--bind"] self.assertIn([str(self.cwd), str(self.cwd)], binds) readonly = [args[index + 1:index + 3] for index, value in enumerate(args) if value == "--ro-bind"] self.assertIn([str(self.cwd / ".git"), str(self.cwd / ".git")], readonly) preflight = calls[0][calls[0].index("--") + 1:] self.assertEqual(pathlib.Path(preflight[0]).name, "omp") self.assertEqual(preflight[1:4], ["--no-extensions", "models", "openai"]) command = calls[1][calls[1].index("--") + 1:] self.assertEqual(pathlib.Path(command[0]).name, "omp") self.assertEqual(command[1], "-p") for flag in ("--no-extensions", "--no-lsp", "--no-session", "--auto-approve"): self.assertIn(flag, command) self.assertEqual(command[command.index("--model") + 1], "openai/gpt-6-luna") self.assertEqual(command[command.index("--thinking") + 1], "high") self.assertEqual(command[command.index("--tools") + 1], "read,grep,glob,edit,write") self.assertNotIn("bash", command) self.assertNotIn("web_search", command) def test_autonomous_opencode_uses_pure_mode_and_synthetic_deny_agent(self): model_key = "openai/gpt-6-luna#high" self._snapshot("opencode", model_key) trace = self._fake_bwrap() meta, prompt = harness._agent("implementer") generated = harness._opencode_loop_agent(meta, prompt) self.assertIn(' "*": deny', generated) self.assertIn(" bash: deny", generated) self.assertIn(" edit: allow", generated) self.assertIn(" task: deny", generated) result = self._invoke_with_fake_bwrap( "opencode", "implementer", "Implement safely", str(self.cwd), model_key, env=self._env(DEV_WORKFLOWS_AUTONOMOUS="1", DW_BWRAP_TRACE=str(trace), DW_MODELS="gpt-6-luna"), ) self.assertEqual(result["returncode"], 0) self.assertEqual(self._calls(), []) calls = [json.loads(line) for line in trace.read_text(encoding="utf-8").splitlines()] self.assertEqual(len(calls), 2) preflight = calls[0][calls[0].index("--") + 1:] self.assertEqual(pathlib.Path(preflight[0]).name, "opencode") self.assertEqual(preflight[1:3], ["--pure", "models"]) command = calls[1][calls[1].index("--") + 1:] self.assertEqual(pathlib.Path(command[0]).name, "opencode") self.assertEqual(command[1:4], ["--pure", "run", "--agent"]) agent_name = command[4] self.assertRegex(agent_name, r"\Adev-workflows-loop-implementer-[0-9a-f]{16}\Z") self.assertIn("--file", calls[1]) def test_autonomous_claude_uses_bare_mode_and_declared_safe_tools(self): trace = self._fake_bwrap() result = self._invoke_with_fake_bwrap( "claude", "reviewer", "Review only", str(self.cwd), "opus", env=self._env(DEV_WORKFLOWS_AUTONOMOUS="1", DW_BWRAP_TRACE=str(trace)), ) self.assertEqual(result["returncode"], 0) self.assertEqual(self._calls(), []) calls = [json.loads(line) for line in trace.read_text(encoding="utf-8").splitlines()] self.assertEqual(len(calls), 2) auth = calls[0][calls[0].index("--") + 1:] self.assertEqual(pathlib.Path(auth[0]).name, "claude") self.assertEqual(auth[1:], ["auth", "status", "--json"]) command = calls[1][calls[1].index("--") + 1:] self.assertIn("--bare", command) self.assertIn("--no-session-persistence", command) self.assertEqual(command[command.index("--permission-mode") + 1], "dontAsk") agent_config = json.loads(command[command.index("--agents") + 1]) self.assertEqual(agent_config["reviewer"]["tools"], ["Read", "Grep", "Glob"]) self.assertEqual(command[command.index("--tools") + 1], "Read,Grep,Glob") self.assertNotIn("Bash", command) def test_autonomous_mode_fails_closed_without_bwrap(self): self._snapshot("omp", "openai/gpt-6-luna") def find_without_bwrap(name, path=None): return None if name == "bwrap" else REAL_WHICH(name, path=path) with mock.patch.object(harness.shutil, "which", side_effect=find_without_bwrap): with self.assertRaisesRegex(harness.HarnessError, "bwrap"): harness.invoke( "omp", "explorer", "Inspect", str(self.cwd), "openai/gpt-6-luna", env=self._env(PATH=str(self.bin), DEV_WORKFLOWS_AUTONOMOUS="1"), ) self.assertEqual(self._calls(), []) def test_autonomous_rejects_non_worktree_cwd_before_dispatch(self): other = self.root / "ordinary-directory" other.mkdir() with self.assertRaisesRegex(harness.HarnessError, "worktree"): harness.invoke( "omp", "explorer", "Inspect", str(other), "openai/gpt-6-luna", env=self._env(DEV_WORKFLOWS_AUTONOMOUS="1"), ) self.assertEqual(self._calls(), []) def test_autonomous_does_not_resolve_cli_from_writable_worktree(self): self._snapshot("opencode", "openai/gpt-6-luna") shadow = self.cwd / "opencode" shadow.write_text("#!/bin/sh\nexit 0\n", encoding="utf-8") shadow.chmod(0o755) with self.assertRaisesRegex(harness.HarnessError, "PATH seguro"): harness.invoke( "opencode", "planner", "Plan", str(self.cwd), "openai/gpt-6-luna", env=self._env(PATH=str(self.cwd), DEV_WORKFLOWS_AUTONOMOUS="1"), ) self.assertEqual(self._calls(), []) def test_unentitled_model_is_blocked_before_cli_is_started(self): self._snapshot("opencode", "openai/gpt-6-luna", entitled=False) with self.assertRaisesRegex(harness.HarnessError, "autorização local"): harness.invoke( "opencode", "planner", "Plan", str(self.cwd), "openai/gpt-6-luna", env=self._env(DW_MODELS="gpt-6-luna"), ) self.assertEqual(self._calls(), []) def test_model_absent_from_local_cli_is_blocked_before_agent_dispatch(self): self._snapshot("opencode", "openai/gpt-6-luna") with self.assertRaisesRegex(harness.HarnessError, "indisponível na CLI local"): harness.invoke( "opencode", "planner", "Plan", str(self.cwd), "openai/gpt-6-luna", env=self._env(DW_MODELS="openai/different-model"), ) calls = self._calls() self.assertEqual(len(calls), 1) self.assertEqual(calls[0]["args"], ["models", "openai"]) if __name__ == "__main__": unittest.main(verbosity=1)