Files
bench/tests/test_empty_branch_guard.py
istosandClaude Fable 5 f8d1bf252d Launch headless agents with permissions that allow their own contract (task 05)
Work agents were launched under acceptEdits with no Bash allowlist, so
headless runs could edit files but never run tests or commit — the exact
contradiction card 05 documents. Each launch intent (work, act-pr,
review) now carries a permissions.allow list granting exactly what its
prompt demands, delivered through the same generated settings JSON as
the event hooks. Project test/check commands arrive as neutral prefixes
via BOARD_AGENT_COMMANDS; a new opencode adapter renders the same three
stances in its config language as the portability proof. A clean agent
exit with an empty branch no longer advances the card to review.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 19:46:23 +02:00

65 lines
2.2 KiB
Python

"""The zero-commit detection behind the board's empty-branch guard: a
work agent that exits cleanly without committing must not advance its
card, so _no_new_commits has to tell an untouched branch from a worked
one."""
import subprocess
import sys
import tempfile
import unittest
from pathlib import Path
REPO = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(REPO / "manager" / "core"))
import agents # noqa: E402
def _git(cwd: Path, *args: str) -> str:
return subprocess.check_output(
["git", "-C", str(cwd), *args], text=True,
stderr=subprocess.DEVNULL).strip()
class NoNewCommits(unittest.TestCase):
def setUp(self):
self._tmp = tempfile.TemporaryDirectory()
self.repo = Path(self._tmp.name) / "repo"
self.repo.mkdir()
_git(self.repo, "init", "-q", "-b", "main")
_git(self.repo, "-c", "user.email=t@t", "-c", "user.name=t",
"commit", "-q", "--allow-empty", "-m", "root")
self.base = _git(self.repo, "rev-parse", "HEAD")
self.worktree = Path(self._tmp.name) / "wt"
_git(self.repo, "worktree", "add", "-q", "-b", "task/x",
str(self.worktree))
def tearDown(self):
self._tmp.cleanup()
def record(self, **overrides):
record = {"worktree": str(self.worktree), "base": self.base}
record.update(overrides)
return record
def test_untouched_branch_is_flagged(self):
self.assertTrue(agents._no_new_commits(self.record()))
def test_a_commit_clears_the_flag(self):
(self.worktree / "f").write_text("x")
_git(self.worktree, "add", "f")
_git(self.worktree, "-c", "user.email=t@t", "-c", "user.name=t",
"commit", "-q", "-m", "work")
self.assertFalse(agents._no_new_commits(self.record()))
def test_unknown_base_or_worktree_never_flags(self):
# Better to advance a card than to hold it on bad bookkeeping.
self.assertFalse(agents._no_new_commits(self.record(base=None)))
self.assertFalse(agents._no_new_commits(self.record(worktree=None)))
self.assertFalse(agents._no_new_commits(
self.record(worktree=str(self.worktree / "gone"))))
if __name__ == "__main__":
unittest.main()