principles-disciple 1.11.0 → 1.13.0

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.
Files changed (233) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +66 -0
  3. package/esbuild.config.js +1 -1
  4. package/openclaw.plugin.json +4 -4
  5. package/package.json +2 -3
  6. package/run-nocturnal.mjs +30 -0
  7. package/scripts/db-migrate.mjs +170 -0
  8. package/scripts/sync-plugin.mjs +250 -6
  9. package/src/commands/archive-impl.ts +136 -0
  10. package/src/commands/capabilities.ts +4 -2
  11. package/src/commands/context.ts +5 -1
  12. package/src/commands/disable-impl.ts +151 -0
  13. package/src/commands/evolution-status.ts +64 -19
  14. package/src/commands/export.ts +8 -6
  15. package/src/commands/focus.ts +8 -20
  16. package/src/commands/nocturnal-review.ts +5 -7
  17. package/src/commands/nocturnal-rollout.ts +1 -12
  18. package/src/commands/nocturnal-train.ts +21 -47
  19. package/src/commands/pain.ts +10 -5
  20. package/src/commands/principle-rollback.ts +4 -2
  21. package/src/commands/promote-impl.ts +274 -0
  22. package/src/commands/rollback-impl.ts +234 -0
  23. package/src/commands/rollback.ts +6 -3
  24. package/src/commands/samples.ts +2 -0
  25. package/src/commands/thinking-os.ts +3 -4
  26. package/src/commands/workflow-debug.ts +2 -1
  27. package/src/config/errors.ts +1 -0
  28. package/src/core/AGENTS.md +34 -0
  29. package/src/core/adaptive-thresholds.ts +4 -3
  30. package/src/core/code-implementation-storage.ts +241 -0
  31. package/src/core/config.ts +5 -2
  32. package/src/core/control-ui-db.ts +29 -10
  33. package/src/core/detection-funnel.ts +12 -7
  34. package/src/core/diagnostician-task-store.ts +156 -0
  35. package/src/core/dictionary.ts +4 -4
  36. package/src/core/empathy-keyword-matcher.ts +7 -3
  37. package/src/core/empathy-types.ts +13 -2
  38. package/src/core/event-log.ts +14 -6
  39. package/src/core/evolution-engine.ts +27 -31
  40. package/src/core/evolution-logger.ts +3 -2
  41. package/src/core/evolution-reducer.ts +110 -31
  42. package/src/core/evolution-types.ts +10 -0
  43. package/src/core/external-training-contract.ts +1 -0
  44. package/src/core/focus-history.ts +38 -24
  45. package/src/core/hygiene/tracker.ts +10 -6
  46. package/src/core/init.ts +5 -2
  47. package/src/core/migration.ts +3 -3
  48. package/src/core/model-deployment-registry.ts +6 -4
  49. package/src/core/model-training-registry.ts +5 -3
  50. package/src/core/nocturnal-arbiter.ts +13 -14
  51. package/src/core/nocturnal-artifact-lineage.ts +117 -0
  52. package/src/core/nocturnal-artificer.ts +257 -0
  53. package/src/core/nocturnal-candidate-scoring.ts +4 -2
  54. package/src/core/nocturnal-compliance.ts +67 -19
  55. package/src/core/nocturnal-dataset.ts +95 -2
  56. package/src/core/nocturnal-executability.ts +2 -3
  57. package/src/core/nocturnal-export.ts +6 -3
  58. package/src/core/nocturnal-rule-implementation-validator.ts +245 -0
  59. package/src/core/nocturnal-trajectory-extractor.ts +10 -3
  60. package/src/core/nocturnal-trinity.ts +319 -61
  61. package/src/core/pain-context-extractor.ts +29 -15
  62. package/src/core/pain.ts +7 -5
  63. package/src/core/path-resolver.ts +16 -15
  64. package/src/core/paths.ts +2 -1
  65. package/src/core/pd-task-reconciler.ts +463 -0
  66. package/src/core/pd-task-service.ts +42 -0
  67. package/src/core/pd-task-store.ts +77 -0
  68. package/src/core/pd-task-types.ts +128 -0
  69. package/src/core/principle-internalization/deprecated-readiness.ts +91 -0
  70. package/src/core/principle-internalization/internalization-routing-policy.ts +208 -0
  71. package/src/core/principle-internalization/lifecycle-metrics.ts +149 -0
  72. package/src/core/principle-internalization/lifecycle-read-model.ts +243 -0
  73. package/src/core/principle-internalization/lifecycle-refresh.ts +11 -0
  74. package/src/core/principle-internalization/principle-lifecycle-service.ts +167 -0
  75. package/src/core/principle-training-state.ts +95 -370
  76. package/src/core/principle-tree-ledger.ts +733 -0
  77. package/src/core/principle-tree-migration.ts +195 -0
  78. package/src/core/profile.ts +3 -1
  79. package/src/core/promotion-gate.ts +14 -18
  80. package/src/core/replay-engine.ts +562 -0
  81. package/src/core/risk-calculator.ts +6 -4
  82. package/src/core/rule-host-helpers.ts +39 -0
  83. package/src/core/rule-host-types.ts +82 -0
  84. package/src/core/rule-host.ts +245 -0
  85. package/src/core/rule-implementation-runtime.ts +38 -0
  86. package/src/core/schema/db-types.ts +16 -0
  87. package/src/core/schema/index.ts +26 -0
  88. package/src/core/schema/migration-runner.ts +207 -0
  89. package/src/core/schema/migrations/001-init-trajectory.ts +211 -0
  90. package/src/core/schema/migrations/002-init-central.ts +122 -0
  91. package/src/core/schema/migrations/003-init-workflow.ts +55 -0
  92. package/src/core/schema/migrations/004-add-thinking-and-gfi.ts +74 -0
  93. package/src/core/schema/migrations/index.ts +31 -0
  94. package/src/core/schema/schema-definitions.ts +650 -0
  95. package/src/core/session-tracker.ts +6 -4
  96. package/src/core/shadow-observation-registry.ts +6 -3
  97. package/src/core/system-logger.ts +2 -2
  98. package/src/core/thinking-models.ts +182 -46
  99. package/src/core/thinking-os-parser.ts +156 -0
  100. package/src/core/training-program.ts +7 -7
  101. package/src/core/trajectory.ts +42 -36
  102. package/src/core/workspace-context.ts +77 -11
  103. package/src/core/workspace-dir-validation.ts +152 -0
  104. package/src/hooks/AGENTS.md +31 -0
  105. package/src/hooks/bash-risk.ts +3 -1
  106. package/src/hooks/edit-verification.ts +9 -5
  107. package/src/hooks/gate-block-helper.ts +5 -1
  108. package/src/hooks/gate.ts +152 -5
  109. package/src/hooks/gfi-gate.ts +9 -2
  110. package/src/hooks/lifecycle-routing.ts +124 -0
  111. package/src/hooks/lifecycle.ts +12 -12
  112. package/src/hooks/llm.ts +17 -109
  113. package/src/hooks/message-sanitize.ts +5 -3
  114. package/src/hooks/pain.ts +19 -15
  115. package/src/hooks/progressive-trust-gate.ts +7 -1
  116. package/src/hooks/prompt.ts +169 -60
  117. package/src/hooks/subagent.ts +5 -4
  118. package/src/hooks/thinking-checkpoint.ts +2 -0
  119. package/src/hooks/trajectory-collector.ts +15 -12
  120. package/src/http/principles-console-route.ts +31 -68
  121. package/src/i18n/commands.ts +2 -2
  122. package/src/index.ts +130 -40
  123. package/src/service/central-database.ts +131 -43
  124. package/src/service/central-health-service.ts +47 -0
  125. package/src/service/central-overview-service.ts +135 -0
  126. package/src/service/central-sync-service.ts +87 -0
  127. package/src/service/control-ui-query-service.ts +46 -36
  128. package/src/service/event-log-auditor.ts +261 -0
  129. package/src/service/evolution-query-service.ts +23 -22
  130. package/src/service/evolution-worker.ts +565 -261
  131. package/src/service/health-query-service.ts +213 -36
  132. package/src/service/nocturnal-runtime.ts +8 -4
  133. package/src/service/nocturnal-service.ts +503 -59
  134. package/src/service/nocturnal-target-selector.ts +5 -7
  135. package/src/service/runtime-summary-service.ts +2 -1
  136. package/src/service/subagent-workflow/deep-reflect-workflow-manager.ts +25 -336
  137. package/src/service/subagent-workflow/dynamic-timeout.ts +30 -0
  138. package/src/service/subagent-workflow/empathy-observer-workflow-manager.ts +48 -386
  139. package/src/service/subagent-workflow/index.ts +2 -0
  140. package/src/service/subagent-workflow/nocturnal-workflow-manager.ts +169 -284
  141. package/src/service/subagent-workflow/runtime-direct-driver.ts +114 -16
  142. package/src/service/subagent-workflow/subagent-error-utils.ts +25 -0
  143. package/src/service/subagent-workflow/types.ts +9 -4
  144. package/src/service/subagent-workflow/workflow-manager-base.ts +573 -0
  145. package/src/service/subagent-workflow/workflow-store.ts +71 -11
  146. package/src/service/trajectory-service.ts +2 -1
  147. package/src/tools/critique-prompt.ts +1 -1
  148. package/src/tools/deep-reflect.ts +175 -209
  149. package/src/tools/model-index.ts +2 -1
  150. package/src/types/event-types.ts +2 -2
  151. package/src/types/principle-tree-schema.ts +29 -23
  152. package/src/utils/file-lock.ts +5 -3
  153. package/src/utils/io.ts +5 -2
  154. package/src/utils/nlp.ts +5 -46
  155. package/src/utils/node-vm-polyfill.ts +11 -0
  156. package/src/utils/plugin-logger.ts +2 -0
  157. package/src/utils/retry.ts +572 -0
  158. package/src/utils/subagent-probe.ts +1 -1
  159. package/templates/langs/en/core/AGENTS.md +0 -13
  160. package/templates/langs/en/core/SOUL.md +1 -31
  161. package/templates/langs/en/core/TOOLS.md +0 -4
  162. package/templates/langs/en/principles/THINKING_OS.md +77 -0
  163. package/templates/langs/en/skills/admin/SKILL.md +0 -1
  164. package/templates/langs/en/skills/evolution-framework-update/SKILL.md +1 -1
  165. package/templates/langs/en/skills/pd-diagnostician/SKILL.md +18 -5
  166. package/templates/langs/zh/core/AGENTS.md +0 -22
  167. package/templates/langs/zh/core/SOUL.md +1 -31
  168. package/templates/langs/zh/core/TOOLS.md +0 -4
  169. package/templates/langs/zh/principles/THINKING_OS.md +77 -0
  170. package/templates/langs/zh/skills/admin/SKILL.md +0 -1
  171. package/templates/langs/zh/skills/evolution-framework-update/SKILL.md +1 -1
  172. package/templates/langs/zh/skills/pd-diagnostician/SKILL.md +25 -4
  173. package/tests/commands/evolution-status.test.ts +119 -0
  174. package/tests/commands/implementation-lifecycle.test.ts +362 -0
  175. package/tests/core/code-implementation-storage.test.ts +398 -0
  176. package/tests/core/evolution-reducer.detector-metadata.test.ts +28 -28
  177. package/tests/core/nocturnal-artifact-lineage.test.ts +53 -0
  178. package/tests/core/nocturnal-artificer.test.ts +241 -0
  179. package/tests/core/nocturnal-compliance-p-principles.test.ts +133 -0
  180. package/tests/core/nocturnal-rule-implementation-validator.test.ts +127 -0
  181. package/tests/core/pd-task-store.test.ts +126 -0
  182. package/tests/core/principle-internalization/deprecated-readiness.test.ts +193 -0
  183. package/tests/core/principle-internalization/internalization-routing-policy.test.ts +212 -0
  184. package/tests/core/principle-internalization/lifecycle-metrics.test.ts +350 -0
  185. package/tests/core/principle-internalization/principle-lifecycle-service.test.ts +211 -0
  186. package/tests/core/principle-training-state.test.ts +228 -1
  187. package/tests/core/principle-tree-ledger.test.ts +423 -0
  188. package/tests/core/regression-v1-9-1.test.ts +265 -0
  189. package/tests/core/replay-engine.test.ts +234 -0
  190. package/tests/core/rule-host-helpers.test.ts +120 -0
  191. package/tests/core/rule-host.test.ts +389 -0
  192. package/tests/core/rule-implementation-runtime.test.ts +64 -0
  193. package/tests/core/workspace-context.test.ts +53 -0
  194. package/tests/core/workspace-dir-validation.test.ts +272 -0
  195. package/tests/hooks/gate-rule-host-pipeline.test.ts +385 -0
  196. package/tests/hooks/pain.test.ts +74 -10
  197. package/tests/hooks/prompt.test.ts +63 -1
  198. package/tests/integration/principle-lifecycle.e2e.test.ts +197 -0
  199. package/tests/integration/tool-hooks-workspace-dir.e2e.test.ts +211 -0
  200. package/tests/service/data-endpoints-regression.test.ts +834 -0
  201. package/tests/service/evolution-worker.test.ts +0 -123
  202. package/tests/service/nocturnal-service-code-candidate.test.ts +330 -0
  203. package/tests/utils/nlp.test.ts +1 -19
  204. package/tests/utils/retry.test.ts +327 -0
  205. package/ui/src/App.tsx +1 -1
  206. package/ui/src/api.ts +4 -0
  207. package/ui/src/charts.tsx +366 -0
  208. package/ui/src/components/WorkspaceConfig.tsx +107 -75
  209. package/ui/src/i18n/ui.ts +89 -31
  210. package/ui/src/pages/EvolutionPage.tsx +1 -1
  211. package/ui/src/pages/OverviewPage.tsx +441 -81
  212. package/ui/src/pages/ThinkingModelsPage.tsx +287 -69
  213. package/ui/src/styles.css +43 -0
  214. package/ui/src/types.ts +17 -1
  215. package/src/agents/nocturnal-dreamer.md +0 -152
  216. package/src/agents/nocturnal-philosopher.md +0 -138
  217. package/src/agents/nocturnal-reflector.md +0 -126
  218. package/src/agents/nocturnal-scribe.md +0 -164
  219. package/templates/workspace/.principles/00-kernel.md +0 -51
  220. package/templates/workspace/.principles/DECISION_POLICY.json +0 -44
  221. package/templates/workspace/.principles/PRINCIPLES.md +0 -20
  222. package/templates/workspace/.principles/PROFILE.json +0 -54
  223. package/templates/workspace/.principles/PROFILE.schema.json +0 -56
  224. package/templates/workspace/.principles/THINKING_OS.md +0 -64
  225. package/templates/workspace/.principles/THINKING_OS_ARCHIVE.md +0 -7
  226. package/templates/workspace/.principles/THINKING_OS_CANDIDATES.md +0 -9
  227. package/templates/workspace/.principles/models/_INDEX.md +0 -27
  228. package/templates/workspace/.principles/models/first_principles.md +0 -62
  229. package/templates/workspace/.principles/models/marketing_4p.md +0 -52
  230. package/templates/workspace/.principles/models/porter_five.md +0 -63
  231. package/templates/workspace/.principles/models/swot.md +0 -60
  232. package/templates/workspace/.principles/models/user_story_map.md +0 -63
  233. package/templates/workspace/.state/WORKBOARD.json +0 -4
@@ -1,15 +1,19 @@
1
+ import * as fs from 'fs';
1
2
  import type {
2
3
  SubagentRunResult,
3
4
  SubagentWaitResult,
4
5
  SubagentGetSessionMessagesResult,
5
6
  PluginLogger,
6
7
  } from '../../openclaw-sdk.js';
8
+ import { isExpectedSubagentError } from './subagent-error-utils.js';
7
9
 
8
10
  export interface TransportDriver {
11
+ /* eslint-disable no-unused-vars -- Reason: interface method params are type signatures, implementations use actual values */
9
12
  run(params: RunParams): Promise<RunResult>;
10
13
  wait(params: WaitParams): Promise<WaitResult>;
11
14
  getResult(params: GetResultParams): Promise<GetResultResult>;
12
15
  cleanup(params: CleanupParams): Promise<void>;
16
+ /* eslint-enable no-unused-vars */
13
17
  }
14
18
 
15
19
  export interface RunParams {
@@ -51,6 +55,7 @@ export interface CleanupParams {
51
55
  deleteTranscript?: boolean;
52
56
  }
53
57
 
58
+ /* eslint-disable no-unused-vars -- Reason: type method params are type signatures, implementations use actual values */
54
59
  type PluginRuntimeSubagent = {
55
60
  run: (params: {
56
61
  sessionKey: string;
@@ -74,21 +79,45 @@ type PluginRuntimeSubagent = {
74
79
  deleteTranscript?: boolean;
75
80
  }) => Promise<void>;
76
81
  };
82
+ /* eslint-enable no-unused-vars */
83
+
84
+ /**
85
+ * OpenClaw plugin SDK's agent.session namespace — always available (not gateway-scoped).
86
+ * These functions are imported directly from OpenClaw's session store module.
87
+ */
88
+ export type AgentSessionAPI = {
89
+ /* eslint-disable no-unused-vars -- Reason: type method params are type signatures, implementations use actual values */
90
+ resolveStorePath: () => string;
91
+ loadSessionStore: (storePath: string, opts?: { skipCache?: boolean }) => Record<string, unknown>;
92
+ saveSessionStore: (storePath: string, store: Record<string, unknown>) => Promise<void>;
93
+ resolveSessionFilePath: (sessionKey: string) => string;
94
+ /** Optional: OpenClaw config object needed for session path resolution */
95
+ config?: unknown;
96
+ /* eslint-enable no-unused-vars */
97
+ };
77
98
 
78
99
  export class RuntimeDirectDriver implements TransportDriver {
79
100
  private readonly subagent: PluginRuntimeSubagent;
80
101
  private readonly logger: PluginLogger;
81
-
82
- constructor(options: { subagent: PluginRuntimeSubagent; logger: PluginLogger }) {
102
+ /** Agent-level session store API — works outside gateway request context (#188) */
103
+ private readonly agentSession: AgentSessionAPI | undefined;
104
+
105
+ constructor(options: {
106
+ subagent: PluginRuntimeSubagent;
107
+ logger: PluginLogger;
108
+ /** Pass api.runtime.agent.session to enable heartbeat-safe cleanup (#188) */
109
+ agentSession?: AgentSessionAPI;
110
+ }) {
83
111
  this.subagent = options.subagent;
84
112
  this.logger = options.logger;
113
+ this.agentSession = options.agentSession;
85
114
  }
86
115
 
87
116
  /** Expose subagent for availability checking (used by workflow manager for surface degrade) */
88
117
  getSubagent(): PluginRuntimeSubagent {
89
118
  return this.subagent;
90
119
  }
91
-
120
+
92
121
  async run(params: RunParams): Promise<RunResult> {
93
122
  // DEFENSIVE: Gateway AgentParamsSchema requires idempotencyKey as NonEmptyString (required).
94
123
  // server-plugins.ts uses conditional spread: ...(v && { v }), so falsy = omitted = validation failure.
@@ -96,7 +125,7 @@ export class RuntimeDirectDriver implements TransportDriver {
96
125
  const idempotencyKey = params.idempotencyKey || `pd:${params.sessionKey}:${Date.now()}`;
97
126
 
98
127
  this.logger.info(`[PD:RuntimeDirectDriver] Spawning subagent: sessionKey=${params.sessionKey}, idemKey=${idempotencyKey.substring(0, 40)}`);
99
-
128
+
100
129
  try {
101
130
  const result = await this.subagent.run({
102
131
  sessionKey: params.sessionKey,
@@ -107,24 +136,28 @@ export class RuntimeDirectDriver implements TransportDriver {
107
136
  expectsCompletionMessage: params.expectsCompletionMessage ?? true,
108
137
  extraSystemPrompt: params.extraSystemPrompt,
109
138
  });
110
-
139
+
111
140
  this.logger.info(`[PD:RuntimeDirectDriver] Spawn succeeded: runId=${result.runId}`);
112
141
  return { runId: result.runId };
113
142
  } catch (error) {
114
- this.logger.error(`[PD:RuntimeDirectDriver] Spawn failed: ${String(error)}`);
143
+ // Suppress expected errors during cron jobs, boot sessions, or isolated sessions.
144
+ // These are not real failures — subagent runtime is only available in gateway requests.
145
+ if (!isExpectedSubagentError(error)) {
146
+ this.logger.error(`[PD:RuntimeDirectDriver] Spawn failed: ${String(error)}`);
147
+ }
115
148
  throw error;
116
149
  }
117
150
  }
118
-
151
+
119
152
  async wait(params: WaitParams): Promise<WaitResult> {
120
153
  this.logger.info(`[PD:RuntimeDirectDriver] Waiting for run: runId=${params.runId}, timeout=${params.timeoutMs}ms`);
121
-
154
+
122
155
  try {
123
156
  const result = await this.subagent.waitForRun({
124
157
  runId: params.runId,
125
158
  timeoutMs: params.timeoutMs,
126
159
  });
127
-
160
+
128
161
  this.logger.info(`[PD:RuntimeDirectDriver] Wait completed: status=${result.status}`);
129
162
  return result;
130
163
  } catch (error) {
@@ -132,26 +165,26 @@ export class RuntimeDirectDriver implements TransportDriver {
132
165
  throw error;
133
166
  }
134
167
  }
135
-
168
+
136
169
  async getResult(params: GetResultParams): Promise<GetResultResult> {
137
170
  this.logger.info(`[PD:RuntimeDirectDriver] Getting messages: sessionKey=${params.sessionKey}`);
138
-
171
+
139
172
  try {
140
173
  const result = await this.subagent.getSessionMessages({
141
174
  sessionKey: params.sessionKey,
142
175
  limit: params.limit ?? 20,
143
176
  });
144
-
177
+
145
178
  return result;
146
179
  } catch (error) {
147
180
  this.logger.error(`[PD:RuntimeDirectDriver] GetResult failed: ${String(error)}`);
148
181
  throw error;
149
182
  }
150
183
  }
151
-
184
+
152
185
  async cleanup(params: CleanupParams): Promise<void> {
153
186
  this.logger.info(`[PD:RuntimeDirectDriver] Cleaning up session: sessionKey=${params.sessionKey}`);
154
-
187
+
155
188
  try {
156
189
  await this.subagent.deleteSession({
157
190
  sessionKey: params.sessionKey,
@@ -159,8 +192,73 @@ export class RuntimeDirectDriver implements TransportDriver {
159
192
  });
160
193
  this.logger.info(`[PD:RuntimeDirectDriver] Cleanup succeeded`);
161
194
  } catch (error) {
162
- this.logger.error(`[PD:RuntimeDirectDriver] Cleanup failed: ${String(error)}`);
163
- throw error;
195
+ const errMsg = String(error);
196
+ // #188/#219: runtime.subagent.deleteSession() only works during gateway requests.
197
+ // Fall back to agent.session API which is always available (not gateway-scoped).
198
+ // Handle multiple error patterns that indicate non-gateway context:
199
+ // - 'gateway request' - Not in a gateway request scope
200
+ // - 'missing scope' - Missing required scope (e.g., operator.admin)
201
+ const isNonGatewayContext =
202
+ errMsg.includes('gateway request') ||
203
+ errMsg.includes('missing scope');
204
+
205
+ if (isNonGatewayContext && this.agentSession) {
206
+ this.logger.info(`[PD:RuntimeDirectDriver] Gateway-scoped cleanup unavailable (${errMsg.split(':')[0]}), falling back to agent.session`);
207
+ await this.cleanupViaAgentSession(params.sessionKey);
208
+ this.logger.info(`[PD:RuntimeDirectDriver] Fallback cleanup succeeded`);
209
+ } else {
210
+ this.logger.error(`[PD:RuntimeDirectDriver] Cleanup failed: ${errMsg}`);
211
+ throw error;
212
+ }
213
+ }
214
+ }
215
+
216
+ /**
217
+ * Heartbeat-safe session cleanup by directly manipulating the session store file.
218
+ * This bypasses the gateway request scope requirement entirely.
219
+ * Also removes transcript files from disk to avoid orphaned files.
220
+ */
221
+ private async cleanupViaAgentSession(sessionKey: string): Promise<void> {
222
+ if (!this.agentSession) {
223
+ throw new Error('agentSession not available for fallback cleanup');
224
+ }
225
+
226
+ const { resolveStorePath, loadSessionStore, saveSessionStore, resolveSessionFilePath } = this.agentSession;
227
+
228
+ // Get the session store file path
229
+ const storePath = resolveStorePath();
230
+
231
+ if (!fs.existsSync(storePath)) {
232
+ return; // No store file, nothing to clean up
233
+ }
234
+
235
+ // Read the store
236
+ const store = loadSessionStore(storePath, { skipCache: true });
237
+ if (!store || typeof store !== 'object') {
238
+ return;
239
+ }
240
+
241
+ // Normalize session key matches OpenClaw's internal lowercase normalization
242
+ const normalizedKey = sessionKey.toLowerCase();
243
+
244
+ if (normalizedKey in store) {
245
+ const entry = store[normalizedKey] as { sessionId?: string; sessionFile?: string } | undefined;
246
+
247
+ // Archive or delete transcript files before removing store entry
248
+ if (entry?.sessionFile) {
249
+ try {
250
+ const transcriptPath = resolveSessionFilePath(normalizedKey);
251
+ if (fs.existsSync(transcriptPath)) {
252
+ fs.unlinkSync(transcriptPath);
253
+ this.logger.info(`[PD:RuntimeDirectDriver] Removed transcript file: ${transcriptPath}`);
254
+ }
255
+ } catch (unlinkErr) {
256
+ this.logger.warn(`[PD:RuntimeDirectDriver] Failed to remove transcript file: ${String(unlinkErr)}`);
257
+ }
258
+ }
259
+
260
+ delete store[normalizedKey];
261
+ await saveSessionStore(storePath, store);
164
262
  }
165
263
  }
166
264
  }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Shared utility for detecting expected subagent unavailability errors.
3
+ * These occur during cron jobs, boot sessions, daemon mode, or isolated sessions
4
+ * where the gateway request context is not available.
5
+ *
6
+ * Callers should suppress warnings for these errors — they are not real failures.
7
+ */
8
+ export function isExpectedSubagentError(err: unknown): boolean {
9
+ const msg = String(err);
10
+ return (
11
+ msg.includes('Plugin runtime subagent methods are only available during a gateway request') ||
12
+ msg.includes('cannot start workflow for boot session') ||
13
+ msg.includes('subagent runtime unavailable') ||
14
+ // #208/#209: Daemon mode — subagent process not connected
15
+ msg.includes('subagent is not available') ||
16
+ // NocturnalWorkflowManager explicit throw when subagent unavailable
17
+ (msg.includes('NocturnalWorkflowManager') && msg.includes('subagent runtime unavailable')) ||
18
+ // Gateway not running (daemon/cron context)
19
+ msg.includes('gateway is not running') ||
20
+ // Process isolation in cron jobs
21
+ msg.includes('process isolation') ||
22
+ // Review fix: Subagent connection issues in daemon mode (more specific to reduce false positives)
23
+ (msg.includes('subagent') && msg.toLowerCase().includes('connection') && (msg.includes('refused') || msg.includes('reset') || msg.includes('econnrefused')))
24
+ );
25
+ }
@@ -145,6 +145,7 @@ export interface WorkflowHandle {
145
145
  * ```
146
146
  */
147
147
  export interface SubagentWorkflowSpec<TResult> {
148
+ /* eslint-disable no-unused-vars -- Reason: interface method params are type signatures, implementations use actual values */
148
149
  /** Unique identifier for this workflow type */
149
150
  workflowType: string;
150
151
  /** Which transport mechanism to use */
@@ -171,6 +172,7 @@ export interface SubagentWorkflowSpec<TResult> {
171
172
  * For runtime_direct: typically finalize only on 'ok', skip on 'timeout'/'error'.
172
173
  */
173
174
  shouldFinalizeOnWaitStatus: (status: 'ok' | 'error' | 'timeout') => boolean;
175
+ /* eslint-enable no-unused-vars */
174
176
  }
175
177
 
176
178
  // ── Empathy Observer Specific Types ──────────────────────────────────────────
@@ -227,6 +229,7 @@ export interface EmpathyObserverWorkflowSpec extends SubagentWorkflowSpec<Empath
227
229
  * This is what the helper exposes to business modules.
228
230
  */
229
231
  export interface WorkflowManager {
232
+ /* eslint-disable no-unused-vars -- Reason: interface method params are type signatures, implementations use actual values */
230
233
  /**
231
234
  * Start a new workflow.
232
235
  * Creates workflow state, spawns subagent, and returns handle.
@@ -286,6 +289,7 @@ export interface WorkflowManager {
286
289
  * Release resources (DB connections, timers).
287
290
  */
288
291
  dispose: () => void;
292
+ /* eslint-enable no-unused-vars */
289
293
  }
290
294
 
291
295
  // ── Workflow Store (for SQLite persistence) ──────────────────────────────────
@@ -305,6 +309,7 @@ export interface WorkflowRow {
305
309
  created_at: number;
306
310
  updated_at: number;
307
311
  last_observed_at?: number | null;
312
+ duration_ms: number | null;
308
313
  metadata_json: string;
309
314
  }
310
315
 
@@ -332,21 +337,21 @@ export interface WorkflowDebugSummary {
332
337
  cleanupState: 'none' | 'pending' | 'failed' | 'completed';
333
338
  lastObservedAt: number | null;
334
339
  metadata: WorkflowMetadata;
335
- recentEvents: Array<{
340
+ recentEvents: {
336
341
  eventType: string;
337
342
  fromState: WorkflowState | null;
338
343
  toState: WorkflowState;
339
344
  reason: string;
340
345
  createdAt: number;
341
346
  payload: Record<string, unknown>;
342
- }>;
347
+ }[];
343
348
  // NOC-16: Trinity stage states
344
- trinityStageStates?: Array<{
349
+ trinityStageStates?: {
345
350
  stage: 'dreamer' | 'philosopher' | 'scribe';
346
351
  status: 'pending' | 'running' | 'completed' | 'failed';
347
352
  reason?: string;
348
353
  completedAt?: number;
349
- }>;
354
+ }[];
350
355
  }
351
356
 
352
357
  // ── Convenience Re-exports ────────────────────────────────────────────────────