diff --git a/.agents/MULTI_AGENT_RULES.md b/.agents/MULTI_AGENT_RULES.md index 19527d5..322a20f 100644 --- a/.agents/MULTI_AGENT_RULES.md +++ b/.agents/MULTI_AGENT_RULES.md @@ -168,7 +168,7 @@ To ensure that agents running in TMUX environments do not lose debug logs or pre - **Identity Verification**: The guard validates process liveness via `pid` + `lstart` to prevent livelocks on PID rollover. ### ⏱️ Timeout Configuration & Alignment Rules -- **Job Execution Limits (`timeout_sec` & `idle_timeout_sec`)**: Each job independently manages its overall execution timeout (`timeout_sec`, default 3600s) and idle timeout without receiving messages (`idle_timeout_sec`). Since v4.5.0 (Issue #18) the idle timeout is the liveness contract's K x N: the agent heartbeats every `heartbeat_sec` (N, default 30 — automatic once it publishes `started --heartbeat N`), and `heartbeat_misses` (K, default 4) missed heartbeats close the job as `deadline_timeout` (default 120 s, `--idle-timeout` overrides). `started` must arrive within `ack_timeout_sec` (T, default 60) of the injection or the job fails as `agent_blocked` without re-injection. herdr status and pane text are never used for these decisions. +- **Job Execution Limits (`timeout_sec` & `idle_timeout_sec`)**: Each job independently manages its overall execution timeout (`timeout_sec`, default 3600s) and idle timeout without receiving messages (`idle_timeout_sec`). Since v4.5.0 (Issue #18) the idle timeout is the liveness contract's K x N: the agent heartbeats every `heartbeat_sec` (N, default 30 — automatic once it publishes `started --heartbeat N`), and `heartbeat_misses` (K, default 4) missed heartbeats close the job as `deadline_timeout` (default 120 s, `--idle-timeout` overrides). `started` must arrive within `ack_timeout_sec` (T, default 180) of the injection or the job fails as `agent_blocked` without re-injection. herdr status and pane text are never used for these decisions. - **Heartbeat timer and agent life**: the automatic timer is bound to the agent process that ran the start command (the nearest agent-CLI ancestor, or `--watch-pid`) and stops within one period once that process is gone; a crashed agent is therefore closed after K x N like any silent one, while an agent that is alive but stuck keeps heartbeating (process liveness, not work liveness). - **Monitor Idle Waiting (`SUB_IDLE_TIMEOUT`)**: The idle timeout for the monitor script (`reconcile.sh`), `SUB_IDLE_TIMEOUT`, must always be set generously to `3600s` (1 hour) or more to align with the maximum job budget. This prevents the monitor from terminating early due to idle detection, which would lose control over background tasks before they finish. diff --git a/.agents/skills/lib_py/delegation/registry.py b/.agents/skills/lib_py/delegation/registry.py index b774f21..8d3de48 100755 --- a/.agents/skills/lib_py/delegation/registry.py +++ b/.agents/skills/lib_py/delegation/registry.py @@ -52,10 +52,12 @@ def generate_job_id(bits: int = 32) -> str: # heartbeats (K x N seconds since the last event) as unresponsive; `started` # must arrive within T seconds of the prompt injection. K x N with these # defaults equals the historical 120 s idle timeout, so a caller that never -# asked for the contract sees the same idle window as before. +# asked for the contract sees the same idle window as before. T is generous: +# a real agent reads the brief and reasons before it runs the start command +# (grok took ~70 s in the v4.5.0 review round), and T only bounds delivery. DEFAULT_HEARTBEAT_SEC = 30 DEFAULT_HEARTBEAT_MISSES = 4 -DEFAULT_ACK_TIMEOUT_SEC = 60 +DEFAULT_ACK_TIMEOUT_SEC = 180 def liveness_window(heartbeat_sec: int, heartbeat_misses: int) -> int: diff --git a/.agents/skills/multi-agent-mux-delegate-job/SKILL.md b/.agents/skills/multi-agent-mux-delegate-job/SKILL.md index 77317b3..e073daa 100644 --- a/.agents/skills/multi-agent-mux-delegate-job/SKILL.md +++ b/.agents/skills/multi-agent-mux-delegate-job/SKILL.md @@ -40,7 +40,7 @@ multi-agent-mux-delegate-job submit \ --agent-session herdr: \ --prompt "Task description or instructions here" \ --role \ - --timeout 3600 [--heartbeat 30 --heartbeat-misses 4 --ack-timeout 60] [--idle-timeout ] + --timeout 3600 [--heartbeat 30 --heartbeat-misses 4 --ack-timeout 180] [--idle-timeout ] # Liveness contract (Issue #18): the agent heartbeats every N s (automatic), # the job is unresponsive after K x N s (--idle-timeout overrides), `started` # must arrive within T s of the injection or the inject fails closed. diff --git a/.agents/skills/multi-agent-mux-delegate-job/multi-agent-mux-delegate-job b/.agents/skills/multi-agent-mux-delegate-job/multi-agent-mux-delegate-job index f9718df..79ed31c 100755 --- a/.agents/skills/multi-agent-mux-delegate-job/multi-agent-mux-delegate-job +++ b/.agents/skills/multi-agent-mux-delegate-job/multi-agent-mux-delegate-job @@ -86,7 +86,7 @@ multi-agent-mux-delegate-job [options] # Liveness contract: the agent heartbeats every --heartbeat N s # (default 30, automatic), the job is unresponsive after # --heartbeat-misses K x N s (default 4 x 30 = 120; --idle-timeout - # overrides), `started` must arrive within --ack-timeout T s (60). + # overrides), `started` must arrive within --ack-timeout T s (180). status --job [--registry-dir ] list [--registry-dir ] verify --job --validate