total-recall-brain 3.44.0 → 3.45.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 (212) hide show
  1. package/bin/total-recall.mjs +6 -4
  2. package/docs/ARCHITECTURE.md +10 -7
  3. package/docs/reference/cli-reference.md +13 -8
  4. package/frontend/dist/assets/index-DACh1dhx.js +5613 -0
  5. package/frontend/dist/index.html +1 -1
  6. package/frontend/src/App.tsx +2 -2
  7. package/frontend/src/pages/PluginsPage.tsx +1 -1
  8. package/package.json +1 -1
  9. package/scaffold/.agent/skills/total-recall/plugins/auth/package-lock.json +7 -7
  10. package/scaffold/.agent/skills/total-recall/plugins/auth/package.json +1 -1
  11. package/scaffold/.agent/skills/total-recall/plugins/auth/plugin.json +1 -1
  12. package/scaffold/.agent/skills/total-recall/plugins/auth/src/cli-secret.mjs +20 -1
  13. package/scaffold/.agent/skills/total-recall/plugins/auth/src/secrets-store.mjs +12 -1
  14. package/scaffold/.agent/skills/total-recall/plugins/automations/BRICK.md +7 -0
  15. package/scaffold/.agent/skills/total-recall/plugins/automations/LICENSE +21 -0
  16. package/scaffold/.agent/skills/total-recall/plugins/automations/README.md +66 -0
  17. package/scaffold/.agent/skills/total-recall/plugins/automations/adapters.mjs +231 -0
  18. package/scaffold/.agent/skills/total-recall/plugins/automations/capability/index.mjs +16 -0
  19. package/scaffold/.agent/skills/total-recall/plugins/automations/cli.mjs +121 -0
  20. package/{src/core/plugin-cron.mjs → scaffold/.agent/skills/total-recall/plugins/automations/cron.mjs} +1 -3
  21. package/scaffold/.agent/skills/total-recall/plugins/automations/inventory.mjs +88 -0
  22. package/scaffold/.agent/skills/total-recall/plugins/automations/package-lock.json +7661 -0
  23. package/scaffold/.agent/skills/total-recall/plugins/automations/package.json +35 -0
  24. package/scaffold/.agent/skills/total-recall/plugins/automations/plugin.json +167 -0
  25. package/scaffold/.agent/skills/total-recall/plugins/automations/scheduler.mjs +246 -0
  26. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/DESIGN.md +42 -0
  27. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/automations.js +2 -0
  28. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/card.js +273 -0
  29. package/scaffold/.agent/skills/total-recall/plugins/code-quality/commands/run-core.mjs +1 -1
  30. package/scaffold/.agent/skills/total-recall/plugins/code-quality/core/check.mjs +57 -5
  31. package/scaffold/.agent/skills/total-recall/plugins/code-quality/core/report-data.mjs +40 -14
  32. package/scaffold/.agent/skills/total-recall/plugins/code-quality/core/report.mjs +15 -40
  33. package/scaffold/.agent/skills/total-recall/plugins/code-quality/package-lock.json +7 -7
  34. package/scaffold/.agent/skills/total-recall/plugins/code-quality/package.json +1 -1
  35. package/scaffold/.agent/skills/total-recall/plugins/code-quality/plugin.json +1 -1
  36. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package-lock.json +7 -7
  37. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package.json +1 -1
  38. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/plugin.json +1 -1
  39. package/scaffold/.agent/skills/total-recall/plugins/embeddings/package-lock.json +7 -7
  40. package/scaffold/.agent/skills/total-recall/plugins/embeddings/package.json +1 -1
  41. package/scaffold/.agent/skills/total-recall/plugins/embeddings/plugin.json +1 -1
  42. package/scaffold/.agent/skills/total-recall/plugins/git/README.md +112 -0
  43. package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/cli.mjs +135 -23
  44. package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/package-lock.json +7 -7
  45. package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/package.json +2 -1
  46. package/scaffold/.agent/skills/total-recall/plugins/git/plugin.json +161 -0
  47. package/scaffold/.agent/skills/total-recall/plugins/git/src/lib/context.mjs +94 -0
  48. package/scaffold/.agent/skills/total-recall/plugins/git/src/lib/phase3-spec-support.mjs +50 -0
  49. package/scaffold/.agent/skills/total-recall/plugins/git/src/lib/runtime.mjs +40 -0
  50. package/scaffold/.agent/skills/total-recall/plugins/git/src/lib/spec-support.mjs +51 -0
  51. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/_support.mjs +195 -0
  52. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/auth.mjs +201 -0
  53. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/bisect.mjs +40 -0
  54. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/cli-meta.mjs +159 -0
  55. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/commit-memory.mjs +30 -0
  56. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/commit.mjs +46 -0
  57. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/fleet.mjs +156 -0
  58. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/force-push.mjs +58 -0
  59. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/group.mjs +119 -0
  60. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/handoff.mjs +59 -0
  61. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/message.mjs +22 -0
  62. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/resolve.mjs +60 -0
  63. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/rules.mjs +81 -0
  64. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/secret-firewall.mjs +66 -0
  65. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/undo.mjs +132 -0
  66. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/why.mjs +16 -0
  67. package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/ui/card.js +2 -2
  68. package/scaffold/.agent/skills/total-recall/plugins/mesh/package-lock.json +7 -7
  69. package/scaffold/.agent/skills/total-recall/plugins/mesh/package.json +1 -1
  70. package/scaffold/.agent/skills/total-recall/plugins/mesh/plugin.json +1 -1
  71. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/README.md +25 -9
  72. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/capability/BRICK.md +1 -1
  73. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/capability/index.mjs +18 -6
  74. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/cli.mjs +124 -24
  75. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package-lock.json +7 -7
  76. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package.json +2 -2
  77. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/plugin.json +147 -14
  78. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/skills/meta-harness/SKILL.md +17 -3
  79. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/adoption.mjs +2 -2
  80. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/alerts.mjs +3 -3
  81. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/cascade.mjs +92 -18
  82. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/control.mjs +145 -0
  83. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/coordinator.mjs +42 -21
  84. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/dispatch-request.mjs +4 -2
  85. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/dispatch.mjs +33 -9
  86. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/documentation.mjs +55 -11
  87. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/executor.mjs +26 -4
  88. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/gate-adapters/hermes.mjs +29 -1
  89. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/gate-adapters/index.mjs +1 -1
  90. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/included-usage.mjs +1 -1
  91. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/jobs.mjs +84 -0
  92. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/learner.mjs +3 -12
  93. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/maintenance.mjs +17 -0
  94. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/mcp-server.mjs +228 -0
  95. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/process-manager.mjs +25 -2
  96. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/reasoning.mjs +1 -1
  97. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/remote-operation.mjs +5 -1
  98. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/review.mjs +34 -3
  99. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/reviews.mjs +25 -0
  100. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/router.mjs +1 -1
  101. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/claude.mjs +319 -0
  102. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/codex.mjs +387 -0
  103. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/result.mjs +67 -0
  104. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/resume.mjs +373 -0
  105. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/run.mjs +223 -0
  106. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session-jobs.mjs +72 -0
  107. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/setup.mjs +6 -3
  108. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/termination.mjs +16 -12
  109. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/threads.mjs +32 -1
  110. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/usage-queue.mjs +1 -1
  111. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/verify-ssss.mjs +3 -3
  112. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/worker.mjs +285 -40
  113. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/worktree.mjs +76 -9
  114. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/DESIGN.md +5 -5
  115. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/card.js +3 -3
  116. package/scaffold/.agent/skills/total-recall/plugins/openwiki/cli.mjs +47 -18
  117. package/scaffold/.agent/skills/total-recall/plugins/openwiki/package-lock.json +7 -7
  118. package/scaffold/.agent/skills/total-recall/plugins/openwiki/package.json +1 -1
  119. package/scaffold/.agent/skills/total-recall/plugins/openwiki/plugin.json +1 -1
  120. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/refresh-diagnostics.mjs +44 -0
  121. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/refresh.mjs +120 -113
  122. package/scaffold/.agent/skills/total-recall/plugins/security/package-lock.json +7 -7
  123. package/scaffold/.agent/skills/total-recall/plugins/security/package.json +1 -1
  124. package/scaffold/.agent/skills/total-recall/plugins/security/plugin.json +1 -1
  125. package/scaffold/.agent/skills/total-recall/references/operations.md +1 -1
  126. package/src/cli/agent.mjs +1 -1
  127. package/src/cli/command.mjs +41 -2
  128. package/src/cli/dream.mjs +93 -69
  129. package/src/cli/harness.mjs +4 -4
  130. package/src/cli/help.mjs +1 -1
  131. package/src/cli/init.mjs +0 -25
  132. package/src/cli/lessons.mjs +51 -0
  133. package/src/cli/memory-plugin.mjs +1 -1
  134. package/src/cli/plugin/copies.mjs +64 -14
  135. package/src/cli/plugin/create.mjs +6 -7
  136. package/src/cli/plugin/index.mjs +11 -7
  137. package/src/cli/plugin/install.mjs +10 -15
  138. package/src/cli/plugin/remove.mjs +1 -1
  139. package/src/cli/plugin/search.mjs +2 -2
  140. package/src/cli/preflight.mjs +19 -6
  141. package/src/cli/proposals.mjs +1 -1
  142. package/src/cli/recall.mjs +66 -23
  143. package/src/cli/remember.mjs +3 -14
  144. package/src/cli/server.mjs +18 -0
  145. package/src/cli/startup.mjs +1 -0
  146. package/src/cli/task.mjs +9 -2
  147. package/src/cli/update.mjs +6 -2
  148. package/src/core/access-ledger.mjs +78 -0
  149. package/src/core/agent-manager.mjs +2 -2
  150. package/src/core/brain-locate.mjs +15 -0
  151. package/src/core/brain-updates.mjs +31 -11
  152. package/src/core/claude-hooks.mjs +3 -1
  153. package/src/core/cleanup-task.mjs +15 -0
  154. package/src/core/cli-commands.mjs +2 -0
  155. package/src/core/cli-maintenance.mjs +4 -1
  156. package/src/core/cli-semantic-index.mjs +23 -3
  157. package/src/core/context-compiler.mjs +20 -0
  158. package/src/core/daemon-loop.mjs +39 -62
  159. package/src/core/default-plugins.mjs +1 -1
  160. package/src/core/dream.mjs +33 -105
  161. package/src/core/ensure-dependencies.mjs +148 -0
  162. package/src/core/fast-recall.mjs +2 -2
  163. package/src/core/field-evaluation.mjs +23 -0
  164. package/src/core/gate-mode.mjs +1 -1
  165. package/src/core/harness-hooks.mjs +14 -2
  166. package/src/core/lesson-hooks.mjs +74 -0
  167. package/src/core/lesson-memory.mjs +24 -0
  168. package/src/core/lesson-sessions.mjs +52 -0
  169. package/src/core/lessons.mjs +96 -0
  170. package/src/core/meta-harness.mjs +2 -2
  171. package/src/core/optimizer.mjs +66 -165
  172. package/src/core/plugin-contracts/card.mjs +3 -0
  173. package/src/core/plugin-loader.mjs +12 -3
  174. package/src/core/plugin-runtime.mjs +40 -1
  175. package/src/core/plugin-store.mjs +35 -23
  176. package/src/core/post-mortem.mjs +52 -36
  177. package/src/core/preflight-gate.mjs +23 -2
  178. package/src/core/proposal-applier.mjs +31 -2
  179. package/src/core/repo-sync.mjs +4 -6
  180. package/src/core/required-plugins.mjs +26 -4
  181. package/src/core/rule-length.mjs +23 -0
  182. package/src/core/runtime.mjs +1 -1
  183. package/src/core/scheduler.mjs +35 -43
  184. package/src/core/schema.mjs +1 -2
  185. package/src/core/search.mjs +4 -3
  186. package/src/core/server-service.mjs +148 -0
  187. package/src/core/session-watcher.mjs +19 -1
  188. package/src/core/skill-gap.mjs +16 -0
  189. package/src/core/ssss-kernel-bridge.mjs +32 -4
  190. package/src/core/startup-health.mjs +6 -1
  191. package/src/core/surface.mjs +65 -54
  192. package/src/core/task-executors.mjs +54 -106
  193. package/src/core/validated-write.mjs +1 -0
  194. package/src/core/vector-field.mjs +134 -192
  195. package/src/server/invoke-core-child.mjs +24 -0
  196. package/src/server/invoke-core-operations.mjs +102 -0
  197. package/src/server/route-manifest.json +0 -56
  198. package/src/server/routes/brains.mjs +0 -18
  199. package/src/server/routes/context.mjs +0 -41
  200. package/src/server/routes/invoke.mjs +26 -1
  201. package/src/server/routes/ssss.mjs +0 -169
  202. package/src/server/routes/system.mjs +0 -15
  203. package/src/server/routes/tasks.mjs +0 -26
  204. package/src/server/routes/vault.mjs +2 -23
  205. package/frontend/dist/assets/index-DD4qONvH.js +0 -5607
  206. package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/README.md +0 -53
  207. package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/plugin.json +0 -129
  208. package/src/core/append-log.mjs +0 -131
  209. package/src/core/plugin-tasks.mjs +0 -173
  210. package/templates/onboarding-interview.md +0 -82
  211. /package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/LICENSE +0 -0
  212. /package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/ui/DESIGN.md +0 -0
@@ -1,4 +1,3 @@
1
- import { loadPluginModule as __loadOwnedPlugin } from './plugin-runtime.mjs';
2
1
  /**
3
2
  * Executor registry for daemon tasks.
4
3
  *
@@ -41,43 +40,18 @@ function policyCheck(task) {
41
40
 
42
41
  async function runDream(task, ctx) {
43
42
  const { runDreamCycle } = await import('./dream.mjs');
44
- await runDreamCycle({
43
+ const result = await runDreamCycle({
45
44
  vaultDir: ctx.vaultDir,
46
45
  skillsDir: ctx.skillsDir,
47
46
  derivedDir: ctx.derivedDir,
48
47
  conflictsDir: ctx.conflictsDir,
49
48
  instructionsFile: ctx.instructionsFile,
49
+ runtimeConfig: ctx.runtimeConfig,
50
50
  });
51
+ if (result?.status !== 'success') return { success: false, error: result?.errors?.join('; ') || 'unsupported', executor: 'dream' };
51
52
  return { success: true, output: 'Dream cycle complete', executor: 'dream' };
52
53
  }
53
54
 
54
- async function runSessionIngest(task, ctx) {
55
- const { scanAndIngest } = await import('./session-watcher.mjs');
56
- const result = scanAndIngest(ctx.sessionsDir);
57
- return {
58
- success: true,
59
- output: `Ingested ${result.ingested} new sessions`,
60
- executor: 'session-ingest',
61
- };
62
- }
63
-
64
- async function runSurfaceCompile(task, ctx) {
65
- const { compileSurface } = await import('./surface.mjs');
66
- await compileSurface({
67
- vaultDir: ctx.vaultDir,
68
- skillsDir: ctx.skillsDir,
69
- derivedDir: ctx.derivedDir,
70
- instructionsFile: ctx.instructionsFile,
71
- });
72
- return { success: true, output: 'Surface recompiled', executor: 'surface-compile' };
73
- }
74
-
75
- async function runPrune(task, ctx) {
76
- const { autoPruneStorage } = await import('./dream.mjs');
77
- autoPruneStorage(ctx.brainDir, ctx.vaultDir, ctx.conflictsDir);
78
- return { success: true, output: 'Storage prune complete', executor: 'prune' };
79
- }
80
-
81
55
  async function runCustom(task, ctx) {
82
56
  const land = task.result?.land || 'inbox';
83
57
  const intent = task.intent || task.body || task.reason || task.slug;
@@ -89,8 +63,8 @@ async function runCustom(task, ctx) {
89
63
  message: `Custom task (log only): ${task.slug} — ${intent}`,
90
64
  });
91
65
  return {
92
- success: true,
93
- output: `Custom task recorded (no vault write): ${intent}`.slice(0, 500),
66
+ success: false,
67
+ error: 'unsupported',
94
68
  executor: 'custom',
95
69
  };
96
70
  }
@@ -207,7 +181,7 @@ async function runLegacyCategoryDispatch(task, ctx) {
207
181
  }
208
182
 
209
183
  if (category === 'system2-deliberation') {
210
- if (process.env.TR_POWER_EXECUTORS !== '1' && !task._research_id) {
184
+ if (process.env.TR_POWER_EXECUTORS !== '1' && !task._research_id && !(task.created_by === 'automations' && task.payload?.scheduledIdle)) {
211
185
  return {
212
186
  success: false,
213
187
  error: 'system2-deliberation requires TR_POWER_EXECUTORS=1 (or research-queue phase)',
@@ -221,6 +195,7 @@ async function runLegacyCategoryDispatch(task, ctx) {
221
195
  inboxDir: path.join(BRAIN_DIR, 'memory-inbox', 'pending'),
222
196
  runtimeConfig,
223
197
  });
198
+ if (result.error || result.success === false) return { success: false, error: result.error || 'Inference failed', executor: 'system2' };
224
199
  return {
225
200
  success: true,
226
201
  output: `Inference complete: ${result.conclusions?.length || 0} conclusions`,
@@ -253,7 +228,9 @@ async function runLegacyCategoryDispatch(task, ctx) {
253
228
  vaultDir: VAULT_DIR,
254
229
  inboxDir: path.join(BRAIN_DIR, 'memory-inbox', 'pending'),
255
230
  runtimeConfig,
231
+ fromTurn: 1,
256
232
  });
233
+ if (result.error) return { success: false, error: result.error, executor: 'post-mortem' };
257
234
  return {
258
235
  success: true,
259
236
  output: `Post-mortem: ${result.nodesCreated || 0} nodes`,
@@ -280,6 +257,7 @@ async function runLegacyCategoryDispatch(task, ctx) {
280
257
  inboxDir: path.join(BRAIN_DIR, 'memory-inbox', 'pending'),
281
258
  runtimeConfig,
282
259
  });
260
+ if (result.error || result.success === false) return { success: false, error: result.error || 'Clarity review failed', executor: 'clarity' };
283
261
  return {
284
262
  success: true,
285
263
  output: `Clarity review: rewrote=${result.rewrote}`,
@@ -287,17 +265,8 @@ async function runLegacyCategoryDispatch(task, ctx) {
287
265
  };
288
266
  }
289
267
  if (String(task.slug || '').startsWith('memory-compaction-')) {
290
- const { runMemoryCompaction } = await import('./fact-seeker.mjs');
291
- const result = await runMemoryCompaction({
292
- vaultDir: VAULT_DIR,
293
- inboxDir: path.join(BRAIN_DIR, 'memory-inbox', 'pending'),
294
- runtimeConfig,
295
- });
296
- return {
297
- success: true,
298
- output: `Compaction: ${result.consolidatedCount || 0} nodes`,
299
- executor: 'compaction',
300
- };
268
+ const { fileCleanupProposals } = await import('./cleanup-task.mjs');
269
+ return fileCleanupProposals(VAULT_DIR);
301
270
  }
302
271
  // generic maintenance: lease vacuum
303
272
  try {
@@ -324,10 +293,10 @@ async function runLegacyCategoryDispatch(task, ctx) {
324
293
  return { success: true, output: 'Maintenance complete', executor: 'maintenance' };
325
294
  }
326
295
 
327
- if (category === 'exploration' || category === 'self-evaluation' || category === 'skill-engineering') {
296
+ if (category === 'self-evaluation' || category === 'skill-engineering') {
328
297
  return {
329
- success: true,
330
- output: `Acknowledged category ${category} (no-op in core mode)`,
298
+ success: false,
299
+ error: 'unsupported',
331
300
  executor: category,
332
301
  };
333
302
  }
@@ -335,7 +304,7 @@ async function runLegacyCategoryDispatch(task, ctx) {
335
304
  // Unknown — fail loud
336
305
  return {
337
306
  success: false,
338
- error: `Unknown task executor/category: executor=${task.executor || 'null'} category=${category || 'null'} kind=${task.kind || 'null'} slug=${task.slug}`,
307
+ error: 'unsupported',
339
308
  executor: 'unknown',
340
309
  };
341
310
  }
@@ -375,7 +344,7 @@ async function runResearchLegacy(task, ctx) {
375
344
  // researched — so it is now a no-op (RESEARCH_SYSTEM2).
376
345
  const topic = String(task.target || '').trim();
377
346
  if (!topic || topic === 'global') {
378
- return { success: true, output: 'No research topic on this task — nothing to research.', executor: 'research' };
347
+ return { success: false, error: 'unsupported', executor: 'research' };
379
348
  }
380
349
 
381
350
  // Prefer deep multi-source research when this came from the research queue
@@ -514,7 +483,7 @@ async function runResearchLegacy(task, ctx) {
514
483
  quarantineDir: path.join(BRAIN_DIR, 'memory-inbox', 'quarantine'),
515
484
  });
516
485
  if (result.skipped) {
517
- return { success: true, output: `Conclusion writer: ${result.skipped}`, executor: 'research' };
486
+ return { success: false, error: 'unsupported', executor: 'research' };
518
487
  }
519
488
  return {
520
489
  success: true,
@@ -525,7 +494,7 @@ async function runResearchLegacy(task, ctx) {
525
494
 
526
495
  return {
527
496
  success: false,
528
- error: `No research handler matched slug=${task.slug} category=${task.category}`,
497
+ error: 'unsupported',
529
498
  executor: 'research',
530
499
  };
531
500
  }
@@ -571,47 +540,39 @@ function findLatestResearchDraftSlug(inboxDir, topic) {
571
540
 
572
541
  // ─── Registry ───────────────────────────────────────────────────────────────────
573
542
 
574
- async function runSecretsRotationCheck(task, ctx) {
575
- const { runSecretsRotationCheck: run } = await __loadOwnedPlugin('auth', 'secrets-rotate');
576
- return run(ctx);
577
- }
578
-
579
- async function runSecretsExportEnv(task, ctx) {
580
- const { runSecretsExportAll } = await __loadOwnedPlugin('auth', 'secrets-rotate');
581
- return runSecretsExportAll(ctx);
543
+ async function runSkillGap(task, ctx) {
544
+ const { requestSkillGap } = await import('./skill-gap.mjs');
545
+ const topic = task.payload?.topic || task.target || /topic "([^"]+)"/.exec(task.reason || '')?.[1];
546
+ const session = task.source_session || task.origin?.session_id;
547
+ return requestSkillGap(topic, task.payload?.evidence ||
548
+ (session ? `session://${session}` : null), { projectRoot: ctx.projectRoot || process.cwd() });
582
549
  }
583
550
 
584
- async function runSecretsRotationAssist(task, ctx) {
585
- // Supervised: ensure prompt is present; does not auto-browser without agent session
586
- const key = task.payload?.secret_key || task.slug?.replace(/^secret-rotate-/, '');
587
- if (!key) {
588
- return { success: false, error: 'missing secret_key', executor: 'secrets-rotation-assist' };
551
+ async function runLessonReview(task, ctx) {
552
+ const { runPostMortem } = await import('./post-mortem.mjs');
553
+ const sessionPath = task.payload?.sessionPath || (task.target && path.join(ctx.sessionsDir, task.target));
554
+ if (!sessionPath) return { success: false, error: 'Lesson review requires a session transcript and turn range' };
555
+ const result = await runPostMortem(sessionPath, {
556
+ vaultDir: ctx.vaultDir, inboxDir: path.join(ctx.brainDir, 'memory-inbox', 'pending'), runtimeConfig: ctx.runtimeConfig,
557
+ // Scheduled snapshots already contain exactly the requested range.
558
+ fromTurn: task.payload?.sessionPath ? 1 : task.payload?.fromTurn,
559
+ toTurn: task.payload?.sessionPath ? Infinity : task.payload?.toTurn,
560
+ sourceRef: task.payload?.sessionId ? `${task.payload.sessionId}/turns/${task.payload.fromTurn}-${task.payload.toTurn}` : task.slug,
561
+ hold: task.payload?.hold === true,
562
+ });
563
+ if (result.error) return { success: false, error: result.error, executor: 'lesson-review' };
564
+ if (task.slug?.startsWith('lesson-review-')) {
565
+ const dir = path.join(ctx.brainDir, 'lesson-reviews');
566
+ fs.mkdirSync(dir, { recursive: true });
567
+ atomicWrite(path.join(dir, `${task.slug}.done`), new Date().toISOString());
589
568
  }
590
- const { getBrowserRotateAssist } = await __loadOwnedPlugin('auth', 'secrets-rotate');
591
- const assist = await getBrowserRotateAssist(ctx.brainDir, key);
592
- return {
593
- success: true,
594
- output: `Browser rotation assist ready for ${key}. Console: ${assist.console_url || 'n/a'}. Use browser tools with human 2FA; then secret rotate --export-env.`,
595
- executor: 'secrets-rotation-assist',
596
- assist: {
597
- key: assist.key,
598
- console_url: assist.console_url,
599
- docs_url: assist.docs_url,
600
- overdue: assist.overdue,
601
- // prompt available to agent; do not echo secrets
602
- prompt: assist.prompt,
603
- },
604
- };
569
+ return { success: true, output: `Lesson review: ${result.patterns?.length || 0} patterns, ${result.facts?.length || 0} facts, ${result.skill_gaps?.length || 0} skill gaps, ${result.violations?.length || 0} violations`, executor: 'lesson-review' };
605
570
  }
606
571
 
607
572
  const EXECUTORS = {
608
- 'secrets-rotation-check': { id: 'secrets-rotation-check', run: runSecretsRotationCheck },
609
- 'secrets-export-env': { id: 'secrets-export-env', run: runSecretsExportEnv },
610
- 'secrets-rotation-assist': { id: 'secrets-rotation-assist', run: runSecretsRotationAssist },
573
+ 'lesson-review': { id: 'lesson-review', run: runLessonReview },
574
+ 'skill-manager': { id: 'skill-manager', run: runSkillGap },
611
575
  dream: { id: 'dream', run: runDream },
612
- 'session-ingest': { id: 'session-ingest', run: runSessionIngest },
613
- 'surface-compile': { id: 'surface-compile', run: runSurfaceCompile },
614
- prune: { id: 'prune', run: runPrune },
615
576
  custom: { id: 'custom', run: runCustom },
616
577
  research: { id: 'research', run: runResearchLegacy },
617
578
  legacy: { id: 'legacy', run: runLegacyDispatch },
@@ -623,31 +584,16 @@ const EXECUTORS = {
623
584
  export function resolveExecutor(task) {
624
585
  const t = normalizeTask(task);
625
586
 
626
- if (t.executor && EXECUTORS[t.executor]) {
627
- return EXECUTORS[t.executor];
628
- }
587
+ if (t.category === 'skill-engineering') return EXECUTORS['skill-manager'];
588
+ if (t.category === 'lesson-review' || t.category === 'self-evaluation') return EXECUTORS['lesson-review'];
589
+
590
+ // An explicit unsupported executor must never fall through to kind/category.
591
+ if (t.executor) return typeof t.executor === 'string' && Object.hasOwn(EXECUTORS, t.executor) ? EXECUTORS[t.executor] : null;
629
592
 
630
593
  // System / named slugs
631
594
  if (t.slug === 'dream' || String(t.slug || '').startsWith('dream-') || t.executor === 'dream') {
632
595
  return EXECUTORS.dream;
633
596
  }
634
- if (String(t.slug || '').startsWith('session-ingest')) return EXECUTORS['session-ingest'];
635
- if (String(t.slug || '').startsWith('surface-compile')) return EXECUTORS['surface-compile'];
636
- if (String(t.slug || '').startsWith('prune-') || t.slug === 'prune') return EXECUTORS.prune;
637
- if (String(t.slug || '').startsWith('secret-rotate-') || t.category === 'secrets-rotation') {
638
- return EXECUTORS['secrets-rotation-assist'];
639
- }
640
- if (String(t.slug || '').startsWith('secrets-rotation-check') || t.executor === 'secrets-rotation-check') {
641
- return EXECUTORS['secrets-rotation-check'];
642
- }
643
- if (String(t.slug || '').startsWith('secrets-export') || t.executor === 'secrets-export-env') {
644
- return EXECUTORS['secrets-export-env'];
645
- }
646
-
647
- if (t.kind === 'custom' || t.category === 'custom' || t.executor === 'custom') {
648
- return EXECUTORS.custom;
649
- }
650
-
651
597
  // Known legacy categories still registered
652
598
  const legacyCategories = new Set([
653
599
  'conscious-enforcement',
@@ -658,13 +604,14 @@ export function resolveExecutor(task) {
658
604
  'proactive-research',
659
605
  'skill-engineering',
660
606
  'self-evaluation',
661
- 'exploration',
662
607
  ]);
663
608
 
664
609
  if (legacyCategories.has(t.category) || t._research_id || t._is_remote_vault_sync) {
665
610
  return EXECUTORS.legacy;
666
611
  }
667
612
 
613
+ if (t.category === 'custom' || (t.kind === 'custom' && !t.category)) return EXECUTORS.custom;
614
+
668
615
  if (t.kind === 'research') return EXECUTORS.research;
669
616
  if (t.kind === 'system' || t.kind === 'maintenance' || t.kind === 'memory') {
670
617
  return EXECUTORS.legacy;
@@ -691,11 +638,12 @@ export async function dispatchTask(task, ctx) {
691
638
  `Unknown task executor for slug=${normalized.slug} ` +
692
639
  `category=${normalized.category} kind=${normalized.kind} executor=${normalized.executor}`;
693
640
  logger.info({ subsystem: 'task-executors', message: msg });
694
- return { success: false, error: msg, executor: 'unknown' };
641
+ return { success: false, error: 'unsupported', executor: 'unknown' };
695
642
  }
696
643
 
697
644
  try {
698
645
  const result = await executor.run(normalized, ctx);
646
+ if (!result || typeof result.success !== 'boolean') return { success: false, error: 'unsupported', executor: executor.id };
699
647
  return { ...result, executor: result.executor || executor.id };
700
648
  } catch (err) {
701
649
  return {
@@ -156,6 +156,7 @@ export async function writeNodeValidatedAsync(node, vaultDir, options = {}) {
156
156
  agentRole,
157
157
  leaseStore,
158
158
  eventLogDir,
159
+ allowLong: options.allowLong === true,
159
160
  });
160
161
 
161
162
  if (result.success && !dryRun) {