feat(swarm-worker): dispatch prose swarm slots to ephemeral Muse subagents

- daemon: route non-shell slot tasks to a fresh subagent session on dev/def/muse
  via muse_hybrid; add bin/ to sys.path so muse_hybrid/prompt_envelope import
  under the tmux supervisor
- prompt_envelope: add wrap_subagent_task() - plain task assignment without
  [TOOL tmux/swarm/cron] meta tags (subagents refused those as relayed test traffic)
- box-ctl/reporter: swarm-attach accepts optional session-id, stored as
  slot.subagent_session_id
- executor: _looks_like_shell requires an existing executable (prose like
  'verify ...' no longer misread as shell)
- poller: pick up pending swarms as well as running
- response-harvester: monitor running slot subagent sessions from swarms.json,
  allow '/' in RESULT/VERB job ids, archive ephemeral threads on any verdict
  (OK or FAIL), reap slot sessions for terminal swarms
This commit is contained in:
operator
2026-10-05 20:18:46 +00:00
parent fc765f270b
commit 59c9965791
7 changed files with 235 additions and 29 deletions
+54
View File
@@ -97,6 +97,60 @@ def post_result(swarm_id, slot_index, result_dict, dry_run=False):
swarm_id, slot_index, str(resp)[:500])
return False
def attach_slot(swarm_id, slot_index, agent_id, session_id=None, dry_run=False):
"""Claim/attach a swarm slot to an agent in box state.
Args:
swarm_id: e.g. "sw-20261005-151307-a222"
slot_index: int slot number
agent_id: agent string, e.g. "dev"
session_id: optional subagent session ID string
dry_run: if True, simulate attach without changing state.
Returns:
True on success, False on failure.
"""
if dry_run:
print("DRY-RUN would run: %s swarm-attach %s %s %s %s"
% (BOX_CTL, swarm_id, slot_index, agent_id, session_id or ""))
return True
cmd = [
sys.executable, BOX_CTL, "swarm-attach",
str(swarm_id), str(slot_index), str(agent_id),
]
if session_id:
cmd.append(str(session_id))
try:
proc = subprocess.run(
cmd,
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
timeout=30,
)
except Exception as e:
log.error("attach_slot %s/%s failed to invoke box-ctl: %s",
swarm_id, slot_index, e)
return False
if proc.returncode != 0:
err = proc.stderr.decode("utf-8", "replace")[:500]
log.error("attach_slot %s/%s box-ctl rc=%d: %s",
swarm_id, slot_index, proc.returncode, err)
return False
try:
resp = json.loads(proc.stdout.decode("utf-8", "replace"))
except ValueError:
log.error("attach_slot %s/%s: box-ctl returned non-JSON output",
swarm_id, slot_index)
return False
if not resp.get("ok"):
log.error("attach_slot %s/%s: box-ctl ok=false: %s",
swarm_id, slot_index, str(resp)[:500])
return False
return True