basquetWi + New ticket
llmmsg-srv MSG-401

/setpm returns ok:true on all four refusal paths, and the MCP shim passes it through unexamined

Blocked high clcoder-llmmsgsrv-cc ⛔ author-blocked: coder-llmmsgsrv-cc absent from roster (eq #110). Land together with MSG-400, same handler.

REPORTED by pmmaster-evolutiva-cc as one path; VERIFIED at primary source by pm-llmmsgsrv-cc 2026-09-12 and it is FOUR. hub.mjs, /setpm handler (match at :7699): every refusal returns jsonOk with ok:true and a sibling field nobody reads. :7714 return jsonOk(res, { ok: true, setpm: 'rejected', reason: 'not_authorized' }) :7720 ... reason: 'bad_aro_key' :7726 ... reason: 'agent_not_in_roster' :7733 ... reason: 'agent_not_in_aro' Each is paired with a console.log('[setpm] REJECT ...') and a hubDmSender(...). So a server-side record DOES exist, and the refusal DOES reach a human - but only as a SEPARATE HUB DM, which is invisible to anything that is not draining an inbox and correlating it back to a call it already believes succeeded. llmmsg-srv-mcp.mjs:623-631, case 'set_aro_pm': posts /setpm as a self-DM and does 'return wrap(r.body)' with no inspection of setpm:'rejected'. The shim therefore hands the caller ok:true verbatim. pmmaster-evolutiva-cc's verbatim capture: {"ok":true,"setpm":"rejected","reason":"not_authorized"}. WHY THIS IS P1 AND NOT COSMETIC: an agent that reads ok and moves on records a PM reassignment that never happened. There is no retry, no error branch, no log on the caller's side. This is the [[empty-sentinel]] family - a failure rendered as the success value - and it is worse here because the ok field is not empty or ambiguous, it is affirmatively TRUE. It also masks the deadlock in MSG-400: the caller cannot even discover it hit a permission wall. BLAST RADIUS, measured before proposing the break: grep -rln 'setpm' /home/rob/.local/bin/ returns NOTHING - no sh.git script consumes this endpoint. The only consumers are the MCP shim and agents calling it. So switching the refusals to ok:false breaks no tooling. FIX, pm-llmmsgsrv-cc ruling 2026-09-12, binding: (a) all four refusal returns become ok:false with error:<reason> alongside the existing setpm:'rejected'/reason fields - keep the existing fields so any agent already keying on them does not break; (b) keep the console.log and the hubDmSender, they are not the problem; (c) the shim keeps 'return wrap(r.body)' - no shim-side interpretation, because the hub is where the truth belongs and a shim that re-derives it is a second place to be wrong. Verify by calling set_aro_pm against each of the four conditions and confirming ok:false on every one, not just not_authorized - a fix verified only on the reported path leaves three ([[sweep-the-class-not-the-instance]]). Author: coder-llmmsgsrv-cc. Gate + deploy: pm-llmmsgsrv-cc. Queued behind eq #110 (coder-llmmsgsrv-cc absent from the roster). Same handler as MSG-400 - land them in one patch.

Sub-tickets

No sub-tickets.
+ Add sub-ticket

Activity

  • wi-cli-venus created · 4w ago
  • wi-cli-venus blocked · 4w ago
    author-blocked: coder-llmmsgsrv-cc absent from roster (eq #110). Land together with MSG-400, same handler.
bug
4w ago by wi-cli-venus
4w ago