metheus-governance-mcp-cli 0.2.272 → 0.2.274
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
|
@@ -3333,37 +3333,46 @@ function normalizeBotRunnerConsumedComments(rawConsumed, nowMs = Date.now()) {
|
|
|
3333
3333
|
return normalized;
|
|
3334
3334
|
}
|
|
3335
3335
|
|
|
3336
|
-
function buildRunnerConsumedCommentLedgerKey(commentIDRaw, routeKeyRaw = "", commentKindRaw = "") {
|
|
3337
|
-
const commentID = String(commentIDRaw || "").trim();
|
|
3338
|
-
if (!commentID) return "";
|
|
3339
|
-
const routeKey = String(routeKeyRaw || "").trim();
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
const
|
|
3351
|
-
const ledgerKey = buildRunnerConsumedCommentLedgerKey(commentID,
|
|
3352
|
-
const directEntry = safeObject(consumedComments[ledgerKey]);
|
|
3353
|
-
if (Object.keys(directEntry).length) {
|
|
3354
|
-
return directEntry;
|
|
3355
|
-
}
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3336
|
+
function buildRunnerConsumedCommentLedgerKey(commentIDRaw, routeKeyRaw = "", commentKindRaw = "") {
|
|
3337
|
+
const commentID = String(commentIDRaw || "").trim();
|
|
3338
|
+
if (!commentID) return "";
|
|
3339
|
+
const routeKey = String(routeKeyRaw || "").trim();
|
|
3340
|
+
if (routeKey) {
|
|
3341
|
+
return `${commentID}::${routeKey}`;
|
|
3342
|
+
}
|
|
3343
|
+
return commentID;
|
|
3344
|
+
}
|
|
3345
|
+
|
|
3346
|
+
function findRunnerConsumedCommentEntry(rawConsumed, commentIDRaw, { routeKey = "", commentKind = "" } = {}) {
|
|
3347
|
+
const commentID = String(commentIDRaw || "").trim();
|
|
3348
|
+
if (!commentID) return {};
|
|
3349
|
+
const consumedComments = normalizeBotRunnerConsumedComments(rawConsumed);
|
|
3350
|
+
const normalizedRouteKey = String(routeKey || "").trim();
|
|
3351
|
+
const ledgerKey = buildRunnerConsumedCommentLedgerKey(commentID, normalizedRouteKey, commentKind);
|
|
3352
|
+
const directEntry = safeObject(consumedComments[ledgerKey]);
|
|
3353
|
+
if (Object.keys(directEntry).length) {
|
|
3354
|
+
return directEntry;
|
|
3355
|
+
}
|
|
3356
|
+
if (normalizedRouteKey) {
|
|
3357
|
+
const routeEntry = Object.values(consumedComments).find((entryRaw) => {
|
|
3358
|
+
const entry = safeObject(entryRaw);
|
|
3359
|
+
return String(entry.comment_id || "").trim() === commentID
|
|
3360
|
+
&& String(entry.route_key || "").trim() === normalizedRouteKey;
|
|
3361
|
+
});
|
|
3362
|
+
if (Object.keys(safeObject(routeEntry)).length > 0) {
|
|
3363
|
+
return safeObject(routeEntry);
|
|
3364
|
+
}
|
|
3365
|
+
}
|
|
3366
|
+
const legacyGlobalEntry = safeObject(consumedComments[commentID]);
|
|
3367
|
+
if (!Object.keys(legacyGlobalEntry).length) {
|
|
3368
|
+
return {};
|
|
3369
|
+
}
|
|
3370
|
+
const legacyRouteKey = String(legacyGlobalEntry.route_key || "").trim();
|
|
3371
|
+
if (normalizedRouteKey && legacyRouteKey && legacyRouteKey !== normalizedRouteKey) {
|
|
3372
|
+
return {};
|
|
3373
|
+
}
|
|
3374
|
+
return legacyGlobalEntry;
|
|
3375
|
+
}
|
|
3367
3376
|
|
|
3368
3377
|
function runnerRouteMatchesProjectConversationScope(candidateRouteRaw, normalizedRouteRaw) {
|
|
3369
3378
|
const candidateRoute = normalizeRunnerRoute(candidateRouteRaw);
|
|
@@ -51,6 +51,100 @@ function intFromRawAllowZero(raw, fallback = 0) {
|
|
|
51
51
|
return Number.isFinite(parsed) ? parsed : fallback;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
function buildRunnerArchiveSourceMessageKey(recordRaw) {
|
|
55
|
+
const parsed = safeObject(safeObject(recordRaw).parsedArchive);
|
|
56
|
+
const chatID = String(parsed.chatID || parsed.chatId || "").trim();
|
|
57
|
+
const messageID = intFromRawAllowZero(parsed.messageID || parsed.messageId, 0);
|
|
58
|
+
if (!chatID || !(messageID > 0)) {
|
|
59
|
+
return "";
|
|
60
|
+
}
|
|
61
|
+
return `${chatID}:${messageID}`;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function buildRunnerLocalInboundReceiptKey(receiptRaw) {
|
|
65
|
+
const receipt = safeObject(receiptRaw);
|
|
66
|
+
const chatID = String(receipt.chat_id || receipt.chatID || "").trim();
|
|
67
|
+
const messageID = intFromRawAllowZero(receipt.message_id || receipt.messageID, 0);
|
|
68
|
+
if (!chatID || !(messageID > 0)) {
|
|
69
|
+
return "";
|
|
70
|
+
}
|
|
71
|
+
return `${chatID}:${messageID}`;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function buildRunnerReceiptReplaySortTime(receiptRaw) {
|
|
75
|
+
const receipt = safeObject(receiptRaw);
|
|
76
|
+
const receiptTime = Date.parse(firstNonEmptyString([
|
|
77
|
+
receipt.occurred_at,
|
|
78
|
+
receipt.occurredAt,
|
|
79
|
+
receipt.received_at,
|
|
80
|
+
receipt.receivedAt,
|
|
81
|
+
]));
|
|
82
|
+
return Number.isFinite(receiptTime) ? receiptTime : 0;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function buildRunnerReceiptBackedReplayRecord(recordRaw, receiptRaw, pendingSelectionOptions = {}) {
|
|
86
|
+
const record = safeObject(recordRaw);
|
|
87
|
+
const receipt = safeObject(receiptRaw);
|
|
88
|
+
const replayOccurredAt = firstNonEmptyString([
|
|
89
|
+
receipt.occurred_at,
|
|
90
|
+
receipt.occurredAt,
|
|
91
|
+
receipt.received_at,
|
|
92
|
+
receipt.receivedAt,
|
|
93
|
+
record.sourceOccurredAt,
|
|
94
|
+
safeObject(record.parsedArchive).occurredAt,
|
|
95
|
+
safeObject(record.parsedArchive).occurred_at,
|
|
96
|
+
record.createdAt,
|
|
97
|
+
record.updatedAt,
|
|
98
|
+
]);
|
|
99
|
+
let staleAfterAt = String(record.staleAfterAt || "").trim();
|
|
100
|
+
const maxPendingAgeMs = intFromRawAllowZero(safeObject(pendingSelectionOptions).maxPendingAgeMs, 0);
|
|
101
|
+
const replayOccurredAtMs = Date.parse(replayOccurredAt);
|
|
102
|
+
if (!staleAfterAt && maxPendingAgeMs > 0 && Number.isFinite(replayOccurredAtMs)) {
|
|
103
|
+
staleAfterAt = new Date(replayOccurredAtMs + maxPendingAgeMs).toISOString();
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
...record,
|
|
107
|
+
sourceOccurredAt: replayOccurredAt,
|
|
108
|
+
staleAfterAt,
|
|
109
|
+
replayTriggeredByLocalReceipt: true,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function buildRunnerReceiptBackedPendingArchiveComments({
|
|
114
|
+
orderedComments,
|
|
115
|
+
currentPollLocalInboundReceipts,
|
|
116
|
+
existingPendingIDs,
|
|
117
|
+
pendingSelectionOptions,
|
|
118
|
+
}) {
|
|
119
|
+
const pendingIDs = new Set(ensureArray(existingPendingIDs).map((value) => String(value || "").trim()).filter(Boolean));
|
|
120
|
+
const latestReceiptsByKey = new Map();
|
|
121
|
+
for (const receiptRaw of ensureArray(currentPollLocalInboundReceipts)) {
|
|
122
|
+
const receipt = safeObject(receiptRaw);
|
|
123
|
+
const receiptKey = buildRunnerLocalInboundReceiptKey(receipt);
|
|
124
|
+
if (!receiptKey) {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
const previous = safeObject(latestReceiptsByKey.get(receiptKey));
|
|
128
|
+
if (buildRunnerReceiptReplaySortTime(receipt) >= buildRunnerReceiptReplaySortTime(previous)) {
|
|
129
|
+
latestReceiptsByKey.set(receiptKey, receipt);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
const replayCandidates = [];
|
|
133
|
+
for (const [receiptKey, receipt] of latestReceiptsByKey.entries()) {
|
|
134
|
+
const matchedRecord = orderedComments.find((record) => buildRunnerArchiveSourceMessageKey(record) === receiptKey);
|
|
135
|
+
const matchedID = String(safeObject(matchedRecord).id || "").trim();
|
|
136
|
+
if (!matchedID || pendingIDs.has(matchedID)) {
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
replayCandidates.push(buildRunnerReceiptBackedReplayRecord(
|
|
140
|
+
matchedRecord,
|
|
141
|
+
receipt,
|
|
142
|
+
pendingSelectionOptions,
|
|
143
|
+
));
|
|
144
|
+
}
|
|
145
|
+
return replayCandidates.sort(compareArchiveCommentRecords);
|
|
146
|
+
}
|
|
147
|
+
|
|
54
148
|
function buildContextSpeakerType(parsedArchiveRaw) {
|
|
55
149
|
const parsed = safeObject(parsedArchiveRaw);
|
|
56
150
|
const kind = String(parsed.kind || "").trim();
|
|
@@ -862,10 +956,24 @@ export function selectRunnerPendingWork({
|
|
|
862
956
|
pending: importedPendingAfterCursor,
|
|
863
957
|
}, pendingSelectionOptions)
|
|
864
958
|
: fullPending;
|
|
959
|
+
const receiptBackedPending = buildRunnerReceiptBackedPendingArchiveComments({
|
|
960
|
+
orderedComments,
|
|
961
|
+
currentPollLocalInboundReceipts: ensureArray(importOutcome?.currentPollLocalInboundReceipts),
|
|
962
|
+
existingPendingIDs: ensureArray(safeObject(pending).pending).map((record) => String(safeObject(record).id || "").trim()),
|
|
963
|
+
pendingSelectionOptions,
|
|
964
|
+
});
|
|
965
|
+
const finalPending = ensureArray(safeObject(pending).pending).length === 0 && receiptBackedPending.length > 0
|
|
966
|
+
? applyPendingAgeSelection({
|
|
967
|
+
...safeObject(pending),
|
|
968
|
+
shouldPrime: false,
|
|
969
|
+
pending: receiptBackedPending,
|
|
970
|
+
}, pendingSelectionOptions)
|
|
971
|
+
: pending;
|
|
865
972
|
return {
|
|
866
973
|
orderedComments,
|
|
867
974
|
inboundComments,
|
|
868
975
|
importedRecords,
|
|
869
|
-
|
|
976
|
+
receiptBackedPending,
|
|
977
|
+
pending: finalPending,
|
|
870
978
|
};
|
|
871
979
|
}
|
package/lib/runner-runtime.mjs
CHANGED
|
@@ -233,6 +233,12 @@ function resolveRunnerLocalInboundArtifactOwners({
|
|
|
233
233
|
.filter(Boolean),
|
|
234
234
|
));
|
|
235
235
|
if (explicitMentions.length > 0) {
|
|
236
|
+
if (normalizedUpdate.fromIsBot !== true) {
|
|
237
|
+
if (currentBotSelector && explicitMentions.includes(currentBotSelector) && currentOwner) {
|
|
238
|
+
return [currentOwner];
|
|
239
|
+
}
|
|
240
|
+
return [];
|
|
241
|
+
}
|
|
236
242
|
const explicitOwners = explicitMentions
|
|
237
243
|
.map((selector) => ownersBySelector.get(selector))
|
|
238
244
|
.filter((owner) => owner && owner.routeKey);
|
|
@@ -254,6 +260,26 @@ function resolveRunnerLocalInboundArtifactOwners({
|
|
|
254
260
|
return currentOwner ? [currentOwner] : [];
|
|
255
261
|
}
|
|
256
262
|
|
|
263
|
+
function currentRouteOwnsRunnerInboundUpdate({
|
|
264
|
+
update,
|
|
265
|
+
routeKey,
|
|
266
|
+
route,
|
|
267
|
+
bot,
|
|
268
|
+
managedConversationBots,
|
|
269
|
+
}) {
|
|
270
|
+
const normalizedRouteKey = String(routeKey || "").trim();
|
|
271
|
+
if (!normalizedRouteKey) {
|
|
272
|
+
return false;
|
|
273
|
+
}
|
|
274
|
+
return resolveRunnerLocalInboundArtifactOwners({
|
|
275
|
+
update,
|
|
276
|
+
routeKey: normalizedRouteKey,
|
|
277
|
+
route,
|
|
278
|
+
bot,
|
|
279
|
+
managedConversationBots,
|
|
280
|
+
}).some((owner) => String(safeObject(owner).routeKey || "").trim() === normalizedRouteKey);
|
|
281
|
+
}
|
|
282
|
+
|
|
257
283
|
function managedConversationBotTargetsCurrentRoute({
|
|
258
284
|
update,
|
|
259
285
|
bot,
|
|
@@ -549,6 +575,14 @@ function groupRunnerLocalInboundArtifactsByRoute(localInboundArtifacts) {
|
|
|
549
575
|
return Object.fromEntries(grouped.entries());
|
|
550
576
|
}
|
|
551
577
|
|
|
578
|
+
function buildRunnerCurrentPollLocalInboundReceipts(localInboundArtifactsByRoute, routeKey) {
|
|
579
|
+
return ensureArray(safeObject(localInboundArtifactsByRoute)[String(routeKey || "").trim()])
|
|
580
|
+
.map((artifactRaw) => ensureArray(safeObject(artifactRaw).receiptEntry))
|
|
581
|
+
.filter((entry) => entry.length === 2)
|
|
582
|
+
.map((entry) => safeObject(entry[1]))
|
|
583
|
+
.filter((receipt) => Object.keys(receipt).length > 0);
|
|
584
|
+
}
|
|
585
|
+
|
|
552
586
|
function buildRunnerRecentLocalInboundEnvelopes(routeStateRaw, recentLocalInboundReceipts) {
|
|
553
587
|
const routeState = safeObject(routeStateRaw);
|
|
554
588
|
const relevantEnvelopes = Object.values(safeObject(recentLocalInboundReceipts))
|
|
@@ -789,6 +823,18 @@ async function archiveRunnerTelegramInboundUpdates({
|
|
|
789
823
|
if (!String(update.text || "").trim()) {
|
|
790
824
|
continue;
|
|
791
825
|
}
|
|
826
|
+
if (
|
|
827
|
+
update.fromIsBot !== true
|
|
828
|
+
&& !currentRouteOwnsRunnerInboundUpdate({
|
|
829
|
+
update,
|
|
830
|
+
routeKey,
|
|
831
|
+
route,
|
|
832
|
+
bot,
|
|
833
|
+
managedConversationBots,
|
|
834
|
+
})
|
|
835
|
+
) {
|
|
836
|
+
continue;
|
|
837
|
+
}
|
|
792
838
|
const dedupeKey = buildArchivedInboundMessageKey(update.chatID, update.messageID);
|
|
793
839
|
if (boolFromRaw(archivePolicy.dedupeInbound, true) && existingKeys.has(dedupeKey)) {
|
|
794
840
|
continue;
|
|
@@ -1106,6 +1152,10 @@ export async function archiveLocalTelegramMessagesForRoute({
|
|
|
1106
1152
|
managedConversationBots,
|
|
1107
1153
|
);
|
|
1108
1154
|
const localInboundArtifactsByRoute = groupRunnerLocalInboundArtifactsByRoute(localInboundArtifacts);
|
|
1155
|
+
const currentPollLocalInboundReceipts = buildRunnerCurrentPollLocalInboundReceipts(
|
|
1156
|
+
localInboundArtifactsByRoute,
|
|
1157
|
+
routeKey,
|
|
1158
|
+
);
|
|
1109
1159
|
const recentLocalInboundReceipts = buildRunnerRecentLocalInboundReceipts(
|
|
1110
1160
|
routeState,
|
|
1111
1161
|
ensureArray(localInboundArtifactsByRoute[routeKey]),
|
|
@@ -1167,7 +1217,9 @@ export async function archiveLocalTelegramMessagesForRoute({
|
|
|
1167
1217
|
persistPollingProgress([], lastUpdateID);
|
|
1168
1218
|
return {
|
|
1169
1219
|
importedCommentIDs: [],
|
|
1220
|
+
importedComments: [],
|
|
1170
1221
|
importedCount: 0,
|
|
1222
|
+
currentPollLocalInboundReceipts,
|
|
1171
1223
|
lastUpdateID,
|
|
1172
1224
|
};
|
|
1173
1225
|
}
|
|
@@ -1211,6 +1263,7 @@ export async function archiveLocalTelegramMessagesForRoute({
|
|
|
1211
1263
|
importedCommentIDs,
|
|
1212
1264
|
importedComments,
|
|
1213
1265
|
importedCount: importedCommentIDs.length,
|
|
1266
|
+
currentPollLocalInboundReceipts,
|
|
1214
1267
|
lastUpdateID: Math.max(lastUpdateID, handledUpdateID),
|
|
1215
1268
|
};
|
|
1216
1269
|
}
|
|
@@ -1007,6 +1007,63 @@ export async function runSelftestRunnerScenarios(push, deps) {
|
|
|
1007
1007
|
);
|
|
1008
1008
|
}
|
|
1009
1009
|
|
|
1010
|
+
try {
|
|
1011
|
+
const pendingWork = selectRunnerPendingWork({
|
|
1012
|
+
comments: [
|
|
1013
|
+
{
|
|
1014
|
+
id: "archived-current-message",
|
|
1015
|
+
createdAt: "2026-03-18T00:00:01.000Z",
|
|
1016
|
+
updatedAt: "2026-03-18T00:00:01.000Z",
|
|
1017
|
+
parsedArchive: { kind: "telegram_message", chatID: "-1001", messageID: 280, body: "@RyoAI3_bot 하이" },
|
|
1018
|
+
},
|
|
1019
|
+
{
|
|
1020
|
+
id: "cursor-comment",
|
|
1021
|
+
createdAt: "2026-03-18T00:04:00.000Z",
|
|
1022
|
+
updatedAt: "2026-03-18T00:04:00.000Z",
|
|
1023
|
+
parsedArchive: { kind: "telegram_message", chatID: "-1001", messageID: 281, body: "@RyoAI_bot already processed" },
|
|
1024
|
+
},
|
|
1025
|
+
],
|
|
1026
|
+
importOutcome: {
|
|
1027
|
+
importedCommentIDs: [],
|
|
1028
|
+
currentPollLocalInboundReceipts: [
|
|
1029
|
+
{
|
|
1030
|
+
chat_id: "-1001",
|
|
1031
|
+
message_id: 280,
|
|
1032
|
+
occurred_at: "2026-03-18T00:05:00.000Z",
|
|
1033
|
+
received_at: "2026-03-18T00:05:00.000Z",
|
|
1034
|
+
update_id: 2001,
|
|
1035
|
+
},
|
|
1036
|
+
],
|
|
1037
|
+
},
|
|
1038
|
+
refreshedState: {
|
|
1039
|
+
last_processed_comment_id: "cursor-comment",
|
|
1040
|
+
last_processed_created_at: "2026-03-18T00:04:00.000Z",
|
|
1041
|
+
},
|
|
1042
|
+
mode: "start",
|
|
1043
|
+
parseArchivedChatComment: () => null,
|
|
1044
|
+
deps: {
|
|
1045
|
+
normalizeArchiveCommentRecord: (record) => record,
|
|
1046
|
+
applyPendingAgeSelection: (selection) => selection,
|
|
1047
|
+
},
|
|
1048
|
+
pendingSelectionOptions: {
|
|
1049
|
+
maxPendingAgeMs: 15 * 60 * 1000,
|
|
1050
|
+
},
|
|
1051
|
+
});
|
|
1052
|
+
push(
|
|
1053
|
+
"runner_pending_selection_replays_current_poll_local_receipt_against_existing_archive_comment",
|
|
1054
|
+
pendingWork.pending.pending.length === 1
|
|
1055
|
+
&& String(pendingWork.pending.pending[0]?.id || "").trim() === "archived-current-message"
|
|
1056
|
+
&& pendingWork.pending.pending[0]?.replayTriggeredByLocalReceipt === true,
|
|
1057
|
+
`pending=${pendingWork.pending.pending.map((item) => `${item.id}:${String(item.replayTriggeredByLocalReceipt === true)}`).join(",") || "(none)"}`,
|
|
1058
|
+
);
|
|
1059
|
+
} catch (err) {
|
|
1060
|
+
push(
|
|
1061
|
+
"runner_pending_selection_replays_current_poll_local_receipt_against_existing_archive_comment",
|
|
1062
|
+
false,
|
|
1063
|
+
String(err?.message || err),
|
|
1064
|
+
);
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1010
1067
|
try {
|
|
1011
1068
|
const selected = selectProjectChatDestination(
|
|
1012
1069
|
[
|
|
@@ -2042,10 +2099,16 @@ export async function runSelftestRunnerScenarios(push, deps) {
|
|
|
2042
2099
|
selectedRecord: humanRecord,
|
|
2043
2100
|
selectedBotUsernames: ["ryoai_bot"],
|
|
2044
2101
|
normalizedIntent: "coordination_request",
|
|
2045
|
-
});
|
|
2046
|
-
const claimedState = loadBotRunnerState();
|
|
2047
|
-
const claimedRequest = safeObject(safeObject(claimedState.requests)[claimed.requestKey]);
|
|
2048
|
-
const claimedConsumed = safeObject(
|
|
2102
|
+
});
|
|
2103
|
+
const claimedState = loadBotRunnerState();
|
|
2104
|
+
const claimedRequest = safeObject(safeObject(claimedState.requests)[claimed.requestKey]);
|
|
2105
|
+
const claimedConsumed = safeObject(
|
|
2106
|
+
Object.values(safeObject(claimedState.consumedComments)).find((entryRaw) => {
|
|
2107
|
+
const entry = safeObject(entryRaw);
|
|
2108
|
+
return String(entry.comment_id || "").trim() === humanRecord.id
|
|
2109
|
+
&& String(entry.route_key || "").trim() === requestRouteKey;
|
|
2110
|
+
}),
|
|
2111
|
+
);
|
|
2049
2112
|
push(
|
|
2050
2113
|
"runner_request_claim_persists_request_and_consumed_comment",
|
|
2051
2114
|
claimed.ok === true
|
|
@@ -1649,12 +1649,13 @@ export async function runSelftestTelegramE2E(push, deps) {
|
|
|
1649
1649
|
const ryoai3Receipt = safeObject(
|
|
1650
1650
|
safeObject(safeObject(ownershipState.routes)[routeRyoai3Key]).recent_local_inbound_receipts?.[`${String(e2eDestination.chat_id)}:83`],
|
|
1651
1651
|
);
|
|
1652
|
+
const ownershipBodies = telegramE2EServer.state.comments.map((item) => String(item.body || ""));
|
|
1652
1653
|
push(
|
|
1653
|
-
"
|
|
1654
|
-
String(ryoai2Receipt.receipt_route_key || "")
|
|
1655
|
-
&& String(
|
|
1656
|
-
&&
|
|
1657
|
-
`owner=${JSON.stringify(ryoai2Receipt)} foreign=${JSON.stringify(ryoai3Receipt)}`,
|
|
1654
|
+
"telegram_human_inbound_does_not_fan_out_to_foreign_owner_routes",
|
|
1655
|
+
!String(ryoai2Receipt.receipt_route_key || "").trim()
|
|
1656
|
+
&& !String(ryoai3Receipt.receipt_route_key || "").trim()
|
|
1657
|
+
&& ownershipBodies.length === 0,
|
|
1658
|
+
`owner=${JSON.stringify(ryoai2Receipt)} foreign=${JSON.stringify(ryoai3Receipt)} comments=${ownershipBodies.join(" || ")}`,
|
|
1658
1659
|
);
|
|
1659
1660
|
} catch (err) {
|
|
1660
1661
|
push("telegram_runner_e2e_local_mock", false, String(err?.message || err));
|