cognitive-core 0.1.2 → 0.2.1

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 (528) hide show
  1. package/.claude/settings.json +111 -2
  2. package/.sessionlog/settings.json +4 -0
  3. package/CLAUDE.md +233 -0
  4. package/README.md +370 -54
  5. package/dist/atlas.d.ts +10 -10
  6. package/dist/atlas.d.ts.map +1 -1
  7. package/dist/atlas.js +79 -48
  8. package/dist/atlas.js.map +1 -1
  9. package/dist/bin/cli-utils.d.ts +37 -0
  10. package/dist/bin/cli-utils.d.ts.map +1 -0
  11. package/dist/bin/cli-utils.js +176 -0
  12. package/dist/bin/cli-utils.js.map +1 -0
  13. package/dist/bin/cognitive-core.d.ts +2 -12
  14. package/dist/bin/cognitive-core.d.ts.map +1 -1
  15. package/dist/bin/cognitive-core.js +76 -351
  16. package/dist/bin/cognitive-core.js.map +1 -1
  17. package/dist/bin/commands/kb.d.ts +6 -0
  18. package/dist/bin/commands/kb.d.ts.map +1 -0
  19. package/dist/bin/commands/kb.js +240 -0
  20. package/dist/bin/commands/kb.js.map +1 -0
  21. package/dist/bin/commands/learn.d.ts +6 -0
  22. package/dist/bin/commands/learn.d.ts.map +1 -0
  23. package/dist/bin/commands/learn.js +91 -0
  24. package/dist/bin/commands/learn.js.map +1 -0
  25. package/dist/bin/commands/legacy.d.ts +12 -0
  26. package/dist/bin/commands/legacy.d.ts.map +1 -0
  27. package/dist/bin/commands/legacy.js +142 -0
  28. package/dist/bin/commands/legacy.js.map +1 -0
  29. package/dist/bin/commands/run.d.ts +3 -0
  30. package/dist/bin/commands/run.d.ts.map +1 -0
  31. package/dist/bin/commands/run.js +99 -0
  32. package/dist/bin/commands/run.js.map +1 -0
  33. package/dist/bin/commands/sessions.d.ts +9 -0
  34. package/dist/bin/commands/sessions.d.ts.map +1 -0
  35. package/dist/bin/commands/sessions.js +183 -0
  36. package/dist/bin/commands/sessions.js.map +1 -0
  37. package/dist/bin/commands/skills.d.ts +6 -0
  38. package/dist/bin/commands/skills.d.ts.map +1 -0
  39. package/dist/bin/commands/skills.js +135 -0
  40. package/dist/bin/commands/skills.js.map +1 -0
  41. package/dist/embeddings/index.d.ts +1 -0
  42. package/dist/embeddings/index.d.ts.map +1 -1
  43. package/dist/embeddings/index.js +2 -0
  44. package/dist/embeddings/index.js.map +1 -1
  45. package/dist/embeddings/inverted-index.d.ts +47 -0
  46. package/dist/embeddings/inverted-index.d.ts.map +1 -0
  47. package/dist/embeddings/inverted-index.js +122 -0
  48. package/dist/embeddings/inverted-index.js.map +1 -0
  49. package/dist/embeddings/manager.d.ts +3 -1
  50. package/dist/embeddings/manager.d.ts.map +1 -1
  51. package/dist/embeddings/manager.js +12 -7
  52. package/dist/embeddings/manager.js.map +1 -1
  53. package/dist/embeddings/vector-store.d.ts +7 -3
  54. package/dist/embeddings/vector-store.d.ts.map +1 -1
  55. package/dist/embeddings/vector-store.js +22 -6
  56. package/dist/embeddings/vector-store.js.map +1 -1
  57. package/dist/factory.d.ts +11 -12
  58. package/dist/factory.d.ts.map +1 -1
  59. package/dist/factory.js +20 -7
  60. package/dist/factory.js.map +1 -1
  61. package/dist/index.d.ts +8 -7
  62. package/dist/index.d.ts.map +1 -1
  63. package/dist/index.js +42 -6
  64. package/dist/index.js.map +1 -1
  65. package/dist/learning/analyzer.d.ts.map +1 -1
  66. package/dist/learning/analyzer.js +17 -35
  67. package/dist/learning/analyzer.js.map +1 -1
  68. package/dist/learning/energy-evaluator.d.ts +128 -0
  69. package/dist/learning/energy-evaluator.d.ts.map +1 -0
  70. package/dist/learning/energy-evaluator.js +175 -0
  71. package/dist/learning/energy-evaluator.js.map +1 -0
  72. package/dist/learning/healing-orchestrator.d.ts +182 -0
  73. package/dist/learning/healing-orchestrator.d.ts.map +1 -0
  74. package/dist/learning/healing-orchestrator.js +250 -0
  75. package/dist/learning/healing-orchestrator.js.map +1 -0
  76. package/dist/learning/index.d.ts +7 -2
  77. package/dist/learning/index.d.ts.map +1 -1
  78. package/dist/learning/index.js +13 -2
  79. package/dist/learning/index.js.map +1 -1
  80. package/dist/learning/instant-loop.d.ts +87 -0
  81. package/dist/learning/instant-loop.d.ts.map +1 -0
  82. package/dist/learning/instant-loop.js +264 -0
  83. package/dist/learning/instant-loop.js.map +1 -0
  84. package/dist/learning/loop-coordinator.d.ts +61 -0
  85. package/dist/learning/loop-coordinator.d.ts.map +1 -0
  86. package/dist/learning/loop-coordinator.js +96 -0
  87. package/dist/learning/loop-coordinator.js.map +1 -0
  88. package/dist/learning/maintenance-scheduler.d.ts +141 -0
  89. package/dist/learning/maintenance-scheduler.d.ts.map +1 -0
  90. package/dist/learning/maintenance-scheduler.js +186 -0
  91. package/dist/learning/maintenance-scheduler.js.map +1 -0
  92. package/dist/learning/meta-learner.d.ts.map +1 -1
  93. package/dist/learning/meta-learner.js +4 -21
  94. package/dist/learning/meta-learner.js.map +1 -1
  95. package/dist/learning/pipeline.d.ts +31 -4
  96. package/dist/learning/pipeline.d.ts.map +1 -1
  97. package/dist/learning/pipeline.js +64 -12
  98. package/dist/learning/pipeline.js.map +1 -1
  99. package/dist/learning/reflexion-generator.d.ts +64 -0
  100. package/dist/learning/reflexion-generator.d.ts.map +1 -0
  101. package/dist/learning/reflexion-generator.js +194 -0
  102. package/dist/learning/reflexion-generator.js.map +1 -0
  103. package/dist/learning/trajectory-sources/entire.d.ts +8 -5
  104. package/dist/learning/trajectory-sources/entire.d.ts.map +1 -1
  105. package/dist/learning/trajectory-sources/entire.js +13 -6
  106. package/dist/learning/trajectory-sources/entire.js.map +1 -1
  107. package/dist/learning/trajectory-sources/index.d.ts +1 -1
  108. package/dist/learning/trajectory-sources/index.d.ts.map +1 -1
  109. package/dist/learning/trajectory-sources/index.js +1 -1
  110. package/dist/learning/trajectory-sources/index.js.map +1 -1
  111. package/dist/learning/trajectory-sources/pipeline.d.ts +4 -4
  112. package/dist/learning/trajectory-sources/pipeline.d.ts.map +1 -1
  113. package/dist/learning/trajectory-sources/pipeline.js +2 -2
  114. package/dist/learning/trajectory-sources/pipeline.js.map +1 -1
  115. package/dist/learning/unified-pipeline.d.ts +311 -0
  116. package/dist/learning/unified-pipeline.d.ts.map +1 -0
  117. package/dist/learning/unified-pipeline.js +844 -0
  118. package/dist/learning/unified-pipeline.js.map +1 -0
  119. package/dist/memory/candidate-retrieval.d.ts +43 -0
  120. package/dist/memory/candidate-retrieval.d.ts.map +1 -0
  121. package/dist/memory/candidate-retrieval.js +43 -0
  122. package/dist/memory/candidate-retrieval.js.map +1 -0
  123. package/dist/memory/causal-store.d.ts +97 -0
  124. package/dist/memory/causal-store.d.ts.map +1 -0
  125. package/dist/memory/causal-store.js +209 -0
  126. package/dist/memory/causal-store.js.map +1 -0
  127. package/dist/memory/coherence.d.ts +71 -0
  128. package/dist/memory/coherence.d.ts.map +1 -0
  129. package/dist/memory/coherence.js +176 -0
  130. package/dist/memory/coherence.js.map +1 -0
  131. package/dist/memory/experience.d.ts +39 -6
  132. package/dist/memory/experience.d.ts.map +1 -1
  133. package/dist/memory/experience.js +193 -49
  134. package/dist/memory/experience.js.map +1 -1
  135. package/dist/memory/index.d.ts +7 -0
  136. package/dist/memory/index.d.ts.map +1 -1
  137. package/dist/memory/index.js +12 -0
  138. package/dist/memory/index.js.map +1 -1
  139. package/dist/memory/knowledge-bank.d.ts +14 -0
  140. package/dist/memory/knowledge-bank.d.ts.map +1 -1
  141. package/dist/memory/knowledge-bank.js +45 -0
  142. package/dist/memory/knowledge-bank.js.map +1 -1
  143. package/dist/memory/meta.d.ts +7 -8
  144. package/dist/memory/meta.d.ts.map +1 -1
  145. package/dist/memory/meta.js +73 -79
  146. package/dist/memory/meta.js.map +1 -1
  147. package/dist/memory/playbook.d.ts +26 -9
  148. package/dist/memory/playbook.d.ts.map +1 -1
  149. package/dist/memory/playbook.js +198 -74
  150. package/dist/memory/playbook.js.map +1 -1
  151. package/dist/memory/reasoning-bank.d.ts +130 -0
  152. package/dist/memory/reasoning-bank.d.ts.map +1 -0
  153. package/dist/memory/reasoning-bank.js +342 -0
  154. package/dist/memory/reasoning-bank.js.map +1 -0
  155. package/dist/memory/reflexion.d.ts +59 -0
  156. package/dist/memory/reflexion.d.ts.map +1 -0
  157. package/dist/memory/reflexion.js +96 -0
  158. package/dist/memory/reflexion.js.map +1 -0
  159. package/dist/memory/system.d.ts +7 -2
  160. package/dist/memory/system.d.ts.map +1 -1
  161. package/dist/memory/system.js +19 -7
  162. package/dist/memory/system.js.map +1 -1
  163. package/dist/memory/temporal-compressor.d.ts +126 -0
  164. package/dist/memory/temporal-compressor.d.ts.map +1 -0
  165. package/dist/memory/temporal-compressor.js +335 -0
  166. package/dist/memory/temporal-compressor.js.map +1 -0
  167. package/dist/persistence/index.d.ts +11 -0
  168. package/dist/persistence/index.d.ts.map +1 -0
  169. package/dist/persistence/index.js +11 -0
  170. package/dist/persistence/index.js.map +1 -0
  171. package/dist/persistence/migrator.d.ts +40 -0
  172. package/dist/persistence/migrator.d.ts.map +1 -0
  173. package/dist/persistence/migrator.js +238 -0
  174. package/dist/persistence/migrator.js.map +1 -0
  175. package/dist/persistence/serializers.d.ts +45 -0
  176. package/dist/persistence/serializers.d.ts.map +1 -0
  177. package/dist/persistence/serializers.js +80 -0
  178. package/dist/persistence/serializers.js.map +1 -0
  179. package/dist/persistence/sqlite-persistence.d.ts +228 -0
  180. package/dist/persistence/sqlite-persistence.d.ts.map +1 -0
  181. package/dist/persistence/sqlite-persistence.js +588 -0
  182. package/dist/persistence/sqlite-persistence.js.map +1 -0
  183. package/dist/runtime/flows/learning.d.ts +10 -12
  184. package/dist/runtime/flows/learning.d.ts.map +1 -1
  185. package/dist/runtime/flows/learning.js +10 -23
  186. package/dist/runtime/flows/learning.js.map +1 -1
  187. package/dist/search/index.d.ts +1 -0
  188. package/dist/search/index.d.ts.map +1 -1
  189. package/dist/search/index.js +2 -0
  190. package/dist/search/index.js.map +1 -1
  191. package/dist/search/moe-gate.d.ts +124 -0
  192. package/dist/search/moe-gate.d.ts.map +1 -0
  193. package/dist/search/moe-gate.js +234 -0
  194. package/dist/search/moe-gate.js.map +1 -0
  195. package/dist/search/router.d.ts +32 -2
  196. package/dist/search/router.d.ts.map +1 -1
  197. package/dist/search/router.js +87 -4
  198. package/dist/search/router.js.map +1 -1
  199. package/dist/session-bank/git-reader.d.ts +9 -4
  200. package/dist/session-bank/git-reader.d.ts.map +1 -1
  201. package/dist/session-bank/git-reader.js +22 -15
  202. package/dist/session-bank/git-reader.js.map +1 -1
  203. package/dist/session-bank/index.d.ts +2 -2
  204. package/dist/session-bank/index.d.ts.map +1 -1
  205. package/dist/session-bank/index.js +2 -2
  206. package/dist/session-bank/index.js.map +1 -1
  207. package/dist/session-bank/parser.d.ts +16 -5
  208. package/dist/session-bank/parser.d.ts.map +1 -1
  209. package/dist/session-bank/parser.js +187 -80
  210. package/dist/session-bank/parser.js.map +1 -1
  211. package/dist/session-bank/session-bank.d.ts +5 -0
  212. package/dist/session-bank/session-bank.d.ts.map +1 -1
  213. package/dist/session-bank/session-bank.js +30 -9
  214. package/dist/session-bank/session-bank.js.map +1 -1
  215. package/dist/session-bank/types.d.ts +4 -1
  216. package/dist/session-bank/types.d.ts.map +1 -1
  217. package/dist/session-bank/types.js +3 -3
  218. package/dist/session-bank/types.js.map +1 -1
  219. package/dist/surfacing/skill-publisher.d.ts.map +1 -1
  220. package/dist/surfacing/skill-publisher.js +15 -43
  221. package/dist/surfacing/skill-publisher.js.map +1 -1
  222. package/dist/surfacing/sqlite-storage-adapter.d.ts.map +1 -1
  223. package/dist/surfacing/sqlite-storage-adapter.js +13 -21
  224. package/dist/surfacing/sqlite-storage-adapter.js.map +1 -1
  225. package/dist/types/config.d.ts +100 -0
  226. package/dist/types/config.d.ts.map +1 -1
  227. package/dist/types/config.js +27 -0
  228. package/dist/types/config.js.map +1 -1
  229. package/dist/types/index.d.ts +2 -2
  230. package/dist/types/index.d.ts.map +1 -1
  231. package/dist/types/index.js +1 -1
  232. package/dist/types/index.js.map +1 -1
  233. package/dist/types/memory.d.ts +52 -0
  234. package/dist/types/memory.d.ts.map +1 -1
  235. package/dist/types/memory.js +13 -0
  236. package/dist/types/memory.js.map +1 -1
  237. package/dist/types/playbook.d.ts +4 -0
  238. package/dist/types/playbook.d.ts.map +1 -1
  239. package/dist/types/playbook.js.map +1 -1
  240. package/dist/utils/error-classifier.d.ts +30 -0
  241. package/dist/utils/error-classifier.d.ts.map +1 -0
  242. package/dist/utils/error-classifier.js +85 -0
  243. package/dist/utils/error-classifier.js.map +1 -0
  244. package/dist/utils/index.d.ts +3 -0
  245. package/dist/utils/index.d.ts.map +1 -1
  246. package/dist/utils/index.js +3 -0
  247. package/dist/utils/index.js.map +1 -1
  248. package/dist/utils/partitioned-store.d.ts +93 -0
  249. package/dist/utils/partitioned-store.d.ts.map +1 -0
  250. package/dist/utils/partitioned-store.js +251 -0
  251. package/dist/utils/partitioned-store.js.map +1 -0
  252. package/dist/utils/trajectory-helpers.d.ts +39 -0
  253. package/dist/utils/trajectory-helpers.d.ts.map +1 -0
  254. package/dist/utils/trajectory-helpers.js +57 -0
  255. package/dist/utils/trajectory-helpers.js.map +1 -0
  256. package/dist/workspace/efficacy-toolkit.d.ts +164 -0
  257. package/dist/workspace/efficacy-toolkit.d.ts.map +1 -0
  258. package/dist/workspace/efficacy-toolkit.js +281 -0
  259. package/dist/workspace/efficacy-toolkit.js.map +1 -0
  260. package/dist/workspace/index.d.ts +2 -1
  261. package/dist/workspace/index.d.ts.map +1 -1
  262. package/dist/workspace/index.js +3 -1
  263. package/dist/workspace/index.js.map +1 -1
  264. package/dist/workspace/runner.d.ts +3 -4
  265. package/dist/workspace/runner.d.ts.map +1 -1
  266. package/dist/workspace/runner.js.map +1 -1
  267. package/dist/workspace/templates/index.d.ts +3 -0
  268. package/dist/workspace/templates/index.d.ts.map +1 -1
  269. package/dist/workspace/templates/index.js +6 -0
  270. package/dist/workspace/templates/index.js.map +1 -1
  271. package/dist/workspace/templates/playbook-decay-detection.d.ts +46 -0
  272. package/dist/workspace/templates/playbook-decay-detection.d.ts.map +1 -0
  273. package/dist/workspace/templates/playbook-decay-detection.js +197 -0
  274. package/dist/workspace/templates/playbook-decay-detection.js.map +1 -0
  275. package/dist/workspace/templates/playbook-efficacy-audit.d.ts +46 -0
  276. package/dist/workspace/templates/playbook-efficacy-audit.d.ts.map +1 -0
  277. package/dist/workspace/templates/playbook-efficacy-audit.js +160 -0
  278. package/dist/workspace/templates/playbook-efficacy-audit.js.map +1 -0
  279. package/dist/workspace/templates/playbook-lifecycle-review.d.ts +51 -0
  280. package/dist/workspace/templates/playbook-lifecycle-review.d.ts.map +1 -0
  281. package/dist/workspace/templates/playbook-lifecycle-review.js +187 -0
  282. package/dist/workspace/templates/playbook-lifecycle-review.js.map +1 -0
  283. package/dist/workspace/types.d.ts +9 -2
  284. package/dist/workspace/types.d.ts.map +1 -1
  285. package/dist/workspace/types.js.map +1 -1
  286. package/package.json +12 -4
  287. package/references/sessionlog/.husky/pre-commit +1 -0
  288. package/references/sessionlog/.lintstagedrc.json +4 -0
  289. package/references/sessionlog/.prettierignore +4 -0
  290. package/references/sessionlog/.prettierrc.json +11 -0
  291. package/references/sessionlog/LICENSE +21 -0
  292. package/references/sessionlog/README.md +453 -0
  293. package/references/sessionlog/eslint.config.js +58 -0
  294. package/references/sessionlog/package-lock.json +3672 -0
  295. package/references/sessionlog/package.json +65 -0
  296. package/references/sessionlog/src/__tests__/agent-hooks.test.ts +570 -0
  297. package/references/sessionlog/src/__tests__/agent-registry.test.ts +127 -0
  298. package/references/sessionlog/src/__tests__/claude-code-hooks.test.ts +225 -0
  299. package/references/sessionlog/src/__tests__/claude-generator.test.ts +46 -0
  300. package/references/sessionlog/src/__tests__/commit-msg.test.ts +86 -0
  301. package/references/sessionlog/src/__tests__/cursor-agent.test.ts +224 -0
  302. package/references/sessionlog/src/__tests__/e2e-live.test.ts +890 -0
  303. package/references/sessionlog/src/__tests__/event-log.test.ts +183 -0
  304. package/references/sessionlog/src/__tests__/flush-sentinel.test.ts +105 -0
  305. package/references/sessionlog/src/__tests__/gemini-agent.test.ts +375 -0
  306. package/references/sessionlog/src/__tests__/git-hooks.test.ts +78 -0
  307. package/references/sessionlog/src/__tests__/hook-managers.test.ts +121 -0
  308. package/references/sessionlog/src/__tests__/lifecycle-tasks.test.ts +759 -0
  309. package/references/sessionlog/src/__tests__/opencode-agent.test.ts +338 -0
  310. package/references/sessionlog/src/__tests__/redaction.test.ts +136 -0
  311. package/references/sessionlog/src/__tests__/session-repo.test.ts +353 -0
  312. package/references/sessionlog/src/__tests__/session-store.test.ts +166 -0
  313. package/references/sessionlog/src/__tests__/setup-ccweb.test.ts +466 -0
  314. package/references/sessionlog/src/__tests__/skill-live.test.ts +461 -0
  315. package/references/sessionlog/src/__tests__/summarize.test.ts +348 -0
  316. package/references/sessionlog/src/__tests__/task-plan-e2e.test.ts +610 -0
  317. package/references/sessionlog/src/__tests__/task-plan-live.test.ts +632 -0
  318. package/references/sessionlog/src/__tests__/transcript-timestamp.test.ts +121 -0
  319. package/references/sessionlog/src/__tests__/types.test.ts +166 -0
  320. package/references/sessionlog/src/__tests__/utils.test.ts +333 -0
  321. package/references/sessionlog/src/__tests__/validation.test.ts +103 -0
  322. package/references/sessionlog/src/__tests__/worktree.test.ts +57 -0
  323. package/references/sessionlog/src/agent/agents/claude-code.ts +1089 -0
  324. package/references/sessionlog/src/agent/agents/cursor.ts +361 -0
  325. package/references/sessionlog/src/agent/agents/gemini-cli.ts +632 -0
  326. package/references/sessionlog/src/agent/agents/opencode.ts +540 -0
  327. package/references/sessionlog/src/agent/registry.ts +143 -0
  328. package/references/sessionlog/src/agent/session-types.ts +113 -0
  329. package/references/sessionlog/src/agent/types.ts +220 -0
  330. package/references/sessionlog/src/cli.ts +597 -0
  331. package/references/sessionlog/src/commands/clean.ts +133 -0
  332. package/references/sessionlog/src/commands/disable.ts +84 -0
  333. package/references/sessionlog/src/commands/doctor.ts +145 -0
  334. package/references/sessionlog/src/commands/enable.ts +202 -0
  335. package/references/sessionlog/src/commands/explain.ts +261 -0
  336. package/references/sessionlog/src/commands/reset.ts +105 -0
  337. package/references/sessionlog/src/commands/resume.ts +180 -0
  338. package/references/sessionlog/src/commands/rewind.ts +195 -0
  339. package/references/sessionlog/src/commands/setup-ccweb.ts +275 -0
  340. package/references/sessionlog/src/commands/status.ts +172 -0
  341. package/references/sessionlog/src/config.ts +165 -0
  342. package/references/sessionlog/src/events/event-log.ts +126 -0
  343. package/references/sessionlog/src/git-operations.ts +558 -0
  344. package/references/sessionlog/src/hooks/git-hooks.ts +165 -0
  345. package/references/sessionlog/src/hooks/lifecycle.ts +391 -0
  346. package/references/sessionlog/src/index.ts +650 -0
  347. package/references/sessionlog/src/security/redaction.ts +283 -0
  348. package/references/sessionlog/src/session/state-machine.ts +452 -0
  349. package/references/sessionlog/src/store/checkpoint-store.ts +509 -0
  350. package/references/sessionlog/src/store/native-store.ts +173 -0
  351. package/references/sessionlog/src/store/provider-types.ts +99 -0
  352. package/references/sessionlog/src/store/session-store.ts +266 -0
  353. package/references/sessionlog/src/strategy/attribution.ts +296 -0
  354. package/references/sessionlog/src/strategy/common.ts +207 -0
  355. package/references/sessionlog/src/strategy/content-overlap.ts +228 -0
  356. package/references/sessionlog/src/strategy/manual-commit.ts +988 -0
  357. package/references/sessionlog/src/strategy/types.ts +279 -0
  358. package/references/sessionlog/src/summarize/claude-generator.ts +115 -0
  359. package/references/sessionlog/src/summarize/summarize.ts +432 -0
  360. package/references/sessionlog/src/types.ts +508 -0
  361. package/references/sessionlog/src/utils/chunk-files.ts +49 -0
  362. package/references/sessionlog/src/utils/commit-message.ts +65 -0
  363. package/references/sessionlog/src/utils/detect-agent.ts +36 -0
  364. package/references/sessionlog/src/utils/hook-managers.ts +125 -0
  365. package/references/sessionlog/src/utils/ide-tags.ts +32 -0
  366. package/references/sessionlog/src/utils/paths.ts +79 -0
  367. package/references/sessionlog/src/utils/preview-rewind.ts +80 -0
  368. package/references/sessionlog/src/utils/rewind-conflict.ts +121 -0
  369. package/references/sessionlog/src/utils/shadow-branch.ts +109 -0
  370. package/references/sessionlog/src/utils/string-utils.ts +46 -0
  371. package/references/sessionlog/src/utils/todo-extract.ts +188 -0
  372. package/references/sessionlog/src/utils/trailers.ts +187 -0
  373. package/references/sessionlog/src/utils/transcript-parse.ts +177 -0
  374. package/references/sessionlog/src/utils/transcript-timestamp.ts +59 -0
  375. package/references/sessionlog/src/utils/tree-ops.ts +219 -0
  376. package/references/sessionlog/src/utils/tty.ts +72 -0
  377. package/references/sessionlog/src/utils/validation.ts +65 -0
  378. package/references/sessionlog/src/utils/worktree.ts +58 -0
  379. package/references/sessionlog/src/wire-types.ts +59 -0
  380. package/references/sessionlog/templates/setup-env.sh +153 -0
  381. package/references/sessionlog/tsconfig.json +18 -0
  382. package/references/sessionlog/vitest.config.ts +12 -0
  383. package/references/skill-tree/.sudocode/issues.jsonl +8 -0
  384. package/references/skill-tree/.sudocode/specs.jsonl +2 -0
  385. package/references/skill-tree/CLAUDE.md +56 -80
  386. package/references/skill-tree/README.md +188 -140
  387. package/references/skill-tree/examples/basic-usage.ts +95 -121
  388. package/references/skill-tree/package-lock.json +369 -26
  389. package/references/skill-tree/package.json +1 -1
  390. package/src/atlas.ts +97 -67
  391. package/src/bin/cli-utils.ts +220 -0
  392. package/src/bin/cognitive-core.ts +84 -392
  393. package/src/bin/commands/kb.ts +266 -0
  394. package/src/bin/commands/learn.ts +100 -0
  395. package/src/bin/commands/legacy.ts +182 -0
  396. package/src/bin/commands/run.ts +113 -0
  397. package/src/bin/commands/sessions.ts +221 -0
  398. package/src/bin/commands/skills.ts +146 -0
  399. package/src/embeddings/index.ts +3 -0
  400. package/src/embeddings/inverted-index.ts +134 -0
  401. package/src/embeddings/manager.ts +13 -8
  402. package/src/embeddings/vector-store.ts +21 -9
  403. package/src/factory.ts +33 -16
  404. package/src/index.ts +136 -9
  405. package/src/learning/analyzer.ts +21 -37
  406. package/src/learning/energy-evaluator.ts +282 -0
  407. package/src/learning/healing-orchestrator.ts +383 -0
  408. package/src/learning/index.ts +66 -9
  409. package/src/learning/instant-loop.ts +357 -0
  410. package/src/learning/maintenance-scheduler.ts +271 -0
  411. package/src/learning/meta-learner.ts +5 -23
  412. package/src/learning/reflexion-generator.ts +273 -0
  413. package/src/learning/trajectory-sources/entire.ts +24 -13
  414. package/src/learning/trajectory-sources/index.ts +2 -2
  415. package/src/learning/trajectory-sources/pipeline.ts +5 -5
  416. package/src/learning/unified-pipeline.ts +1191 -0
  417. package/src/memory/candidate-retrieval.ts +72 -0
  418. package/src/memory/causal-store.ts +273 -0
  419. package/src/memory/coherence.ts +252 -0
  420. package/src/memory/experience.ts +217 -50
  421. package/src/memory/index.ts +43 -0
  422. package/src/memory/knowledge-bank.ts +57 -0
  423. package/src/memory/meta.ts +78 -96
  424. package/src/memory/playbook.ts +239 -75
  425. package/src/memory/reasoning-bank.ts +458 -0
  426. package/src/memory/reflexion.ts +122 -0
  427. package/src/memory/system.ts +21 -5
  428. package/src/memory/temporal-compressor.ts +409 -0
  429. package/src/persistence/index.ts +37 -0
  430. package/src/persistence/migrator.ts +298 -0
  431. package/src/persistence/serializers.ts +79 -0
  432. package/src/persistence/sqlite-persistence.ts +925 -0
  433. package/src/runtime/flows/learning.ts +25 -42
  434. package/src/search/index.ts +10 -0
  435. package/src/search/moe-gate.ts +304 -0
  436. package/src/search/router.ts +111 -4
  437. package/src/session-bank/git-reader.ts +29 -19
  438. package/src/session-bank/index.ts +4 -2
  439. package/src/session-bank/parser.ts +280 -98
  440. package/src/session-bank/session-bank.ts +33 -12
  441. package/src/session-bank/types.ts +8 -5
  442. package/src/surfacing/skill-publisher.ts +17 -49
  443. package/src/surfacing/sqlite-storage-adapter.ts +16 -32
  444. package/src/types/config.ts +30 -0
  445. package/src/types/index.ts +3 -0
  446. package/src/types/memory.ts +30 -0
  447. package/src/types/playbook.ts +4 -0
  448. package/src/utils/error-classifier.ts +113 -0
  449. package/src/utils/index.ts +18 -0
  450. package/src/utils/partitioned-store.ts +299 -0
  451. package/src/utils/trajectory-helpers.ts +79 -0
  452. package/src/workspace/efficacy-toolkit.ts +496 -0
  453. package/src/workspace/index.ts +29 -0
  454. package/src/workspace/runner.ts +3 -3
  455. package/src/workspace/templates/index.ts +24 -0
  456. package/src/workspace/templates/playbook-decay-detection.ts +272 -0
  457. package/src/workspace/templates/playbook-efficacy-audit.ts +246 -0
  458. package/src/workspace/templates/playbook-lifecycle-review.ts +274 -0
  459. package/src/workspace/types.ts +10 -2
  460. package/tests/embeddings/inverted-index.test.ts +138 -0
  461. package/tests/feature-toggles.test.ts +275 -0
  462. package/tests/fixtures/behavioral-trajectories.ts +210 -0
  463. package/tests/gap-fixes.test.ts +17 -4
  464. package/tests/integration/cli-e2e.test.ts +621 -0
  465. package/tests/integration/e2e.test.ts +6 -5
  466. package/tests/integration/entire-e2e.test.ts +314 -125
  467. package/tests/integration/persistence-e2e.test.ts +741 -0
  468. package/tests/integration/phase-e2e.test.ts +1143 -0
  469. package/tests/integration/pipeline-data-correctness.test.ts +794 -0
  470. package/tests/integration/session-bank.test.ts +20 -14
  471. package/tests/integration/sessionlog-e2e.test.ts +329 -0
  472. package/tests/integration/unified-pipeline-e2e.test.ts +634 -0
  473. package/tests/learning/analyzer.test.ts +1 -1
  474. package/tests/learning/energy-evaluator.test.ts +180 -0
  475. package/tests/learning/entire-trajectory-source.test.ts +25 -25
  476. package/tests/learning/healing-orchestrator.test.ts +269 -0
  477. package/tests/learning/instant-loop.test.ts +243 -0
  478. package/tests/learning/maintenance-scheduler.test.ts +191 -0
  479. package/tests/learning/meta-learner.test.ts +418 -0
  480. package/tests/learning/pipeline-memory-updates.test.ts +721 -0
  481. package/tests/learning/reflexion-generator.test.ts +411 -0
  482. package/tests/learning/trajectory-sources.test.ts +12 -4
  483. package/tests/learning/unified-pipeline-efficacy.test.ts +232 -0
  484. package/tests/learning/unified-pipeline.test.ts +322 -0
  485. package/tests/mcp/playbook-server.test.ts +6 -1
  486. package/tests/memory/candidate-retrieval.test.ts +167 -0
  487. package/tests/memory/causal-store.test.ts +276 -0
  488. package/tests/memory/coherence.test.ts +232 -0
  489. package/tests/memory/experience.test.ts +8 -3
  490. package/tests/memory/meta.test.ts +399 -0
  491. package/tests/memory/playbook.test.ts +307 -1
  492. package/tests/memory/provenance.test.ts +11 -2
  493. package/tests/memory/reasoning-bank.test.ts +239 -0
  494. package/tests/memory/reflexion.test.ts +166 -0
  495. package/tests/memory/skill-exporter.test.ts +6 -1
  496. package/tests/memory/system.test.ts +6 -1
  497. package/tests/memory/temporal-compressor.test.ts +318 -0
  498. package/tests/persistence/migrator.test.ts +1009 -0
  499. package/tests/persistence/sqlite-persistence.test.ts +635 -0
  500. package/tests/runtime/agent-manager.test.ts +6 -1
  501. package/tests/runtime/delegate.test.ts +6 -1
  502. package/tests/search/evaluator.test.ts +257 -0
  503. package/tests/search/moe-gate.test.ts +250 -0
  504. package/tests/search/refinement-loop.test.ts +11 -2
  505. package/tests/search/router.test.ts +81 -2
  506. package/tests/search/verification-runner.test.ts +357 -0
  507. package/tests/session-bank/fixtures/sessionlog-root-metadata.json +16 -0
  508. package/tests/session-bank/fixtures/sessionlog-session/full.jsonl +6 -0
  509. package/tests/session-bank/fixtures/sessionlog-session/metadata.json +55 -0
  510. package/tests/session-bank/git-reader.test.ts +13 -13
  511. package/tests/session-bank/parser.test.ts +135 -3
  512. package/tests/session-bank/session-bank.test.ts +1 -1
  513. package/tests/surfacing/skill-library.test.ts +6 -1
  514. package/tests/surfacing/skill-publisher.test.ts +24 -58
  515. package/tests/surfacing/sqlite-storage-adapter.test.ts +11 -23
  516. package/tests/utils/error-classifier.test.ts +149 -0
  517. package/tests/utils/partitioned-store.test.ts +230 -0
  518. package/tests/utils/trajectory-helpers.test.ts +163 -0
  519. package/tests/workspace/efficacy-toolkit.test.ts +404 -0
  520. package/tests/workspace/full-flow.test.ts +10 -4
  521. package/tests/workspace/runner.test.ts +10 -4
  522. package/tests/workspace/templates/playbook-efficacy.test.ts +377 -0
  523. package/docs/DESIGN-workspace-migration.md +0 -1079
  524. package/docs/PLAN-agentic-workspace-implementation.md +0 -717
  525. package/docs/PLAN-graph-migration.md +0 -299
  526. package/docs/PLAN-session-bank-implementation.md +0 -474
  527. package/src/learning/pipeline.ts +0 -323
  528. package/tests/learning/pipeline.test.ts +0 -176
@@ -0,0 +1,357 @@
1
+ /**
2
+ * InstantLoop — Hot-path, per-trajectory learning
3
+ *
4
+ * Runs synchronously after every trajectory completion (<200ms budget).
5
+ * No LLM calls. No batch thresholds. Pure in-memory updates:
6
+ *
7
+ * 1. Store experience via MemorySystem.storeTrajectory()
8
+ * 2. Bump matched playbooks (recordSuccess / recordFailure)
9
+ * 3. Extract lightweight knowledge notes (heuristic only)
10
+ * 4. Access scores are bumped automatically by the memory layer
11
+ */
12
+
13
+ import type { Trajectory } from '../types/index.js';
14
+ import { createObservation } from '../types/knowledge.js';
15
+ import type { MemorySystem } from '../memory/system.js';
16
+ import type { PlaybookMatch } from '../memory/playbook.js';
17
+ import type { CausalEdge } from '../memory/causal-store.js';
18
+ import { ReflexionGenerator, type ReflexionGeneratorConfig } from './reflexion-generator.js';
19
+
20
+ /**
21
+ * Result of a single instant-loop pass
22
+ */
23
+ export interface InstantLoopResult {
24
+ /** ID of the stored experience */
25
+ experienceId: string;
26
+ /** Playbooks whose confidence was updated */
27
+ matchedPlaybooks: Array<{ id: string; confidenceDelta: number }>;
28
+ /** Number of knowledge notes extracted (0 if knowledge bank disabled) */
29
+ knowledgeNotesExtracted: number;
30
+ /** Number of causal edges extracted */
31
+ causalEdgesExtracted: number;
32
+ /** ID of the generated reflexion episode (if reflexion is enabled) */
33
+ reflexionEpisodeId?: string;
34
+ /** Wall-clock duration of the instant loop in ms */
35
+ durationMs: number;
36
+ }
37
+
38
+ /**
39
+ * InstantLoop configuration
40
+ */
41
+ export interface InstantLoopConfig {
42
+ /** Max knowledge notes to extract per trajectory (default: 3) */
43
+ maxInstantKnowledgeNotes?: number;
44
+ /** Max playbooks to match per trajectory (default: 3) */
45
+ maxPlaybookMatches?: number;
46
+ /** Enable reflexion episode generation (default: true) */
47
+ enableReflexion?: boolean;
48
+ /** Enable causal edge extraction (default: true) */
49
+ enableCausalExtraction?: boolean;
50
+ /** Configuration for the reflexion generator */
51
+ reflexionConfig?: ReflexionGeneratorConfig;
52
+ }
53
+
54
+ /**
55
+ * InstantLoop — lightweight, per-trajectory learning
56
+ */
57
+ export class InstantLoop {
58
+ private memory: MemorySystem;
59
+ private config: Required<Pick<InstantLoopConfig, 'maxInstantKnowledgeNotes' | 'maxPlaybookMatches' | 'enableReflexion' | 'enableCausalExtraction'>>;
60
+ private reflexionGenerator: ReflexionGenerator;
61
+
62
+ constructor(memory: MemorySystem, config?: InstantLoopConfig) {
63
+ this.memory = memory;
64
+ this.config = {
65
+ maxInstantKnowledgeNotes: config?.maxInstantKnowledgeNotes ?? 3,
66
+ maxPlaybookMatches: config?.maxPlaybookMatches ?? 3,
67
+ enableReflexion: config?.enableReflexion ?? true,
68
+ enableCausalExtraction: config?.enableCausalExtraction ?? true,
69
+ };
70
+ this.reflexionGenerator = new ReflexionGenerator(config?.reflexionConfig);
71
+ }
72
+
73
+ /**
74
+ * Process a single trajectory immediately after completion.
75
+ * Target: <200ms for typical trajectories.
76
+ */
77
+ async process(trajectory: Trajectory): Promise<InstantLoopResult> {
78
+ const start = Date.now();
79
+
80
+ // 1. Store experience
81
+ const experience = await this.memory.storeTrajectory(trajectory);
82
+
83
+ // 2. Find matching playbooks and bump confidence
84
+ const matchResult = await this.bumpPlaybooks(trajectory);
85
+
86
+ // 3. Extract lightweight knowledge (heuristic, no LLM)
87
+ const knowledgeNotesExtracted = await this.extractKnowledge(trajectory);
88
+
89
+ // 4. Extract lightweight causal edges (if enabled)
90
+ const causalEdgesExtracted = this.config.enableCausalExtraction
91
+ ? await this.extractCausalEdges(trajectory)
92
+ : 0;
93
+
94
+ // 5. Generate and store reflexion episode
95
+ let reflexionEpisodeId: string | undefined;
96
+ if (this.config.enableReflexion) {
97
+ try {
98
+ const episode = await this.reflexionGenerator.generate(
99
+ trajectory,
100
+ matchResult.playbookMatches
101
+ );
102
+ await this.memory.reflexion.add(episode);
103
+ reflexionEpisodeId = episode.id;
104
+ } catch {
105
+ // Non-critical — don't fail the instant loop for reflexion errors
106
+ }
107
+ }
108
+
109
+ return {
110
+ experienceId: experience.id,
111
+ matchedPlaybooks: matchResult.deltas,
112
+ knowledgeNotesExtracted,
113
+ causalEdgesExtracted,
114
+ reflexionEpisodeId,
115
+ durationMs: Date.now() - start,
116
+ };
117
+ }
118
+
119
+ /**
120
+ * Find matching playbooks and update their confidence based on trajectory outcome.
121
+ * Returns both confidence deltas and the original PlaybookMatch objects for reflexion.
122
+ */
123
+ private async bumpPlaybooks(
124
+ trajectory: Trajectory
125
+ ): Promise<{
126
+ deltas: Array<{ id: string; confidenceDelta: number }>;
127
+ playbookMatches: PlaybookMatch[];
128
+ }> {
129
+ const deltas: Array<{ id: string; confidenceDelta: number }> = [];
130
+
131
+ // Find playbooks matching this trajectory's task description
132
+ let matches: PlaybookMatch[];
133
+ try {
134
+ matches = await this.memory.playbooks.findMatching(
135
+ trajectory.task.description,
136
+ {
137
+ k: this.config.maxPlaybookMatches,
138
+ domains: trajectory.task.domain ? [trajectory.task.domain] : undefined,
139
+ minScore: 0.3,
140
+ }
141
+ );
142
+ } catch {
143
+ return { deltas, playbookMatches: [] };
144
+ }
145
+
146
+ for (const match of matches) {
147
+ const before = match.playbook.confidence;
148
+
149
+ if (trajectory.outcome.success) {
150
+ await this.memory.playbooks.recordSuccess(
151
+ match.playbook.id,
152
+ trajectory.id,
153
+ trajectory.task.domain,
154
+ );
155
+ } else {
156
+ await this.memory.playbooks.recordFailure(
157
+ match.playbook.id,
158
+ trajectory.id,
159
+ trajectory.task.domain ?? 'unknown',
160
+ trajectory.outcome.errorInfo ?? 'Unknown failure',
161
+ );
162
+ }
163
+
164
+ // Read back the updated confidence
165
+ const updated = await this.memory.playbooks.get(match.playbook.id);
166
+ const after = updated?.confidence ?? before;
167
+
168
+ deltas.push({
169
+ id: match.playbook.id,
170
+ confidenceDelta: after - before,
171
+ });
172
+ }
173
+
174
+ return { deltas, playbookMatches: matches };
175
+ }
176
+
177
+ /**
178
+ * Extract lightweight knowledge from a trajectory (heuristic, no LLM).
179
+ *
180
+ * Parses error messages, tool names, and file paths from trajectory steps
181
+ * and stores them as KnowledgeNote observations.
182
+ */
183
+ private async extractKnowledge(trajectory: Trajectory): Promise<number> {
184
+ const kb = this.memory.knowledgeBank;
185
+ if (!kb) return 0;
186
+
187
+ const notes: Array<{ subject: string; content: string }> = [];
188
+
189
+ // Extract error patterns from failed steps
190
+ if (!trajectory.outcome.success && trajectory.outcome.errorInfo) {
191
+ notes.push({
192
+ subject: `error:${trajectory.task.domain ?? 'general'}`,
193
+ content: `Error encountered: ${trajectory.outcome.errorInfo.slice(0, 300)}`,
194
+ });
195
+ }
196
+
197
+ // Extract tool usage patterns from steps
198
+ const toolNames = new Set<string>();
199
+ const filePaths = new Set<string>();
200
+
201
+ for (const step of trajectory.steps) {
202
+ // Extract tool names from action strings
203
+ const toolMatch = step.action?.match(/^(\w+(?:[A-Z]\w*)*)\s/);
204
+ if (toolMatch) {
205
+ toolNames.add(toolMatch[1]);
206
+ }
207
+
208
+ // Extract file paths from observations
209
+ const pathMatches = step.observation?.match(
210
+ /(?:\/[\w.-]+)+(?:\.[\w]+)/g
211
+ );
212
+ if (pathMatches) {
213
+ for (const p of pathMatches.slice(0, 5)) {
214
+ filePaths.add(p);
215
+ }
216
+ }
217
+ }
218
+
219
+ // Create a tool-usage note if tools were used
220
+ if (toolNames.size > 0 && trajectory.outcome.success) {
221
+ notes.push({
222
+ subject: `tools:${trajectory.task.domain ?? 'general'}`,
223
+ content: `Successful approach used tools: ${[...toolNames].join(', ')}`,
224
+ });
225
+ }
226
+
227
+ // Create a file-paths note for context
228
+ if (filePaths.size > 0) {
229
+ notes.push({
230
+ subject: `files:${trajectory.task.domain ?? 'general'}`,
231
+ content: `Files involved: ${[...filePaths].slice(0, 10).join(', ')}`,
232
+ });
233
+ }
234
+
235
+ // Store up to maxInstantKnowledgeNotes
236
+ const domain = trajectory.task.domain ?? 'general';
237
+ let stored = 0;
238
+ for (const note of notes.slice(0, this.config.maxInstantKnowledgeNotes)) {
239
+ try {
240
+ const observation = createObservation({
241
+ title: note.subject,
242
+ body: note.content,
243
+ domain: [domain],
244
+ entities: [note.subject],
245
+ confidence: trajectory.outcome.success ? 0.7 : 0.4,
246
+ source: {
247
+ origin: 'extracted',
248
+ trajectories: [trajectory.id],
249
+ },
250
+ });
251
+ await kb.addObservation(observation);
252
+ stored++;
253
+ } catch {
254
+ // Non-critical — don't fail the instant loop for knowledge extraction errors
255
+ }
256
+ }
257
+
258
+ return stored;
259
+ }
260
+
261
+ /**
262
+ * Extract lightweight causal edges from a trajectory.
263
+ *
264
+ * From failed trajectories: error message → root cause (if identifiable)
265
+ * From successful trajectories: approach → outcome patterns
266
+ */
267
+ private async extractCausalEdges(trajectory: Trajectory): Promise<number> {
268
+ const causalStore = this.memory.causal;
269
+ let extracted = 0;
270
+ const domain = trajectory.task.domain ?? 'general';
271
+ const now = new Date();
272
+
273
+ try {
274
+ if (!trajectory.outcome.success && trajectory.outcome.errorInfo) {
275
+ // Failed trajectory: extract error → root cause pattern
276
+ const errorInfo = trajectory.outcome.errorInfo.slice(0, 300);
277
+ const taskDesc = trajectory.task.description.slice(0, 200);
278
+
279
+ const edge: CausalEdge = {
280
+ id: `ce-fail-${trajectory.id}`,
281
+ cause: `Task: ${taskDesc}`,
282
+ effect: `Error: ${errorInfo}`,
283
+ confidence: 0.4,
284
+ domain,
285
+ sourceTrajectoryIds: [trajectory.id],
286
+ observedCount: 1,
287
+ createdAt: now,
288
+ updatedAt: now,
289
+ };
290
+ await causalStore.add(edge);
291
+ extracted++;
292
+ }
293
+
294
+ if (trajectory.outcome.success) {
295
+ // Successful trajectory: approach → outcome
296
+ const taskDesc = trajectory.task.description.slice(0, 200);
297
+ const solutionSummary = trajectory.outcome.solution !== undefined
298
+ ? String(trajectory.outcome.solution).slice(0, 200)
299
+ : 'Task completed successfully';
300
+
301
+ const edge: CausalEdge = {
302
+ id: `ce-succ-${trajectory.id}`,
303
+ cause: `Approach: ${taskDesc}`,
304
+ effect: `Outcome: ${solutionSummary}`,
305
+ confidence: 0.7,
306
+ domain,
307
+ sourceTrajectoryIds: [trajectory.id],
308
+ observedCount: 1,
309
+ createdAt: now,
310
+ updatedAt: now,
311
+ };
312
+ await causalStore.add(edge);
313
+ extracted++;
314
+
315
+ // Extract tool → outcome edges from steps with high attribution
316
+ for (const step of trajectory.steps) {
317
+ if (
318
+ step.attributionScore !== undefined &&
319
+ step.attributionScore > 0.7 &&
320
+ step.action
321
+ ) {
322
+ const toolMatch = step.action.match(/^(\w+(?:[A-Z]\w*)*)\s/);
323
+ if (toolMatch) {
324
+ const toolEdge: CausalEdge = {
325
+ id: `ce-tool-${trajectory.id}-${toolMatch[1]}`,
326
+ cause: `Used tool ${toolMatch[1]} for ${domain} task`,
327
+ effect: `Contributed to successful outcome (attribution: ${step.attributionScore.toFixed(2)})`,
328
+ confidence: 0.5,
329
+ domain,
330
+ sourceTrajectoryIds: [trajectory.id],
331
+ observedCount: 1,
332
+ createdAt: now,
333
+ updatedAt: now,
334
+ };
335
+ await causalStore.add(toolEdge);
336
+ extracted++;
337
+ }
338
+ }
339
+ }
340
+ }
341
+ } catch {
342
+ // Non-critical — don't fail the instant loop for causal extraction errors
343
+ }
344
+
345
+ return extracted;
346
+ }
347
+ }
348
+
349
+ /**
350
+ * Create an InstantLoop
351
+ */
352
+ export function createInstantLoop(
353
+ memory: MemorySystem,
354
+ config?: InstantLoopConfig
355
+ ): InstantLoop {
356
+ return new InstantLoop(memory, config);
357
+ }
@@ -0,0 +1,271 @@
1
+ /**
2
+ * MaintenanceScheduler — Circadian-style duty-gated maintenance scheduling.
3
+ *
4
+ * Inspired by ruvector's CircadianController (ruvector-nervous-system/routing/circadian.rs).
5
+ * Gates background maintenance work using configurable triggers:
6
+ *
7
+ * - 'manual': Only runs when explicitly requested
8
+ * - 'afterNBatches': Runs after N batch cycles complete
9
+ * - 'periodic': Runs on a time interval
10
+ *
11
+ * Maintenance tasks are deferred during active batch processing to avoid
12
+ * contention. A duty-factor model ensures maintenance doesn't starve
13
+ * the primary learning pipeline.
14
+ */
15
+
16
+ /**
17
+ * Maintenance trigger mode.
18
+ */
19
+ export type MaintenanceMode = 'manual' | 'afterNBatches' | 'periodic';
20
+
21
+ /**
22
+ * Configuration for the MaintenanceScheduler.
23
+ */
24
+ export interface MaintenanceSchedulerConfig {
25
+ /** Trigger mode (default: 'afterNBatches') */
26
+ mode: MaintenanceMode;
27
+ /** For 'afterNBatches' mode: batches between maintenance runs (default: 5) */
28
+ batchInterval: number;
29
+ /** For 'periodic' mode: milliseconds between runs (default: 3600000 = 1h) */
30
+ intervalMs: number;
31
+ /** Skip maintenance if a batch is currently running (default: true) */
32
+ deferDuringBatch: boolean;
33
+ /** Maximum queued maintenance tasks before dropping oldest (default: 10) */
34
+ maxQueueSize: number;
35
+ }
36
+
37
+ const DEFAULT_CONFIG: MaintenanceSchedulerConfig = {
38
+ mode: 'afterNBatches',
39
+ batchInterval: 5,
40
+ intervalMs: 3_600_000,
41
+ deferDuringBatch: true,
42
+ maxQueueSize: 10,
43
+ };
44
+
45
+ /**
46
+ * A maintenance task that can be scheduled.
47
+ */
48
+ export interface MaintenanceTask {
49
+ /** Unique name for this task (e.g., 'knowledge-defrag', 'temporal-compression') */
50
+ name: string;
51
+ /** Priority (higher = run first) */
52
+ priority: number;
53
+ /** The async work to perform */
54
+ execute: () => Promise<MaintenanceTaskResult>;
55
+ }
56
+
57
+ /**
58
+ * Result of a maintenance task execution.
59
+ */
60
+ export interface MaintenanceTaskResult {
61
+ taskName: string;
62
+ success: boolean;
63
+ durationMs: number;
64
+ details?: Record<string, unknown>;
65
+ }
66
+
67
+ /**
68
+ * Result of a full maintenance cycle.
69
+ */
70
+ export interface MaintenanceCycleResult {
71
+ /** Whether the cycle actually ran (false if deferred or not due) */
72
+ ran: boolean;
73
+ /** Reason the cycle was skipped, if applicable */
74
+ skipReason?: 'not_due' | 'batch_in_progress' | 'manual_mode' | 'queue_empty';
75
+ /** Results from each task that ran */
76
+ taskResults: MaintenanceTaskResult[];
77
+ /** Total duration of the cycle in ms */
78
+ totalDurationMs: number;
79
+ /** Timestamp of this cycle */
80
+ timestamp: Date;
81
+ }
82
+
83
+ /**
84
+ * MaintenanceScheduler — duty-gated background maintenance scheduling.
85
+ */
86
+ export class MaintenanceScheduler {
87
+ private config: MaintenanceSchedulerConfig;
88
+ private registeredTasks: MaintenanceTask[] = [];
89
+ private batchesSinceLastMaintenance = 0;
90
+ private lastMaintenanceTime = 0;
91
+ private isBatchRunning = false;
92
+ private cycleHistory: MaintenanceCycleResult[] = [];
93
+
94
+ constructor(config?: Partial<MaintenanceSchedulerConfig>) {
95
+ this.config = { ...DEFAULT_CONFIG, ...config };
96
+ }
97
+
98
+ /**
99
+ * Register a maintenance task.
100
+ * Tasks are sorted by priority (descending) before execution.
101
+ */
102
+ registerTask(task: MaintenanceTask): void {
103
+ // Replace existing task with same name
104
+ this.registeredTasks = this.registeredTasks.filter(t => t.name !== task.name);
105
+ this.registeredTasks.push(task);
106
+ this.registeredTasks.sort((a, b) => b.priority - a.priority);
107
+ }
108
+
109
+ /**
110
+ * Unregister a maintenance task by name.
111
+ */
112
+ unregisterTask(name: string): void {
113
+ this.registeredTasks = this.registeredTasks.filter(t => t.name !== name);
114
+ }
115
+
116
+ /**
117
+ * Signal that a batch cycle has completed.
118
+ * For 'afterNBatches' mode, this increments the counter.
119
+ */
120
+ onBatchComplete(): void {
121
+ this.batchesSinceLastMaintenance++;
122
+ }
123
+
124
+ /**
125
+ * Signal that a batch is starting (for deferral logic).
126
+ */
127
+ onBatchStart(): void {
128
+ this.isBatchRunning = true;
129
+ }
130
+
131
+ /**
132
+ * Signal that a batch has finished running.
133
+ */
134
+ onBatchEnd(): void {
135
+ this.isBatchRunning = false;
136
+ }
137
+
138
+ /**
139
+ * Check whether maintenance should run now.
140
+ */
141
+ shouldRunMaintenance(): boolean {
142
+ if (this.config.mode === 'manual') return false;
143
+ if (this.config.deferDuringBatch && this.isBatchRunning) return false;
144
+ if (this.registeredTasks.length === 0) return false;
145
+
146
+ if (this.config.mode === 'afterNBatches') {
147
+ return this.batchesSinceLastMaintenance >= this.config.batchInterval;
148
+ }
149
+
150
+ if (this.config.mode === 'periodic') {
151
+ const now = Date.now();
152
+ return (now - this.lastMaintenanceTime) >= this.config.intervalMs;
153
+ }
154
+
155
+ return false;
156
+ }
157
+
158
+ /**
159
+ * Run a maintenance cycle.
160
+ * Executes all registered tasks in priority order.
161
+ *
162
+ * Can be called manually regardless of mode — bypasses trigger checks.
163
+ */
164
+ async runMaintenance(options?: { force?: boolean }): Promise<MaintenanceCycleResult> {
165
+ const start = Date.now();
166
+
167
+ // Check if we should run (unless forced)
168
+ if (!options?.force) {
169
+ if (this.config.deferDuringBatch && this.isBatchRunning) {
170
+ return this.skipResult('batch_in_progress', start);
171
+ }
172
+ if (this.registeredTasks.length === 0) {
173
+ return this.skipResult('queue_empty', start);
174
+ }
175
+ }
176
+
177
+ // Execute tasks in priority order
178
+ const taskResults: MaintenanceTaskResult[] = [];
179
+ for (const task of this.registeredTasks) {
180
+ const taskStart = Date.now();
181
+ try {
182
+ const result = await task.execute();
183
+ taskResults.push(result);
184
+ } catch (error) {
185
+ taskResults.push({
186
+ taskName: task.name,
187
+ success: false,
188
+ durationMs: Date.now() - taskStart,
189
+ details: {
190
+ error: error instanceof Error ? error.message : String(error),
191
+ },
192
+ });
193
+ }
194
+ }
195
+
196
+ // Reset counters
197
+ this.batchesSinceLastMaintenance = 0;
198
+ this.lastMaintenanceTime = Date.now();
199
+
200
+ const result: MaintenanceCycleResult = {
201
+ ran: true,
202
+ taskResults,
203
+ totalDurationMs: Date.now() - start,
204
+ timestamp: new Date(),
205
+ };
206
+
207
+ this.cycleHistory.push(result);
208
+ if (this.cycleHistory.length > this.config.maxQueueSize) {
209
+ this.cycleHistory.shift();
210
+ }
211
+
212
+ return result;
213
+ }
214
+
215
+ /**
216
+ * Get the list of registered tasks.
217
+ */
218
+ getRegisteredTasks(): readonly MaintenanceTask[] {
219
+ return this.registeredTasks;
220
+ }
221
+
222
+ /**
223
+ * Get maintenance cycle history.
224
+ */
225
+ getCycleHistory(): readonly MaintenanceCycleResult[] {
226
+ return this.cycleHistory;
227
+ }
228
+
229
+ /**
230
+ * Get the number of batches since last maintenance.
231
+ */
232
+ getBatchesSinceLastMaintenance(): number {
233
+ return this.batchesSinceLastMaintenance;
234
+ }
235
+
236
+ /**
237
+ * Get current configuration.
238
+ */
239
+ getConfig(): Readonly<MaintenanceSchedulerConfig> {
240
+ return this.config;
241
+ }
242
+
243
+ /**
244
+ * Update configuration.
245
+ */
246
+ updateConfig(config: Partial<MaintenanceSchedulerConfig>): void {
247
+ this.config = { ...this.config, ...config };
248
+ }
249
+
250
+ private skipResult(
251
+ reason: MaintenanceCycleResult['skipReason'],
252
+ start: number,
253
+ ): MaintenanceCycleResult {
254
+ return {
255
+ ran: false,
256
+ skipReason: reason,
257
+ taskResults: [],
258
+ totalDurationMs: Date.now() - start,
259
+ timestamp: new Date(),
260
+ };
261
+ }
262
+ }
263
+
264
+ /**
265
+ * Create a MaintenanceScheduler.
266
+ */
267
+ export function createMaintenanceScheduler(
268
+ config?: Partial<MaintenanceSchedulerConfig>,
269
+ ): MaintenanceScheduler {
270
+ return new MaintenanceScheduler(config);
271
+ }
@@ -17,6 +17,7 @@ import { createMetaObservation, createMetaStrategy } from '../types/index.js';
17
17
  import type { MetaMemory } from '../memory/meta.js';
18
18
  import type { PlaybookMatch } from '../memory/playbook.js';
19
19
  import type { MetaReflectionOutput } from '../workspace/templates/meta-reflection.js';
20
+ import { detectRepeatedActions, extractToolNames } from '../utils/trajectory-helpers.js';
20
21
 
21
22
  /**
22
23
  * Routing decision from the router
@@ -375,31 +376,12 @@ export class MetaLearner {
375
376
  toolsUsed: string[];
376
377
  } {
377
378
  const steps = trajectory.steps;
378
- const toolsUsed = new Set<string>();
379
- let backtrackingOccurred = false;
380
-
381
- // Collect tools used (extract from action)
382
- for (const step of steps) {
383
- // Try to extract tool name from action (e.g., "tool_use: Bash" or just "Bash")
384
- const toolMatch = step.action.match(/^(?:tool_use:\s*)?(\w+)/);
385
- if (toolMatch) {
386
- toolsUsed.add(toolMatch[1]);
387
- }
388
- }
389
379
 
390
- // Check for backtracking (similar actions repeated)
391
- const actionCounts = new Map<string, number>();
392
- for (const step of steps) {
393
- const normalized = step.action.toLowerCase().slice(0, 50);
394
- actionCounts.set(normalized, (actionCounts.get(normalized) ?? 0) + 1);
395
- }
380
+ // Collect tools used
381
+ const toolsUsed = extractToolNames(steps);
396
382
 
397
- for (const count of actionCounts.values()) {
398
- if (count > 2) {
399
- backtrackingOccurred = true;
400
- break;
401
- }
402
- }
383
+ // Check for backtracking (similar actions repeated)
384
+ const backtrackingOccurred = detectRepeatedActions(steps, 3).length > 0;
403
385
 
404
386
  // Check for decomposition (multiple sub-tasks)
405
387
  const decompositionUsed =