metheus-governance-mcp-cli 0.2.207 → 0.2.208

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
@@ -2623,7 +2623,7 @@ function inferRunnerRequestClaimIntent(selectedRecord) {
2623
2623
  if (looksLikeRunnerClaimQuestion(rawText) && normalizedText.split(/\s+/).filter(Boolean).length <= 8) {
2624
2624
  return "status_query";
2625
2625
  }
2626
- return "general_execution";
2626
+ return "";
2627
2627
  }
2628
2628
 
2629
2629
  function resolveRunnerRequestClaimIntent({
@@ -2647,6 +2647,16 @@ function buildSyntheticReplyChainConversationID(normalizedRoute, chatID, anchorM
2647
2647
  return `reply_chain:${provider}:${normalizedChatID}:${normalizedAnchorMessageID}`;
2648
2648
  }
2649
2649
 
2650
+ function buildSyntheticHumanOpeningConversationID(normalizedRoute, chatID, messageID) {
2651
+ const provider = String(normalizedRoute?.provider || "").trim() || "unknown";
2652
+ const normalizedChatID = String(chatID || "").trim() || "-";
2653
+ const normalizedMessageID = intFromRawAllowZero(messageID, 0);
2654
+ if (normalizedMessageID <= 0) {
2655
+ return "";
2656
+ }
2657
+ return `human_opening:${provider}:${normalizedChatID}:${normalizedMessageID}`;
2658
+ }
2659
+
2650
2660
  function findRunnerRequestsForScope(state, normalizedRoute, selectors = {}) {
2651
2661
  const requests = normalizeBotRunnerRequests(state?.requests);
2652
2662
  const projectID = String(normalizedRoute?.projectID || "").trim();
@@ -3259,13 +3269,17 @@ async function claimRunnerRequestForHumanComment({
3259
3269
  normalizedIntent,
3260
3270
  selectedRecord,
3261
3271
  });
3262
- const requestKey = buildRunnerRequestKey({
3272
+ let stateForClaim = safeObject(replyChainResolution.state);
3273
+ const normalizedSharedHumanIntent = safeObject(sharedHumanIntent);
3274
+ const provisionalNormalizedIntent = String(
3275
+ normalizedSharedHumanIntent.intentType || resolvedNormalizedIntent || "",
3276
+ ).trim().toLowerCase();
3277
+ const provisionalRequestKey = buildRunnerRequestKey({
3263
3278
  normalizedRoute,
3264
3279
  selectedRecord,
3265
3280
  selectedBotUsernames,
3266
- normalizedIntent: resolvedNormalizedIntent,
3281
+ normalizedIntent: provisionalNormalizedIntent,
3267
3282
  });
3268
- let stateForClaim = safeObject(replyChainResolution.state);
3269
3283
  const baseConversationID = String(
3270
3284
  parsed.conversationID
3271
3285
  || replyChainContext.conversationID
@@ -3285,9 +3299,6 @@ async function claimRunnerRequestForHumanComment({
3285
3299
  requests: backfilled.requests,
3286
3300
  };
3287
3301
  }
3288
- const requests = normalizeBotRunnerRequests(stateForClaim.requests);
3289
- const existing = safeObject(requests[requestKey]);
3290
- const normalizedSharedHumanIntent = safeObject(sharedHumanIntent);
3291
3302
  const currentMessageID = intFromRawAllowZero(parsed.messageID, 0);
3292
3303
  let sharedConversationSource = currentMessageID > 0
3293
3304
  ? pickRunnerSharedConversationSourceRequest(
@@ -3295,7 +3306,7 @@ async function claimRunnerRequestForHumanComment({
3295
3306
  chatID: String(parsed.chatID || parsed.chatId || "").trim(),
3296
3307
  messageID: currentMessageID,
3297
3308
  }),
3298
- requestKey,
3309
+ provisionalRequestKey,
3299
3310
  )
3300
3311
  : {};
3301
3312
  if (
@@ -3309,14 +3320,38 @@ async function claimRunnerRequestForHumanComment({
3309
3320
  runtime,
3310
3321
  chatID: String(parsed.chatID || parsed.chatId || "").trim(),
3311
3322
  messageID: currentMessageID,
3312
- excludeRequestKey: requestKey,
3323
+ excludeRequestKey: provisionalRequestKey,
3313
3324
  }));
3314
3325
  }
3315
3326
  const resolvedConversationID = String(
3316
3327
  baseConversationID
3317
3328
  || sharedConversationSource.conversation_id
3329
+ || (
3330
+ Object.keys(normalizedSharedHumanIntent).length > 0
3331
+ ? buildSyntheticHumanOpeningConversationID(
3332
+ normalizedRoute,
3333
+ String(parsed.chatID || parsed.chatId || "").trim(),
3334
+ currentMessageID,
3335
+ )
3336
+ : ""
3337
+ )
3318
3338
  || "",
3319
3339
  ).trim();
3340
+ const preferredNormalizedIntent = String(
3341
+ normalizedSharedHumanIntent.intentType
3342
+ || sharedConversationSource.normalized_intent
3343
+ || referencedRequest.normalized_intent
3344
+ || resolvedNormalizedIntent
3345
+ || "",
3346
+ ).trim().toLowerCase();
3347
+ const requestKey = buildRunnerRequestKey({
3348
+ normalizedRoute,
3349
+ selectedRecord,
3350
+ selectedBotUsernames,
3351
+ normalizedIntent: preferredNormalizedIntent,
3352
+ });
3353
+ const requests = normalizeBotRunnerRequests(stateForClaim.requests);
3354
+ const existing = safeObject(requests[requestKey]);
3320
3355
  if (isFinalRunnerRequestStatus(existing.status)) {
3321
3356
  return {
3322
3357
  ok: false,
@@ -3412,10 +3447,10 @@ async function claimRunnerRequestForHumanComment({
3412
3447
  ? sharedConversationSource.next_expected_responders
3413
3448
  : ensureArray(referencedRequest.next_expected_responders).length
3414
3449
  ? referencedRequest.next_expected_responders
3415
- : normalizedSharedHumanIntent.initialResponderSelectors,
3450
+ : [],
3416
3451
  normalizeTelegramMentionUsername,
3417
3452
  ),
3418
- normalized_intent: resolvedNormalizedIntent,
3453
+ normalized_intent: preferredNormalizedIntent,
3419
3454
  status: "claimed",
3420
3455
  claimed_by_route: String(routeKey || "").trim(),
3421
3456
  claimed_at: firstNonEmptyString([existing.claimed_at, nowISO]) || nowISO,
@@ -949,7 +949,7 @@ function normalizeExecutionContract(rawContract) {
949
949
  || contract.target_summary_bot
950
950
  || "",
951
951
  ).trim().replace(/^@+/, "").toLowerCase();
952
- const nextResponders = uniqueOrdered(
952
+ const explicitNextResponders = uniqueOrdered(
953
953
  ensureArray(contract.next_responders || contract.nextResponders || contract.responders)
954
954
  .map((item) => String(item || "").trim().replace(/^@+/, "").toLowerCase())
955
955
  .filter(Boolean),
@@ -962,6 +962,13 @@ function normalizeExecutionContract(rawContract) {
962
962
  ].includes(type)
963
963
  ? type
964
964
  : "";
965
+ const nextResponders = explicitNextResponders.length > 0
966
+ ? explicitNextResponders
967
+ : normalizedType === "delegation"
968
+ ? uniqueOrdered(assignments.map((item) => String(item.target_bot || item.targetBot || "").trim().replace(/^@+/, "").toLowerCase()).filter(Boolean))
969
+ : normalizedType === "summary_request" && summaryBot
970
+ ? [summaryBot]
971
+ : [];
965
972
  const actionable = contract.actionable === true
966
973
  || (normalizedType === "delegation" && assignments.length > 0)
967
974
  || (normalizedType === "summary_request" && Boolean(summaryBot))
@@ -101,11 +101,18 @@ function normalizeExecutionContractForArchive(rawContract) {
101
101
  })
102
102
  .filter(Boolean);
103
103
  const summaryBot = normalizeMentionUsername(contract.summary_bot || contract.summaryBot || "");
104
- const nextResponders = Array.from(new Set(
104
+ const explicitNextResponders = Array.from(new Set(
105
105
  ensureArray(contract.next_responders || contract.nextResponders || contract.responders)
106
106
  .map((item) => normalizeMentionUsername(item))
107
107
  .filter(Boolean),
108
108
  ));
109
+ const nextResponders = explicitNextResponders.length > 0
110
+ ? explicitNextResponders
111
+ : type === "delegation"
112
+ ? Array.from(new Set(assignments.map((item) => normalizeMentionUsername(item.target_bot)).filter(Boolean)))
113
+ : type === "summary_request" && summaryBot
114
+ ? [summaryBot]
115
+ : [];
109
116
  const actionable = contract.actionable === true;
110
117
  if (!type && !assignments.length && !summaryBot && !nextResponders.length && !actionable) {
111
118
  return null;
@@ -1109,14 +1109,26 @@ function buildHumanIntentFromPersistedRunnerRequest({
1109
1109
  .filter((item) => item && (managedSelectors.size === 0 || managedSelectors.has(item))),
1110
1110
  );
1111
1111
  const intentMode = String(persistedRequest.conversation_intent_mode || "").trim();
1112
- const intentType = normalizeHumanIntentType(
1112
+ const persistedReplyExpectation = normalizeReplyExpectation(
1113
+ persistedRequest.conversation_reply_expectation,
1114
+ "",
1115
+ );
1116
+ const persistedExecutionActionable = persistedRequest.execution_contract_actionable === true;
1117
+ const persistedNormalizedIntent = normalizeHumanIntentType(
1113
1118
  persistedRequest.normalized_intent || persistedRequest.intent_type,
1114
1119
  "",
1115
1120
  );
1116
- const replyExpectation = normalizeReplyExpectation(
1117
- persistedRequest.conversation_reply_expectation,
1121
+ const intentType = normalizeHumanIntentType(
1122
+ (
1123
+ persistedNormalizedIntent === "general_execution"
1124
+ && persistedReplyExpectation !== "actionable"
1125
+ && !persistedExecutionActionable
1126
+ )
1127
+ ? ""
1128
+ : persistedNormalizedIntent,
1118
1129
  "",
1119
1130
  );
1131
+ const replyExpectation = persistedReplyExpectation;
1120
1132
  const participantSelectors = normalizeManagedSelectors(persistedRequest.conversation_participants);
1121
1133
  const initialResponderSelectors = normalizeManagedSelectors(persistedRequest.conversation_initial_responders);
1122
1134
  const allowedResponderSelectors = normalizeManagedSelectors(persistedRequest.conversation_allowed_responders);
@@ -1261,7 +1273,7 @@ function buildDirectHumanResponseContract({
1261
1273
  }
1262
1274
  }
1263
1275
  const requiresActionableContract = (
1264
- (replyExpectation === "actionable" || intentMode === "delegated_single_lead")
1276
+ replyExpectation === "actionable"
1265
1277
  && Boolean(currentBotSelector)
1266
1278
  && initialResponderSelectors.includes(currentBotSelector)
1267
1279
  );
@@ -3307,11 +3319,18 @@ function normalizeConversationExecutionContract(
3307
3319
  || contract.summary_bot
3308
3320
  || conversationContext?.summaryBotUsername,
3309
3321
  );
3310
- const nextResponders = uniqueOrdered(
3311
- ensureArray(contract.nextResponders || contract.next_responders || contract.responders)
3312
- .map((item) => normalizeMentionSelector(item))
3313
- .filter((item) => !allowedResponderSet.size || allowedResponderSet.has(item)),
3314
- );
3322
+ const explicitNextResponders = uniqueOrdered(
3323
+ ensureArray(contract.nextResponders || contract.next_responders || contract.responders)
3324
+ .map((item) => normalizeMentionSelector(item))
3325
+ .filter((item) => !allowedResponderSet.size || allowedResponderSet.has(item)),
3326
+ );
3327
+ const nextResponders = explicitNextResponders.length > 0
3328
+ ? explicitNextResponders
3329
+ : normalizedType === "delegation"
3330
+ ? uniqueOrdered(assignments.map((item) => normalizeMentionSelector(item.targetBot)).filter(Boolean))
3331
+ : normalizedType === "summary_request" && summaryBot
3332
+ ? [summaryBot]
3333
+ : [];
3315
3334
  const actionable = contract.actionable === true
3316
3335
  || (normalizedType === "delegation" && assignments.length > 0)
3317
3336
  || (normalizedType === "summary_request" && Boolean(summaryBot || nextResponders.length))
@@ -3386,11 +3405,18 @@ function normalizeResponseExecutionContract(rawContract, responseContract, { cur
3386
3405
  contract.summaryBot
3387
3406
  || contract.summary_bot,
3388
3407
  );
3389
- const nextResponders = uniqueOrdered(
3408
+ const explicitNextResponders = uniqueOrdered(
3390
3409
  ensureArray(contract.nextResponders || contract.next_responders || contract.responders)
3391
3410
  .map((item) => normalizeMentionSelector(item))
3392
3411
  .filter(Boolean),
3393
3412
  );
3413
+ const nextResponders = explicitNextResponders.length > 0
3414
+ ? explicitNextResponders
3415
+ : normalizedType === "delegation"
3416
+ ? uniqueOrdered(assignments.map((item) => normalizeMentionSelector(item.targetBot)).filter(Boolean))
3417
+ : normalizedType === "summary_request" && summaryBot
3418
+ ? [summaryBot]
3419
+ : [];
3394
3420
  const actionable = contract.actionable === true
3395
3421
  || (normalizedType === "delegation" && assignments.length > 0)
3396
3422
  || (normalizedType === "summary_request" && Boolean(summaryBot || nextResponders.length))
@@ -3411,7 +3437,7 @@ function normalizeResponseExecutionContract(rawContract, responseContract, { cur
3411
3437
  };
3412
3438
  }
3413
3439
 
3414
- function buildImplicitSummaryRequestContract(conversationContext, currentBotSelector) {
3440
+ function buildImplicitSummaryRequestContract(conversationContext, currentBotSelector) {
3415
3441
  if (String(conversationContext?.mode || "").trim() !== "public_multi_bot") {
3416
3442
  return null;
3417
3443
  }
@@ -3426,15 +3452,45 @@ function buildImplicitSummaryRequestContract(conversationContext, currentBotSele
3426
3452
  if (!summaryBotSelector || !currentSelector || summaryBotSelector === currentSelector) {
3427
3453
  return null;
3428
3454
  }
3429
- return {
3430
- type: "summary_request",
3431
- actionable: true,
3432
- assignments: [],
3433
- summaryBot: summaryBotSelector,
3434
- nextResponders: [summaryBotSelector],
3435
- implicit: true,
3436
- };
3437
- }
3455
+ return {
3456
+ type: "summary_request",
3457
+ actionable: true,
3458
+ assignments: [],
3459
+ summaryBot: summaryBotSelector,
3460
+ nextResponders: [summaryBotSelector],
3461
+ implicit: true,
3462
+ };
3463
+ }
3464
+
3465
+ function collectExecutionContractNextResponders(executionContract) {
3466
+ const contract = safeObject(executionContract);
3467
+ const normalizedType = String(
3468
+ contract.type
3469
+ || contract.contract_type
3470
+ || contract.contractType
3471
+ || "",
3472
+ ).trim().toLowerCase();
3473
+ const explicitNextResponders = uniqueOrdered(
3474
+ ensureArray(contract.nextResponders || contract.next_responders || contract.responders)
3475
+ .map((item) => normalizeMentionSelector(item))
3476
+ .filter(Boolean),
3477
+ );
3478
+ if (explicitNextResponders.length > 0) {
3479
+ return explicitNextResponders;
3480
+ }
3481
+ if (normalizedType === "delegation") {
3482
+ return uniqueOrdered(
3483
+ ensureArray(contract.assignments)
3484
+ .map((item) => normalizeMentionSelector(safeObject(item).targetBot || safeObject(item).target_bot))
3485
+ .filter(Boolean),
3486
+ );
3487
+ }
3488
+ const summaryBot = normalizeMentionSelector(contract.summaryBot || contract.summary_bot);
3489
+ if (normalizedType === "summary_request" && summaryBot) {
3490
+ return [summaryBot];
3491
+ }
3492
+ return [];
3493
+ }
3438
3494
 
3439
3495
  function conversationSessionIsExpired(session, policy, nowMs = Date.now()) {
3440
3496
  const expiresAtMs = parseISOStringMs(safeObject(session).expires_at);
@@ -4866,6 +4922,24 @@ export async function processRunnerSelectedRecord({
4866
4922
  .filter(Boolean),
4867
4923
  );
4868
4924
  let requiresActionableContract = safeObject(aiPayload.response_contract).require_actionable_contract === true;
4925
+ const normalizedConversationInitialResponders = uniqueOrdered(
4926
+ ensureArray(conversationContext?.initialResponderSelectors)
4927
+ .map((item) => normalizeMentionSelector(item))
4928
+ .filter(Boolean),
4929
+ );
4930
+ const normalizedConversationAllowedResponders = uniqueOrdered(
4931
+ ensureArray(conversationContext?.allowedResponderSelectors)
4932
+ .map((item) => normalizeMentionSelector(item))
4933
+ .filter(Boolean),
4934
+ );
4935
+ const peerAllowedResponders = normalizedConversationAllowedResponders.filter((item) => item && item !== currentBotSelector);
4936
+ const requiresPeerDelegationContract = conversationContext?.mode === "public_multi_bot"
4937
+ && String(conversationContext?.stage || "").trim() === "human_opening"
4938
+ && conversationContext?.allowBotToBot === true
4939
+ && Boolean(currentBotSelector)
4940
+ && normalizedConversationInitialResponders.length === 1
4941
+ && normalizedConversationInitialResponders.includes(currentBotSelector)
4942
+ && peerAllowedResponders.length > 0;
4869
4943
  const directHumanPeerMap = humanIntentContext?.peerMap instanceof Map
4870
4944
  ? humanIntentContext.peerMap
4871
4945
  : buildConversationPeerMap(bot, normalizedRoute, executionDeps);
@@ -4883,6 +4957,10 @@ export async function processRunnerSelectedRecord({
4883
4957
  if (delegatedBotMentions.length > 0) {
4884
4958
  allowedActionableTypes = new Set(["delegation"]);
4885
4959
  }
4960
+ if (requiresPeerDelegationContract) {
4961
+ allowedActionableTypes = new Set(["delegation"]);
4962
+ requiresActionableContract = true;
4963
+ }
4886
4964
  let hasValidActionableContract = Boolean(
4887
4965
  executionContract
4888
4966
  && executionContract.actionable === true
@@ -4923,7 +5001,7 @@ export async function processRunnerSelectedRecord({
4923
5001
  allow_skip: false,
4924
5002
  must_reply: true,
4925
5003
  require_actionable_contract: true,
4926
- human_intent_mode: effectiveResponseContractPayload.human_intent_mode || (delegatedBotMentions.length > 0 ? "delegated_single_lead" : ""),
5004
+ human_intent_mode: effectiveResponseContractPayload.human_intent_mode || ((delegatedBotMentions.length > 0 || requiresPeerDelegationContract) ? "delegated_single_lead" : ""),
4927
5005
  human_lead_bot: delegatedBotMentions.length > 0
4928
5006
  ? currentBotSelector
4929
5007
  : String(effectiveResponseContractPayload.human_lead_bot || "").trim(),
@@ -4934,10 +5012,10 @@ export async function processRunnerSelectedRecord({
4934
5012
  ? ensureArray(effectiveResponseContractPayload.human_allowed_responders)
4935
5013
  : uniqueOrdered([
4936
5014
  currentBotSelector,
4937
- ...delegatedBotMentions,
5015
+ ...(delegatedBotMentions.length > 0 ? delegatedBotMentions : peerAllowedResponders),
4938
5016
  ].filter(Boolean)),
4939
- allow_bot_to_bot: delegatedBotMentions.length > 0 || effectiveResponseContractPayload.human_intent_mode === "delegated_single_lead",
4940
- allowed_contract_types: delegatedBotMentions.length > 0
5017
+ allow_bot_to_bot: delegatedBotMentions.length > 0 || requiresPeerDelegationContract || effectiveResponseContractPayload.human_intent_mode === "delegated_single_lead",
5018
+ allowed_contract_types: delegatedBotMentions.length > 0 || requiresPeerDelegationContract
4941
5019
  ? ["delegation", "summary_request", "final_summary"]
4942
5020
  : ensureArray(effectiveResponseContractPayload.allowed_contract_types).length
4943
5021
  ? ensureArray(effectiveResponseContractPayload.allowed_contract_types)
@@ -5256,10 +5334,7 @@ export async function processRunnerSelectedRecord({
5256
5334
  last_execution_contract_type: String(executionContract?.type || "").trim(),
5257
5335
  last_execution_contract_actionable: executionContract?.actionable === true,
5258
5336
  last_execution_contract_targets: ensureArray(executionContract?.assignments).map((item) => normalizeMentionSelector(item.targetBot)).filter(Boolean),
5259
- next_expected_responders: uniqueOrdered([
5260
- ...ensureArray(executionContract?.nextResponders).map((item) => normalizeMentionSelector(item)).filter(Boolean),
5261
- normalizeMentionSelector(executionContract?.summaryBot),
5262
- ]),
5337
+ next_expected_responders: collectExecutionContractNextResponders(executionContract),
5263
5338
  last_speaker_bot_username: currentBotSelector,
5264
5339
  speaker_counts: speakerCounts,
5265
5340
  last_sender_bot_username: String(effectiveConversationContext?.senderBotUsername || "").trim(),
@@ -5355,10 +5430,7 @@ export async function processRunnerSelectedRecord({
5355
5430
  execution_contract_type: String(executionContract?.type || "").trim(),
5356
5431
  execution_contract_actionable: executionContract?.actionable === true,
5357
5432
  execution_contract_targets: ensureArray(executionContract?.assignments).map((item) => normalizeMentionSelector(item.targetBot)).filter(Boolean),
5358
- next_expected_responders: uniqueOrdered([
5359
- ...ensureArray(executionContract?.nextResponders).map((item) => normalizeMentionSelector(item)).filter(Boolean),
5360
- normalizeMentionSelector(executionContract?.summaryBot),
5361
- ]),
5433
+ next_expected_responders: collectExecutionContractNextResponders(executionContract),
5362
5434
  artifact_validation: String(artifactValidation.status || "").trim() || "none",
5363
5435
  artifact_paths: summarizeValidatedArtifactPaths(artifactValidation),
5364
5436
  ctxpack_version_id: String(safeObject(aiResult?.ctxpackUpdate).version_id || "").trim(),
@@ -1569,9 +1569,9 @@ export async function runSelftestRunnerScenarios(push, deps) {
1569
1569
  });
1570
1570
  const inferredExecutionRequest = safeObject(safeObject(loadBotRunnerState().requests)[inferredExecutionClaim.requestKey]);
1571
1571
  push(
1572
- "runner_request_claim_defaults_actionable_messages_to_general_execution",
1572
+ "runner_request_claim_leaves_unclassified_messages_unresolved",
1573
1573
  inferredExecutionClaim.ok === true
1574
- && String(inferredExecutionRequest.normalized_intent || "") === "general_execution",
1574
+ && String(inferredExecutionRequest.normalized_intent || "") === "",
1575
1575
  `intent=${String(inferredExecutionRequest.normalized_intent || "(none)")} request=${String(inferredExecutionClaim.requestKey || "(none)")}`,
1576
1576
  );
1577
1577
 
@@ -4785,7 +4785,7 @@ export async function runSelftestRunnerScenarios(push, deps) {
4785
4785
  push(
4786
4786
  "direct_human_public_delegate_fallback_uses_response_allowed_responders",
4787
4787
  processed.kind === "replied"
4788
- && aiCalls === 1
4788
+ && aiCalls === 2
4789
4789
  && String(deliveredConversation[0]?.mode || "") === "public_multi_bot"
4790
4790
  && Array.isArray(deliveredConversation[0]?.allowedResponderSelectors)
4791
4791
  && deliveredConversation[0].allowedResponderSelectors.includes("ryoai3_bot")
@@ -5064,14 +5064,14 @@ export async function runSelftestRunnerScenarios(push, deps) {
5064
5064
  },
5065
5065
  });
5066
5066
  push(
5067
- "delegated_single_lead_lead_opening_requires_actionable_contract",
5067
+ "delegated_single_lead_lead_opening_requires_delegation_contract_for_peer_followup",
5068
5068
  processed.kind === "skipped"
5069
5069
  && aiCalls === 2
5070
- && /actionable execution contract/i.test(String(processed.skippedRecord?.reason || "")),
5071
- `kind=${String(processed.kind || "(none)")} ai_calls=${aiCalls} reason=${String(processed.skippedRecord?.reason || "(none)")}`,
5070
+ && !String(deliveredText || "").trim(),
5071
+ `kind=${String(processed.kind || "(none)")} ai_calls=${aiCalls} reply=${String(deliveredText || "(none)")}`,
5072
5072
  );
5073
5073
  } catch (err) {
5074
- push("delegated_single_lead_lead_opening_requires_actionable_contract", false, String(err?.message || err));
5074
+ push("delegated_single_lead_lead_opening_requires_delegation_contract_for_peer_followup", false, String(err?.message || err));
5075
5075
  }
5076
5076
 
5077
5077
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "metheus-governance-mcp-cli",
3
- "version": "0.2.207",
3
+ "version": "0.2.208",
4
4
  "description": "Metheus Governance MCP CLI (setup + stdio proxy)",
5
5
  "type": "module",
6
6
  "files": [