Agents arm sleep/poll to wait for hub replies - fix at the primitive
Elazar-directed via db-venus-cc 2026-09-12. Agents arm 'sleep 90'/'sleep 180' in Bash and poll has_unread to wait for a DM reply, though hub messages are PUSHED between tool turns. Elazar says it is not the first time. DIAGNOSIS: the prohibition ALREADY EXISTS and is already imperative - ~/.claude/llmmsg-protocol.md:13 'After sending, rely on push. Do not sleep, poll, set timers, loop, back off, or repeat checks.' So this is NOT a wording defect, it is a DISTRIBUTION defect: that file is lazy-loaded, so a mid-task agent is working off the one descriptive clause in the MCP instructions string ('Messages arrive as <channel ...> notifications between tool turns') which is not phrased as a prohibition. Fix at the primitive: (a) fourth imperative Operating rule in the shim instructions string, (b) corrective line on the has_unread tool RESPONSE so the tool corrects the agent at the moment of the mistake. NOT on read_unread - the poke->read_unread drain is the CORRECT path and global CLAUDE.md mandates it; ban the WAIT, not the drain. MEASUREMENT GAP: has_unread is shim-local (no httpRequest), so no hub-side record of any call exists - the frequency cannot be quantified from v2.sqlite. REACH: instructions + tool descriptions + tool responses are all session-scoped, so none of this reaches sessions currently doing it; pair with one ARO note.
Activity
-
SHIPPED, commit 1ed9946 in /opt/llmmsg-srv, pushed (main...origin/main, no ahead marker). node --check passed. No service restart: the MCP shim is a per-session spawned process, not llmmsg-srv-venus.service. DIAGNOSIS (the reason this is not a wording fix): the imperative prohibition ALREADY EXISTED, verbatim, at ~/.claude/llmmsg-protocol.md:13 - 'After sending, rely on push. Do not sleep, poll, set timers, loop, back off, or repeat checks. Call read_unread only if the user asked or there is clear evidence a reply is missing.' Grepped, not inferred. The file is lazy-loaded, so a mid-task agent never reads it and works off the shim instructions instead, where the push guarantee was one DESCRIPTIVE clause outside the numbered Operating rules. Distribution defect. THREE SURFACES CHANGED. (1) instructions string :223 - new imperative Operating rule (4). (2) has_unread tool description :311 - same prohibition, read before the call. (3) has_unread response handler :620 - an unconditional note field. (3) is the load-bearing half: instructions and tool descriptions reach an agent only on SESSION RESTART, a tool response reaches the agent making the mistake in the turn it makes it. READ_UNREAD DELIBERATELY UNTOUCHED. Poke -> read_unread is the correct path and global CLAUDE.md mandates it. A blanket 'never poll' in the shim would contradict the unread-poke trigger and manufacture the next confused agent. Ban the WAIT, not the DRAIN. It would also cost tokens on every drain, twelve hours after OPS-228 cut 102.8 chars/msg. COVERAGE STATEMENT - two limits, neither papered over. (a) NOT EXERCISED LIVE. All three surfaces are session-scoped; this session's shim predates the commit, and per shim-schema-only-on-session-restart a shim deploy can never be verified from my own tool list. Syntax + diff are the only evidence held; first live exercise is any agent restarted after 2026-09-12 06:58 UTC. (b) FREQUENCY IS UNMEASURABLE. has_unread is shim-local (no httpRequest), so the hub holds no record that any agent ever called it - Elazar's 'not the first time' cannot be quantified from v2.sqlite and I did not imply it could. DISTRIBUTED: one send, delivery_count 3, to db-venus-cc (reporter), nw-venus-cc (venus relay) and pmmaster-evolutiva-cc (fleet PM), because the code fix reaches none of the sessions currently doing it.