nlm-memory 0.21.0 → 0.21.13

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 (413) hide show
  1. package/README.md +67 -12
  2. package/assets/replay-eval-dark.svg +26 -0
  3. package/assets/replay-eval-light.svg +26 -0
  4. package/dist/cli/digest.js +34 -7
  5. package/dist/cli/digest.js.map +1 -1
  6. package/dist/cli/nlm.d.ts +14 -0
  7. package/dist/cli/nlm.js +450 -65
  8. package/dist/cli/nlm.js.map +1 -1
  9. package/dist/cli/reprocess-job-adapters.d.ts +35 -0
  10. package/dist/cli/reprocess-job-adapters.js +80 -0
  11. package/dist/cli/reprocess-job-adapters.js.map +1 -0
  12. package/dist/cli/scope-coverage.js +4 -1
  13. package/dist/cli/scope-coverage.js.map +1 -1
  14. package/dist/cli/supersede.js +8 -7
  15. package/dist/cli/supersede.js.map +1 -1
  16. package/dist/core/actions/actions-log.d.ts +65 -8
  17. package/dist/core/actions/actions-log.js +134 -17
  18. package/dist/core/actions/actions-log.js.map +1 -1
  19. package/dist/core/actions/overlay.d.ts +11 -2
  20. package/dist/core/actions/overlay.js +18 -6
  21. package/dist/core/actions/overlay.js.map +1 -1
  22. package/dist/core/adapters/from-source.js +11 -3
  23. package/dist/core/adapters/from-source.js.map +1 -1
  24. package/dist/core/adapters/fs-wiki-writer.d.ts +44 -0
  25. package/dist/core/adapters/fs-wiki-writer.js +132 -0
  26. package/dist/core/adapters/fs-wiki-writer.js.map +1 -0
  27. package/dist/core/adapters/hermes-agent.d.ts +15 -2
  28. package/dist/core/adapters/hermes-agent.js +57 -11
  29. package/dist/core/adapters/hermes-agent.js.map +1 -1
  30. package/dist/core/adapters/memory-wiki-writer.d.ts +8 -0
  31. package/dist/core/adapters/memory-wiki-writer.js +16 -0
  32. package/dist/core/adapters/memory-wiki-writer.js.map +1 -0
  33. package/dist/core/adapters/muse.d.ts +51 -0
  34. package/dist/core/adapters/muse.js +271 -0
  35. package/dist/core/adapters/muse.js.map +1 -0
  36. package/dist/core/adapters/opencode.d.ts +11 -4
  37. package/dist/core/adapters/opencode.js +41 -7
  38. package/dist/core/adapters/opencode.js.map +1 -1
  39. package/dist/core/alerts/alert-state.d.ts +17 -0
  40. package/dist/core/alerts/alert-state.js +45 -0
  41. package/dist/core/alerts/alert-state.js.map +1 -0
  42. package/dist/core/alerts/check-and-alert.d.ts +28 -0
  43. package/dist/core/alerts/check-and-alert.js +53 -0
  44. package/dist/core/alerts/check-and-alert.js.map +1 -0
  45. package/dist/core/alerts/drift-transition.d.ts +27 -0
  46. package/dist/core/alerts/drift-transition.js +56 -0
  47. package/dist/core/alerts/drift-transition.js.map +1 -0
  48. package/dist/core/alerts/embedder-transition.d.ts +23 -0
  49. package/dist/core/alerts/embedder-transition.js +40 -0
  50. package/dist/core/alerts/embedder-transition.js.map +1 -0
  51. package/dist/core/alerts/fire-alert.d.ts +24 -0
  52. package/dist/core/alerts/fire-alert.js +72 -0
  53. package/dist/core/alerts/fire-alert.js.map +1 -0
  54. package/dist/core/alerts/job-alert.d.ts +12 -0
  55. package/dist/core/alerts/job-alert.js +37 -0
  56. package/dist/core/alerts/job-alert.js.map +1 -0
  57. package/dist/core/alerts/types.d.ts +104 -0
  58. package/dist/core/alerts/types.js +11 -0
  59. package/dist/core/alerts/types.js.map +1 -0
  60. package/dist/core/alerts/wiki-alert.d.ts +15 -0
  61. package/dist/core/alerts/wiki-alert.js +31 -0
  62. package/dist/core/alerts/wiki-alert.js.map +1 -0
  63. package/dist/core/classifier/prompt.d.ts +13 -0
  64. package/dist/core/classifier/prompt.js +52 -2
  65. package/dist/core/classifier/prompt.js.map +1 -1
  66. package/dist/core/dataset/build-dataset.d.ts +16 -1
  67. package/dist/core/dataset/build-dataset.js +105 -45
  68. package/dist/core/dataset/build-dataset.js.map +1 -1
  69. package/dist/core/digest/compose.d.ts +8 -0
  70. package/dist/core/digest/compose.js +54 -0
  71. package/dist/core/digest/compose.js.map +1 -1
  72. package/dist/core/digest/hook-injection.d.ts +1 -1
  73. package/dist/core/digest/hook-injection.js +9 -1
  74. package/dist/core/digest/hook-injection.js.map +1 -1
  75. package/dist/core/digest/hook-version-parity.d.ts +31 -0
  76. package/dist/core/digest/hook-version-parity.js +56 -0
  77. package/dist/core/digest/hook-version-parity.js.map +1 -0
  78. package/dist/core/embedding/pg-embed-backfill.js +1 -1
  79. package/dist/core/embedding/pg-embed-backfill.js.map +1 -1
  80. package/dist/core/exemplars/capture-from-session.d.ts +1 -1
  81. package/dist/core/exemplars/capture-from-session.js +3 -3
  82. package/dist/core/exemplars/capture-from-session.js.map +1 -1
  83. package/dist/core/exemplars/embed-backfill.d.ts +9 -0
  84. package/dist/core/exemplars/embed-backfill.js +9 -1
  85. package/dist/core/exemplars/embed-backfill.js.map +1 -1
  86. package/dist/core/exemplars/recall-code.d.ts +1 -1
  87. package/dist/core/exemplars/recall-code.js +2 -2
  88. package/dist/core/exemplars/recall-code.js.map +1 -1
  89. package/dist/core/facts/backfill-facts.d.ts +1 -1
  90. package/dist/core/facts/backfill-facts.js +4 -4
  91. package/dist/core/facts/backfill-facts.js.map +1 -1
  92. package/dist/core/facts/embed-backfill.d.ts +54 -0
  93. package/dist/core/facts/embed-backfill.js +109 -0
  94. package/dist/core/facts/embed-backfill.js.map +1 -0
  95. package/dist/core/facts/reconcile-facts.d.ts +42 -0
  96. package/dist/core/facts/reconcile-facts.js +133 -0
  97. package/dist/core/facts/reconcile-facts.js.map +1 -0
  98. package/dist/core/health/embed-failure-state.d.ts +4 -0
  99. package/dist/core/health/embed-failure-state.js +12 -0
  100. package/dist/core/health/embed-failure-state.js.map +1 -0
  101. package/dist/core/health/warmup-retry.d.ts +27 -0
  102. package/dist/core/health/warmup-retry.js +53 -0
  103. package/dist/core/health/warmup-retry.js.map +1 -0
  104. package/dist/core/health/warmup-state.d.ts +15 -0
  105. package/dist/core/health/warmup-state.js +15 -1
  106. package/dist/core/health/warmup-state.js.map +1 -1
  107. package/dist/core/hook/cite-memo.d.ts +11 -7
  108. package/dist/core/hook/cite-memo.js +25 -17
  109. package/dist/core/hook/cite-memo.js.map +1 -1
  110. package/dist/core/hook/hook-log.d.ts +13 -2
  111. package/dist/core/hook/hook-log.js +16 -8
  112. package/dist/core/hook/hook-log.js.map +1 -1
  113. package/dist/core/hook/memo.d.ts +10 -6
  114. package/dist/core/hook/memo.js +25 -17
  115. package/dist/core/hook/memo.js.map +1 -1
  116. package/dist/core/hook/pointer-block.d.ts +8 -1
  117. package/dist/core/hook/pointer-block.js +17 -4
  118. package/dist/core/hook/pointer-block.js.map +1 -1
  119. package/dist/core/hook/resolve-conversation-by-query.d.ts +6 -5
  120. package/dist/core/hook/resolve-conversation-by-query.js +24 -12
  121. package/dist/core/hook/resolve-conversation-by-query.js.map +1 -1
  122. package/dist/core/ingest/ingest-session.d.ts +1 -1
  123. package/dist/core/ingest/ingest-session.js +3 -3
  124. package/dist/core/ingest/ingest-session.js.map +1 -1
  125. package/dist/core/ingest/reclassify-oversized.d.ts +1 -1
  126. package/dist/core/ingest/reclassify-oversized.js +2 -2
  127. package/dist/core/ingest/reclassify-oversized.js.map +1 -1
  128. package/dist/core/ingest/reprocess.d.ts +1 -1
  129. package/dist/core/ingest/reprocess.js +2 -2
  130. package/dist/core/ingest/reprocess.js.map +1 -1
  131. package/dist/core/jobs/job-supervisor.d.ts +168 -0
  132. package/dist/core/jobs/job-supervisor.js +335 -0
  133. package/dist/core/jobs/job-supervisor.js.map +1 -0
  134. package/dist/core/learner/model.d.ts +63 -0
  135. package/dist/core/learner/model.js +30 -0
  136. package/dist/core/learner/model.js.map +1 -0
  137. package/dist/core/learner/service.d.ts +42 -0
  138. package/dist/core/learner/service.js +74 -0
  139. package/dist/core/learner/service.js.map +1 -0
  140. package/dist/core/learner/summary.d.ts +28 -0
  141. package/dist/core/learner/summary.js +70 -0
  142. package/dist/core/learner/summary.js.map +1 -0
  143. package/dist/core/learner/validate.d.ts +18 -0
  144. package/dist/core/learner/validate.js +95 -0
  145. package/dist/core/learner/validate.js.map +1 -0
  146. package/dist/core/metrics/re-derivation.d.ts +31 -2
  147. package/dist/core/metrics/re-derivation.js +36 -4
  148. package/dist/core/metrics/re-derivation.js.map +1 -1
  149. package/dist/core/outcome/coverage.d.ts +1 -1
  150. package/dist/core/outcome/coverage.js +2 -2
  151. package/dist/core/outcome/coverage.js.map +1 -1
  152. package/dist/core/outcome/rollup.d.ts +1 -1
  153. package/dist/core/outcome/rollup.js +4 -4
  154. package/dist/core/outcome/rollup.js.map +1 -1
  155. package/dist/core/providers/provider-registry.d.ts +40 -23
  156. package/dist/core/providers/provider-registry.js +99 -81
  157. package/dist/core/providers/provider-registry.js.map +1 -1
  158. package/dist/core/recall/citation-log.d.ts +10 -5
  159. package/dist/core/recall/citation-log.js +21 -10
  160. package/dist/core/recall/citation-log.js.map +1 -1
  161. package/dist/core/recall/hook-recall-log.d.ts +5 -2
  162. package/dist/core/recall/hook-recall-log.js +12 -6
  163. package/dist/core/recall/hook-recall-log.js.map +1 -1
  164. package/dist/core/recall/miss-log.d.ts +7 -4
  165. package/dist/core/recall/miss-log.js +18 -11
  166. package/dist/core/recall/miss-log.js.map +1 -1
  167. package/dist/core/recall/query-log.d.ts +8 -5
  168. package/dist/core/recall/query-log.js +16 -9
  169. package/dist/core/recall/query-log.js.map +1 -1
  170. package/dist/core/recall/recall-service.d.ts +10 -1
  171. package/dist/core/recall/recall-service.js +31 -12
  172. package/dist/core/recall/recall-service.js.map +1 -1
  173. package/dist/core/recall/recent-log.d.ts +6 -1
  174. package/dist/core/recall/recent-log.js +13 -5
  175. package/dist/core/recall/recent-log.js.map +1 -1
  176. package/dist/core/recall/related-concepts.d.ts +29 -0
  177. package/dist/core/recall/related-concepts.js +67 -0
  178. package/dist/core/recall/related-concepts.js.map +1 -0
  179. package/dist/core/recall/related-exemplars.d.ts +1 -1
  180. package/dist/core/recall/related-exemplars.js +2 -2
  181. package/dist/core/recall/related-exemplars.js.map +1 -1
  182. package/dist/core/recall/related-facts.d.ts +1 -1
  183. package/dist/core/recall/related-facts.js +3 -3
  184. package/dist/core/recall/related-facts.js.map +1 -1
  185. package/dist/core/recall-facts/fact-query-log.d.ts +8 -4
  186. package/dist/core/recall-facts/fact-query-log.js +16 -8
  187. package/dist/core/recall-facts/fact-query-log.js.map +1 -1
  188. package/dist/core/recall-facts/fact-recall-service.d.ts +2 -2
  189. package/dist/core/recall-facts/fact-recall-service.js +12 -12
  190. package/dist/core/recall-facts/fact-recall-service.js.map +1 -1
  191. package/dist/core/scheduler/scan-once.js +15 -14
  192. package/dist/core/scheduler/scan-once.js.map +1 -1
  193. package/dist/core/scheduler/scheduler.d.ts +3 -0
  194. package/dist/core/scheduler/scheduler.js +15 -11
  195. package/dist/core/scheduler/scheduler.js.map +1 -1
  196. package/dist/core/signals/failure-mode-recall.d.ts +1 -1
  197. package/dist/core/signals/failure-mode-recall.js +2 -2
  198. package/dist/core/signals/failure-mode-recall.js.map +1 -1
  199. package/dist/core/signals/stamp-scope.d.ts +2 -2
  200. package/dist/core/signals/stamp-scope.js +2 -2
  201. package/dist/core/signals/stamp-scope.js.map +1 -1
  202. package/dist/core/sources/source-registry.d.ts +49 -28
  203. package/dist/core/sources/source-registry.js +113 -70
  204. package/dist/core/sources/source-registry.js.map +1 -1
  205. package/dist/core/storage/pg-code-exemplar-store.d.ts +19 -10
  206. package/dist/core/storage/pg-code-exemplar-store.js +58 -27
  207. package/dist/core/storage/pg-code-exemplar-store.js.map +1 -1
  208. package/dist/core/storage/pg-entity-store.d.ts +6 -1
  209. package/dist/core/storage/pg-entity-store.js +33 -18
  210. package/dist/core/storage/pg-entity-store.js.map +1 -1
  211. package/dist/core/storage/pg-fact-ingest.d.ts +1 -1
  212. package/dist/core/storage/pg-fact-ingest.js +10 -7
  213. package/dist/core/storage/pg-fact-ingest.js.map +1 -1
  214. package/dist/core/storage/pg-fact-store.d.ts +29 -17
  215. package/dist/core/storage/pg-fact-store.js +99 -46
  216. package/dist/core/storage/pg-fact-store.js.map +1 -1
  217. package/dist/core/storage/pg-learner-store.d.ts +27 -0
  218. package/dist/core/storage/pg-learner-store.js +174 -0
  219. package/dist/core/storage/pg-learner-store.js.map +1 -0
  220. package/dist/core/storage/pg-session-store.d.ts +24 -20
  221. package/dist/core/storage/pg-session-store.js +162 -90
  222. package/dist/core/storage/pg-session-store.js.map +1 -1
  223. package/dist/core/storage/pg-signal-store.d.ts +10 -5
  224. package/dist/core/storage/pg-signal-store.js +24 -12
  225. package/dist/core/storage/pg-signal-store.js.map +1 -1
  226. package/dist/core/storage/pg-storage.d.ts +4 -0
  227. package/dist/core/storage/pg-storage.js +6 -0
  228. package/dist/core/storage/pg-storage.js.map +1 -1
  229. package/dist/core/storage/pg-workstream-store.d.ts +16 -11
  230. package/dist/core/storage/pg-workstream-store.js +46 -29
  231. package/dist/core/storage/pg-workstream-store.js.map +1 -1
  232. package/dist/core/storage/sqlite-code-exemplar-store.d.ts +24 -10
  233. package/dist/core/storage/sqlite-code-exemplar-store.js +84 -40
  234. package/dist/core/storage/sqlite-code-exemplar-store.js.map +1 -1
  235. package/dist/core/storage/sqlite-entity-store.d.ts +8 -1
  236. package/dist/core/storage/sqlite-entity-store.js +46 -27
  237. package/dist/core/storage/sqlite-entity-store.js.map +1 -1
  238. package/dist/core/storage/sqlite-fact-store.d.ts +45 -19
  239. package/dist/core/storage/sqlite-fact-store.js +172 -64
  240. package/dist/core/storage/sqlite-fact-store.js.map +1 -1
  241. package/dist/core/storage/sqlite-learner-store.d.ts +33 -0
  242. package/dist/core/storage/sqlite-learner-store.js +178 -0
  243. package/dist/core/storage/sqlite-learner-store.js.map +1 -0
  244. package/dist/core/storage/sqlite-outcome-store.d.ts +37 -22
  245. package/dist/core/storage/sqlite-outcome-store.js +90 -37
  246. package/dist/core/storage/sqlite-outcome-store.js.map +1 -1
  247. package/dist/core/storage/sqlite-session-store.d.ts +29 -20
  248. package/dist/core/storage/sqlite-session-store.js +207 -121
  249. package/dist/core/storage/sqlite-session-store.js.map +1 -1
  250. package/dist/core/storage/sqlite-signal-store.d.ts +12 -5
  251. package/dist/core/storage/sqlite-signal-store.js +27 -15
  252. package/dist/core/storage/sqlite-signal-store.js.map +1 -1
  253. package/dist/core/storage/sqlite-storage.d.ts +4 -0
  254. package/dist/core/storage/sqlite-storage.js +10 -2
  255. package/dist/core/storage/sqlite-storage.js.map +1 -1
  256. package/dist/core/storage/sqlite-workstream-store.d.ts +16 -11
  257. package/dist/core/storage/sqlite-workstream-store.js +52 -31
  258. package/dist/core/storage/sqlite-workstream-store.js.map +1 -1
  259. package/dist/core/storage/supersedence-log.d.ts +10 -7
  260. package/dist/core/storage/supersedence-log.js +19 -14
  261. package/dist/core/storage/supersedence-log.js.map +1 -1
  262. package/dist/core/tenancy/default-team.d.ts +6 -0
  263. package/dist/core/tenancy/default-team.js +7 -0
  264. package/dist/core/tenancy/default-team.js.map +1 -0
  265. package/dist/core/tenancy/hosted-mode.d.ts +9 -0
  266. package/dist/core/tenancy/hosted-mode.js +12 -0
  267. package/dist/core/tenancy/hosted-mode.js.map +1 -0
  268. package/dist/core/tenancy/team-auth.d.ts +16 -0
  269. package/dist/core/tenancy/team-auth.js +22 -0
  270. package/dist/core/tenancy/team-auth.js.map +1 -0
  271. package/dist/core/tenancy/team-token-store.d.ts +45 -0
  272. package/dist/core/tenancy/team-token-store.js +52 -0
  273. package/dist/core/tenancy/team-token-store.js.map +1 -0
  274. package/dist/core/tenancy/tenant-clause.d.ts +37 -0
  275. package/dist/core/tenancy/tenant-clause.js +11 -0
  276. package/dist/core/tenancy/tenant-clause.js.map +1 -0
  277. package/dist/core/tenancy/tenant-state-path.d.ts +28 -0
  278. package/dist/core/tenancy/tenant-state-path.js +49 -0
  279. package/dist/core/tenancy/tenant-state-path.js.map +1 -0
  280. package/dist/core/wiki/project.d.ts +17 -0
  281. package/dist/core/wiki/project.js +37 -0
  282. package/dist/core/wiki/project.js.map +1 -0
  283. package/dist/core/wiki/reconcile.d.ts +15 -0
  284. package/dist/core/wiki/reconcile.js +14 -0
  285. package/dist/core/wiki/reconcile.js.map +1 -0
  286. package/dist/core/wiki/render.d.ts +5 -0
  287. package/dist/core/wiki/render.js +84 -0
  288. package/dist/core/wiki/render.js.map +1 -0
  289. package/dist/core/wiki/rollup.d.ts +28 -0
  290. package/dist/core/wiki/rollup.js +91 -0
  291. package/dist/core/wiki/rollup.js.map +1 -0
  292. package/dist/core/wiki/select.d.ts +8 -0
  293. package/dist/core/wiki/select.js +7 -0
  294. package/dist/core/wiki/select.js.map +1 -0
  295. package/dist/core/wiki/slug.d.ts +36 -0
  296. package/dist/core/wiki/slug.js +71 -0
  297. package/dist/core/wiki/slug.js.map +1 -0
  298. package/dist/core/wiki/types.d.ts +37 -0
  299. package/dist/core/wiki/types.js +2 -0
  300. package/dist/core/wiki/types.js.map +1 -0
  301. package/dist/core/work-digest/build-work-digest.d.ts +1 -1
  302. package/dist/core/work-digest/build-work-digest.js +3 -3
  303. package/dist/core/work-digest/build-work-digest.js.map +1 -1
  304. package/dist/core/workstream/bind.d.ts +1 -1
  305. package/dist/core/workstream/bind.js +10 -10
  306. package/dist/core/workstream/bind.js.map +1 -1
  307. package/dist/core/workstream/rollup.d.ts +1 -1
  308. package/dist/core/workstream/rollup.js +6 -6
  309. package/dist/core/workstream/rollup.js.map +1 -1
  310. package/dist/hook/hook-helpers.d.ts +14 -0
  311. package/dist/hook/hook-helpers.js +29 -2
  312. package/dist/hook/hook-helpers.js.map +1 -1
  313. package/dist/hook/pre-compact-hook.js +6 -4
  314. package/dist/hook/pre-compact-hook.js.map +1 -1
  315. package/dist/hook/prompt-recall-hook.d.ts +5 -2
  316. package/dist/hook/prompt-recall-hook.js +28 -17
  317. package/dist/hook/prompt-recall-hook.js.map +1 -1
  318. package/dist/hook/recall-over-http.d.ts +27 -3
  319. package/dist/hook/recall-over-http.js +44 -11
  320. package/dist/hook/recall-over-http.js.map +1 -1
  321. package/dist/hook/session-end-hook.js +7 -5
  322. package/dist/hook/session-end-hook.js.map +1 -1
  323. package/dist/hook/session-start-hook.d.ts +14 -1
  324. package/dist/hook/session-start-hook.js +55 -15
  325. package/dist/hook/session-start-hook.js.map +1 -1
  326. package/dist/hook/stop-hook.js +9 -7
  327. package/dist/hook/stop-hook.js.map +1 -1
  328. package/dist/http/app.d.ts +41 -3
  329. package/dist/http/app.js +355 -96
  330. package/dist/http/app.js.map +1 -1
  331. package/dist/install/claude-code.d.ts +17 -0
  332. package/dist/install/claude-code.js +44 -5
  333. package/dist/install/claude-code.js.map +1 -1
  334. package/dist/install/codex.d.ts +23 -2
  335. package/dist/install/codex.js +111 -14
  336. package/dist/install/codex.js.map +1 -1
  337. package/dist/install/cursor.d.ts +2 -2
  338. package/dist/install/cursor.js +7 -7
  339. package/dist/install/cursor.js.map +1 -1
  340. package/dist/install/hermes.d.ts +8 -0
  341. package/dist/install/hermes.js +28 -5
  342. package/dist/install/hermes.js.map +1 -1
  343. package/dist/install/local-source.d.ts +20 -0
  344. package/dist/install/local-source.js +28 -0
  345. package/dist/install/local-source.js.map +1 -0
  346. package/dist/install/mcp-block.d.ts +77 -0
  347. package/dist/install/mcp-block.js +99 -0
  348. package/dist/install/mcp-block.js.map +1 -0
  349. package/dist/install/pi.d.ts +26 -0
  350. package/dist/install/pi.js +43 -0
  351. package/dist/install/pi.js.map +1 -1
  352. package/dist/install/setup.js +6 -0
  353. package/dist/install/setup.js.map +1 -1
  354. package/dist/install/windsurf.d.ts +2 -2
  355. package/dist/install/windsurf.js +7 -7
  356. package/dist/install/windsurf.js.map +1 -1
  357. package/dist/llm/classifier-box.d.ts +5 -0
  358. package/dist/llm/classifier-box.js +5 -0
  359. package/dist/llm/classifier-box.js.map +1 -1
  360. package/dist/mcp/server.d.ts +73 -16
  361. package/dist/mcp/server.js +306 -83
  362. package/dist/mcp/server.js.map +1 -1
  363. package/dist/ports/clock.d.ts +12 -0
  364. package/dist/ports/clock.js +10 -0
  365. package/dist/ports/clock.js.map +1 -0
  366. package/dist/ports/code-exemplar-store.d.ts +13 -13
  367. package/dist/ports/entity-store.d.ts +5 -1
  368. package/dist/ports/fact-store.d.ts +0 -0
  369. package/dist/ports/fact-store.js +0 -0
  370. package/dist/ports/fact-store.js.map +1 -1
  371. package/dist/ports/learner-store.d.ts +80 -0
  372. package/dist/ports/learner-store.js +19 -0
  373. package/dist/ports/learner-store.js.map +1 -0
  374. package/dist/ports/outcome.d.ts +3 -3
  375. package/dist/ports/session-store.d.ts +20 -14
  376. package/dist/ports/session-store.js +5 -0
  377. package/dist/ports/session-store.js.map +1 -1
  378. package/dist/ports/signal-store.d.ts +12 -8
  379. package/dist/ports/spawn-child.d.ts +14 -0
  380. package/dist/ports/spawn-child.js +10 -0
  381. package/dist/ports/spawn-child.js.map +1 -0
  382. package/dist/ports/storage.d.ts +6 -0
  383. package/dist/ports/transcript-adapter.d.ts +11 -0
  384. package/dist/ports/wiki-writer.d.ts +19 -0
  385. package/dist/ports/wiki-writer.js +12 -0
  386. package/dist/ports/wiki-writer.js.map +1 -0
  387. package/dist/ports/workstream-store.d.ts +19 -12
  388. package/dist/shared/types.d.ts +22 -0
  389. package/dist/shared/types.js.map +1 -1
  390. package/dist/shared/version.d.ts +9 -0
  391. package/dist/shared/version.js +11 -0
  392. package/dist/shared/version.js.map +1 -0
  393. package/dist/ui/assets/index-D6F3xAis.js +11 -0
  394. package/dist/ui/index.html +1 -1
  395. package/migrations/033_actions_kind_check.sql +58 -0
  396. package/migrations/034_tenancy_teams_and_stamps.sql +40 -0
  397. package/migrations/035_tenancy_entity_rekey.sql +75 -0
  398. package/migrations/036_tenant_name_uniqueness.sql +59 -0
  399. package/migrations/037_sessions_covering_index.sql +25 -0
  400. package/migrations/038_sources_muse.sql +33 -0
  401. package/migrations/039_learner_evidence.sql +51 -0
  402. package/migrations/pg/033_actions_kind_check.sql +17 -0
  403. package/migrations/pg/034_tenancy.sql +77 -0
  404. package/migrations/pg/035_tenant_name_uniqueness.sql +15 -0
  405. package/migrations/pg/036_sources_muse.sql +12 -0
  406. package/migrations/pg/037_learner_evidence.sql +55 -0
  407. package/nlm/index.js +246 -55
  408. package/package.json +10 -5
  409. package/plugin/.codex-plugin/plugin.json +2 -2
  410. package/plugin/scripts/prompt-recall-hook.mjs +244 -55
  411. package/plugin/scripts/session-start-hook.mjs +273 -53
  412. package/plugin/scripts/stop-hook.mjs +195 -37
  413. package/dist/ui/assets/index-CSaBtgXD.js +0 -11
package/README.md CHANGED
@@ -11,7 +11,7 @@
11
11
  <a href="https://github.com/pbmagnet4/nlm-memory/actions/workflows/ci.yml"><img src="https://github.com/pbmagnet4/nlm-memory/actions/workflows/ci.yml/badge.svg?branch=main" alt="CI status" /></a>
12
12
  <a href="https://github.com/pbmagnet4/nlm-memory/blob/main/LICENSE"><img src="https://img.shields.io/github/license/pbmagnet4/nlm-memory?color=blue" alt="License: Apache 2.0" /></a>
13
13
  <a href="https://nodejs.org"><img src="https://img.shields.io/node/v/nlm-memory?color=brightgreen" alt="Node 20+" /></a>
14
- <img src="https://img.shields.io/badge/tests-1%2C700%2B%20passing-success" alt="1,700+ tests passing" />
14
+ <img src="https://img.shields.io/badge/tests-2%2C000%2B%20passing-success" alt="2,000+ tests passing" />
15
15
  <img src="https://img.shields.io/badge/MCP-9%20runtimes-8A2BE2" alt="MCP across 9 runtimes" />
16
16
  <img src="https://img.shields.io/badge/hooks-4%20runtimes-7B2CBF" alt="Hooks on 4 runtimes" />
17
17
  <img src="https://img.shields.io/badge/telemetry-none-informational" alt="Zero telemetry" />
@@ -82,7 +82,7 @@ One corpus across every adapter. MCP works against all nine. **Automatic context
82
82
 
83
83
  | Runtime | Connect | Sessions read from | Hooks |
84
84
  |---|---|---|---|
85
- | **Claude Code** | `nlm connect claude-code` | `~/.claude/projects/**/*.jsonl` | 6 hooks: UserPromptSubmit, SessionStart, SessionEnd, Stop, PreCompact, SubagentStart |
85
+ | **Claude Code** | `nlm connect claude-code` | `~/.claude/projects/**/*.jsonl` | 5 hooks: UserPromptSubmit, SessionStart, SessionEnd, Stop, PreCompact |
86
86
  | **Codex CLI** | `nlm connect codex` | `~/.codex/sessions/` | Marketplace plugin (UserPromptSubmit + Stop) |
87
87
  | **Hermes** (WebUI) | `nlm connect hermes` | `~/.hermes/sessions/` | MCP only (writes the MCP server block to `~/.hermes/config.yaml`) |
88
88
  | **Hermes Agent** (NousResearch CLI) | `nlm connect hermes-agent` | `~/.hermes/state.db` | 6 hooks: pre_llm_call, post_llm_call, on_session_start/end/finalize/reset (Python plugin in `~/.hermes/plugins/nlm-memory/`) |
@@ -102,11 +102,11 @@ Two delivery paths. They share the same index.
102
102
 
103
103
  ### 1. Hooks — automatic context injection
104
104
 
105
- Hooks deliver memory into agent context. Four runtimes ship hooks today: Claude Code (six-hook lifecycle), Codex CLI (UserPromptSubmit + Stop via the marketplace plugin), Hermes Agent (six parallel hooks), and pi.dev (one `input` hook via [nlm/](nlm/README.md)). Cursor, Windsurf, and OpenCode don't expose a pre-prompt hook today, so the `--with-rules` install path drops a static rules snippet that asks the agent to call `recall_sessions` itself on history-flavored prompts (see [docs/hooks.md](docs/hooks.md) for the snippet). Full lifecycle, modes, logging surface, and the daily liveness canary documented in [docs/hooks.md](docs/hooks.md).
105
+ Hooks deliver memory into agent context. Four runtimes ship hooks today: Claude Code (five-hook lifecycle), Codex CLI (UserPromptSubmit + Stop via the marketplace plugin), Hermes Agent (six parallel hooks), and pi.dev (one `input` hook via [nlm/](nlm/README.md)). Cursor, Windsurf, and OpenCode don't expose a pre-prompt hook today, so the `--with-rules` install path drops a static rules snippet that asks the agent to call `recall_sessions` itself on history-flavored prompts (see [docs/hooks.md](docs/hooks.md) for the snippet). Full lifecycle, modes, logging surface, and the daily liveness canary documented in [docs/hooks.md](docs/hooks.md).
106
106
 
107
107
  On fresh installs, the **SessionStart** hook injects the pointer block at conversation open. The **UserPromptSubmit** (per-prompt) lane is off by default: measured pulls are 72.4% useful vs 18.2% ambient on the same judge (see [reports/usefulness/2026-07-03-consumption-measurements.md](reports/usefulness/2026-07-03-consumption-measurements.md)), so pull-first via the recall MCP tools is the recommended posture. Set `NLM_HOOK_PROMPT_RECALL=on` to re-enable per-prompt injection.
108
108
 
109
- **Claude Code** — six hooks written to `~/.claude/settings.json` via `nlm connect claude-code`:
109
+ **Claude Code** — five hooks written to `~/.claude/settings.json` via `nlm connect claude-code`:
110
110
 
111
111
  | Event | What NLM does | Mode |
112
112
  |---|---|---|
@@ -115,7 +115,6 @@ On fresh installs, the **SessionStart** hook injects the pointer block at conver
115
115
  | **SessionEnd** | Delete the per-conversation memo on session close so state files don't accumulate | always on |
116
116
  | **Stop** | Scan the model's response for citations of surfaced session IDs → updates `useful_hit_rate` and builds the reranker training substrate | always on |
117
117
  | **PreCompact** | Flush the per-conversation surfaced-IDs memo so post-compaction recalls aren't gated | always on |
118
- | **SubagentStart** | Record parent→subagent links so threads stay coherent across dispatches | always on |
119
118
 
120
119
  **Hermes Agent** — six hooks installed to `~/.hermes/plugins/nlm-memory/` via `nlm connect hermes-agent`. All calls are fire-and-forget except `pre_llm_call`, which returns a context string for injection:
121
120
 
@@ -134,11 +133,45 @@ On fresh installs, the **SessionStart** hook injects the pointer block at conver
134
133
  |---|---|---|
135
134
  | **input** | Score user message → if relevant sessions found, prepend pointer block to the prompt text via `{ action: "transform" }` | yes (returns transformed text) |
136
135
 
137
- All three fail-open: any daemon error yields a clean exit and never blocks the model. Switch Claude Code hooks to **shadow** mode (log-only, no injection) with `NLM_HOOK_MODE=shadow`.
136
+ Parent-to-subagent links need no hook: the adapter derives them from the runtime session id at ingest, so subagent threads stay coherent with zero per-dispatch overhead. All hooks fail open: any daemon error yields a clean exit and never blocks the model. Switch Claude Code hooks to **shadow** mode (log-only, no injection) with `NLM_HOOK_MODE=shadow`.
138
137
 
139
138
  ### 2. MCP — explicit tools any agent can call
140
139
 
141
- Container-hosted agents (Hermes WebUI, Codex CLI, etc.) hit the Streamable-HTTP `POST /mcp` endpoint with `Authorization: Bearer ${NLM_MCP_TOKEN}`. Stdio MCP is also supported for Claude Code via `~/.mcp.json`.
140
+ **Streamable-HTTP `POST /mcp` is the default transport on every runtime.** `nlm connect <runtime>` writes it for you:
141
+
142
+ ```json
143
+ { "type": "http", "url": "http://127.0.0.1:3940/mcp",
144
+ "headers": { "Authorization": "Bearer ${NLM_MCP_TOKEN}" } }
145
+ ```
146
+
147
+ One daemon-backed server answers every session on every surface. The endpoint is stateless — a fresh transport and server per request, no session affinity — so it scales from a single laptop to a hosted multi-tenant deployment without changing shape, and the team is resolved from the bearer token rather than assumed. Nothing but the daemon touches the corpus.
148
+
149
+ Stdio remains available via `nlm connect <runtime> --stdio`. Its one advantage is that it builds its own stack and so works with the daemon stopped. The trade is real: a process per session, each opening the SQLite corpus directly, and no multi-tenancy (the stdio path is pinned to the single local team). Prefer HTTP unless you specifically need to run without a daemon.
150
+
151
+ Re-running `nlm connect` on an install that predates this default rewrites the old stdio block in place, so upgrades carry over rather than silently keeping the per-session shape.
152
+
153
+ ---
154
+
155
+ ## Does it actually help?
156
+
157
+ We measured it instead of asserting it. A pre-registered replay eval took 100 real prompts from a live operator's hook log and replayed each one twice with the same generator: once with the context NLM had injected, once without. A judge from a different model family scored each pair blind, with response order randomized. The pass bar was written down before the run and could not move afterward.
158
+
159
+ <picture>
160
+ <source media="(prefers-color-scheme: dark)" srcset="assets/replay-eval-dark.svg" />
161
+ <source media="(prefers-color-scheme: light)" srcset="assets/replay-eval-light.svg" />
162
+ <img alt="Recall-impact replay eval results: decisive rate 0.840 against a 0.30 bar, win rate 0.881 against a 0.60 bar, harm check 0.119 against a 0.40 maximum. PASS on every pre-registered gate." src="assets/replay-eval-light.svg" width="720" />
163
+ </picture>
164
+
165
+ The injected context changed the judged outcome in 84% of pairs. When it did, the memory-armed answer won 88% of blind judgments, and the judge agreed with itself on 20 of 20 double-judged pairs. The known biases in the setup run against the memory arm, not for it: the replay generator is weaker than a production agent, and both arms saw truncated prompt previews.
166
+
167
+ One corpus and one judge is evidence, not universality. So don't take our number. The harness ships in this repo and runs against your own hook log:
168
+
169
+ ```bash
170
+ npm run eval:recall-impact-replay -- --pilot # 10-pair mechanics check
171
+ npm run eval:recall-impact-replay # full pre-registered run
172
+ ```
173
+
174
+ Full method, gates, and declared limitations: [the run report](reports/replay-eval/2026-07-22-recall-impact.md) and [the pre-registered spec](docs/superpowers/specs/2026-07-21-recall-impact-replay-eval-design.md).
142
175
 
143
176
  ---
144
177
 
@@ -199,6 +232,10 @@ NLM aggregates signals into failure modes per `(repo, model)` pair. A mode surfa
199
232
  GET /api/signals/failure-modes?repo=<repo>&model=<model>
200
233
  ```
201
234
 
235
+ ### Outcome rollup
236
+
237
+ Signals also feed a corpus-internal outcome verdict per session, derived from later independent evidence only: a reported signal, supersession, a continuation edge, or nothing yet (`unobserved`, shown honestly). Never the agent's own opinion of its work, and never an LLM's grade of it. `get_session` returns the verdict with its evidence; `nlm digest` reports 30-day coverage. The design is deliberately conservative: a session with no downstream evidence stays `unobserved` instead of guessing.
238
+
202
239
  ### Inspection
203
240
 
204
241
  ```sh
@@ -233,7 +270,7 @@ Off by default — enable with `NLM_CODE_EXEMPLARS_ENABLED=1`. Capture rides the
233
270
  | Tool | What it does |
234
271
  |---|---|
235
272
  | `recall_sessions` | Hybrid keyword+semantic search across the full session corpus. Returns label, started_at, snippet, match score, `status`, and `superseded_by`. Superseded sessions are included (down-ranked, badged) so a decision investigation sees overturned reasoning; prefer the `superseded_by` successor for current state. |
236
- | `get_session` | Full body of one session by ID. Includes enriched `supersedes` / `supersededBy` links (id + label + summary) so chasing corrected facts doesn't need a second round-trip. |
273
+ | `get_session` | Full body of one session by ID. Includes enriched `supersedes` / `supersededBy` links (id + label + summary) and a derived `outcome` verdict (held / overturned / built-upon / unobserved, with evidence) from the corpus-internal outcome rollup. |
237
274
  | `recall_facts` | Search structured facts: decisions, open questions, project state. Filterable by entity and kind. |
238
275
  | `get_fact_history` | Full version history of one fact — how a decision evolved over time. |
239
276
  | `cite_session` | Mark a session as explicitly referenced. Drives the `useful_hit_rate` metric and the future learned reranker. |
@@ -241,6 +278,7 @@ Off by default — enable with `NLM_CODE_EXEMPLARS_ENABLED=1`. Capture rides the
241
278
  **When to call `cite_session`:** Call it when a surfaced session actually changes what you say — you referenced it explicitly, it corrected a decision, or you called `get_session` to read the full body. Do not call it for sessions you scanned and discarded. The Stop hook auto-detects citation when a session ID appears verbatim in your response; `cite_session` covers the deliberate case where the session influenced your reasoning without being quoted directly. Both paths feed the same signal loop.
242
279
 
243
280
  | `mark_superseded` | Retroactively retire a stale session and point it at the newer one that replaces it. The editable-timeline write path — see [docs/supersedence.md](docs/supersedence.md). |
281
+ | `report_outcome` | Write an outcome signal (pass / fail / fix / exhausted) for a session or correlation key. The contract surface for deterministic producers: CI, quality gates, automation platforms. Agents rarely self-report; wire your pipelines to this, not your prompts. |
244
282
  | `recall_code` | Semantic search over captured code exemplars — "code that passed/failed a gate like this task." Returns positives plus labeled negatives. Registered only when `NLM_CODE_EXEMPLARS_ENABLED=1`. |
245
283
 
246
284
  ---
@@ -251,7 +289,7 @@ Daemon binds `127.0.0.1:3940` (override with `NLM_PORT`). Selected endpoints:
251
289
 
252
290
  | Method | Path | Auth | Purpose |
253
291
  |---|---|---|---|
254
- | GET | `/api/health` | Host-only | Liveness probe; returns `{version, status, service}` |
292
+ | GET | `/api/health` | Host-only | Liveness probe: version, warmup + embedding-lane state, corpus stats, `update: {current, latest, behind}` from the daily npm check, and `job: {name, state, processed, total, startedAt, lastAdvanceAt, restarts, restartsTotal} \| null` — the daemon-supervised `reprocess` run (null when idle: never started, or the daemon just restarted, since the supervisor holds no state across restarts). `restarts` is the restarts-without-progress counter (resets on any advance); `restartsTotal` is the run's lifetime respawn count, never reset — it's the one to watch for OOM churn on a run that keeps making progress between crashes. |
255
293
  | GET | `/api/recall` | Bearer/Origin | Hybrid recall — `?q=`, `?mode=keyword\|semantic\|hybrid`, `?limit=`, `?include_superseded=true` (default off; opt-in to surface overturned sessions down-ranked, badged with `superseded_by`). Each result carries `status` + `superseded_by`. |
256
294
  | GET | `/api/recall/stats` | Bearer/Origin | 7-day stats: total, hit_rate, useful_hit_rate, top queries |
257
295
  | GET | `/api/recall/recent` | Bearer/Origin | Last N recall events for live tail/telemetry |
@@ -265,9 +303,11 @@ Daemon binds `127.0.0.1:3940` (override with `NLM_PORT`). Selected endpoints:
265
303
  | POST | `/api/data/restore` | Bearer/Origin | Stage a snapshot for apply-on-restart |
266
304
  | POST | `/api/citation/explicit` | Bearer/Origin | Log an explicit session citation (the route backing the `cite_session` MCP tool; payload `{id, conversation_id?, reason?}`) |
267
305
  | POST | `/api/hook/pre-compact` | Bearer/Origin | Hook endpoint; flushes the surfaced-IDs memo |
268
- | ALL | `/mcp` | Bearer required | Streamable-HTTP MCP transport for container agents |
306
+ | ALL | `/mcp` | Bearer required | Streamable-HTTP MCP transport — the default for every runtime; stateless, team resolved from the token |
269
307
  | GET | `/api/recall-code` | Bearer/Origin | Semantic code-exemplar search — `?q=`, `?repo=`, `?lang=`, `?k=`, `?negatives=0`. Requires `NLM_CODE_EXEMPLARS_ENABLED=1`. |
270
308
  | POST | `/api/exemplar` | Bearer/Origin | Direct code-exemplar push (capture also happens automatically from code-bearing signals). Requires the flag. |
309
+ | POST | `/api/jobs/reprocess` | Bearer/Origin | Start a daemon-supervised `reprocess` run (body: optional `{args: string[]}`, forwarded verbatim as CLI flags). 202 + snapshot on start, 409 + snapshot if one's already active. Backs `nlm reprocess --daemon`. |
310
+ | DELETE | `/api/jobs/reprocess` | Bearer/Origin | Stop the active supervised run (no-op if idle/already terminal). 200 + snapshot. |
271
311
 
272
312
  `/api/*` is gated by three layers: 127.0.0.1 Host check (defeats DNS rebinding), Origin check when the browser sends one (defeats cross-origin drive-by), Bearer fallback when Origin is absent (server-to-server clients).
273
313
 
@@ -282,7 +322,7 @@ nlm digest # print to stdout
282
322
  nlm digest --telegram # post to Telegram (TELEGRAM_BOT_TOKEN + TELEGRAM_CHAT_ID)
283
323
  ```
284
324
 
285
- Reports 24h real-traffic (probes filtered), 7d hit_rate + useful_hit_rate, top 5 queries, and a **`WARN hook silent`** alert when Claude Code ran yesterday but no live hook fires were logged. That alert is the canary for post-install drift — node upgrades, `settings.json` hand-edits, and `dist/` moves silently break the hook while Claude Code keeps working. Setup-time smoke tests can't catch this; only the daily correlation can.
325
+ Reports 24h real-traffic (probes filtered), 7d hit_rate + useful_hit_rate, honest cited-precision, top 5 queries, a tier-B outcome coverage line (held / overturned / built-upon / unobserved over the last 30 days), a `Jobs:` line for the daemon-supervised `reprocess` run (active progress, appending `, N restarts` when the run has OOM-churned at least once, a completed/exhausted/stopped outcome, or "no active job"), and a **`WARN hook silent`** alert when Claude Code ran yesterday but no live hook fires were logged. That alert is the canary for post-install drift — node upgrades, `settings.json` hand-edits, and `dist/` moves silently break the hook while Claude Code keeps working. Setup-time smoke tests can't catch this; only the daily correlation can.
286
326
 
287
327
  Wire to cron for a morning push:
288
328
 
@@ -324,6 +364,7 @@ ingest: runtime transcript (jsonl/sqlite)
324
364
  recall: prompt / query
325
365
  -> tokenize + match scoring (label x3, entity-exact x4, decision x2, summary x1, phrase-bonus +5)
326
366
  -> hybrid: BM25-style keyword + vector cosine, fused by score
367
+ -> recency decay (180-day half-life, floored) x supersedence down-rank
327
368
  -> select-top-N gate (per-fire cap 3, per-conversation cap 10)
328
369
  -> pointer block prepended to model context (hooks) or returned as tool result (MCP)
329
370
  ```
@@ -368,6 +409,14 @@ recall: prompt / query
368
409
  | `NLM_HOOK_FACT_MIN_CORROBORATION` | `2` | Minimum number of sessions that must have asserted a fact before it qualifies for hook injection. Set to `1` to include single-source facts. |
369
410
  | `NLM_HOOK_FACT_MIN_CONFIDENCE` | `0.7` | Minimum classifier confidence for a fact to qualify for hook injection. |
370
411
  | `TELEGRAM_BOT_TOKEN` / `TELEGRAM_CHAT_ID` | — | Required for `nlm digest --telegram` |
412
+ | `NLM_ALERT_WEBHOOK` | — | Set to a URL to enable daemon self-reporting: version-drift and embedder-cold transitions POST a CloudEvents-shaped payload here. Unset means zero network calls. |
413
+ | `NLM_ALERT_WEBHOOK_TOKEN` | — | Optional bearer token sent as `Authorization: Bearer <token>` on every `NLM_ALERT_WEBHOOK` POST. Only used when the webhook is set. |
414
+ | `NLM_JOB_STALL_MINUTES` | `20` | Minutes a daemon-supervised `reprocess` run (see `POST /api/jobs/reprocess`) can go without a progress advance before the supervisor calls it stalled and fires `nlm.job.stalled` via `NLM_ALERT_WEBHOOK`. The same event type also fires with `reason: "exhausted"` (restart budget used up) and `reason: "spawn_failed"` (the child process itself never launched — EMFILE/ENOMEM/bad binary). |
415
+ | `NLM_WIKI_DIR` | — (opt-in, off by default) | The wiki projection is off unless this is set. When set, every `NLM_WIKI_INTERVAL_HOURS` the SQLite-backend daemon rolls up fact subjects that cleared the page threshold into a markdown tree at `<dir>/Memory`, reconciled against the previous run so an unchanged page writes zero bytes. Unset means no timer, no directory, no log line — an upgrade never surprises you with new files under your home directory. A failed run leaves the previous tree untouched and fires `nlm.wiki.projection_failed` via `NLM_ALERT_WEBHOOK`; a run whose written page count doesn't match what the corpus currently qualifies for fires `nlm.wiki.coverage_drift`. Postgres backend: not implemented, daemon never starts it. |
416
+ | `NLM_WIKI_INTERVAL_HOURS` | `6` | How often the wiki projection re-runs once `NLM_WIKI_DIR` is set. |
417
+ | `NLM_WIKI_MIN_FACTS` | `3` | Minimum current (non-superseded, non-retired) fact count a subject needs to earn a wiki page. |
418
+ | `NLM_WIKI_MIN_SESSIONS` | `3` | Minimum distinct contributing sessions a subject needs to earn a wiki page. |
419
+ | `NLM_WIKI_LINK_BASE` | `http://127.0.0.1:<NLM_PORT>` | Base URL a wiki page's session links point at. Override when the vault is synced somewhere the daemon's own loopback address won't resolve. |
371
420
 
372
421
  ### Changing the classifier from the UI
373
422
 
@@ -492,8 +541,9 @@ npm install
492
541
  npm run build # compile dist/ — commit the result, it ships in the repo
493
542
  npm run dev # hot-reload daemon
494
543
  npm run ui:dev # hot-reload UI at localhost:5173 (proxies /api to :3940)
495
- npm test # 1,700+ tests across 245 files
544
+ npm test # 2,000+ tests across 240 files
496
545
  npm run typecheck
546
+ npm run verify:codex-release # verify Codex plugin and shared MCP entrypoint
497
547
  node dist/cli/nlm.js doctor # pre-publish: verify DB invariants (exit 1 on violations)
498
548
  ```
499
549
 
@@ -501,6 +551,11 @@ Architecture: hexagonal. `src/core/` knows about ports (interfaces), not adapter
501
551
 
502
552
  `dist/` is built on install via the `prepare` script (runs automatically on `npm install` from git or registry) and packed into the published tarball via the `files` field. Not tracked in git.
503
553
 
554
+ Releases run `verify:codex-release -- --check-packed` after the distributable
555
+ build and before publishing. It checks the Codex plugin manifest, lifecycle
556
+ hook attribution, the `nlm mcp` shared MCP entrypoint, and the files npm will
557
+ actually ship.
558
+
504
559
  ---
505
560
 
506
561
  ## License
@@ -0,0 +1,26 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="720" height="264" viewBox="0 0 720 264" font-family="-apple-system,Segoe UI,Helvetica,Arial,sans-serif">
2
+ <text x="16" y="28" font-size="15" font-weight="600" fill="#e6edf3">Recall-impact replay eval, pre-registered (n=100, blind judge)</text>
3
+ <text x="16" y="72" font-size="13" font-weight="600" fill="#e6edf3">Decisive rate</text>
4
+ <text x="16" y="88" font-size="11" fill="#9198a1">injection changed the outcome</text>
5
+ <rect x="240" y="62" width="380" height="20" rx="4" fill="#3d444d" opacity="0.35"/>
6
+ <rect x="240" y="62" width="319" height="20" rx="4" fill="#5E97D6"/>
7
+ <line x1="354" y1="56" x2="354" y2="88" stroke="#9198a1" stroke-width="2" stroke-dasharray="3,3"/>
8
+ <text x="360" y="54" font-size="10" fill="#9198a1">bar: at least 0.30</text>
9
+ <text x="569" y="76" font-size="13" font-weight="700" fill="#e6edf3">0.840</text>
10
+ <text x="16" y="130" font-size="13" font-weight="600" fill="#e6edf3">Win rate</text>
11
+ <text x="16" y="146" font-size="11" fill="#9198a1">memory arm won, decisive pairs</text>
12
+ <rect x="240" y="120" width="380" height="20" rx="4" fill="#3d444d" opacity="0.35"/>
13
+ <rect x="240" y="120" width="335" height="20" rx="4" fill="#5E97D6"/>
14
+ <line x1="468" y1="114" x2="468" y2="146" stroke="#9198a1" stroke-width="2" stroke-dasharray="3,3"/>
15
+ <text x="474" y="112" font-size="10" fill="#9198a1">bar: at least 0.60</text>
16
+ <text x="585" y="134" font-size="13" font-weight="700" fill="#e6edf3">0.881</text>
17
+ <text x="16" y="188" font-size="13" font-weight="600" fill="#e6edf3">Harm check</text>
18
+ <text x="16" y="204" font-size="11" fill="#9198a1">baseline arm won</text>
19
+ <rect x="240" y="178" width="380" height="20" rx="4" fill="#3d444d" opacity="0.35"/>
20
+ <rect x="240" y="178" width="45" height="20" rx="4" fill="#5E97D6"/>
21
+ <line x1="392" y1="172" x2="392" y2="204" stroke="#9198a1" stroke-width="2" stroke-dasharray="3,3"/>
22
+ <text x="398" y="170" font-size="10" fill="#9198a1">bar: at most 0.40</text>
23
+ <text x="295" y="192" font-size="13" font-weight="700" fill="#e6edf3">0.119</text>
24
+ <text x="16" y="236" font-size="10" fill="#9198a1">Verdict: PASS on every pre-registered gate. Judge agreement 20/20 on the double-judged subsample.</text>
25
+ <text x="16" y="252" font-size="10" fill="#9198a1">Method and limitations: reports/replay-eval/2026-07-22-recall-impact.md</text>
26
+ </svg>
@@ -0,0 +1,26 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="720" height="264" viewBox="0 0 720 264" font-family="-apple-system,Segoe UI,Helvetica,Arial,sans-serif">
2
+ <text x="16" y="28" font-size="15" font-weight="600" fill="#1f2328">Recall-impact replay eval, pre-registered (n=100, blind judge)</text>
3
+ <text x="16" y="72" font-size="13" font-weight="600" fill="#1f2328">Decisive rate</text>
4
+ <text x="16" y="88" font-size="11" fill="#59636e">injection changed the outcome</text>
5
+ <rect x="240" y="62" width="380" height="20" rx="4" fill="#d0d7de" opacity="0.35"/>
6
+ <rect x="240" y="62" width="319" height="20" rx="4" fill="#3B6EA5"/>
7
+ <line x1="354" y1="56" x2="354" y2="88" stroke="#59636e" stroke-width="2" stroke-dasharray="3,3"/>
8
+ <text x="360" y="54" font-size="10" fill="#59636e">bar: at least 0.30</text>
9
+ <text x="569" y="76" font-size="13" font-weight="700" fill="#1f2328">0.840</text>
10
+ <text x="16" y="130" font-size="13" font-weight="600" fill="#1f2328">Win rate</text>
11
+ <text x="16" y="146" font-size="11" fill="#59636e">memory arm won, decisive pairs</text>
12
+ <rect x="240" y="120" width="380" height="20" rx="4" fill="#d0d7de" opacity="0.35"/>
13
+ <rect x="240" y="120" width="335" height="20" rx="4" fill="#3B6EA5"/>
14
+ <line x1="468" y1="114" x2="468" y2="146" stroke="#59636e" stroke-width="2" stroke-dasharray="3,3"/>
15
+ <text x="474" y="112" font-size="10" fill="#59636e">bar: at least 0.60</text>
16
+ <text x="585" y="134" font-size="13" font-weight="700" fill="#1f2328">0.881</text>
17
+ <text x="16" y="188" font-size="13" font-weight="600" fill="#1f2328">Harm check</text>
18
+ <text x="16" y="204" font-size="11" fill="#59636e">baseline arm won</text>
19
+ <rect x="240" y="178" width="380" height="20" rx="4" fill="#d0d7de" opacity="0.35"/>
20
+ <rect x="240" y="178" width="45" height="20" rx="4" fill="#3B6EA5"/>
21
+ <line x1="392" y1="172" x2="392" y2="204" stroke="#59636e" stroke-width="2" stroke-dasharray="3,3"/>
22
+ <text x="398" y="170" font-size="10" fill="#59636e">bar: at most 0.40</text>
23
+ <text x="295" y="192" font-size="13" font-weight="700" fill="#1f2328">0.119</text>
24
+ <text x="16" y="236" font-size="10" fill="#59636e">Verdict: PASS on every pre-registered gate. Judge agreement 20/20 on the double-judged subsample.</text>
25
+ <text x="16" y="252" font-size="10" fill="#59636e">Method and limitations: reports/replay-eval/2026-07-22-recall-impact.md</text>
26
+ </svg>
@@ -17,9 +17,12 @@ import { readHookRecallLog } from "../core/recall/hook-recall-log.js";
17
17
  import { readCitationLog } from "../core/recall/citation-log.js";
18
18
  import { checkHookLiveness } from "../core/digest/hook-liveness.js";
19
19
  import { checkHookInjection } from "../core/digest/hook-injection.js";
20
+ import { checkHookVersionParity } from "../core/digest/hook-version-parity.js";
21
+ import { NLM_VERSION } from "../shared/version.js";
20
22
  import { hookAuthHeaders } from "../hook/hook-auth.js";
21
23
  import { computeOutcomeCoverage } from "../core/outcome/coverage.js";
22
24
  import { loadOutcomeCoverageInput } from "../core/storage/sqlite-outcome-store.js";
25
+ import { DEFAULT_TEAM_ID } from "../core/tenancy/default-team.js";
23
26
  /** Sessions ended in the last N days count toward the Tier-B coverage block. */
24
27
  const OUTCOME_COVERAGE_WINDOW_DAYS = 30;
25
28
  function defaultDbPath() {
@@ -37,8 +40,8 @@ async function loadOutcomeCoverage() {
37
40
  const db = new Database(dbPath, { readonly: true });
38
41
  try {
39
42
  const sinceIso = new Date(Date.now() - OUTCOME_COVERAGE_WINDOW_DAYS * 24 * 60 * 60 * 1000).toISOString();
40
- const input = await loadOutcomeCoverageInput(db, { sinceIso });
41
- return await computeOutcomeCoverage(input);
43
+ const input = await loadOutcomeCoverageInput(db, DEFAULT_TEAM_ID, { sinceIso });
44
+ return await computeOutcomeCoverage(DEFAULT_TEAM_ID, input);
42
45
  }
43
46
  finally {
44
47
  db.close();
@@ -54,7 +57,13 @@ export async function runDigest(opts) {
54
57
  try {
55
58
  const [statsRes, recentRes, datasetRes] = await Promise.all([
56
59
  fetchJson(`${base}/api/recall/stats`, timeoutMs),
57
- fetchJson(`${base}/api/recall/recent?limit=200`, timeoutMs),
60
+ // The composer strips probe traffic AFTER this fetch, so the limit has to
61
+ // cover a full day of RAW entries, probes included. At limit=200 a host
62
+ // emitting ~800 probes/day filled the whole window with probes: the 200
63
+ // most recent rows spanned 7h, every one a probe, and the digest reported
64
+ // "0 queries yesterday (none)" on a day with 27 real pull queries
65
+ // (observed 2026-08-13). Sized for a noisy day, not a quiet one.
66
+ fetchJson(`${base}/api/recall/recent?limit=5000`, timeoutMs),
58
67
  fetchJson(`${base}/api/dataset`, timeoutMs * 2),
59
68
  ]);
60
69
  stats = statsRes;
@@ -83,15 +92,21 @@ export async function runDigest(opts) {
83
92
  hookLogPath,
84
93
  hookLogExists,
85
94
  });
86
- const injectionResult = checkHookInjection(hookLog);
87
- const hookAlert = [livenessAlert, injectionResult.message].filter(Boolean).join("\n") || null;
95
+ // "off"/"0"/"false" all disable ambient injection; unset means enabled.
96
+ const promptRecall = (process.env["NLM_HOOK_PROMPT_RECALL"] ?? "").trim().toLowerCase();
97
+ const ambientRecallEnabled = !["off", "0", "false", "no"].includes(promptRecall);
98
+ const injectionResult = checkHookInjection(hookLog, undefined, ambientRecallEnabled);
99
+ // Liveness proves hooks fired; parity proves the CURRENT hooks fired. The
100
+ // second is what catches an install still pointing at a stale dist/.
101
+ const versionAlert = checkHookVersionParity(hookLog, NLM_VERSION);
102
+ const hookAlert = [livenessAlert, injectionResult.message, versionAlert].filter(Boolean).join("\n") || null;
88
103
  // True cited-precision over the 7-day window (the honest "was recall useful"
89
104
  // metric). Best-effort: a log-read failure must not break the digest.
90
105
  let precision = null;
91
106
  try {
92
107
  const [recallEntries, citationEntries] = await Promise.all([
93
- readHookRecallLog(7),
94
- readCitationLog(7),
108
+ readHookRecallLog(DEFAULT_TEAM_ID, 7),
109
+ readCitationLog(DEFAULT_TEAM_ID, 7),
95
110
  ]);
96
111
  const result = computePrecision(recallEntries, citationEntries);
97
112
  precision = {
@@ -109,6 +124,17 @@ export async function runDigest(opts) {
109
124
  catch {
110
125
  outcomeCoverage = null;
111
126
  }
127
+ // Best-effort: a health-fetch failure must not break the rest of the
128
+ // digest — it just falls back to the same "no active job" line an idle
129
+ // supervisor would report.
130
+ let job = null;
131
+ try {
132
+ const healthRes = await fetchJson(`${base}/api/health`, timeoutMs);
133
+ job = healthRes.job ?? null;
134
+ }
135
+ catch {
136
+ job = null;
137
+ }
112
138
  const text = composeDigest({
113
139
  stats,
114
140
  recent,
@@ -116,6 +142,7 @@ export async function runDigest(opts) {
116
142
  hookAlert,
117
143
  precision,
118
144
  outcomeCoverage,
145
+ job,
119
146
  });
120
147
  if (opts.telegram) {
121
148
  await postTelegram(text);
@@ -1 +1 @@
1
- {"version":3,"file":"digest.js","sourceRoot":"","sources":["../../src/cli/digest.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"digest.js","sourceRoot":"","sources":["../../src/cli/digest.ts"],"names":[],"mappings":"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"}
package/dist/cli/nlm.d.ts CHANGED
@@ -22,10 +22,24 @@
22
22
  * nlm disconnect claude-code — remove MCP block from ~/.mcp.json
23
23
  * nlm disconnect codex — remove Codex plugin
24
24
  * nlm digest — print a daily-activity digest (or --telegram to post)
25
+ * nlm reconcile-facts — retire live facts contradicting an authorities file
25
26
  * nlm init - print (or write) the agent recall contract snippet
26
27
  */
28
+ import { computeReDerivationRate, sqliteReDerivationDeps } from "../core/metrics/re-derivation.js";
27
29
  export declare function resolveDigestDate(date: string | undefined): string;
28
30
  export declare function shouldAppendTrend(lastLineTs: string | null, now: number): boolean;
31
+ /**
32
+ * Recomputes `computeReDerivationRate` and overwrites the pairs cache file
33
+ * (#405) that `@core/storage/sqlite-outcome-store.js` reads instead of
34
+ * recomputing the same O(n^2) scan inline. Called every 24h corpus-monitor
35
+ * cycle (not gated by `shouldAppendTrend`, which only paces the separate
36
+ * append-only trend log) so the cache stays ~24h fresh while the monitor
37
+ * runs. Exported for direct testing and smoke runs against a corpus copy.
38
+ * `tenantId` scopes both the session scan (sqliteReDerivationDeps) and the
39
+ * cache file this write targets — two tenants must never compute or read
40
+ * each other's pairs.
41
+ */
42
+ export declare function persistReDerivationPairs(rawDb: Parameters<typeof sqliteReDerivationDeps>[0], tenantId: string, pairsPath: string, windowDays: number): Promise<Awaited<ReturnType<typeof computeReDerivationRate>>>;
29
43
  export interface ClassifierEvalDeps {
30
44
  readonly classify: (transcript: string) => Promise<import("../ports/llm-client.js").ClassifyResult>;
31
45
  readonly provider: string;