Round-1 review of PR #41 (claude N1, codex R1/R2). N1 - the wrapper stopped its stall watcher with `kill` followed by an unbounded `wait`. A TERM that lands in the watcher's fork-exec window is swallowed (bash defers terminating signals in the forked child until the exec), the watcher then installs its own handler and lives until the job closes, and the wrapper hung until someone killed the watcher by hand (reproduced twice in test_issue14's ack test; the wrapper trace stops at `kill` + `wait`). R1 - a wrapper that is itself terminated left the watcher orphaned. R2 - a `completed` or a re-dispatch that landed during a blocking herdr wait (up to 60 s) was still followed by the idle notice and the nudge. - multi-agent-mux-delegate-job: `stop_stall_watch` sends TERM, polls up to 5 s, then KILLs and reports "ignored TERM; killed"; `start_stall_watch` passes `--watch-pid $$`. - lib_py/stall_watch.py: `--watch-pid` (rc 0 once that pid is gone, checked between herdr calls); `_dispatch_open()` re-reads the record after every wait and right before the nudge - terminal status, another dispatch token or attempt, or a missing record ends the run without a notice; a refused `stalled:idle` publish withholds the nudge (`_notify` returns False). - delegate-job SKILL.md: the watcher's lifetime contract; exit-code rows 2 and 3 name the idle clock and the wall-clock label; "before v4.7.5" -> v4.8.0 (M5, NB2). - tests/test_issue30_stall_watch.py (M8): the module-wide Linux mark is narrowed to S6 (/proc); r4's stub stamps time.time() so its cross-process comparison holds on macOS too (47 passed, 1 skipped here). - tests/test_issue30_stall_watch_stop.py (new, macOS and Linux): the stop routine against a TERM-ignoring stand-in returns in 4-12 s; the wrapper returns (rc 3) with a TERM-ignoring watcher shim; `--watch-pid` ends the watcher; a TERM to the real wrapper leaves no watcher; a job completed or re-dispatched during the wait is not nudged; a refused notice withholds the nudge. Every one of them hangs or fails on the round-1 code. Not in this commit (follow-ups): M7 test hook in product code (no adapter is unreliable, a seam is needed), M9/B3 public-broker latency (on this host even `started` sometimes never reaches the subscriber), the leading-zero budget parse (NB1) and M1/M2/M4/M6 go on the #17 item 4 list. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
multi-agent-mux-delegate-job 스킬
작업(Job)을 자율 에이전트(claude-code/hermes/agy/grok-build/codex/opencode/human)에게 위임하고 MQTT
이벤트 채널로 비동기 관찰하는 범용 에이전트 협업 스킬. 시작점은 SKILL.md.
- 프로토콜/스키마:
job-protocol.md - 브로커 PoC→운영 전환:
mqtt-broker-setup.md - 레지스트리 포맷/동시성:
registry.md - 참조 구현:
multi-agent-mux-delegate-job(bash wrapper),scripts/publish_event.py,scripts/job_subscriber.py,scripts/registry.py,scripts/mqtt_common.py - v4.3.0 이후: 위
scripts/*.py는 호환 shim이며 실제 구현은.agents/skills/lib_py/delegation/에 있다 (issue #5 phase 1). 스크립트 경로와 CLI 계약은 그대로이며,lib.sh헬퍼는python -m lib_py.delegation.cli를 호출한다. - 영구 감사 로그:
.mam/delegate_job_logs/<job_id>/(meta.json·events.ndjson·status.json) —multi-agent-mux-delegate-job logs <id>또는multi-agent-mux-delegate-job logs --list로 조회 (SKILL.md "Audit Logs" 참조)