From 76ff395eebc22a7ebb6bc47f12472542221e499e Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 21 Oct 2026 17:48:20 -0400 Subject: [PATCH] Chokehold release finds the units it paused ChokeholdAnswer.held walked thread.goal.active(), which is NoGoal for every paused goal, so a quoting answer released nothing and the chokehold held the fleet forever. It reads the thread's goal itself. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01AeUaZjvChAcb6qAd6zPYmw --- src/agent_comms/commander/vibe_check.py | 2 +- tests/test_chokehold_release.py | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 tests/test_chokehold_release.py diff --git a/src/agent_comms/commander/vibe_check.py b/src/agent_comms/commander/vibe_check.py index ee1d297645..9c87c12079 100644 --- a/src/agent_comms/commander/vibe_check.py +++ b/src/agent_comms/commander/vibe_check.py @@ -276,7 +276,7 @@ def held(comms: Comms) -> tuple[str, ...]: return tuple( name for name, thread in comms.registry.all_threads().items() - if any(goal.state.lifts_on_compliance for goal in thread.goal.active()) + if any(goal.state.lifts_on_compliance for goal in thread.goal) ) diff --git a/tests/test_chokehold_release.py b/tests/test_chokehold_release.py new file mode 100644 index 0000000000..8301d619b3 --- /dev/null +++ b/tests/test_chokehold_release.py @@ -0,0 +1,24 @@ +"""A unit the chokehold paused is found again, so a quoting answer can resume it.""" + +from functools import partial + +from agent_comms.commander.vibe_check import ChokeholdAnswer +from agent_comms.goal_actions import ChokeholdPausedGoalAction, PausedGoalAction +from agent_comms.tool_caller import ThreadCaller +from agent_comms.tools import invoke_tool + + +def _unit(comms, monkeypatch, name): + monkeypatch.setenv("AGENT_COMMS_THREAD", name) + comms.registry.declare(comms.registry.new_thread(name=name, tags=frozenset(), worktree="/wt")) + partial(invoke_tool, caller=ThreadCaller(name))(comms, "comms_set_goal", {"text": "work"}) + + +def test_a_chokehold_paused_unit_is_held_and_an_owner_pause_is_not(comms, monkeypatch): + _unit(comms, monkeypatch, "choked") + _unit(comms, monkeypatch, "owner-paused") + _unit(comms, monkeypatch, "running") + comms.goals.update_goal("choked", ChokeholdPausedGoalAction()) + comms.goals.update_goal("owner-paused", PausedGoalAction()) + + assert ChokeholdAnswer.held(comms) == ("choked",)