github-issue-tower-defence-management 1.122.6 → 1.122.8

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/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## [1.122.8](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/compare/v1.122.7...v1.122.8) (2026-07-14)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * instruct unconditional re-raise in stale-owner-call reminder ([#1168](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/issues/1168)) ([f246cd3](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/f246cd385befd0f29c51576593a1ecb2fd23bf40))
7
+
8
+ ## [1.122.7](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/compare/v1.122.6...v1.122.7) (2026-07-14)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **silent-monitor:** shorten silent-session reminder defaults to a calm neutral status notice ([#1166](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/issues/1166)) ([3f29b69](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/3f29b69065c005b8d41db3e68ead624f9c26ef95))
14
+
1
15
  ## [1.122.6](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/compare/v1.122.5...v1.122.6) (2026-07-13)
2
16
 
3
17
 
@@ -9,45 +9,44 @@ const formatMinutes = (seconds) => {
9
9
  const composeIdleSubAgentSection = (idleSubAgents) => {
10
10
  const lines = idleSubAgents.map((subAgent) => `- ${subAgent.label}: no output for ${formatMinutes(subAgent.silentSeconds)}`);
11
11
  return [
12
- `${silentSessionReminderSentinel_1.SILENT_SESSION_REMINDER_SENTINEL} The system has already detected, from each sub-process's last tool activity, that it has produced no output for about the minutes shown below. Please treat that figure as the authoritative system signal; there is no need to spend effort re-deriving whether the sub-process is alive. Around five minutes of silence is a real warning of a possible hang: please base your assessment on concrete evidence rather than speculation ("probably still working"), and please keep the warning in view until evidence resolves it.`,
12
+ `${silentSessionReminderSentinel_1.SILENT_SESSION_REMINDER_SENTINEL} This is an automated status check. The following sub-process(es) have produced no output for about the minutes shown, measured from their last tool activity:`,
13
13
  ...lines,
14
- 'For each one, determine the CAUSE by a concrete check and report the result. Verify specifically: (a) whether there is genuinely no recent activity anywhere — including a very recent push or commit, or output from any nested sub-processes this sub-process itself started; and (b) whether it is legitimately blocked waiting on an external dependency (a continuous-integration run, an external API, or another process). Waiting on continuous integration is plausible, but confirm it by investigation before concluding do not assume. Based on the check: if it is genuinely stuck, take action (restart, hand off, or replace it); if it is legitimately waiting, state that conclusion together with the concrete evidence you found. Owner notification is not required, but please output your investigation result in this session so it remains as a log.',
14
+ 'For each one: if it is waiting on an external dependency (a continuous-integration run, an external API, or another process), no action is neededplease log one line noting the wait. If it appears stuck, please restart it, hand it off, or replace it.',
15
15
  ].join('\n');
16
16
  };
17
17
  const composeLongRunningSubAgentSection = (longRunningSubAgents) => {
18
18
  const lines = longRunningSubAgents.map((subAgent) => `- ${subAgent.label}: running for ${formatMinutes(subAgent.runningSeconds)}`);
19
19
  return [
20
- `${silentSessionReminderSentinel_1.SILENT_SESSION_REMINDER_SENTINEL} The following sub-process(es) have been running longer than a task should normally take, which may mean an infinite loop, a task that is too large, or being stuck in an incorrect approach that is not making forward progress:`,
20
+ `${silentSessionReminderSentinel_1.SILENT_SESSION_REMINDER_SENTINEL} This is an automated status check. The following sub-process(es) have been running longer than a task usually takes:`,
21
21
  ...lines,
22
- 'Verify each one is genuinely advancing toward completion; do not dismiss it merely because it produced output recently. If it is not progressing, intervene: break the task down, restart, hand off, or replace it.',
22
+ 'If one is not making progress toward completion, consider breaking the task down, restarting it, handing it off, or replacing it. If it is progressing normally, no action is needed.',
23
23
  ].join('\n');
24
24
  };
25
25
  const composeOwnerCallFormatGuidance = (ownerCallMarker) => {
26
- const markerInstruction = ownerCallMarker !== null && ownerCallMarker.length > 0
27
- ? `Emit the owner-call as the configured owner-call marker tag "${ownerCallMarker}" as a complete matching pair — opening marker, content, then closing marker — on a single line with no newline inside the tag.`
28
- : `Emit the owner-call as the configured owner-call marker tag as a complete matching pair — opening marker, content, then closing marker — on a single line with no newline inside the tag.`;
29
- return `${markerInstruction} The content between the markers needs to begin with the 🔴 emoji immediately, with no space after it. The owner's app only surfaces the notification together with its content when the exact, well-formed tag with the leading 🔴 is present; a malformed tag (a broken or missing closing marker, or a missing leading 🔴) results in only a red indicator with no readable content. Make the owner-call message fully self-contained: the owner should be able to understand the whole situation — what happened, what you are asking, and any decision needed from this single latest owner-call message alone, without reading or scrolling back to earlier messages. Please avoid telling the owner to scroll up, go back, or read previous or above messages; if context is needed, restate it inside the owner-call message itself.`;
26
+ const tagLabel = ownerCallMarker !== null && ownerCallMarker.length > 0
27
+ ? ` "${ownerCallMarker}"`
28
+ : '';
29
+ return `Format reminder: write the owner-call marker tag${tagLabel} as a complete opening and closing pair on one line, with the content starting immediately with the 🔴 emoji and written to be self-contained, so the owner can understand the situation, the ask, and any decision needed from that single message.`;
30
30
  };
31
31
  exports.composeOwnerCallFormatGuidance = composeOwnerCallFormatGuidance;
32
32
  const composeMainStalledMessage = (mainSilentSeconds, ownerCallMarker) => {
33
33
  const minutes = Math.floor(mainSilentSeconds / 60);
34
34
  return [
35
- `${silentSessionReminderSentinel_1.SILENT_SESSION_REMINDER_SENTINEL} You have produced no output for ${minutes} minutes. Idle waiting wastes this live session, so please keep making progress. Always work proactively and stay ahead of the work: anticipate the next steps and, at every point, choose the fastest path so the whole task finishes as early as possible, rather than waiting passively. Finish every task in the shortest possible time — but "fastest" means correct and incident-free, not merely quick: a fast but wrong result is worthless and causes incidents, so be fast without breaking things. Use parallel execution and your whole team of sub-agents to minimize total wall-clock time. Your goal is to drive every task to completion and have the owner confirm that all tasks are done. Please leave this session open rather than closing it on your own — it is closed only after the owner has verified completion and asks you to close it. Self-check now:`,
36
- `1. Every request from the owner is registered as a session task and your task list is kept current (mark tasks completed when done); verify nothing is missing or stale.`,
37
- `2. Your plan is the fastest correct path: parallelize independent work across sub-agents, delegate, and remove needless serialization. Choose the fastest safe method, not the easiest.`,
38
- `3. A monitor is in place that detects when any sub-agent produces no output for 5 minutes.`,
39
- `4. If you are blocked on an owner decision — or once you believe all tasks are complete — do not wait passively: the owner is not notified of passive waiting and will not reply unless you raise a new call-to-user, so raise one now (to get the decision, or to ask the owner to verify completion). If you have COMPLETED or ANSWERED a request from the owner in this session, please fire the owner-call to report the RESULT to the owner: completing or answering an owner's requested action is itself a reason to fire the owner-call. Completing or answering an owner request WITHOUT firing the owner-call means the owner is not notified — the owner's app only surfaces this session when the owner-call fires — so the task silently stalls. If this self-check reminder keeps arriving, it is likely because an owner request was completed or answered without firing the owner-call; fire the owner-call now to report the result to the owner. ${(0, exports.composeOwnerCallFormatGuidance)(ownerCallMarker)} If no owner input is needed yet, resume immediately and drive all remaining tasks to completion.`,
40
- `Also, in your next output, report an estimate of how many minutes you expect to need to finish all remaining tasks.`,
35
+ `${silentSessionReminderSentinel_1.SILENT_SESSION_REMINDER_SENTINEL} This is an automated status check. No output has been observed for ${minutes} minutes. If you are waiting on an external process, no action is needed please log one line explaining the wait. Otherwise please continue with the next step, with these points in mind:`,
36
+ `1. Keep the session task list current, marking finished items as done.`,
37
+ `2. Run independent pieces of work in parallel across sub-agents.`,
38
+ `3. Keep a monitor in place that notices when a sub-agent has produced no output for about 5 minutes.`,
39
+ `4. When an owner decision is needed, or when an owner request has been completed or answered, please share it through a new owner-call the owner is notified only when one is raised. ${(0, exports.composeOwnerCallFormatGuidance)(ownerCallMarker)}`,
40
+ `Please also include in your next output an estimate of the remaining minutes to finish all tasks.`,
41
41
  ].join('\n');
42
42
  };
43
43
  const composeMainStalledWithStaleOwnerCallMessage = (mainSilentSeconds, unansweredOwnerCallAgeSeconds, ownerCallMarker) => {
44
44
  const silentMinutes = Math.floor(mainSilentSeconds / 60);
45
45
  const ownerCallAgeMinutes = Math.floor(unansweredOwnerCallAgeSeconds / 60);
46
46
  return [
47
- `${silentSessionReminderSentinel_1.SILENT_SESSION_REMINDER_SENTINEL} You have produced no output for ${silentMinutes} minutes, and the owner call you raised ${ownerCallAgeMinutes} minutes ago is still unanswered. An owner call outstanding this long may have been missed, may have scrolled out of the owner's view, or may no longer reflect your current situation, so do not keep waiting on it passively. Act now, choosing one of the following:`,
48
- `1. If you are still blocked on the owner, re-raise your pending ask NOW as a fresh owner call. Make it fully self-contained: restate the whole situation what happened, what you are asking, and any decision needed — inside the new owner call itself, so the owner understands everything from that single latest message without scrolling back. ${(0, exports.composeOwnerCallFormatGuidance)(ownerCallMarker)}`,
49
- `2. If you are no longer blocked the answer became unnecessary, you can proceed safely, or the information arrived another way — resume immediately and drive all remaining tasks to completion.`,
50
- `This reminder does not notify the owner; only a fresh owner call from you surfaces this session to the owner. Also, in your next output, report an estimate of how many minutes you expect to need to finish all remaining tasks.`,
47
+ `${silentSessionReminderSentinel_1.SILENT_SESSION_REMINDER_SENTINEL} This is an automated status check. No output has been observed for ${silentMinutes} minutes, and the owner call raised ${ownerCallAgeMinutes} minutes ago has not yet been acknowledged by the owner.`,
48
+ `An owner call without an acknowledgment whether it carried a completion report, a question, or a decision requestis still awaiting the owner's acknowledgment, and the earlier message may have been missed. Please re-raise its content as a fresh, self-contained owner call. ${(0, exports.composeOwnerCallFormatGuidance)(ownerCallMarker)}`,
49
+ `Please also include in your next output an estimate of the remaining minutes to finish all tasks.`,
51
50
  ].join('\n');
52
51
  };
53
52
  class DefaultSilentSessionMessageComposer {
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultSilentSessionMessageComposer.js","sourceRoot":"","sources":["../../../src/domain/usecases/DefaultSilentSessionMessageComposer.ts"],"names":[],"mappings":";;;AAKA,mFAAmF;AAEnF,MAAM,aAAa,GAAG,CAAC,OAAe,EAAU,EAAE;IAChD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACzC,OAAO,GAAG,OAAO,GAAG,CAAC;AACvB,CAAC,CAAC;AAEF,MAAM,0BAA0B,GAAG,CACjC,aAAiC,EACzB,EAAE;IACV,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAC7B,CAAC,QAAQ,EAAE,EAAE,CACX,KAAK,QAAQ,CAAC,KAAK,mBAAmB,aAAa,CACjD,QAAQ,CAAC,aAAa,CACvB,EAAE,CACN,CAAC;IACF,OAAO;QACL,GAAG,gEAAgC,ugBAAugB;QAC1iB,GAAG,KAAK;QACR,g1BAAg1B;KACj1B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC,CAAC;AAEF,MAAM,iCAAiC,GAAG,CACxC,oBAAwC,EAChC,EAAE;IACV,MAAM,KAAK,GAAG,oBAAoB,CAAC,GAAG,CACpC,CAAC,QAAQ,EAAE,EAAE,CACX,KAAK,QAAQ,CAAC,KAAK,iBAAiB,aAAa,CAC/C,QAAQ,CAAC,cAAc,CACxB,EAAE,CACN,CAAC;IACF,OAAO;QACL,GAAG,gEAAgC,mOAAmO;QACtQ,GAAG,KAAK;QACR,qNAAqN;KACtN,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC,CAAC;AAEK,MAAM,8BAA8B,GAAG,CAC5C,eAA8B,EACtB,EAAE;IACV,MAAM,iBAAiB,GACrB,eAAe,KAAK,IAAI,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC;QACpD,CAAC,CAAC,gEAAgE,eAAe,iIAAiI;QAClN,CAAC,CAAC,2LAA2L,CAAC;IAClM,OAAO,GAAG,iBAAiB,gzBAAgzB,CAAC;AAC90B,CAAC,CAAC;AARW,QAAA,8BAA8B,kCAQzC;AAEF,MAAM,yBAAyB,GAAG,CAChC,iBAAyB,EACzB,eAA8B,EACtB,EAAE;IACV,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,GAAG,EAAE,CAAC,CAAC;IACnD,OAAO;QACL,GAAG,gEAAgC,oCAAoC,OAAO,s1BAAs1B;QACp6B,0KAA0K;QAC1K,yLAAyL;QACzL,4FAA4F;QAC5F,u6BAAu6B,IAAA,sCAA8B,EAAC,eAAe,CAAC,mGAAmG;QACzjC,qHAAqH;KACtH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC,CAAC;AAEF,MAAM,2CAA2C,GAAG,CAClD,iBAAyB,EACzB,6BAAqC,EACrC,eAA8B,EACtB,EAAE;IACV,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,GAAG,EAAE,CAAC,CAAC;IACzD,MAAM,mBAAmB,GAAG,IAAI,CAAC,KAAK,CAAC,6BAA6B,GAAG,EAAE,CAAC,CAAC;IAC3E,OAAO;QACL,GAAG,gEAAgC,oCAAoC,aAAa,2CAA2C,mBAAmB,yQAAyQ;QAC3Z,0VAA0V,IAAA,sCAA8B,EAAC,eAAe,CAAC,EAAE;QAC3Y,mMAAmM;QACnM,mOAAmO;KACpO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC,CAAC;AAEF,MAAa,mCAAmC;IAC9C,YAA6B,kBAAiC,IAAI;QAArC,oBAAe,GAAf,eAAe,CAAsB;QAElE,8BAAyB,GAAG,CAAC,iBAAyB,EAAU,EAAE;YAChE,OAAO,yBAAyB,CAAC,iBAAiB,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QAC5E,CAAC,CAAC;QAEF,gDAA2C,GAAG,CAC5C,iBAAyB,EACzB,6BAAqC,EAC7B,EAAE;YACV,OAAO,2CAA2C,CAChD,iBAAiB,EACjB,6BAA6B,EAC7B,IAAI,CAAC,eAAe,CACrB,CAAC;QACJ,CAAC,CAAC;QAEF,2BAAsB,GAAG,CAAC,aAAoC,EAAU,EAAE;YACxE,MAAM,QAAQ,GAAa,EAAE,CAAC;YAC9B,IAAI,aAAa,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3C,QAAQ,CAAC,IAAI,CAAC,0BAA0B,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC;YACzE,CAAC;YACD,IAAI,aAAa,CAAC,oBAAoB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAClD,QAAQ,CAAC,IAAI,CACX,iCAAiC,CAAC,aAAa,CAAC,oBAAoB,CAAC,CACtE,CAAC;YACJ,CAAC;YACD,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/B,CAAC,CAAC;IA5BmE,CAAC;CA6BvE;AA9BD,kFA8BC"}
1
+ {"version":3,"file":"DefaultSilentSessionMessageComposer.js","sourceRoot":"","sources":["../../../src/domain/usecases/DefaultSilentSessionMessageComposer.ts"],"names":[],"mappings":";;;AAKA,mFAAmF;AAEnF,MAAM,aAAa,GAAG,CAAC,OAAe,EAAU,EAAE;IAChD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACzC,OAAO,GAAG,OAAO,GAAG,CAAC;AACvB,CAAC,CAAC;AAEF,MAAM,0BAA0B,GAAG,CACjC,aAAiC,EACzB,EAAE;IACV,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAC7B,CAAC,QAAQ,EAAE,EAAE,CACX,KAAK,QAAQ,CAAC,KAAK,mBAAmB,aAAa,CACjD,QAAQ,CAAC,aAAa,CACvB,EAAE,CACN,CAAC;IACF,OAAO;QACL,GAAG,gEAAgC,gKAAgK;QACnM,GAAG,KAAK;QACR,8PAA8P;KAC/P,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC,CAAC;AAEF,MAAM,iCAAiC,GAAG,CACxC,oBAAwC,EAChC,EAAE;IACV,MAAM,KAAK,GAAG,oBAAoB,CAAC,GAAG,CACpC,CAAC,QAAQ,EAAE,EAAE,CACX,KAAK,QAAQ,CAAC,KAAK,iBAAiB,aAAa,CAC/C,QAAQ,CAAC,cAAc,CACxB,EAAE,CACN,CAAC;IACF,OAAO;QACL,GAAG,gEAAgC,uHAAuH;QAC1J,GAAG,KAAK;QACR,uLAAuL;KACxL,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC,CAAC;AAEK,MAAM,8BAA8B,GAAG,CAC5C,eAA8B,EACtB,EAAE;IACV,MAAM,QAAQ,GACZ,eAAe,KAAK,IAAI,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC;QACpD,CAAC,CAAC,KAAK,eAAe,GAAG;QACzB,CAAC,CAAC,EAAE,CAAC;IACT,OAAO,mDAAmD,QAAQ,sPAAsP,CAAC;AAC3T,CAAC,CAAC;AARW,QAAA,8BAA8B,kCAQzC;AAEF,MAAM,yBAAyB,GAAG,CAChC,iBAAyB,EACzB,eAA8B,EACtB,EAAE;IACV,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,GAAG,EAAE,CAAC,CAAC;IACnD,OAAO;QACL,GAAG,gEAAgC,uEAAuE,OAAO,8LAA8L;QAC/S,wEAAwE;QACxE,kEAAkE;QAClE,sGAAsG;QACtG,2LAA2L,IAAA,sCAA8B,EACvN,eAAe,CAChB,EAAE;QACH,mGAAmG;KACpG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC,CAAC;AAEF,MAAM,2CAA2C,GAAG,CAClD,iBAAyB,EACzB,6BAAqC,EACrC,eAA8B,EACtB,EAAE;IACV,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,GAAG,EAAE,CAAC,CAAC;IACzD,MAAM,mBAAmB,GAAG,IAAI,CAAC,KAAK,CAAC,6BAA6B,GAAG,EAAE,CAAC,CAAC;IAC3E,OAAO;QACL,GAAG,gEAAgC,uEAAuE,aAAa,uCAAuC,mBAAmB,0DAA0D;QAC3O,wRAAwR,IAAA,sCAA8B,EACpT,eAAe,CAChB,EAAE;QACH,mGAAmG;KACpG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC,CAAC;AAEF,MAAa,mCAAmC;IAC9C,YAA6B,kBAAiC,IAAI;QAArC,oBAAe,GAAf,eAAe,CAAsB;QAElE,8BAAyB,GAAG,CAAC,iBAAyB,EAAU,EAAE;YAChE,OAAO,yBAAyB,CAAC,iBAAiB,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QAC5E,CAAC,CAAC;QAEF,gDAA2C,GAAG,CAC5C,iBAAyB,EACzB,6BAAqC,EAC7B,EAAE;YACV,OAAO,2CAA2C,CAChD,iBAAiB,EACjB,6BAA6B,EAC7B,IAAI,CAAC,eAAe,CACrB,CAAC;QACJ,CAAC,CAAC;QAEF,2BAAsB,GAAG,CAAC,aAAoC,EAAU,EAAE;YACxE,MAAM,QAAQ,GAAa,EAAE,CAAC;YAC9B,IAAI,aAAa,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3C,QAAQ,CAAC,IAAI,CAAC,0BAA0B,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC;YACzE,CAAC;YACD,IAAI,aAAa,CAAC,oBAAoB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAClD,QAAQ,CAAC,IAAI,CACX,iCAAiC,CAAC,aAAa,CAAC,oBAAoB,CAAC,CACtE,CAAC;YACJ,CAAC;YACD,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/B,CAAC,CAAC;IA5BmE,CAAC;CA6BvE;AA9BD,kFA8BC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "github-issue-tower-defence-management",
3
- "version": "1.122.6",
3
+ "version": "1.122.8",
4
4
  "description": "",
5
5
  "main": "bin/index.js",
6
6
  "scripts": {
@@ -159,7 +159,7 @@ describe('notifySilentTmuxSessions', () => {
159
159
  (call) => call[0] === 'tmux' && call[1][0] === 'send-keys',
160
160
  );
161
161
  expect(sendCall?.[1][2]).toBe(SESSION_NAME);
162
- expect(sendCall?.[1][4]).toContain('You have produced no output for');
162
+ expect(sendCall?.[1][4]).toContain('No output has been observed for');
163
163
  });
164
164
 
165
165
  it('does not notify a silent github-named live session on its first candidate cycle', async () => {
@@ -234,7 +234,7 @@ describe('notifySilentTmuxSessions', () => {
234
234
  `${SILENT_SESSION_REMINDER_SENTINEL} CUSTOM_MAIN_TEMPLATE`,
235
235
  );
236
236
  expect(sendCall?.[1][4]).toContain(
237
- 'Please avoid telling the owner to scroll up, go back, or read previous or above messages',
237
+ 'complete opening and closing pair on one line',
238
238
  );
239
239
  });
240
240
 
@@ -308,10 +308,12 @@ describe('notifySilentTmuxSessions', () => {
308
308
  (call) => call[0] === 'tmux' && call[1][0] === 'send-keys',
309
309
  );
310
310
  expect(sendCall?.[1][2]).toBe(SESSION_NAME);
311
- expect(sendCall?.[1][4]).toContain('is still unanswered');
311
+ expect(sendCall?.[1][4]).toContain('has not yet been acknowledged');
312
312
  expect(sendCall?.[1][4]).toContain(
313
- 're-raise your pending ask NOW as a fresh owner call',
313
+ 're-raise its content as a fresh, self-contained owner call',
314
314
  );
315
+ expect(sendCall?.[1][4]).not.toContain('no longer blocked');
316
+ expect(sendCall?.[1][4]).not.toContain('continue with the next step');
315
317
  });
316
318
 
317
319
  it('defers the first cycle then notifies on the next cycle once the persisted candidate state confirms a second consecutive cycle', async () => {
@@ -47,7 +47,7 @@ describe('ConfigurableSilentSessionMessageComposer', () => {
47
47
  expect(fallback.composeMainStalledSection).not.toHaveBeenCalled();
48
48
  });
49
49
 
50
- it('appends the owner-call format guidance, including the self-contained and no-scroll-back requirements, to the configured main template', () => {
50
+ it('appends the owner-call format guidance, including the self-contained requirement, to the configured main template', () => {
51
51
  const fallback = createFallback();
52
52
  const composer = new ConfigurableSilentSessionMessageComposer(
53
53
  {
@@ -60,15 +60,10 @@ describe('ConfigurableSilentSessionMessageComposer', () => {
60
60
  const section = composer.composeMainStalledSection(600);
61
61
  expect(section).toContain('CUSTOM_MAIN');
62
62
  expect(section).toContain(
63
- 'the configured owner-call marker tag "<<OWNER_CALL>>" as a complete matching pair',
63
+ 'owner-call marker tag "<<OWNER_CALL>>" as a complete opening and closing pair on one line',
64
64
  );
65
65
  expect(section).toContain('🔴');
66
- expect(section).toContain(
67
- 'Make the owner-call message fully self-contained: the owner should be able to understand the whole situation — what happened, what you are asking, and any decision needed — from this single latest owner-call message alone, without reading or scrolling back to earlier messages.',
68
- );
69
- expect(section).toContain(
70
- 'Please avoid telling the owner to scroll up, go back, or read previous or above messages; if context is needed, restate it inside the owner-call message itself.',
71
- );
66
+ expect(section).toContain('written to be self-contained');
72
67
  });
73
68
 
74
69
  it('uses the fallback stale-owner-call section when no stale-owner-call template is configured', () => {
@@ -102,7 +97,7 @@ describe('ConfigurableSilentSessionMessageComposer', () => {
102
97
  expect(section).toContain('CUSTOM_STALE_OWNER_CALL');
103
98
  expect(section).toContain(SILENT_SESSION_REMINDER_SENTINEL);
104
99
  expect(section).toContain(
105
- 'the configured owner-call marker tag "<<OWNER_CALL>>" as a complete matching pair',
100
+ 'owner-call marker tag "<<OWNER_CALL>>" as a complete opening and closing pair on one line',
106
101
  );
107
102
  expect(
108
103
  fallback.composeMainStalledWithStaleOwnerCallSection,
@@ -23,78 +23,61 @@ describe('DefaultSilentSessionMessageComposer', () => {
23
23
  expect(section).toContain(SILENT_SESSION_REMINDER_SENTINEL);
24
24
  });
25
25
 
26
- it('renders the configured main-stalled message with the silent minutes substituted', () => {
26
+ it('renders the main-stalled message as a neutral automated status notice with the silent minutes substituted', () => {
27
27
  const section = composer.composeMainStalledSection(600);
28
- expect(section).toContain('You have produced no output for 10 minutes.');
29
- expect(section).toContain('Idle waiting wastes this live session');
28
+ expect(section).toContain('This is an automated status check.');
29
+ expect(section).toContain('No output has been observed for 10 minutes.');
30
30
  expect(section).toContain(
31
- 'Always work proactively and stay ahead of the work',
31
+ 'If you are waiting on an external process, no action is needed — please log one line explaining the wait.',
32
32
  );
33
- expect(section).toContain('rather than waiting passively');
34
- expect(section).toContain('Self-check now:');
33
+ expect(section).toContain('Otherwise please continue with the next step');
35
34
  expect(section).toContain('1.');
36
35
  expect(section).toContain('2.');
37
36
  expect(section).toContain('3.');
38
37
  expect(section).toContain('4.');
39
- expect(section).toContain(
40
- 'report an estimate of how many minutes you expect to need',
41
- );
42
- });
43
-
44
- it('floors the silent seconds to whole minutes', () => {
45
- const section = composer.composeMainStalledSection(659);
46
- expect(section).toContain('You have produced no output for 10 minutes.');
47
38
  });
48
39
 
49
- it('instructs the required owner-call notification format with the leading red circle and single-line complete tag', () => {
40
+ it('states each of the four checkpoints exactly once', () => {
50
41
  const section = composer.composeMainStalledSection(600);
51
- expect(section).toContain('🔴');
52
- expect(section).toContain(
53
- 'The content between the markers needs to begin with the 🔴 emoji immediately, with no space after it.',
54
- );
55
- expect(section).toContain(
56
- 'complete matching pair — opening marker, content, then closing marker — on a single line with no newline inside the tag.',
57
- );
58
- expect(section).toContain(
59
- 'a malformed tag (a broken or missing closing marker, or a missing leading 🔴) results in only a red indicator with no readable content.',
60
- );
42
+ const occurrences = (needle: string): number =>
43
+ section.split(needle).length - 1;
44
+ expect(occurrences('Keep the session task list current')).toBe(1);
45
+ expect(occurrences('Run independent pieces of work in parallel')).toBe(1);
46
+ expect(
47
+ occurrences(
48
+ 'Keep a monitor in place that notices when a sub-agent has produced no output for about 5 minutes.',
49
+ ),
50
+ ).toBe(1);
51
+ expect(occurrences('share it through a new owner-call')).toBe(1);
61
52
  });
62
53
 
63
- it('requires the owner-call message to be fully self-contained and forbids telling the owner to scroll back', () => {
54
+ it('requests a remaining-minutes estimate in the next output', () => {
64
55
  const section = composer.composeMainStalledSection(600);
65
56
  expect(section).toContain(
66
- 'Make the owner-call message fully self-contained: the owner should be able to understand the whole situation — what happened, what you are asking, and any decision needed — from this single latest owner-call message alone, without reading or scrolling back to earlier messages.',
67
- );
68
- expect(section).toContain(
69
- 'Please avoid telling the owner to scroll up, go back, or read previous or above messages; if context is needed, restate it inside the owner-call message itself.',
57
+ 'an estimate of the remaining minutes to finish all tasks',
70
58
  );
71
59
  });
72
60
 
73
- it('instructs the agent to fire the owner-call when an owner request has been completed or answered', () => {
74
- const section = composer.composeMainStalledSection(600);
75
- expect(section).toContain(
76
- 'If you have COMPLETED or ANSWERED a request from the owner in this session, please fire the owner-call to report the RESULT to the owner',
77
- );
78
- expect(section).toContain(
79
- "completing or answering an owner's requested action is itself a reason to fire the owner-call",
80
- );
61
+ it('floors the silent seconds to whole minutes', () => {
62
+ const section = composer.composeMainStalledSection(659);
63
+ expect(section).toContain('No output has been observed for 10 minutes.');
81
64
  });
82
65
 
83
- it('explains that completing an owner request without an owner-call leaves the owner unnotified', () => {
66
+ it('states the owner-call tag format exactly once: complete pair on one line, content starting with the red-circle emoji, self-contained', () => {
84
67
  const section = composer.composeMainStalledSection(600);
68
+ const formatOccurrences =
69
+ section.split('complete opening and closing pair on one line').length - 1;
70
+ expect(formatOccurrences).toBe(1);
71
+ expect(section).toContain('🔴');
85
72
  expect(section).toContain(
86
- 'Completing or answering an owner request WITHOUT firing the owner-call means the owner is not notified',
87
- );
88
- expect(section).toContain(
89
- "the owner's app only surfaces this session when the owner-call fires",
73
+ 'with the content starting immediately with the 🔴 emoji',
90
74
  );
75
+ expect(section).toContain('written to be self-contained');
91
76
  });
92
77
 
93
- it('states the causal link that the reminder keeps arriving because no owner-call was fired', () => {
78
+ it('explains that the owner is notified only when an owner-call is raised', () => {
94
79
  const section = composer.composeMainStalledSection(600);
95
- expect(section).toContain(
96
- 'If this self-check reminder keeps arriving, it is likely because an owner request was completed or answered without firing the owner-call; fire the owner-call now to report the result to the owner.',
97
- );
80
+ expect(section).toContain('the owner is notified only when one is raised');
98
81
  });
99
82
 
100
83
  it('interpolates the configured owner-call marker into the format guidance when provided', () => {
@@ -103,7 +86,7 @@ describe('DefaultSilentSessionMessageComposer', () => {
103
86
  );
104
87
  const section = markedComposer.composeMainStalledSection(600);
105
88
  expect(section).toContain(
106
- 'the configured owner-call marker tag "<<OWNER_CALL>>" as a complete matching pair',
89
+ 'owner-call marker tag "<<OWNER_CALL>>" as a complete opening and closing pair on one line',
107
90
  );
108
91
  expect(section).toContain('🔴');
109
92
  });
@@ -111,7 +94,7 @@ describe('DefaultSilentSessionMessageComposer', () => {
111
94
  it('falls back to generic owner-call format guidance when no marker is configured', () => {
112
95
  const section = composer.composeMainStalledSection(600);
113
96
  expect(section).toContain(
114
- 'Emit the owner-call as the configured owner-call marker tag as a complete matching pair',
97
+ 'owner-call marker tag as a complete opening and closing pair on one line',
115
98
  );
116
99
  expect(section).not.toContain('""');
117
100
  });
@@ -130,43 +113,63 @@ describe('DefaultSilentSessionMessageComposer', () => {
130
113
  3659,
131
114
  );
132
115
  expect(section).toContain(
133
- 'You have produced no output for 10 minutes, and the owner call you raised 60 minutes ago is still unanswered.',
116
+ 'No output has been observed for 10 minutes, and the owner call raised 60 minutes ago has not yet been acknowledged by the owner.',
134
117
  );
135
118
  });
136
119
 
137
- it('directs the agent to re-raise its pending ask as a fresh fully self-contained owner call', () => {
120
+ it('instructs unconditionally to re-raise the content as a fresh self-contained owner call', () => {
138
121
  const section = composer.composeMainStalledWithStaleOwnerCallSection(
139
122
  600,
140
123
  3600,
141
124
  );
142
125
  expect(section).toContain(
143
- 'If you are still blocked on the owner, re-raise your pending ask NOW as a fresh owner call.',
144
- );
145
- expect(section).toContain(
146
- 'Make it fully self-contained: restate the whole situation — what happened, what you are asking, and any decision needed — inside the new owner call itself',
126
+ 'Please re-raise its content as a fresh, self-contained owner call.',
147
127
  );
148
128
  });
149
129
 
150
- it('directs the agent to continue autonomously when it is no longer blocked', () => {
130
+ it('frames every unanswered owner call kind as awaiting acknowledgment', () => {
151
131
  const section = composer.composeMainStalledWithStaleOwnerCallSection(
152
132
  600,
153
133
  3600,
154
134
  );
135
+ expect(section).toContain('acknowledg');
155
136
  expect(section).toContain(
156
- 'If you are no longer blocked — the answer became unnecessary, you can proceed safely, or the information arrived another way — resume immediately and drive all remaining tasks to completion.',
137
+ 'a completion report, a question, or a decision request',
138
+ );
139
+ expect(section).toContain("still awaiting the owner's acknowledgment");
140
+ });
141
+
142
+ it('contains no not-blocked escape phrasing and no conditional re-raise phrasing', () => {
143
+ const section = composer.composeMainStalledWithStaleOwnerCallSection(
144
+ 600,
145
+ 3600,
157
146
  );
147
+ expect(section).not.toContain('no longer blocked');
148
+ expect(section).not.toContain('continue with the next step');
149
+ expect(section).not.toContain('If you are still waiting');
150
+ expect(section).not.toContain('If you are');
158
151
  });
159
152
 
160
- it('states that the stale-owner-call reminder itself does not notify the owner', () => {
153
+ it('requests a remaining-minutes estimate in the stale-owner-call section', () => {
161
154
  const section = composer.composeMainStalledWithStaleOwnerCallSection(
162
155
  600,
163
156
  3600,
164
157
  );
165
158
  expect(section).toContain(
166
- 'This reminder does not notify the owner; only a fresh owner call from you surfaces this session to the owner.',
159
+ 'an estimate of the remaining minutes to finish all tasks',
167
160
  );
168
161
  });
169
162
 
163
+ it('states the owner-call format guidance exactly once in the stale-owner-call section', () => {
164
+ const section = composer.composeMainStalledWithStaleOwnerCallSection(
165
+ 600,
166
+ 3600,
167
+ );
168
+ const formatOccurrences =
169
+ section.split('complete opening and closing pair on one line').length - 1;
170
+ expect(formatOccurrences).toBe(1);
171
+ });
172
+
170
173
  it('interpolates the configured owner-call marker into the stale-owner-call format guidance', () => {
171
174
  const markedComposer = new DefaultSilentSessionMessageComposer(
172
175
  '<<OWNER_CALL>>',
@@ -176,7 +179,7 @@ describe('DefaultSilentSessionMessageComposer', () => {
176
179
  3600,
177
180
  );
178
181
  expect(section).toContain(
179
- 'the configured owner-call marker tag "<<OWNER_CALL>>" as a complete matching pair',
182
+ 'owner-call marker tag "<<OWNER_CALL>>" as a complete opening and closing pair on one line',
180
183
  );
181
184
  expect(section).toContain('🔴');
182
185
  });
@@ -188,7 +191,7 @@ describe('DefaultSilentSessionMessageComposer', () => {
188
191
  3600,
189
192
  );
190
193
  expect(staleSection).not.toBe(plainSection);
191
- expect(plainSection).not.toContain('is still unanswered');
194
+ expect(plainSection).not.toContain('has not yet been acknowledged');
192
195
  });
193
196
 
194
197
  it('emits a distinct idle message for a sub-agent that is only output-idle', () => {
@@ -205,12 +208,12 @@ describe('DefaultSilentSessionMessageComposer', () => {
205
208
  });
206
209
  expect(section).toContain('sub-process-idle');
207
210
  expect(section).toContain('no output for 6m');
208
- expect(section).toContain('restart, hand off, or replace it');
211
+ expect(section).toContain('please restart it, hand it off, or replace it');
209
212
  expect(section).toContain('waiting on an external dependency');
210
- expect(section).not.toContain('infinite loop');
213
+ expect(section).not.toContain('running longer than a task usually takes');
211
214
  });
212
215
 
213
- it('presents the system-detected idle duration as the authoritative signal in the idle message', () => {
216
+ it('frames the idle message as an automated status check with the system-measured duration', () => {
214
217
  const section = composer.composeSubAgentSection({
215
218
  idleSubAgents: [
216
219
  {
@@ -222,36 +225,14 @@ describe('DefaultSilentSessionMessageComposer', () => {
222
225
  ],
223
226
  longRunningSubAgents: [],
224
227
  });
228
+ expect(section).toContain('This is an automated status check.');
225
229
  expect(section).toContain(
226
- "The system has already detected, from each sub-process's last tool activity, that it has produced no output for about the minutes shown below.",
227
- );
228
- expect(section).toContain(
229
- 'Please treat that figure as the authoritative system signal; there is no need to spend effort re-deriving whether the sub-process is alive.',
230
+ 'produced no output for about the minutes shown, measured from their last tool activity',
230
231
  );
231
232
  expect(section).toContain('no output for 6m');
232
233
  });
233
234
 
234
- it('forbids speculation and dismissal without evidence in the idle message', () => {
235
- const section = composer.composeSubAgentSection({
236
- idleSubAgents: [
237
- {
238
- label: 'sub-process-idle',
239
- silentSeconds: 360,
240
- runningSeconds: 60,
241
- waitingOnExternalProcess: false,
242
- },
243
- ],
244
- longRunningSubAgents: [],
245
- });
246
- expect(section).toContain(
247
- 'Around five minutes of silence is a real warning of a possible hang',
248
- );
249
- expect(section).toContain(
250
- 'please base your assessment on concrete evidence rather than speculation ("probably still working"), and please keep the warning in view until evidence resolves it.',
251
- );
252
- });
253
-
254
- it('requires a concrete cause-check covering recent activity and external-dependency waiting in the idle message', () => {
235
+ it('tells the agent that logging one line suffices for a legitimate external wait in the idle message', () => {
255
236
  const section = composer.composeSubAgentSection({
256
237
  idleSubAgents: [
257
238
  {
@@ -263,35 +244,11 @@ describe('DefaultSilentSessionMessageComposer', () => {
263
244
  ],
264
245
  longRunningSubAgents: [],
265
246
  });
266
- expect(section).toContain('determine the CAUSE by a concrete check');
267
247
  expect(section).toContain(
268
- 'a very recent push or commit, or output from any nested sub-processes this sub-process itself started',
248
+ 'a continuous-integration run, an external API, or another process',
269
249
  );
270
250
  expect(section).toContain(
271
- 'legitimately blocked waiting on an external dependency',
272
- );
273
- expect(section).toContain(
274
- 'confirm it by investigation before concluding — do not assume',
275
- );
276
- expect(section).toContain(
277
- 'if it is legitimately waiting, state that conclusion together with the concrete evidence you found',
278
- );
279
- });
280
-
281
- it('requires logging the investigation result even though owner notification is not required', () => {
282
- const section = composer.composeSubAgentSection({
283
- idleSubAgents: [
284
- {
285
- label: 'sub-process-idle',
286
- silentSeconds: 360,
287
- runningSeconds: 60,
288
- waitingOnExternalProcess: false,
289
- },
290
- ],
291
- longRunningSubAgents: [],
292
- });
293
- expect(section).toContain(
294
- 'Owner notification is not required, but please output your investigation result in this session so it remains as a log.',
251
+ 'no action is needed please log one line noting the wait',
295
252
  );
296
253
  });
297
254
 
@@ -309,14 +266,12 @@ describe('DefaultSilentSessionMessageComposer', () => {
309
266
  });
310
267
  expect(section).toContain('sub-process-long');
311
268
  expect(section).toContain('running for 20m');
312
- expect(section).toContain('infinite loop');
313
- expect(section).toContain('too large');
314
- expect(section).toContain('not making forward progress');
269
+ expect(section).toContain('running longer than a task usually takes');
315
270
  expect(section).toContain(
316
- 'do not dismiss it merely because it produced output recently',
271
+ 'breaking the task down, restarting it, handing it off, or replacing it',
317
272
  );
318
273
  expect(section).toContain(
319
- 'break the task down, restart, hand off, or replace',
274
+ 'If it is progressing normally, no action is needed.',
320
275
  );
321
276
  });
322
277
 
@@ -348,9 +303,8 @@ describe('DefaultSilentSessionMessageComposer', () => {
348
303
  longRunningSubAgents: [subAgent],
349
304
  });
350
305
  expect(section).toContain('no output for 6m');
351
- expect(section).toContain('determine the CAUSE by a concrete check');
352
306
  expect(section).toContain('running for 20m');
353
- expect(section).toContain('infinite loop');
307
+ expect(section).toContain('running longer than a task usually takes');
354
308
  const sentinelOccurrences =
355
309
  section.split(SILENT_SESSION_REMINDER_SENTINEL).length - 1;
356
310
  expect(sentinelOccurrences).toBe(2);
@@ -382,12 +336,19 @@ describe('DefaultSilentSessionMessageComposer', () => {
382
336
  expect(longRunningSection).not.toContain('idle-only');
383
337
  });
384
338
 
385
- it('composes default texts free of prohibition-styled vocabulary that trips model safety classifiers', () => {
339
+ it('composes default texts free of pressure- and prohibition-styled vocabulary that trips model safety classifiers', () => {
386
340
  const flaggedPatterns = [
387
341
  /unacceptable/i,
388
342
  /\bnever\b/i,
389
343
  /\b[Dd]o NOT\b/,
390
344
  /\b[Yy]ou MUST\b/,
345
+ /\bwastes?\b/i,
346
+ /silently stalls/i,
347
+ /\bstall(s|ed|ing)?\b/i,
348
+ /raise one now/i,
349
+ /fire the owner-call now/i,
350
+ /do not wait passively/i,
351
+ /is prohibited/i,
391
352
  ];
392
353
  const markedComposer = new DefaultSilentSessionMessageComposer(
393
354
  '<<OWNER_CALL>>',
@@ -20,9 +20,9 @@ const composeIdleSubAgentSection = (
20
20
  )}`,
21
21
  );
22
22
  return [
23
- `${SILENT_SESSION_REMINDER_SENTINEL} The system has already detected, from each sub-process's last tool activity, that it has produced no output for about the minutes shown below. Please treat that figure as the authoritative system signal; there is no need to spend effort re-deriving whether the sub-process is alive. Around five minutes of silence is a real warning of a possible hang: please base your assessment on concrete evidence rather than speculation ("probably still working"), and please keep the warning in view until evidence resolves it.`,
23
+ `${SILENT_SESSION_REMINDER_SENTINEL} This is an automated status check. The following sub-process(es) have produced no output for about the minutes shown, measured from their last tool activity:`,
24
24
  ...lines,
25
- 'For each one, determine the CAUSE by a concrete check and report the result. Verify specifically: (a) whether there is genuinely no recent activity anywhere — including a very recent push or commit, or output from any nested sub-processes this sub-process itself started; and (b) whether it is legitimately blocked waiting on an external dependency (a continuous-integration run, an external API, or another process). Waiting on continuous integration is plausible, but confirm it by investigation before concluding do not assume. Based on the check: if it is genuinely stuck, take action (restart, hand off, or replace it); if it is legitimately waiting, state that conclusion together with the concrete evidence you found. Owner notification is not required, but please output your investigation result in this session so it remains as a log.',
25
+ 'For each one: if it is waiting on an external dependency (a continuous-integration run, an external API, or another process), no action is neededplease log one line noting the wait. If it appears stuck, please restart it, hand it off, or replace it.',
26
26
  ].join('\n');
27
27
  };
28
28
 
@@ -36,20 +36,20 @@ const composeLongRunningSubAgentSection = (
36
36
  )}`,
37
37
  );
38
38
  return [
39
- `${SILENT_SESSION_REMINDER_SENTINEL} The following sub-process(es) have been running longer than a task should normally take, which may mean an infinite loop, a task that is too large, or being stuck in an incorrect approach that is not making forward progress:`,
39
+ `${SILENT_SESSION_REMINDER_SENTINEL} This is an automated status check. The following sub-process(es) have been running longer than a task usually takes:`,
40
40
  ...lines,
41
- 'Verify each one is genuinely advancing toward completion; do not dismiss it merely because it produced output recently. If it is not progressing, intervene: break the task down, restart, hand off, or replace it.',
41
+ 'If one is not making progress toward completion, consider breaking the task down, restarting it, handing it off, or replacing it. If it is progressing normally, no action is needed.',
42
42
  ].join('\n');
43
43
  };
44
44
 
45
45
  export const composeOwnerCallFormatGuidance = (
46
46
  ownerCallMarker: string | null,
47
47
  ): string => {
48
- const markerInstruction =
48
+ const tagLabel =
49
49
  ownerCallMarker !== null && ownerCallMarker.length > 0
50
- ? `Emit the owner-call as the configured owner-call marker tag "${ownerCallMarker}" as a complete matching pair — opening marker, content, then closing marker — on a single line with no newline inside the tag.`
51
- : `Emit the owner-call as the configured owner-call marker tag as a complete matching pair — opening marker, content, then closing marker — on a single line with no newline inside the tag.`;
52
- return `${markerInstruction} The content between the markers needs to begin with the 🔴 emoji immediately, with no space after it. The owner's app only surfaces the notification together with its content when the exact, well-formed tag with the leading 🔴 is present; a malformed tag (a broken or missing closing marker, or a missing leading 🔴) results in only a red indicator with no readable content. Make the owner-call message fully self-contained: the owner should be able to understand the whole situation — what happened, what you are asking, and any decision needed from this single latest owner-call message alone, without reading or scrolling back to earlier messages. Please avoid telling the owner to scroll up, go back, or read previous or above messages; if context is needed, restate it inside the owner-call message itself.`;
50
+ ? ` "${ownerCallMarker}"`
51
+ : '';
52
+ return `Format reminder: write the owner-call marker tag${tagLabel} as a complete opening and closing pair on one line, with the content starting immediately with the 🔴 emoji and written to be self-contained, so the owner can understand the situation, the ask, and any decision needed from that single message.`;
53
53
  };
54
54
 
55
55
  const composeMainStalledMessage = (
@@ -58,12 +58,14 @@ const composeMainStalledMessage = (
58
58
  ): string => {
59
59
  const minutes = Math.floor(mainSilentSeconds / 60);
60
60
  return [
61
- `${SILENT_SESSION_REMINDER_SENTINEL} You have produced no output for ${minutes} minutes. Idle waiting wastes this live session, so please keep making progress. Always work proactively and stay ahead of the work: anticipate the next steps and, at every point, choose the fastest path so the whole task finishes as early as possible, rather than waiting passively. Finish every task in the shortest possible time — but "fastest" means correct and incident-free, not merely quick: a fast but wrong result is worthless and causes incidents, so be fast without breaking things. Use parallel execution and your whole team of sub-agents to minimize total wall-clock time. Your goal is to drive every task to completion and have the owner confirm that all tasks are done. Please leave this session open rather than closing it on your own — it is closed only after the owner has verified completion and asks you to close it. Self-check now:`,
62
- `1. Every request from the owner is registered as a session task and your task list is kept current (mark tasks completed when done); verify nothing is missing or stale.`,
63
- `2. Your plan is the fastest correct path: parallelize independent work across sub-agents, delegate, and remove needless serialization. Choose the fastest safe method, not the easiest.`,
64
- `3. A monitor is in place that detects when any sub-agent produces no output for 5 minutes.`,
65
- `4. If you are blocked on an owner decision — or once you believe all tasks are complete — do not wait passively: the owner is not notified of passive waiting and will not reply unless you raise a new call-to-user, so raise one now (to get the decision, or to ask the owner to verify completion). If you have COMPLETED or ANSWERED a request from the owner in this session, please fire the owner-call to report the RESULT to the owner: completing or answering an owner's requested action is itself a reason to fire the owner-call. Completing or answering an owner request WITHOUT firing the owner-call means the owner is not notified — the owner's app only surfaces this session when the owner-call fires — so the task silently stalls. If this self-check reminder keeps arriving, it is likely because an owner request was completed or answered without firing the owner-call; fire the owner-call now to report the result to the owner. ${composeOwnerCallFormatGuidance(ownerCallMarker)} If no owner input is needed yet, resume immediately and drive all remaining tasks to completion.`,
66
- `Also, in your next output, report an estimate of how many minutes you expect to need to finish all remaining tasks.`,
61
+ `${SILENT_SESSION_REMINDER_SENTINEL} This is an automated status check. No output has been observed for ${minutes} minutes. If you are waiting on an external process, no action is needed please log one line explaining the wait. Otherwise please continue with the next step, with these points in mind:`,
62
+ `1. Keep the session task list current, marking finished items as done.`,
63
+ `2. Run independent pieces of work in parallel across sub-agents.`,
64
+ `3. Keep a monitor in place that notices when a sub-agent has produced no output for about 5 minutes.`,
65
+ `4. When an owner decision is needed, or when an owner request has been completed or answered, please share it through a new owner-call the owner is notified only when one is raised. ${composeOwnerCallFormatGuidance(
66
+ ownerCallMarker,
67
+ )}`,
68
+ `Please also include in your next output an estimate of the remaining minutes to finish all tasks.`,
67
69
  ].join('\n');
68
70
  };
69
71
 
@@ -75,10 +77,11 @@ const composeMainStalledWithStaleOwnerCallMessage = (
75
77
  const silentMinutes = Math.floor(mainSilentSeconds / 60);
76
78
  const ownerCallAgeMinutes = Math.floor(unansweredOwnerCallAgeSeconds / 60);
77
79
  return [
78
- `${SILENT_SESSION_REMINDER_SENTINEL} You have produced no output for ${silentMinutes} minutes, and the owner call you raised ${ownerCallAgeMinutes} minutes ago is still unanswered. An owner call outstanding this long may have been missed, may have scrolled out of the owner's view, or may no longer reflect your current situation, so do not keep waiting on it passively. Act now, choosing one of the following:`,
79
- `1. If you are still blocked on the owner, re-raise your pending ask NOW as a fresh owner call. Make it fully self-contained: restate the whole situation what happened, what you are asking, and any decision needed — inside the new owner call itself, so the owner understands everything from that single latest message without scrolling back. ${composeOwnerCallFormatGuidance(ownerCallMarker)}`,
80
- `2. If you are no longer blocked — the answer became unnecessary, you can proceed safely, or the information arrived another way — resume immediately and drive all remaining tasks to completion.`,
81
- `This reminder does not notify the owner; only a fresh owner call from you surfaces this session to the owner. Also, in your next output, report an estimate of how many minutes you expect to need to finish all remaining tasks.`,
80
+ `${SILENT_SESSION_REMINDER_SENTINEL} This is an automated status check. No output has been observed for ${silentMinutes} minutes, and the owner call raised ${ownerCallAgeMinutes} minutes ago has not yet been acknowledged by the owner.`,
81
+ `An owner call without an acknowledgment whether it carried a completion report, a question, or a decision requestis still awaiting the owner's acknowledgment, and the earlier message may have been missed. Please re-raise its content as a fresh, self-contained owner call. ${composeOwnerCallFormatGuidance(
82
+ ownerCallMarker,
83
+ )}`,
84
+ `Please also include in your next output an estimate of the remaining minutes to finish all tasks.`,
82
85
  ].join('\n');
83
86
  };
84
87
 
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultSilentSessionMessageComposer.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/DefaultSilentSessionMessageComposer.ts"],"names":[],"mappings":"AACA,OAAO,EACL,4BAA4B,EAC5B,qBAAqB,EACtB,MAAM,mDAAmD,CAAC;AAwC3D,eAAO,MAAM,8BAA8B,GACzC,iBAAiB,MAAM,GAAG,IAAI,KAC7B,MAMF,CAAC;AAgCF,qBAAa,mCAAoC,YAAW,4BAA4B;IAC1E,OAAO,CAAC,QAAQ,CAAC,eAAe;gBAAf,eAAe,GAAE,MAAM,GAAG,IAAW;IAElE,yBAAyB,GAAI,mBAAmB,MAAM,KAAG,MAAM,CAE7D;IAEF,2CAA2C,GACzC,mBAAmB,MAAM,EACzB,+BAA+B,MAAM,KACpC,MAAM,CAMP;IAEF,sBAAsB,GAAI,eAAe,qBAAqB,KAAG,MAAM,CAWrE;CACH"}
1
+ {"version":3,"file":"DefaultSilentSessionMessageComposer.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/DefaultSilentSessionMessageComposer.ts"],"names":[],"mappings":"AACA,OAAO,EACL,4BAA4B,EAC5B,qBAAqB,EACtB,MAAM,mDAAmD,CAAC;AAwC3D,eAAO,MAAM,8BAA8B,GACzC,iBAAiB,MAAM,GAAG,IAAI,KAC7B,MAMF,CAAC;AAmCF,qBAAa,mCAAoC,YAAW,4BAA4B;IAC1E,OAAO,CAAC,QAAQ,CAAC,eAAe;gBAAf,eAAe,GAAE,MAAM,GAAG,IAAW;IAElE,yBAAyB,GAAI,mBAAmB,MAAM,KAAG,MAAM,CAE7D;IAEF,2CAA2C,GACzC,mBAAmB,MAAM,EACzB,+BAA+B,MAAM,KACpC,MAAM,CAMP;IAEF,sBAAsB,GAAI,eAAe,qBAAqB,KAAG,MAAM,CAWrE;CACH"}