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,166 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import { ReflexionMemory } from '../../src/memory/reflexion.js';
3
+ import type { ReflexionEpisode } from '../../src/types/memory.js';
4
+ import { createSqlitePersistence } from '../../src/persistence/index.js';
5
+ import { mkdtemp, rm } from 'node:fs/promises';
6
+ import { join } from 'node:path';
7
+ import { tmpdir } from 'node:os';
8
+
9
+ function createSampleEpisode(overrides?: Partial<ReflexionEpisode>): ReflexionEpisode {
10
+ return {
11
+ id: overrides?.id ?? crypto.randomUUID(),
12
+ trajectoryId: overrides?.trajectoryId ?? `traj-${crypto.randomUUID()}`,
13
+ taskSummary: overrides?.taskSummary ?? 'Fix the typescript import error',
14
+ outcome: overrides?.outcome ?? 'success',
15
+ selfCritique: overrides?.selfCritique ?? 'Completed efficiently in 2 steps',
16
+ keyInsights: overrides?.keyInsights ?? ['Tools used: ReadFile, EditFile'],
17
+ strategyAssessment: overrides?.strategyAssessment ?? 'Succeeded without playbook guidance',
18
+ suggestedPlaybookUpdates: overrides?.suggestedPlaybookUpdates ?? [],
19
+ domain: overrides?.domain ?? 'typescript',
20
+ createdAt: overrides?.createdAt ?? new Date(),
21
+ };
22
+ }
23
+
24
+ describe('ReflexionMemory', () => {
25
+ let tempDir: string;
26
+ let memory: ReflexionMemory;
27
+ let persistence: any;
28
+
29
+ beforeEach(async () => {
30
+ tempDir = await mkdtemp(join(tmpdir(), 'atlas-reflexion-test-'));
31
+ persistence = createSqlitePersistence({ baseDir: tempDir });
32
+ await persistence.init();
33
+ memory = new ReflexionMemory(persistence);
34
+ await memory.init();
35
+ });
36
+
37
+ afterEach(async () => {
38
+ await memory.close();
39
+ persistence.close();
40
+ await rm(tempDir, { recursive: true, force: true });
41
+ });
42
+
43
+ describe('add and get', () => {
44
+ it('should store and retrieve a reflexion episode', async () => {
45
+ const episode = createSampleEpisode();
46
+ await memory.add(episode);
47
+
48
+ const retrieved = await memory.get(episode.id);
49
+ expect(retrieved).toBeDefined();
50
+ expect(retrieved?.taskSummary).toBe('Fix the typescript import error');
51
+ expect(retrieved?.outcome).toBe('success');
52
+ expect(retrieved?.keyInsights).toHaveLength(1);
53
+ });
54
+
55
+ it('should return undefined for non-existent id', async () => {
56
+ const result = await memory.get('non-existent');
57
+ expect(result).toBeUndefined();
58
+ });
59
+ });
60
+
61
+ describe('getByTrajectory', () => {
62
+ it('should find an episode by trajectory ID', async () => {
63
+ const trajectoryId = 'specific-trajectory-id';
64
+ const episode = createSampleEpisode({ trajectoryId });
65
+ await memory.add(episode);
66
+
67
+ const retrieved = await memory.getByTrajectory(trajectoryId);
68
+ expect(retrieved).toBeDefined();
69
+ expect(retrieved?.trajectoryId).toBe(trajectoryId);
70
+ expect(retrieved?.id).toBe(episode.id);
71
+ });
72
+
73
+ it('should return undefined for non-existent trajectory', async () => {
74
+ await memory.add(createSampleEpisode());
75
+
76
+ const result = await memory.getByTrajectory('no-such-trajectory');
77
+ expect(result).toBeUndefined();
78
+ });
79
+ });
80
+
81
+ describe('getRecent', () => {
82
+ it('should return episodes sorted by most recent first', async () => {
83
+ const ep1 = createSampleEpisode({
84
+ taskSummary: 'First task',
85
+ createdAt: new Date('2025-01-01'),
86
+ });
87
+ const ep2 = createSampleEpisode({
88
+ taskSummary: 'Second task',
89
+ createdAt: new Date('2025-06-01'),
90
+ });
91
+ const ep3 = createSampleEpisode({
92
+ taskSummary: 'Third task',
93
+ createdAt: new Date('2025-03-01'),
94
+ });
95
+
96
+ await memory.add(ep1);
97
+ await memory.add(ep2);
98
+ await memory.add(ep3);
99
+
100
+ const recent = await memory.getRecent({ k: 3 });
101
+ expect(recent).toHaveLength(3);
102
+ expect(recent[0].taskSummary).toBe('Second task');
103
+ expect(recent[1].taskSummary).toBe('Third task');
104
+ expect(recent[2].taskSummary).toBe('First task');
105
+ });
106
+
107
+ it('should limit results to k', async () => {
108
+ for (let i = 0; i < 5; i++) {
109
+ await memory.add(createSampleEpisode({ taskSummary: `Task ${i}` }));
110
+ }
111
+
112
+ const recent = await memory.getRecent({ k: 2 });
113
+ expect(recent).toHaveLength(2);
114
+ });
115
+
116
+ it('should filter by domain', async () => {
117
+ await memory.add(createSampleEpisode({ domain: 'typescript' }));
118
+ await memory.add(createSampleEpisode({ domain: 'python' }));
119
+ await memory.add(createSampleEpisode({ domain: 'typescript' }));
120
+
121
+ const results = await memory.getRecent({ domain: 'typescript' });
122
+ expect(results).toHaveLength(2);
123
+ expect(results.every((ep) => ep.domain === 'typescript')).toBe(true);
124
+ });
125
+
126
+ it('should filter by outcome', async () => {
127
+ await memory.add(createSampleEpisode({ outcome: 'success' }));
128
+ await memory.add(createSampleEpisode({ outcome: 'failure' }));
129
+ await memory.add(createSampleEpisode({ outcome: 'success' }));
130
+ await memory.add(createSampleEpisode({ outcome: 'partial' }));
131
+
132
+ const failures = await memory.getRecent({ outcome: 'failure' });
133
+ expect(failures).toHaveLength(1);
134
+ expect(failures[0].outcome).toBe('failure');
135
+
136
+ const successes = await memory.getRecent({ outcome: 'success' });
137
+ expect(successes).toHaveLength(2);
138
+ });
139
+
140
+ it('should combine domain and outcome filters', async () => {
141
+ await memory.add(createSampleEpisode({ domain: 'typescript', outcome: 'success' }));
142
+ await memory.add(createSampleEpisode({ domain: 'typescript', outcome: 'failure' }));
143
+ await memory.add(createSampleEpisode({ domain: 'python', outcome: 'success' }));
144
+
145
+ const results = await memory.getRecent({
146
+ domain: 'typescript',
147
+ outcome: 'failure',
148
+ });
149
+ expect(results).toHaveLength(1);
150
+ expect(results[0].domain).toBe('typescript');
151
+ expect(results[0].outcome).toBe('failure');
152
+ });
153
+ });
154
+
155
+ describe('count', () => {
156
+ it('should return correct count', async () => {
157
+ expect(await memory.count()).toBe(0);
158
+
159
+ await memory.add(createSampleEpisode());
160
+ expect(await memory.count()).toBe(1);
161
+
162
+ await memory.add(createSampleEpisode());
163
+ expect(await memory.count()).toBe(2);
164
+ });
165
+ });
166
+ });
@@ -9,6 +9,7 @@ import {
9
9
  exportPlaybooksAsSkills,
10
10
  exportPlaybookAsSkill,
11
11
  } from '../../src/memory/skill-exporter.js';
12
+ import { createSqlitePersistence } from '../../src/persistence/index.js';
12
13
  import type { Playbook } from '../../src/types/playbook.js';
13
14
 
14
15
  function createSamplePlaybook(overrides?: Partial<Playbook>): Playbook {
@@ -272,16 +273,20 @@ describe('exportPlaybooksAsSkills', () => {
272
273
  let tempDir: string;
273
274
  let outputDir: string;
274
275
  let library: PlaybookLibrary;
276
+ let persistence: any;
275
277
 
276
278
  beforeEach(async () => {
277
279
  tempDir = await mkdtemp(join(tmpdir(), 'atlas-skill-export-'));
278
280
  outputDir = join(tempDir, 'skills-output');
279
- library = createPlaybookLibrary(tempDir);
281
+ persistence = createSqlitePersistence({ baseDir: tempDir });
282
+ await persistence.init();
283
+ library = createPlaybookLibrary(persistence);
280
284
  await library.init();
281
285
  });
282
286
 
283
287
  afterEach(async () => {
284
288
  await library.close();
289
+ persistence.close();
285
290
  await rm(tempDir, { recursive: true, force: true });
286
291
  });
287
292
 
@@ -2,17 +2,21 @@ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
2
  import { MemorySystem, createMemorySystem } from '../../src/memory/system.js';
3
3
  import { createTrajectory, createStep, createTask, successOutcome, failureOutcome } from '../../src/types/index.js';
4
4
  import { createPlaybook } from '../../src/types/playbook.js';
5
+ import { createSqlitePersistence } from '../../src/persistence/index.js';
5
6
  import * as fs from 'node:fs/promises';
6
7
  import * as path from 'node:path';
7
8
 
8
9
  describe('MemorySystem', () => {
9
10
  let memory: MemorySystem;
10
11
  let testDir: string;
12
+ let persistence: any;
11
13
 
12
14
  beforeEach(async () => {
13
15
  testDir = path.join(process.cwd(), '.test-memory-system-' + Date.now());
14
16
  await fs.mkdir(testDir, { recursive: true });
15
- memory = createMemorySystem(testDir, {
17
+ persistence = createSqlitePersistence({ baseDir: testDir });
18
+ await persistence.init();
19
+ memory = createMemorySystem(persistence, testDir, {
16
20
  maxExperiences: 4,
17
21
  maxStrategies: 3,
18
22
  });
@@ -21,6 +25,7 @@ describe('MemorySystem', () => {
21
25
 
22
26
  afterEach(async () => {
23
27
  await memory.close();
28
+ persistence.close();
24
29
  await fs.rm(testDir, { recursive: true, force: true });
25
30
  });
26
31
 
@@ -0,0 +1,318 @@
1
+ import { describe, it, expect, beforeEach } from 'vitest';
2
+ import { TemporalCompressor, type CompressionResult } from '../../src/memory/temporal-compressor.js';
3
+ import type { Experience } from '../../src/types/memory.js';
4
+
5
+ function makeExperience(overrides: Partial<Experience> = {}): Experience {
6
+ return {
7
+ id: overrides.id ?? `exp-${crypto.randomUUID().slice(0, 8)}`,
8
+ taskInput: overrides.taskInput ?? 'Fix the broken authentication module in the login flow',
9
+ solutionOutput: overrides.solutionOutput ?? 'Updated the auth middleware to check token expiry. Fixed the session refresh logic. Added error handling for expired tokens.',
10
+ feedback: overrides.feedback ?? 'All tests pass. Authentication working correctly.',
11
+ success: overrides.success ?? true,
12
+ domain: overrides.domain ?? 'backend',
13
+ trajectoryId: overrides.trajectoryId ?? `traj-${crypto.randomUUID().slice(0, 8)}`,
14
+ usageCount: overrides.usageCount ?? 0,
15
+ accessScore: overrides.accessScore ?? 1.0,
16
+ retrievalCount: overrides.retrievalCount ?? 0,
17
+ createdAt: overrides.createdAt ?? new Date(),
18
+ tier: overrides.tier ?? 'hot',
19
+ compressed: overrides.compressed,
20
+ metadata: overrides.metadata ?? {},
21
+ } as Experience;
22
+ }
23
+
24
+ describe('TemporalCompressor', () => {
25
+ let compressor: TemporalCompressor;
26
+
27
+ beforeEach(() => {
28
+ compressor = new TemporalCompressor({
29
+ hotThreshold: 0.5,
30
+ warmThreshold: 0.2,
31
+ evictionThreshold: 0.05,
32
+ hysteresis: 0.05,
33
+ });
34
+ });
35
+
36
+ describe('hot experiences with high accessScore stay hot', () => {
37
+ it('should not change tier for high-scoring experiences', async () => {
38
+ const experiences = [
39
+ makeExperience({ id: 'high-1', accessScore: 0.9, tier: 'hot' }),
40
+ makeExperience({ id: 'high-2', accessScore: 0.7, tier: 'hot' }),
41
+ ];
42
+
43
+ const result = await compressor.compress(experiences);
44
+
45
+ expect(result.unchanged).toContain('high-1');
46
+ expect(result.unchanged).toContain('high-2');
47
+ expect(result.demoted).toHaveLength(0);
48
+ expect(result.evicted).toHaveLength(0);
49
+ });
50
+ });
51
+
52
+ describe('low accessScore experiences demote to warm', () => {
53
+ it('should mark low-scoring hot experience as pending on first pass', async () => {
54
+ const experiences = [
55
+ makeExperience({ id: 'low-1', accessScore: 0.3, tier: 'hot' }),
56
+ ];
57
+
58
+ // First pass: should be unchanged (hysteresis)
59
+ const result1 = await compressor.compress(experiences);
60
+ expect(result1.unchanged).toContain('low-1');
61
+ expect(result1.demoted).toHaveLength(0);
62
+ });
63
+
64
+ it('should demote on second consecutive pass below threshold', async () => {
65
+ const experiences = [
66
+ makeExperience({ id: 'low-1', accessScore: 0.3, tier: 'hot' }),
67
+ ];
68
+
69
+ // First pass: marks pending
70
+ await compressor.compress(experiences);
71
+
72
+ // Second pass: should demote
73
+ const result2 = await compressor.compress(experiences);
74
+ expect(result2.demoted).toContain('low-1');
75
+ expect(result2.updates.has('low-1')).toBe(true);
76
+ expect(result2.updates.get('low-1')!.tier).toBe('warm');
77
+ });
78
+ });
79
+
80
+ describe('warm to cold strips to summary', () => {
81
+ it('should demote warm to cold after two passes', async () => {
82
+ const experiences = [
83
+ makeExperience({
84
+ id: 'warm-1',
85
+ accessScore: 0.1,
86
+ tier: 'warm',
87
+ compressed: {
88
+ keySteps: ['Step 1: Check auth', 'Step 2: Fix token'],
89
+ summary: '',
90
+ originalStepCount: 5,
91
+ },
92
+ }),
93
+ ];
94
+
95
+ // First pass: mark pending
96
+ await compressor.compress(experiences);
97
+
98
+ // Second pass: demote
99
+ const result2 = await compressor.compress(experiences);
100
+ expect(result2.demoted).toContain('warm-1');
101
+ expect(result2.updates.get('warm-1')!.tier).toBe('cold');
102
+ });
103
+ });
104
+
105
+ describe('cold to evicted returns eviction recommendation', () => {
106
+ it('should evict cold experience below eviction threshold after two passes', async () => {
107
+ const experiences = [
108
+ makeExperience({
109
+ id: 'cold-1',
110
+ accessScore: 0.02,
111
+ tier: 'cold',
112
+ compressed: {
113
+ keySteps: [],
114
+ summary: 'Old task summary',
115
+ originalStepCount: 3,
116
+ },
117
+ }),
118
+ ];
119
+
120
+ // First pass: mark pending
121
+ await compressor.compress(experiences);
122
+
123
+ // Second pass: evict
124
+ const result2 = await compressor.compress(experiences);
125
+ expect(result2.evicted).toContain('cold-1');
126
+ });
127
+
128
+ it('should not evict non-cold experiences even if below eviction threshold', async () => {
129
+ const experiences = [
130
+ makeExperience({ id: 'hot-low', accessScore: 0.01, tier: 'hot' }),
131
+ ];
132
+
133
+ // Two passes: should demote to warm, not evict
134
+ await compressor.compress(experiences);
135
+ const result2 = await compressor.compress(experiences);
136
+
137
+ expect(result2.evicted).toHaveLength(0);
138
+ expect(result2.demoted).toContain('hot-low');
139
+ expect(result2.updates.get('hot-low')!.tier).toBe('warm');
140
+ });
141
+ });
142
+
143
+ describe('hysteresis prevents single-pass oscillation', () => {
144
+ it('should not demote on a single pass', async () => {
145
+ const experiences = [
146
+ makeExperience({ id: 'hyst-1', accessScore: 0.3, tier: 'hot' }),
147
+ ];
148
+
149
+ const result = await compressor.compress(experiences);
150
+ expect(result.demoted).toHaveLength(0);
151
+ expect(result.unchanged).toContain('hyst-1');
152
+ });
153
+
154
+ it('should require score above threshold+hysteresis for promotion', async () => {
155
+ const experiences = [
156
+ makeExperience({ id: 'promo-1', accessScore: 0.22, tier: 'cold' }),
157
+ ];
158
+
159
+ // 0.22 < warmThreshold(0.2) + hysteresis(0.05) = 0.25
160
+ const result = await compressor.compress(experiences);
161
+ expect(result.promoted).toHaveLength(0);
162
+ expect(result.unchanged).toContain('promo-1');
163
+ });
164
+
165
+ it('should promote when score is above threshold+hysteresis', async () => {
166
+ const experiences = [
167
+ makeExperience({ id: 'promo-2', accessScore: 0.3, tier: 'cold' }),
168
+ ];
169
+
170
+ // 0.3 >= warmThreshold(0.2) + hysteresis(0.05) = 0.25
171
+ const result = await compressor.compress(experiences);
172
+ expect(result.promoted).toContain('promo-2');
173
+ expect(result.updates.get('promo-2')!.tier).toBe('warm');
174
+ });
175
+ });
176
+
177
+ describe('compression preserves critical fields', () => {
178
+ it('compressToWarm should preserve id, domain, success, taskInput', () => {
179
+ const exp = makeExperience({
180
+ id: 'preserve-1',
181
+ domain: 'frontend',
182
+ success: true,
183
+ taskInput: 'Fix the CSS layout issue',
184
+ });
185
+
186
+ const warm = compressor.compressToWarm(exp);
187
+
188
+ expect(warm.id).toBe('preserve-1');
189
+ expect(warm.domain).toBe('frontend');
190
+ expect(warm.success).toBe(true);
191
+ expect(warm.taskInput).toBe('Fix the CSS layout issue');
192
+ expect(warm.tier).toBe('warm');
193
+ });
194
+
195
+ it('compressToCold should preserve id, domain, success', () => {
196
+ const exp = makeExperience({
197
+ id: 'preserve-2',
198
+ domain: 'backend',
199
+ success: false,
200
+ taskInput: 'A very long task input that should be truncated at two hundred characters maximum to save space in the cold tier representation while still preserving enough context for future retrieval purposes',
201
+ compressed: {
202
+ keySteps: ['Step 1'],
203
+ summary: '',
204
+ originalStepCount: 5,
205
+ },
206
+ });
207
+
208
+ const cold = compressor.compressToCold(exp);
209
+
210
+ expect(cold.id).toBe('preserve-2');
211
+ expect(cold.domain).toBe('backend');
212
+ expect(cold.success).toBe(false);
213
+ expect(cold.tier).toBe('cold');
214
+ expect(cold.taskInput.length).toBeLessThanOrEqual(200);
215
+ });
216
+ });
217
+
218
+ describe('compressToWarm keeps key steps', () => {
219
+ it('should extract key steps from metadata trajectory steps', () => {
220
+ const exp = makeExperience({
221
+ metadata: {
222
+ steps: [
223
+ { action: 'Read src/auth.ts', observation: 'File contains auth logic', attributionScore: 0.8 },
224
+ { action: 'Think about approach', observation: 'Considering options', attributionScore: 0.1 },
225
+ { action: 'Edit src/auth.ts', observation: 'File updated successfully', attributionScore: 0.9 },
226
+ { action: 'Bash npm test', observation: 'All 15 tests pass', attributionScore: 0.6 },
227
+ ],
228
+ stepCount: 4,
229
+ },
230
+ });
231
+
232
+ const warm = compressor.compressToWarm(exp);
233
+
234
+ expect(warm.compressed).toBeDefined();
235
+ expect(warm.compressed!.keySteps.length).toBeGreaterThan(0);
236
+ expect(warm.compressed!.originalStepCount).toBe(4);
237
+ expect(warm.tier).toBe('warm');
238
+ });
239
+
240
+ it('should fall back to line-based extraction without metadata', () => {
241
+ const exp = makeExperience({
242
+ solutionOutput: 'Line 1: Started investigation\nLine 2: Found the bug\nLine 3: Error in auth module\nLine 4: Applied fix\nLine 5: Ran tests\nLine 6: All tests pass\nLine 7: Done',
243
+ metadata: {},
244
+ });
245
+
246
+ const warm = compressor.compressToWarm(exp);
247
+
248
+ expect(warm.compressed).toBeDefined();
249
+ expect(warm.compressed!.keySteps.length).toBeGreaterThan(0);
250
+ });
251
+ });
252
+
253
+ describe('compressToCold produces readable summary', () => {
254
+ it('should generate a summary from key steps', () => {
255
+ const exp = makeExperience({
256
+ taskInput: 'Fix authentication bug in login handler',
257
+ domain: 'backend',
258
+ success: true,
259
+ feedback: 'All tests pass',
260
+ compressed: {
261
+ keySteps: ['Check auth middleware', 'Fix token validation', 'Add error handling'],
262
+ summary: '',
263
+ originalStepCount: 8,
264
+ },
265
+ });
266
+
267
+ const cold = compressor.compressToCold(exp);
268
+
269
+ expect(cold.compressed).toBeDefined();
270
+ expect(cold.compressed!.summary.length).toBeGreaterThan(0);
271
+ expect(cold.compressed!.summary).toContain('backend');
272
+ expect(cold.compressed!.summary).toContain('Successfully');
273
+ expect(cold.solutionOutput).toBe(cold.compressed!.summary);
274
+ });
275
+
276
+ it('should reflect failure in summary', () => {
277
+ const exp = makeExperience({
278
+ taskInput: 'Deploy to production',
279
+ domain: 'devops',
280
+ success: false,
281
+ feedback: 'Deployment failed',
282
+ compressed: {
283
+ keySteps: ['Build step failed'],
284
+ summary: '',
285
+ originalStepCount: 3,
286
+ },
287
+ });
288
+
289
+ const cold = compressor.compressToCold(exp);
290
+
291
+ expect(cold.compressed!.summary).toContain('Failed to');
292
+ });
293
+ });
294
+
295
+ describe('mixed scenarios', () => {
296
+ it('should handle a batch with mixed tiers and scores', async () => {
297
+ const experiences = [
298
+ makeExperience({ id: 'hot-high', accessScore: 0.8, tier: 'hot' }),
299
+ makeExperience({ id: 'hot-low', accessScore: 0.15, tier: 'hot' }),
300
+ makeExperience({ id: 'warm-ok', accessScore: 0.3, tier: 'warm' }),
301
+ makeExperience({ id: 'cold-dead', accessScore: 0.01, tier: 'cold' }),
302
+ ];
303
+
304
+ // First pass
305
+ const result1 = await compressor.compress(experiences);
306
+ expect(result1.unchanged).toContain('hot-high');
307
+ // hot-low is pending demotion
308
+ // warm-ok should be promoted (0.3 > 0.5+0.05? No, 0.3 < 0.55)
309
+ // Actually warm → hot needs 0.55, and 0.3 < 0.55 so unchanged
310
+ expect(result1.promoted).toHaveLength(0);
311
+
312
+ // Second pass
313
+ const result2 = await compressor.compress(experiences);
314
+ expect(result2.demoted).toContain('hot-low');
315
+ expect(result2.unchanged).toContain('hot-high');
316
+ });
317
+ });
318
+ });