metheus-governance-mcp-cli 0.2.201 → 0.2.202

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cli.mjs CHANGED
@@ -6319,6 +6319,7 @@ function stableTextModulo(rawValue, modulo = 1) {
6319
6319
  return hash % normalizedModulo;
6320
6320
  }
6321
6321
 
6322
+ /* Dead small_talk helper kept only as commented legacy code after lookup-only migration.
6322
6323
  function buildRunnerSmallTalkReply({ route, executionPlan } = {}) {
6323
6324
  const normalizedRoute = safeObject(route);
6324
6325
  const roleProfileName = normalizeRunnerRoleProfileName(
@@ -6355,6 +6356,7 @@ function buildRunnerSmallTalkReply({ route, executionPlan } = {}) {
6355
6356
  const templatePool = roleSpecificReplies[roleProfileName] || roleSpecificReplies.monitor;
6356
6357
  return templatePool[stableTextModulo(`${displayName}:${roleProfileName}`, templatePool.length)];
6357
6358
  }
6359
+ */
6358
6360
 
6359
6361
  function buildInformationalMiniExecutionOverride({ route, executionPlan } = {}) {
6360
6362
  const safeRoute = safeObject(route);
@@ -6616,11 +6618,11 @@ async function resolveInformationalQueryReply({
6616
6618
  user_message: messageText,
6617
6619
  bot_name: firstNonEmptyString([route?.botName, route?.serverBotName, route?.server_bot_name, route?.name]),
6618
6620
  bot_role: String(route?.role || route?.roleProfile || "").trim(),
6619
- proposed_summary: buildRunnerSmallTalkReply({ route, executionPlan }),
6620
6621
  },
6621
6622
  execution_override: executionOverride,
6622
6623
  };
6623
6624
  }
6625
+ /* Dead legacy direct small_talk branch kept commented for reference.
6624
6626
  if (false && normalizedIntentType === "small_talk") {
6625
6627
  return {
6626
6628
  handled: true,
@@ -6628,6 +6630,7 @@ async function resolveInformationalQueryReply({
6628
6630
  source: "small_talk",
6629
6631
  };
6630
6632
  }
6633
+ */
6631
6634
  if (normalizedIntentType === "workspace_query") {
6632
6635
  const workspace = resolveProjectWorkspaceBindingSummary(route?.projectID, executionPlan?.workspaceDir || route?.workspaceDir || "");
6633
6636
  const workspaceDir = String(workspace.workspace_dir || "").trim();
@@ -6641,7 +6644,6 @@ async function resolveInformationalQueryReply({
6641
6644
  source: "project.workspace",
6642
6645
  lookup: {
6643
6646
  ...workspace,
6644
- proposed_summary: reply,
6645
6647
  },
6646
6648
  execution_override: executionOverride,
6647
6649
  };
@@ -6660,7 +6662,6 @@ async function resolveInformationalQueryReply({
6660
6662
  source: "project.bot_roles",
6661
6663
  lookup: {
6662
6664
  ...payload,
6663
- proposed_summary: buildProjectBotRolesText(payload),
6664
6665
  },
6665
6666
  execution_override: executionOverride,
6666
6667
  };
@@ -6730,7 +6731,6 @@ async function resolveInformationalQueryReply({
6730
6731
  source: "project.file.locate",
6731
6732
  lookup: {
6732
6733
  ...payload,
6733
- proposed_summary: buildProjectFileLocateText(payload),
6734
6734
  },
6735
6735
  execution_override: executionOverride,
6736
6736
  };
@@ -14394,21 +14394,6 @@ async function runSelftest(flags = {}) {
14394
14394
  String(parsedEnv.SLACK_BOT_TOKEN || "") === "xoxb-test",
14395
14395
  `token=${String(parsedEnv.SLACK_BOT_TOKEN || "(missing)")}`,
14396
14396
  );
14397
- const monitorGreeting = buildRunnerSmallTalkReply({
14398
- route: { botName: "RyoAI_bot", roleProfile: "monitor" },
14399
- executionPlan: { roleProfileName: "monitor" },
14400
- });
14401
- const reviewGreeting = buildRunnerSmallTalkReply({
14402
- route: { botName: "RyoAI2_bot", roleProfile: "review" },
14403
- executionPlan: { roleProfileName: "review" },
14404
- });
14405
- push(
14406
- "small_talk_reply_varies_by_bot_and_role",
14407
- monitorGreeting.includes("RyoAI_bot")
14408
- && reviewGreeting.includes("RyoAI2_bot")
14409
- && monitorGreeting !== reviewGreeting,
14410
- `monitor=${monitorGreeting} review=${reviewGreeting}`,
14411
- );
14412
14397
  const informationalMiniReply = await resolveInformationalQueryReply({
14413
14398
  intentType: "small_talk",
14414
14399
  route: { botName: "RyoAI_bot", role: "monitor", roleProfile: "monitor" },
@@ -14441,6 +14426,7 @@ async function runSelftest(flags = {}) {
14441
14426
  safeObject(informationalMiniReply).handled === true
14442
14427
  && String(safeObject(informationalMiniReply).response_mode || "") === "lookup_only"
14443
14428
  && String(safeObject(informationalMiniReply).reply || "") === ""
14429
+ && !Object.prototype.hasOwnProperty.call(safeObject(safeObject(informationalMiniReply).lookup), "proposed_summary")
14444
14430
  && String(safeObject(safeObject(informationalMiniReply).execution_override).role_profile?.client || "") === "gpt"
14445
14431
  && String(safeObject(safeObject(informationalMiniReply).execution_override).role_profile?.model || "") === String(expectedInformationalModel || "")
14446
14432
  && String(safeObject(safeObject(informationalMiniReply).execution_override).role_profile?.permissionMode || "") === "read_only"
@@ -1786,9 +1786,6 @@ export function buildLocalBotPrompt(payload, { terse = true } = {}) {
1786
1786
  if (queryLookupResponseMode) {
1787
1787
  lines.push(`- Response mode: ${queryLookupResponseMode}`);
1788
1788
  }
1789
- if (String(queryLookup.proposed_reply || "").trim()) {
1790
- lines.push(`- Proposed factual reply: ${String(queryLookup.proposed_reply || "").trim()}`);
1791
- }
1792
1789
  if (queryLookupFacts != null) {
1793
1790
  lines.push("Structured lookup facts:");
1794
1791
  lines.push(JSON.stringify(queryLookupFacts, null, 2));
@@ -1994,7 +1991,7 @@ export function buildLocalBotPrompt(payload, { terse = true } = {}) {
1994
1991
  String(conversation.intent_mode || "").trim() === "delegated_single_lead"
1995
1992
  ? (selfIsLeadBot
1996
1993
  ? "This bot is the lead bot for a delegated public collaboration. It may assign work publicly only to allowed responders, and it may not expand the participant set."
1997
- : "This bot is not the lead bot. Respond only when the lead bot or the human explicitly addresses this bot, and do not start peer-to-peer chains.")
1994
+ : "This bot is not the lead bot. Prefer replying when the human, the lead bot, or another managed bot explicitly addresses this bot in the live room context. Do not expand the participant set beyond the allowed responders.")
1998
1995
  : "Use the human conversation contract as the source of truth for who may reply.",
1999
1996
  conversation.allow_bot_to_bot === true
2000
1997
  ? "If another bot explicitly mentioned you and you are in the allowed responders list, you may answer that bot publicly in the room."
@@ -3331,15 +3331,6 @@ async function resolvePublicConversationContext({
3331
3331
  },
3332
3332
  { currentBotSelector: senderBotSelector, excludeCurrentTargetAssignments: false },
3333
3333
  );
3334
- const assignmentTargets = uniqueOrdered(
3335
- ensureArray(executionContract?.assignments)
3336
- .map((item) => normalizeMentionSelector(item.targetBot))
3337
- .filter(Boolean),
3338
- );
3339
- const contractNextResponders = uniqueOrdered([
3340
- ...ensureArray(executionContract?.nextResponders).map((item) => normalizeMentionSelector(item)).filter(Boolean),
3341
- normalizeMentionSelector(executionContract?.summaryBot),
3342
- ]);
3343
3334
  if (!hasActiveRequest && String(session.status || "").trim() === "closed") {
3344
3335
  return {
3345
3336
  mode: "public_multi_bot",
@@ -3496,130 +3487,15 @@ async function resolvePublicConversationContext({
3496
3487
  session,
3497
3488
  };
3498
3489
  }
3499
- if (!executionContract || executionContract.actionable !== true) {
3500
- return {
3501
- mode: "public_multi_bot",
3502
- id: String(parsed.conversationID || "").trim(),
3503
- stage: "ignored_non_actionable_bot_reply",
3504
- skip: true,
3505
- reason: "bot reply did not include an actionable execution contract",
3506
- intentMode,
3507
- allowBotToBot,
3508
- participants: buildConversationParticipantViews(participants, peerMap),
3509
- participantSelectors: participants,
3510
- allowedResponders: buildConversationParticipantViews(normalizedAllowedResponders, peerMap),
3511
- allowedResponderSelectors: normalizedAllowedResponders,
3512
- summaryBotUsername: summaryBotSelector,
3513
- executionContract,
3514
- policy,
3515
- session,
3516
- };
3517
- }
3518
- if (intentMode === "delegated_single_lead" && normalizedLeadBotSelector) {
3519
- const senderIsLeadBot = senderBotSelector === normalizedLeadBotSelector;
3520
- const currentIsLeadBot = currentBotSelector === normalizedLeadBotSelector;
3521
- if (senderIsLeadBot) {
3522
- if (currentIsLeadBot) {
3523
- return {
3524
- mode: "public_multi_bot",
3525
- id: String(parsed.conversationID || "").trim(),
3526
- stage: "ignored_lead_waits_for_peer",
3527
- skip: true,
3528
- reason: "delegated single-lead conversation waits for a peer bot after the lead bot issues public instructions",
3529
- intentMode,
3530
- allowBotToBot,
3531
- participants: buildConversationParticipantViews(participants, peerMap),
3532
- participantSelectors: participants,
3533
- allowedResponders: buildConversationParticipantViews(normalizedAllowedResponders, peerMap),
3534
- allowedResponderSelectors: normalizedAllowedResponders,
3535
- summaryBotUsername: summaryBotSelector,
3536
- policy,
3537
- session,
3538
- };
3539
- }
3540
- if (executionContract.type !== "delegation" || !assignmentTargets.includes(currentBotSelector)) {
3541
- return {
3542
- mode: "public_multi_bot",
3543
- id: String(parsed.conversationID || "").trim(),
3544
- stage: "ignored_unaddressed_peer",
3545
- skip: true,
3546
- reason: "lead bot reply did not include an actionable assignment for this peer bot",
3547
- intentMode,
3548
- allowBotToBot,
3549
- participants: buildConversationParticipantViews(participants, peerMap),
3550
- participantSelectors: participants,
3551
- allowedResponders: buildConversationParticipantViews(normalizedAllowedResponders, peerMap),
3552
- allowedResponderSelectors: normalizedAllowedResponders,
3553
- summaryBotUsername: summaryBotSelector,
3554
- executionContract,
3555
- policy,
3556
- session,
3557
- };
3558
- }
3559
- } else if (currentIsLeadBot) {
3560
- if (!contractNextResponders.includes(currentBotSelector)) {
3561
- return {
3562
- mode: "public_multi_bot",
3563
- id: String(parsed.conversationID || "").trim(),
3564
- stage: "ignored_peer_without_lead_call",
3565
- skip: true,
3566
- reason: "peer reply did not request follow-up from the lead or summary bot",
3567
- intentMode,
3568
- allowBotToBot,
3569
- participants: buildConversationParticipantViews(participants, peerMap),
3570
- participantSelectors: participants,
3571
- allowedResponders: buildConversationParticipantViews(normalizedAllowedResponders, peerMap),
3572
- allowedResponderSelectors: normalizedAllowedResponders,
3573
- summaryBotUsername: summaryBotSelector,
3574
- executionContract,
3575
- policy,
3576
- session,
3577
- };
3578
- }
3579
- } else {
3580
- return {
3581
- mode: "public_multi_bot",
3582
- id: String(parsed.conversationID || "").trim(),
3583
- stage: "ignored_peer_to_peer_chain",
3584
- skip: true,
3585
- reason: "delegated single-lead conversation routes peer replies back to the lead bot only",
3586
- intentMode,
3587
- allowBotToBot,
3588
- participants: buildConversationParticipantViews(participants, peerMap),
3589
- participantSelectors: participants,
3590
- allowedResponders: buildConversationParticipantViews(normalizedAllowedResponders, peerMap),
3591
- allowedResponderSelectors: normalizedAllowedResponders,
3592
- summaryBotUsername: summaryBotSelector,
3593
- executionContract,
3594
- policy,
3595
- session,
3596
- };
3597
- }
3598
- }
3599
- const currentBotIsContractTarget = assignmentTargets.includes(currentBotSelector) || contractNextResponders.includes(currentBotSelector);
3600
- if (!currentBotIsContractTarget) {
3601
- return {
3602
- mode: "public_multi_bot",
3603
- id: String(parsed.conversationID || "").trim(),
3604
- stage: "ignored_unassigned_bot_reply",
3605
- skip: true,
3606
- reason: "execution contract did not target this bot",
3607
- intentMode,
3608
- allowBotToBot,
3609
- participants: buildConversationParticipantViews(participants, peerMap),
3610
- participantSelectors: participants,
3611
- allowedResponders: buildConversationParticipantViews(normalizedAllowedResponders, peerMap),
3612
- allowedResponderSelectors: normalizedAllowedResponders,
3613
- summaryBotUsername: summaryBotSelector,
3614
- executionContract,
3615
- policy,
3616
- session,
3617
- };
3618
- }
3619
- return {
3620
- mode: "public_multi_bot",
3621
- id: String(parsed.conversationID || "").trim(),
3622
- stage: "bot_reply",
3490
+ // For public multi-bot bot replies, let the client AI decide whether the
3491
+ // latest room message is a real delegation/follow-up. The runtime keeps only
3492
+ // structural guards here (participant membership, allowed responders,
3493
+ // self-reply, closed/expired sessions). Semantic contract interpretation is
3494
+ // intentionally deferred to the AI layer.
3495
+ return {
3496
+ mode: "public_multi_bot",
3497
+ id: String(parsed.conversationID || "").trim(),
3498
+ stage: "bot_reply",
3623
3499
  intentMode,
3624
3500
  allowBotToBot,
3625
3501
  participants: buildConversationParticipantViews(participants, peerMap),
@@ -296,7 +296,6 @@ export function buildRunnerInputPayload({
296
296
  handled: true,
297
297
  source: String(safeDirectQueryReply.source || "").trim(),
298
298
  response_mode: String(safeDirectQueryReply.response_mode || "").trim(),
299
- proposed_reply: String(safeDirectQueryReply.reply || "").trim(),
300
299
  facts: Object.prototype.hasOwnProperty.call(safeDirectQueryReply, "lookup")
301
300
  ? directQueryReply.lookup
302
301
  : null,
@@ -8233,14 +8233,14 @@ export async function runSelftestRunnerScenarios(push, deps) {
8233
8233
  },
8234
8234
  });
8235
8235
  push(
8236
- "delegated_single_lead_blocks_peer_to_peer_chain",
8237
- processed.kind === "skipped"
8238
- && aiCalls === 0
8239
- && /lead bot only|lead bot/i.test(String(processed.skippedRecord?.reason || "")),
8240
- `kind=${String(processed.kind || "(none)")} ai_calls=${aiCalls} reason=${String(processed.skippedRecord?.reason || "(none)")}`,
8236
+ "delegated_single_lead_peer_to_peer_reply_reaches_ai_decision",
8237
+ processed.kind === "replied"
8238
+ && aiCalls === 1
8239
+ && String(processed.result?.execution_contract_type || "") === "summary_request",
8240
+ `kind=${String(processed.kind || "(none)")} ai_calls=${aiCalls} contract=${String(processed.result?.execution_contract_type || "(none)")} reason=${String(processed.skippedRecord?.reason || "(none)")}`,
8241
8241
  );
8242
8242
  } catch (err) {
8243
- push("delegated_single_lead_blocks_peer_to_peer_chain", false, String(err?.message || err));
8243
+ push("delegated_single_lead_peer_to_peer_reply_reaches_ai_decision", false, String(err?.message || err));
8244
8244
  }
8245
8245
 
8246
8246
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "metheus-governance-mcp-cli",
3
- "version": "0.2.201",
3
+ "version": "0.2.202",
4
4
  "description": "Metheus Governance MCP CLI (setup + stdio proxy)",
5
5
  "type": "module",
6
6
  "files": [