diff --git a/src/agent_harness/__main__.py b/src/agent_harness/__main__.py index 87cee0c..e1a737e 100644 --- a/src/agent_harness/__main__.py +++ b/src/agent_harness/__main__.py @@ -888,6 +888,7 @@ def main(argv: list[str] | None = None) -> int: # starts for `--help` on a machine with no queue and no credentials, and # only the default value is needed to print it. from .executor import DEFAULT_CONTEXT_BUDGET + from .session_executor import DEFAULT_AGENT_COMMAND parser = argparse.ArgumentParser(prog="agent-harness", description=__doc__) parser.add_argument( @@ -1123,9 +1124,17 @@ def main(argv: list[str] | None = None) -> int: ) p_run.add_argument( "--agent", - default="claude -p {prompt_file}", + # The executor's default, not a second one. They disagreed: the + # executor's carried `--permission-mode acceptEdits` and the CLI's did + # not, so `run --session-host` without this flag produced an agent that + # could not write. It reported no changes and read as a model that had + # considered the task and declined — measured, and it cost a run. + default=" ".join(DEFAULT_AGENT_COMMAND), metavar="CMD", - help="CLI agent to run per item. `{prompt_file}` is substituted.", + help="CLI agent to run per item. `{prompt_file}` is substituted. " + "Defaults to the agent command the session executor declares, which " + "grants edit permission — an agent that cannot write reports no " + "changes, which is indistinguishable from one that chose to make none.", ) p_run.add_argument("--limit", type=int, help="stop after N items") p_run.add_argument( diff --git a/tests/test_cli_roles.py b/tests/test_cli_roles.py index af3c28a..e7c987c 100644 --- a/tests/test_cli_roles.py +++ b/tests/test_cli_roles.py @@ -287,3 +287,33 @@ def capture(self: Any, method: str, url: str, **kwargs: Any) -> Any: assert "timeout" not in sent["json"] and "role" not in sent["json"] assert sent["headers"]["x-api-key"] == "shared-key" assert "Authorization" not in sent["headers"] + + +def test_the_cli_agent_default_is_the_executor_s() -> None: + """They disagreed, and the CLI's was the one that could not write. + + `session_executor.DEFAULT_AGENT_COMMAND` carries `--permission-mode + acceptEdits`; the CLI's `--agent` default did not. So `run --session-host` + without the flag produced an agent that was refused every Edit, reported + no changes, and read as a model that had considered the task and declined. + + Measured: it cost a full agent run, and the agent's own account of the + refusal sat in a scrollback nothing reads. + + Asserted against the source rather than a parsed value, because the defect + was *a second default existing at all* — a literal here that happens to + match today would drift again tomorrow. + """ + import inspect + + from agent_harness import __main__ + from agent_harness.session_executor import DEFAULT_AGENT_COMMAND + + source = inspect.getsource(__main__) + assert 'default=" ".join(DEFAULT_AGENT_COMMAND)' in source, ( + "the CLI must take the executor's agent command, not declare its own" + ) + assert '"--permission-mode"' in inspect.getsource( + __import__("agent_harness.session_executor", fromlist=["x"]) + ), "and that command must still grant edit permission" + assert "--permission-mode" in " ".join(DEFAULT_AGENT_COMMAND)