Reproduction first (herdr 0.9.3, a real claude, one-off server, job 51ccd800): after a job that left a background subagent running (`← 1 agent` on screen for 5 min), herdr reported `working` only while the job ran and `idle` ~10 s after `completed`; a second submit with a 20 s idle wait was injected, not cancelled. The 2026-10-04 observation (0.9.1, 10+ min of `working`) does not reproduce on 0.9.3, so the herdr idle wait stays and the registry wait runs before it (plan §4.3 (나)). - lib_py/delegation/wrapper.py: `open-jobs` (diagnostic) and `wait-open-jobs`. An open job of the session is live when the #18 contract says so: `running` with an event in events.log within idle_timeout_sec; `pending` with a dispatch signal (dispatch_wait_at, else created_at) within ack_timeout_sec. A dead record is reported (`stale open job <id> ignored (...)`) and never waited for. The waiter signals every 10 s by merging dispatch_wait_at into its own pending record through the registry's transition boundary (status untouched, no event), so later waiters see it alive; a waiter whose wrapper is gone stops and its signal goes stale (Creator's challenge, job bf8863e1). Release is FIFO by (created_at, job_id): `clear` when no live running job remains and this job is the earliest live pending one; `busy <ids>` at the bound min(MAM_DISPATCH_WAIT_S, remaining wall clock). - the wrapper: _registry_wait after the preflight in both dispatch paths; `busy` closes the job as cancelled/session_busy (phase registry_wait), exit 5 - the existing contract. - tests/test_issue50_dispatch.py: the open-job table (status x age x signal x spelling), FIFO and the tie, the signal as a registry merge, the bound, a dead wrapper, finalize-end's new phase, both call sites. - tests/test_issue50_dispatch_herdr.py: a real herdr 0.9.3 server per test (short mkdtemp HOME, fake claude the server reports idle, the real publish path over the suite's broker): C1 wait-then-run, C2 the bound, C3 a dead running record, C4 the loop runner's first job behind an onboarding, C5 a session without a row, C7 two waiters in FIFO order with no cancellation, C8 a killed waiter skipped once stale; and three concurrent `create --onboard` / `worktree_prepare.sh --onboard` in one server (one server process survives the shims' concurrent bootstrap, so no bootstrap lock is needed). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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" 참조)