instar 1.3.40 → 1.3.42

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.
@@ -0,0 +1,82 @@
1
+ /**
2
+ * OutstandingPromptTracker — anti-ping-pong invariant for the mentor live loop.
3
+ *
4
+ * Spec: MENTOR-LIVE-READINESS §Fix 2b "Implementation surface" item 4 + Justin's original
5
+ * concern (the rebuilt-slow ping-pong: a 15-min mentor tick + a Codey reply that takes
6
+ * 16+ min = naive next-tick re-sends while the prior is in flight → loop).
7
+ *
8
+ * Justin's user-fidelity correction made this THE real cadence gate (Fix 1 idle-probe
9
+ * was removed; users don't probe). The mentor refuses to send a new prompt while any
10
+ * prior prompt is outstanding within `replyTimeoutMs`. On timeout expiry without a reply
11
+ * → degradation event + Attention entry (silent reply-loss is observable).
12
+ *
13
+ * Pure in-memory + a small persistence shim so a server restart doesn't lose the "I'm
14
+ * waiting on a reply" state (would otherwise re-send + double-prompt Codey).
15
+ *
16
+ * Keyed per-mentee. The same `corr` round-trips: mark on send, clear on matching reply.
17
+ */
18
+ export interface OutstandingPromptTrackerOptions {
19
+ /** Absolute path to the JSON file backing the tracker (per-mentee state). */
20
+ filePath: string;
21
+ /** A reply that doesn't arrive within this window is treated as orphaned. */
22
+ replyTimeoutMs?: number;
23
+ /** Injected for testability. */
24
+ now?: () => number;
25
+ }
26
+ export type CheckResult = {
27
+ ok: true;
28
+ } | {
29
+ ok: false;
30
+ reason: 'prior-prompt-in-flight';
31
+ outstandingCorr: string;
32
+ sentAt: number;
33
+ };
34
+ export declare class OutstandingPromptTracker {
35
+ private readonly filePath;
36
+ private readonly replyTimeoutMs;
37
+ private readonly now;
38
+ private entries;
39
+ /** Per-(reason,day) dedup for the orphan-degradation notification. */
40
+ private orphanedNotifiedFor;
41
+ constructor(opts: OutstandingPromptTrackerOptions);
42
+ /**
43
+ * Returns `{ok: true}` if the mentor can send a new prompt to this mentee; otherwise
44
+ * `{ok: false, reason: 'prior-prompt-in-flight'}` (the tick must refuse the send). An
45
+ * EXPIRED outstanding (past replyTimeoutMs) is automatically swept here and does NOT
46
+ * block — the caller can also call sweepExpired() explicitly to surface orphans.
47
+ */
48
+ canSendTo(mentee: string): CheckResult;
49
+ /** Record that a prompt with this `corr` was sent to this mentee at now(). */
50
+ markSent(corr: string, mentee: string): void;
51
+ /**
52
+ * Clear an outstanding prompt by `corr` (called when the matching reply arrives).
53
+ * Returns true if an outstanding entry existed (legitimate reply); false if not
54
+ * (a reply with no outstanding match — possibly a late reply after orphan-sweep,
55
+ * or a spurious reply; the caller may want to log this).
56
+ */
57
+ clearByCorr(corr: string): boolean;
58
+ /**
59
+ * Find + remove orphans (sentAt + replyTimeoutMs < now). Returns the list. Caller
60
+ * decides whether to fire DegradationReporter / Attention. The dedup field stays
61
+ * across calls so the same orphan-episode doesn't re-fire repeatedly.
62
+ */
63
+ sweepExpired(): Array<{
64
+ corr: string;
65
+ mentee: string;
66
+ sentAt: number;
67
+ ageMs: number;
68
+ }>;
69
+ /** Idempotent: once an orphan-notify has fired for a (corr), don't re-fire. */
70
+ recordOrphanNotified(corr: string): boolean;
71
+ /** Test helper. */
72
+ size(): number;
73
+ /** Test helper. */
74
+ list(): Array<{
75
+ corr: string;
76
+ mentee: string;
77
+ sentAt: number;
78
+ }>;
79
+ private load;
80
+ private persist;
81
+ }
82
+ //# sourceMappingURL=OutstandingPromptTracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OutstandingPromptTracker.d.ts","sourceRoot":"","sources":["../../src/scheduler/OutstandingPromptTracker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,MAAM,WAAW,+BAA+B;IAC9C,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,CAAC;IACjB,6EAA6E;IAC7E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gCAAgC;IAChC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAiBD,MAAM,MAAM,WAAW,GACnB;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GACZ;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,wBAAwB,CAAC;IAAC,eAAe,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7F,qBAAa,wBAAwB;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,OAAO,CAAiC;IAChD,sEAAsE;IACtE,OAAO,CAAC,mBAAmB,CAAc;gBAE7B,IAAI,EAAE,+BAA+B;IASjD;;;;;OAKG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW;IAUtC,8EAA8E;IAC9E,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAK5C;;;;;OAKG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAMlC;;;;OAIG;IACH,YAAY,IAAI,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAatF,+EAA+E;IAC/E,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAM3C,mBAAmB;IACnB,IAAI,IAAI,MAAM;IAId,mBAAmB;IACnB,IAAI,IAAI,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAI/D,OAAO,CAAC,IAAI;IAkBZ,OAAO,CAAC,OAAO;CAahB"}
@@ -0,0 +1,136 @@
1
+ /**
2
+ * OutstandingPromptTracker — anti-ping-pong invariant for the mentor live loop.
3
+ *
4
+ * Spec: MENTOR-LIVE-READINESS §Fix 2b "Implementation surface" item 4 + Justin's original
5
+ * concern (the rebuilt-slow ping-pong: a 15-min mentor tick + a Codey reply that takes
6
+ * 16+ min = naive next-tick re-sends while the prior is in flight → loop).
7
+ *
8
+ * Justin's user-fidelity correction made this THE real cadence gate (Fix 1 idle-probe
9
+ * was removed; users don't probe). The mentor refuses to send a new prompt while any
10
+ * prior prompt is outstanding within `replyTimeoutMs`. On timeout expiry without a reply
11
+ * → degradation event + Attention entry (silent reply-loss is observable).
12
+ *
13
+ * Pure in-memory + a small persistence shim so a server restart doesn't lose the "I'm
14
+ * waiting on a reply" state (would otherwise re-send + double-prompt Codey).
15
+ *
16
+ * Keyed per-mentee. The same `corr` round-trips: mark on send, clear on matching reply.
17
+ */
18
+ import fs from 'node:fs';
19
+ import path from 'node:path';
20
+ import { SafeFsExecutor } from '../core/SafeFsExecutor.js';
21
+ const DEFAULT_REPLY_TIMEOUT_MS = 20 * 60 * 1000; // 20 min — > the 15-min tick interval.
22
+ export class OutstandingPromptTracker {
23
+ filePath;
24
+ replyTimeoutMs;
25
+ now;
26
+ entries;
27
+ /** Per-(reason,day) dedup for the orphan-degradation notification. */
28
+ orphanedNotifiedFor;
29
+ constructor(opts) {
30
+ this.filePath = opts.filePath;
31
+ this.replyTimeoutMs = opts.replyTimeoutMs ?? DEFAULT_REPLY_TIMEOUT_MS;
32
+ this.now = opts.now ?? Date.now;
33
+ this.entries = new Map();
34
+ this.orphanedNotifiedFor = new Set();
35
+ this.load();
36
+ }
37
+ /**
38
+ * Returns `{ok: true}` if the mentor can send a new prompt to this mentee; otherwise
39
+ * `{ok: false, reason: 'prior-prompt-in-flight'}` (the tick must refuse the send). An
40
+ * EXPIRED outstanding (past replyTimeoutMs) is automatically swept here and does NOT
41
+ * block — the caller can also call sweepExpired() explicitly to surface orphans.
42
+ */
43
+ canSendTo(mentee) {
44
+ this.sweepExpired();
45
+ for (const [corr, p] of this.entries) {
46
+ if (p.mentee === mentee) {
47
+ return { ok: false, reason: 'prior-prompt-in-flight', outstandingCorr: corr, sentAt: p.sentAt };
48
+ }
49
+ }
50
+ return { ok: true };
51
+ }
52
+ /** Record that a prompt with this `corr` was sent to this mentee at now(). */
53
+ markSent(corr, mentee) {
54
+ this.entries.set(corr, { sentAt: this.now(), mentee });
55
+ this.persist();
56
+ }
57
+ /**
58
+ * Clear an outstanding prompt by `corr` (called when the matching reply arrives).
59
+ * Returns true if an outstanding entry existed (legitimate reply); false if not
60
+ * (a reply with no outstanding match — possibly a late reply after orphan-sweep,
61
+ * or a spurious reply; the caller may want to log this).
62
+ */
63
+ clearByCorr(corr) {
64
+ const had = this.entries.delete(corr);
65
+ if (had)
66
+ this.persist();
67
+ return had;
68
+ }
69
+ /**
70
+ * Find + remove orphans (sentAt + replyTimeoutMs < now). Returns the list. Caller
71
+ * decides whether to fire DegradationReporter / Attention. The dedup field stays
72
+ * across calls so the same orphan-episode doesn't re-fire repeatedly.
73
+ */
74
+ sweepExpired() {
75
+ const cutoff = this.now() - this.replyTimeoutMs;
76
+ const out = [];
77
+ for (const [corr, p] of this.entries) {
78
+ if (p.sentAt < cutoff) {
79
+ out.push({ corr, mentee: p.mentee, sentAt: p.sentAt, ageMs: this.now() - p.sentAt });
80
+ this.entries.delete(corr);
81
+ }
82
+ }
83
+ if (out.length > 0)
84
+ this.persist();
85
+ return out;
86
+ }
87
+ /** Idempotent: once an orphan-notify has fired for a (corr), don't re-fire. */
88
+ recordOrphanNotified(corr) {
89
+ if (this.orphanedNotifiedFor.has(corr))
90
+ return false;
91
+ this.orphanedNotifiedFor.add(corr);
92
+ return true;
93
+ }
94
+ /** Test helper. */
95
+ size() {
96
+ return this.entries.size;
97
+ }
98
+ /** Test helper. */
99
+ list() {
100
+ return [...this.entries].map(([corr, p]) => ({ corr, mentee: p.mentee, sentAt: p.sentAt }));
101
+ }
102
+ load() {
103
+ if (!fs.existsSync(this.filePath))
104
+ return;
105
+ try {
106
+ const raw = fs.readFileSync(this.filePath, 'utf-8');
107
+ const parsed = JSON.parse(raw);
108
+ if (parsed && parsed.v === 1 && parsed.entries && typeof parsed.entries === 'object') {
109
+ for (const [corr, p] of Object.entries(parsed.entries)) {
110
+ if (p && typeof p.sentAt === 'number' && typeof p.mentee === 'string') {
111
+ this.entries.set(corr, { sentAt: p.sentAt, mentee: p.mentee });
112
+ }
113
+ }
114
+ }
115
+ }
116
+ catch {
117
+ // Corrupted state → start fresh; better than crashing the mentor on a bad file.
118
+ this.entries = new Map();
119
+ }
120
+ }
121
+ persist() {
122
+ const file = {
123
+ v: 1,
124
+ entries: Object.fromEntries(this.entries),
125
+ };
126
+ try {
127
+ fs.mkdirSync(path.dirname(this.filePath), { recursive: true });
128
+ SafeFsExecutor.atomicWriteJsonSync(this.filePath, file, { operation: 'OutstandingPromptTracker.persist' });
129
+ }
130
+ catch (err) {
131
+ // eslint-disable-next-line no-console
132
+ console.warn(`[mentor] OutstandingPromptTracker persist failed (non-fatal) at ${this.filePath}:`, err instanceof Error ? err.message : String(err));
133
+ }
134
+ }
135
+ }
136
+ //# sourceMappingURL=OutstandingPromptTracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OutstandingPromptTracker.js","sourceRoot":"","sources":["../../src/scheduler/OutstandingPromptTracker.ts"],"names":[],"mappings":"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"}
@@ -61,6 +61,12 @@ export declare class AgentServer {
61
61
  private mentorBotAdapterToken;
62
62
  /** Lazily-constructed a2a audit ledger (shared across mentor sends/recvs). */
63
63
  private a2aLedger;
64
+ /** Lazily-constructed processed-id store (idempotency for inbound mentor-reply). */
65
+ private a2aProcessedIds;
66
+ /** Lazily-constructed outstanding-prompt tracker (anti-ping-pong). */
67
+ private mentorOutstanding;
68
+ /** Reply-jsonl path (Codey's reply persisted here for Stage-B forensics). */
69
+ private mentorReplyJsonlPath;
64
70
  private failureLedger;
65
71
  private failureAttributionEngine;
66
72
  private burnDetector;
@@ -246,6 +252,22 @@ export declare class AgentServer {
246
252
  private getOrCreateMentorBot;
247
253
  /** Lazily construct + cache the a2a audit ledger. Paths default under stateDir. */
248
254
  private getOrCreateA2aLedger;
255
+ /** Lazily construct + cache the processed-id store (idempotency for inbound replies). */
256
+ private getOrCreateA2aProcessedIds;
257
+ /** Lazily construct + cache the outstanding-prompt tracker (anti-ping-pong). */
258
+ private getOrCreateMentorOutstanding;
259
+ /**
260
+ * Install the mentor-reply recipient hook on the mentor-bot adapter. Called from
261
+ * getOrCreateMentorBot once the adapter is up. The hook routes role=`mentor-reply`
262
+ * from Codey to a handler that (1) clears the outstanding-prompt entry by `corr`
263
+ * (so the next mentor tick can send again), and (2) persists the reply to a
264
+ * jsonl file Stage-B forensics reads. This is the capability-handle invariant from
265
+ * the spec: the reply-ingestion path CANNOT call spawnStageA / deliverToMentee /
266
+ * scheduler / Threadline — it only writes the reply + clears tracking.
267
+ */
268
+ private installMentorReceiverHook;
269
+ /** Snapshot of mentor config for use outside the runner's getConfig closure. */
270
+ private getMentorConfigSnapshot;
249
271
  private buildMentorRunner;
250
272
  /**
251
273
  * Start the HTTP server.
@@ -1 +1 @@
1
- {"version":3,"file":"AgentServer.d.ts","sourceRoot":"","sources":["../../src/server/AgentServer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AgentServer.d.ts","sourceRoot":"","sources":["../../src/server/AgentServer.ts"],"names":[],"mappings":"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"}
@@ -38,8 +38,11 @@ import { MentorOnboardingRunner, DEFAULT_MENTOR_CONFIG } from '../scheduler/Ment
38
38
  import { STAGE_A_ALLOWED_TOOLS } from '../monitoring/MentorStageA.js';
39
39
  import { analyzeForensics } from '../scheduler/MentorStageBForensics.js';
40
40
  import { TelegramAdapter as MentorTelegramAdapter } from '../messaging/TelegramAdapter.js';
41
- import { sendAgentMessage } from '../messaging/AgentTelegramComms.js';
41
+ import { sendAgentMessage, A2A_VERSION } from '../messaging/AgentTelegramComms.js';
42
42
  import { AgentTelegramLedger, defaultLedgerPaths as defaultA2aLedgerPaths } from '../messaging/AgentTelegramLedger.js';
43
+ import { ProcessedIdStore } from '../messaging/ProcessedIdStore.js';
44
+ import { buildAgentMessageHook } from '../messaging/installAgentMessageHook.js';
45
+ import { OutstandingPromptTracker } from '../scheduler/OutstandingPromptTracker.js';
43
46
  import { parseCodexRollout } from '../monitoring/CodexRolloutParser.js';
44
47
  import { BurnDetector } from '../monitoring/BurnDetector.js';
45
48
  import { BurnThrottleRunbook } from '../monitoring/BurnThrottleRunbook.js';
@@ -78,6 +81,12 @@ export class AgentServer {
78
81
  mentorBotAdapterToken = null;
79
82
  /** Lazily-constructed a2a audit ledger (shared across mentor sends/recvs). */
80
83
  a2aLedger = null;
84
+ /** Lazily-constructed processed-id store (idempotency for inbound mentor-reply). */
85
+ a2aProcessedIds = null;
86
+ /** Lazily-constructed outstanding-prompt tracker (anti-ping-pong). */
87
+ mentorOutstanding = null;
88
+ /** Reply-jsonl path (Codey's reply persisted here for Stage-B forensics). */
89
+ mentorReplyJsonlPath = null;
81
90
  failureLedger = null;
82
91
  failureAttributionEngine = null;
83
92
  // Burn-detection-and-self-heal system (six-phase umbrella spec at
@@ -591,6 +600,10 @@ export class AgentServer {
591
600
  try {
592
601
  this.mentorBotAdapter = new MentorTelegramAdapter({ token: botToken, chatId: menteeChatId }, this.config.stateDir, { subDir: 'agent-telegram/mentor-bot', suppressLifelineAutoCreate: true });
593
602
  this.mentorBotAdapterToken = botToken;
603
+ // Install the mentor-reply recipient hook now that the adapter is up. The handler
604
+ // clears the outstanding-prompt by corr + persists the reply for Stage-B.
605
+ const mentorBotId = botToken.split(':')[0];
606
+ this.installMentorReceiverHook(this.mentorBotAdapter, mentorBotId);
594
607
  return this.mentorBotAdapter;
595
608
  }
596
609
  catch (err) {
@@ -607,6 +620,87 @@ export class AgentServer {
607
620
  }
608
621
  return this.a2aLedger;
609
622
  }
623
+ /** Lazily construct + cache the processed-id store (idempotency for inbound replies). */
624
+ getOrCreateA2aProcessedIds() {
625
+ if (!this.a2aProcessedIds) {
626
+ this.a2aProcessedIds = new ProcessedIdStore({
627
+ filePath: path.join(this.config.stateDir, 'a2a-processed-ids.json'),
628
+ });
629
+ }
630
+ return this.a2aProcessedIds;
631
+ }
632
+ /** Lazily construct + cache the outstanding-prompt tracker (anti-ping-pong). */
633
+ getOrCreateMentorOutstanding() {
634
+ if (!this.mentorOutstanding) {
635
+ this.mentorOutstanding = new OutstandingPromptTracker({
636
+ filePath: path.join(this.config.stateDir, 'mentor-outstanding-prompts.json'),
637
+ });
638
+ }
639
+ return this.mentorOutstanding;
640
+ }
641
+ /**
642
+ * Install the mentor-reply recipient hook on the mentor-bot adapter. Called from
643
+ * getOrCreateMentorBot once the adapter is up. The hook routes role=`mentor-reply`
644
+ * from Codey to a handler that (1) clears the outstanding-prompt entry by `corr`
645
+ * (so the next mentor tick can send again), and (2) persists the reply to a
646
+ * jsonl file Stage-B forensics reads. This is the capability-handle invariant from
647
+ * the spec: the reply-ingestion path CANNOT call spawnStageA / deliverToMentee /
648
+ * scheduler / Threadline — it only writes the reply + clears tracking.
649
+ */
650
+ installMentorReceiverHook(bot, mentorBotId) {
651
+ const cfg = this.getMentorConfigSnapshot();
652
+ if (!cfg.menteeBotId)
653
+ return;
654
+ const recipientCfg = {
655
+ localAgent: 'echo',
656
+ knownAgents: { [`instar-${cfg.menteeFramework}`]: { botId: cfg.menteeBotId } },
657
+ acceptRoles: { [`instar-${cfg.menteeFramework}`]: ['mentor-reply'] },
658
+ skewWindowMs: 24 * 60 * 60 * 1000,
659
+ maxVersion: A2A_VERSION,
660
+ };
661
+ const outstanding = this.getOrCreateMentorOutstanding();
662
+ const replyJsonl = path.join(this.config.stateDir, 'mentor-replies.jsonl');
663
+ this.mentorReplyJsonlPath = replyJsonl;
664
+ const mentorReplyHandler = async (msg, ctx) => {
665
+ // (1) Clear the outstanding-prompt by corr (the next tick can send again).
666
+ const had = outstanding.clearByCorr(msg.corr);
667
+ if (!had) {
668
+ // Spurious / late reply (no outstanding match). Still persist it for forensics.
669
+ console.warn(`[mentor] mentor-reply for unknown corr=${msg.corr} (late after orphan-sweep?); persisting anyway`);
670
+ }
671
+ // (2) Persist the reply for Stage-B (append-only JSONL). Capability-handle
672
+ // invariant: this is the ONLY outbound effect; no spawn/deliver/schedule.
673
+ try {
674
+ fs.mkdirSync(path.dirname(replyJsonl), { recursive: true });
675
+ const row = {
676
+ ts: Date.now(),
677
+ fromAgent: msg.from,
678
+ corr: msg.corr,
679
+ replyId: msg.id,
680
+ topicId: ctx.topicId,
681
+ message: msg.body,
682
+ };
683
+ fs.appendFileSync(replyJsonl, JSON.stringify(row) + '\n', 'utf-8');
684
+ }
685
+ catch (err) {
686
+ console.warn('[mentor] mentor-reply persist failed (non-fatal):', err instanceof Error ? err.message : String(err));
687
+ }
688
+ };
689
+ const hook = buildAgentMessageHook({
690
+ config: recipientCfg,
691
+ ledger: this.getOrCreateA2aLedger(),
692
+ processedIds: this.getOrCreateA2aProcessedIds(),
693
+ roleHandlers: new Map([['mentor-reply', mentorReplyHandler]]),
694
+ });
695
+ bot.setAgentMessageHook(hook);
696
+ }
697
+ /** Snapshot of mentor config for use outside the runner's getConfig closure. */
698
+ getMentorConfigSnapshot() {
699
+ return {
700
+ ...DEFAULT_MENTOR_CONFIG,
701
+ ...(this.config.mentor ?? {}),
702
+ };
703
+ }
610
704
  buildMentorRunner(ledger, options, serverDataDir) {
611
705
  const getConfig = () => ({
612
706
  ...DEFAULT_MENTOR_CONFIG,
@@ -723,17 +817,45 @@ export class AgentServer {
723
817
  console.warn(`[mentor] deliverToMentee skipped — mentor-bot config incomplete (need mentor.botToken + menteeBotId + menteeChatId + menteeTopicId; framework=${framework})`);
724
818
  return;
725
819
  }
820
+ const menteeAgent = `instar-${framework}`;
821
+ // Anti-ping-pong (spec §Fix 2b item 4 + Justin's original concern). Refuse to
822
+ // send a new prompt while a prior one is unanswered within replyTimeoutMs.
823
+ const outstanding = self.getOrCreateMentorOutstanding();
824
+ const orphans = outstanding.sweepExpired();
825
+ for (const orphan of orphans) {
826
+ if (outstanding.recordOrphanNotified(orphan.corr)) {
827
+ console.warn(`[mentor] orphaned prompt — no reply within ${orphan.ageMs}ms (corr=${orphan.corr}, mentee=${orphan.mentee})`);
828
+ try {
829
+ DegradationReporter.getInstance().report({
830
+ feature: 'mentor.reply-orphaned',
831
+ primary: 'mentor receives Codey reply within replyTimeoutMs',
832
+ fallback: 'tick continues; no auto-resend; Stage-B sees the routed-sent row + no matching reply row',
833
+ reason: `outstanding prompt corr=${orphan.corr} aged ${orphan.ageMs}ms without a mentor-reply`,
834
+ impact: 'mentor cycle silently lost a reply; next tick allowed to retry',
835
+ });
836
+ }
837
+ catch { /* best-effort */ }
838
+ }
839
+ }
840
+ const check = outstanding.canSendTo(menteeAgent);
841
+ if (!check.ok) {
842
+ console.warn(`[mentor] deliverToMentee deferred — prior-prompt-in-flight (corr=${check.outstandingCorr}, sentAt=${check.sentAt})`);
843
+ return;
844
+ }
726
845
  const bot = self.getOrCreateMentorBot(cfg.botToken, cfg.menteeChatId);
727
846
  if (!bot)
728
847
  return;
729
848
  const ledger = self.getOrCreateA2aLedger();
849
+ const corr = `mp-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
730
850
  try {
731
- await sendAgentMessage({
851
+ const result = await sendAgentMessage({
732
852
  fromAgent: 'echo',
733
- toAgent: `instar-${framework}`,
853
+ toAgent: menteeAgent,
734
854
  role: 'mentor',
735
855
  toTopicId: cfg.menteeTopicId,
736
856
  message,
857
+ id: corr,
858
+ correlationId: corr,
737
859
  }, {
738
860
  send: async (topicId, text) => {
739
861
  try {
@@ -746,12 +868,16 @@ export class AgentServer {
746
868
  },
747
869
  appendAudit: (row) => ledger.appendSent(row),
748
870
  now: () => Date.now(),
749
- mintId: () => `mp-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`,
871
+ mintId: () => corr,
750
872
  allowedRoles: new Set(['mentor']),
751
873
  botToken: cfg.botToken,
752
- fromBotId: cfg.botToken.split(':')[0], // bot id is the prefix before the secret
874
+ fromBotId: cfg.botToken.split(':')[0],
753
875
  toBotId: cfg.menteeBotId,
754
876
  });
877
+ if (result.ok) {
878
+ // Mark only on successful send — a failed send doesn't owe a reply.
879
+ outstanding.markSent(corr, menteeAgent);
880
+ }
755
881
  }
756
882
  catch (err) {
757
883
  console.warn('[mentor] deliverToMentee send failed (non-fatal):', err instanceof Error ? err.message : String(err));