github-issue-tower-defence-management 1.122.5 → 1.122.7

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.7](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/compare/v1.122.6...v1.122.7) (2026-07-14)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **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))
7
+
8
+ ## [1.122.6](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/compare/v1.122.5...v1.122.6) (2026-07-13)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **silent-monitor:** neutralize imperative reminder wording that trips model safety classifiers ([#1164](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/issues/1164)) ([e82e704](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/e82e70438b3e6be00d20d5a3e5037c6bb7ea0325))
14
+
1
15
  ## [1.122.5](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/compare/v1.122.4...v1.122.5) (2026-07-12)
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. Treat that figure as the authoritative system signal; do NOT spend effort re-deriving whether the sub-process is alive. Around five minutes of silence is a real warning of a possible hang: do NOT speak from speculation ("probably still working") and do NOT dismiss it without evidence.`,
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 you MUST 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 MUST 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 MUST 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. NEVER tell 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 and is unacceptable. 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; never wait 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. Do NOT close this session on your own — it is closed only after the owner has verified completion and tells 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, you MUST 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 NEVER 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 is still unanswered.`,
48
+ `If you are still waiting on that answer, the older owner call may have been missed, so please re-raise the ask as a fresh, self-contained owner call. ${(0, exports.composeOwnerCallFormatGuidance)(ownerCallMarker)}`,
49
+ `If you are no longer blocked, please continue with the next step. 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":"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"}
1
+ {"version":3,"file":"DefaultSilentSessionMessageComposer.js","sourceRoot":"","sources":["../../../src/domain/usecases/DefaultSilentSessionMessageComposer.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "github-issue-tower-defence-management",
3
- "version": "1.122.5",
3
+ "version": "1.122.7",
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
- 'NEVER tell 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
 
@@ -310,7 +310,7 @@ describe('notifySilentTmuxSessions', () => {
310
310
  expect(sendCall?.[1][2]).toBe(SESSION_NAME);
311
311
  expect(sendCall?.[1][4]).toContain('is still unanswered');
312
312
  expect(sendCall?.[1][4]).toContain(
313
- 're-raise your pending ask NOW as a fresh owner call',
313
+ 're-raise the ask as a fresh, self-contained owner call',
314
314
  );
315
315
  });
316
316
 
@@ -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 MUST 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
- 'NEVER tell 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('never wait 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 MUST 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 MUST 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
- 'NEVER tell 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, you MUST 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 NEVER 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,40 +113,30 @@ 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 is still unanswered.',
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('suggests re-raising the pending ask as a fresh self-contained owner call when still waiting', () => {
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 the ask 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('suggests continuing when no longer blocked and requests a remaining-minutes estimate', () => {
151
131
  const section = composer.composeMainStalledWithStaleOwnerCallSection(
152
132
  600,
153
133
  3600,
154
134
  );
155
135
  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.',
157
- );
158
- });
159
-
160
- it('states that the stale-owner-call reminder itself does not notify the owner', () => {
161
- const section = composer.composeMainStalledWithStaleOwnerCallSection(
162
- 600,
163
- 3600,
136
+ 'If you are no longer blocked, please continue with the next step.',
164
137
  );
165
138
  expect(section).toContain(
166
- 'This reminder does not notify the owner; only a fresh owner call from you surfaces this session to the owner.',
139
+ 'an estimate of the remaining minutes to finish all tasks',
167
140
  );
168
141
  });
169
142
 
@@ -176,7 +149,7 @@ describe('DefaultSilentSessionMessageComposer', () => {
176
149
  3600,
177
150
  );
178
151
  expect(section).toContain(
179
- 'the configured owner-call marker tag "<<OWNER_CALL>>" as a complete matching pair',
152
+ 'owner-call marker tag "<<OWNER_CALL>>" as a complete opening and closing pair on one line',
180
153
  );
181
154
  expect(section).toContain('🔴');
182
155
  });
@@ -205,12 +178,12 @@ describe('DefaultSilentSessionMessageComposer', () => {
205
178
  });
206
179
  expect(section).toContain('sub-process-idle');
207
180
  expect(section).toContain('no output for 6m');
208
- expect(section).toContain('restart, hand off, or replace it');
181
+ expect(section).toContain('please restart it, hand it off, or replace it');
209
182
  expect(section).toContain('waiting on an external dependency');
210
- expect(section).not.toContain('infinite loop');
183
+ expect(section).not.toContain('running longer than a task usually takes');
211
184
  });
212
185
 
213
- it('presents the system-detected idle duration as the authoritative signal in the idle message', () => {
186
+ it('frames the idle message as an automated status check with the system-measured duration', () => {
214
187
  const section = composer.composeSubAgentSection({
215
188
  idleSubAgents: [
216
189
  {
@@ -222,36 +195,14 @@ describe('DefaultSilentSessionMessageComposer', () => {
222
195
  ],
223
196
  longRunningSubAgents: [],
224
197
  });
198
+ expect(section).toContain('This is an automated status check.');
225
199
  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
- 'Treat that figure as the authoritative system signal; do NOT spend effort re-deriving whether the sub-process is alive.',
200
+ 'produced no output for about the minutes shown, measured from their last tool activity',
230
201
  );
231
202
  expect(section).toContain('no output for 6m');
232
203
  });
233
204
 
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
- 'do NOT speak from speculation ("probably still working") and do NOT dismiss it without evidence.',
251
- );
252
- });
253
-
254
- it('requires a concrete cause-check covering recent activity and external-dependency waiting in the idle message', () => {
205
+ it('tells the agent that logging one line suffices for a legitimate external wait in the idle message', () => {
255
206
  const section = composer.composeSubAgentSection({
256
207
  idleSubAgents: [
257
208
  {
@@ -263,35 +214,11 @@ describe('DefaultSilentSessionMessageComposer', () => {
263
214
  ],
264
215
  longRunningSubAgents: [],
265
216
  });
266
- expect(section).toContain('determine the CAUSE by a concrete check');
267
- expect(section).toContain(
268
- 'a very recent push or commit, or output from any nested sub-processes this sub-process itself started',
269
- );
270
- expect(section).toContain(
271
- 'legitimately blocked waiting on an external dependency',
272
- );
273
217
  expect(section).toContain(
274
- 'confirm it by investigation before concluding do not assume',
218
+ 'a continuous-integration run, an external API, or another process',
275
219
  );
276
220
  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 you MUST output your investigation result in this session so it remains as a log.',
221
+ 'no action is needed please log one line noting the wait',
295
222
  );
296
223
  });
297
224
 
@@ -309,14 +236,12 @@ describe('DefaultSilentSessionMessageComposer', () => {
309
236
  });
310
237
  expect(section).toContain('sub-process-long');
311
238
  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');
239
+ expect(section).toContain('running longer than a task usually takes');
315
240
  expect(section).toContain(
316
- 'do not dismiss it merely because it produced output recently',
241
+ 'breaking the task down, restarting it, handing it off, or replacing it',
317
242
  );
318
243
  expect(section).toContain(
319
- 'break the task down, restart, hand off, or replace',
244
+ 'If it is progressing normally, no action is needed.',
320
245
  );
321
246
  });
322
247
 
@@ -348,9 +273,8 @@ describe('DefaultSilentSessionMessageComposer', () => {
348
273
  longRunningSubAgents: [subAgent],
349
274
  });
350
275
  expect(section).toContain('no output for 6m');
351
- expect(section).toContain('determine the CAUSE by a concrete check');
352
276
  expect(section).toContain('running for 20m');
353
- expect(section).toContain('infinite loop');
277
+ expect(section).toContain('running longer than a task usually takes');
354
278
  const sentinelOccurrences =
355
279
  section.split(SILENT_SESSION_REMINDER_SENTINEL).length - 1;
356
280
  expect(sentinelOccurrences).toBe(2);
@@ -382,6 +306,46 @@ describe('DefaultSilentSessionMessageComposer', () => {
382
306
  expect(longRunningSection).not.toContain('idle-only');
383
307
  });
384
308
 
309
+ it('composes default texts free of pressure- and prohibition-styled vocabulary that trips model safety classifiers', () => {
310
+ const flaggedPatterns = [
311
+ /unacceptable/i,
312
+ /\bnever\b/i,
313
+ /\b[Dd]o NOT\b/,
314
+ /\b[Yy]ou MUST\b/,
315
+ /\bwastes?\b/i,
316
+ /silently stalls/i,
317
+ /\bstall(s|ed|ing)?\b/i,
318
+ /raise one now/i,
319
+ /fire the owner-call now/i,
320
+ /do not wait passively/i,
321
+ /is prohibited/i,
322
+ ];
323
+ const markedComposer = new DefaultSilentSessionMessageComposer(
324
+ '<<OWNER_CALL>>',
325
+ );
326
+ const subAgent = {
327
+ label: 'sub-process-1',
328
+ silentSeconds: 360,
329
+ runningSeconds: 1200,
330
+ waitingOnExternalProcess: false,
331
+ };
332
+ const composedDefaultTexts = [
333
+ composer.composeMainStalledSection(600),
334
+ markedComposer.composeMainStalledSection(600),
335
+ composer.composeMainStalledWithStaleOwnerCallSection(600, 3600),
336
+ markedComposer.composeMainStalledWithStaleOwnerCallSection(600, 3600),
337
+ composer.composeSubAgentSection({
338
+ idleSubAgents: [subAgent],
339
+ longRunningSubAgents: [subAgent],
340
+ }),
341
+ ];
342
+ for (const text of composedDefaultTexts) {
343
+ for (const pattern of flaggedPatterns) {
344
+ expect(text).not.toMatch(pattern);
345
+ }
346
+ }
347
+ });
348
+
385
349
  it('does not contain any host-specific or internal identifiers', () => {
386
350
  const mainSection = composer.composeMainStalledSection(600);
387
351
  const subAgent = {
@@ -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. Treat that figure as the authoritative system signal; do NOT spend effort re-deriving whether the sub-process is alive. Around five minutes of silence is a real warning of a possible hang: do NOT speak from speculation ("probably still working") and do NOT dismiss it without evidence.`,
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 you MUST 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 MUST 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 MUST 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. NEVER tell 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 and is unacceptable. 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; never wait 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. Do NOT close this session on your own — it is closed only after the owner has verified completion and tells 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, you MUST 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 NEVER 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 is still unanswered.`,
81
+ `If you are still waiting on that answer, the older owner call may have been missed, so please re-raise the ask as a fresh, self-contained owner call. ${composeOwnerCallFormatGuidance(
82
+ ownerCallMarker,
83
+ )}`,
84
+ `If you are no longer blocked, please continue with the next step. 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"}