diff --git a/tests/test_tier2_slash_command_spec.py b/tests/test_tier2_slash_command_spec.py new file mode 100644 index 00000000..31c4ff52 --- /dev/null +++ b/tests/test_tier2_slash_command_spec.py @@ -0,0 +1,89 @@ +"""Contract tests for the Tier 2 slash command, agent profile, and config fragment. + +These tests verify that the templates the bootstrap copies to the Tier 2 +clone contain the protocol contract that Tier 2 autonomous relies on. +""" +import json +import re +from pathlib import Path + +COMMAND_PATH = Path("conductor/tier2/commands/tier-2-auto-execute.md") +AGENT_PATH = Path("conductor/tier2/agents/tier2-autonomous.md") +CONFIG_PATH = Path("conductor/tier2/opencode.json.fragment") + + +def test_command_file_exists() -> None: + assert COMMAND_PATH.exists() + + +def test_command_has_frontmatter() -> None: + content = COMMAND_PATH.read_text(encoding="utf-8") + assert re.match(r"^---\n.*?\n---\n", content, re.DOTALL) + + +def test_command_takes_track_name_argument() -> None: + content = COMMAND_PATH.read_text(encoding="utf-8") + assert "$ARGUMENTS" in content + assert "track-name" in content or "" in content + + +def test_command_uses_git_switch_not_checkout() -> None: + content = COMMAND_PATH.read_text(encoding="utf-8") + assert "git switch -c" in content + protocol_marker = "## Protocol" + next_section_marker = "## Hard Bans" + start = content.find(protocol_marker) + end = content.find(next_section_marker) + assert start != -1 and end != -1 + protocol_section = content[start:end] + import re as _re + shell_lines = _re.findall(r"^\s*\d+\.\s*`(git [^`]+)`", protocol_section, _re.MULTILINE) + assert shell_lines, "expected numbered git commands in protocol" + assert all("checkout" not in line for line in shell_lines), f"protocol uses git checkout: {shell_lines}" + + +def test_command_fetches_origin_main() -> None: + content = COMMAND_PATH.read_text(encoding="utf-8") + assert "git fetch origin main" in content + + +def test_command_initializes_failcount_state() -> None: + content = COMMAND_PATH.read_text(encoding="utf-8") + assert "load_state" in content or "fresh state" in content.lower() + + +def test_command_calls_should_give_up() -> None: + content = COMMAND_PATH.read_text(encoding="utf-8") + assert "should_give_up" in content + + +def test_command_writes_report_on_give_up() -> None: + content = COMMAND_PATH.read_text(encoding="utf-8") + assert "write_failure_report" in content + + +def test_command_prints_abort_banner() -> None: + content = COMMAND_PATH.read_text(encoding="utf-8") + assert "TRACK ABORTED" in content or "ABORTED" in content + + +def test_agent_file_exists() -> None: + assert AGENT_PATH.exists() + + +def test_agent_denies_destructive_git() -> None: + content = AGENT_PATH.read_text(encoding="utf-8") + assert '"git push*": deny' in content + assert '"git checkout*": deny' in content + assert '"git restore*": deny' in content + assert '"git reset*": deny' in content + + +def test_config_fragment_valid_json() -> None: + data = json.loads(CONFIG_PATH.read_text(encoding="utf-8")) + assert data["default_agent"] == "tier2-autonomous" + perms = data["agent"]["tier2-autonomous"]["permission"] + assert "git push*" in perms["bash"] + assert "git checkout*" in perms["bash"] + assert "git restore*" in perms["bash"] + assert "git reset*" in perms["bash"]