hippo-memory 1.70.0 → 1.71.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (629) hide show
  1. package/README.md +1 -1
  2. package/dist/agent-memories/claude-code.d.ts +4 -2
  3. package/dist/agent-memories/claude-code.js +14 -5
  4. package/dist/agent-memories/files.js +23 -12
  5. package/dist/agent-memories/markdown.d.ts +1 -3
  6. package/dist/agent-memories/markdown.js +1 -3
  7. package/dist/agent-memories/report.js +2 -1
  8. package/dist/agent-memories/sync.d.ts +4 -2
  9. package/dist/agent-memories/sync.js +10 -5
  10. package/dist/api/assemble.d.ts +7 -44
  11. package/dist/api/assemble.js +2 -22
  12. package/dist/api/audit.d.ts +5 -1
  13. package/dist/api/audit.js +9 -1
  14. package/dist/api/auth.d.ts +13 -22
  15. package/dist/api/auth.js +34 -24
  16. package/dist/api/auto-sleep.js +2 -2
  17. package/dist/api/availability.d.ts +2 -15
  18. package/dist/api/availability.js +2 -15
  19. package/dist/api/context-select.js +3 -4
  20. package/dist/api/context-types.d.ts +10 -35
  21. package/dist/api/context.d.ts +5 -22
  22. package/dist/api/context.js +21 -38
  23. package/dist/api/dormant.d.ts +5 -21
  24. package/dist/api/dormant.js +7 -26
  25. package/dist/api/drill-down.d.ts +7 -46
  26. package/dist/api/drill-down.js +5 -26
  27. package/dist/api/forget.d.ts +5 -24
  28. package/dist/api/forget.js +5 -28
  29. package/dist/api/graph.d.ts +8 -0
  30. package/dist/api/graph.js +7 -0
  31. package/dist/api/index.d.ts +2 -0
  32. package/dist/api/index.js +2 -0
  33. package/dist/api/instruction-detect.js +16 -5
  34. package/dist/api/ledger-db.d.ts +2 -1
  35. package/dist/api/ledger-db.js +5 -3
  36. package/dist/api/memories.d.ts +5 -0
  37. package/dist/api/memories.js +7 -0
  38. package/dist/api/objects.d.ts +9 -0
  39. package/dist/api/objects.js +11 -0
  40. package/dist/api/on-store.js +5 -3
  41. package/dist/api/predictions.d.ts +9 -0
  42. package/dist/api/predictions.js +18 -0
  43. package/dist/api/promote.d.ts +13 -17
  44. package/dist/api/promote.js +11 -19
  45. package/dist/api/prompt-hook.d.ts +4 -4
  46. package/dist/api/prompt-hook.js +10 -9
  47. package/dist/api/recall-cli.d.ts +55 -0
  48. package/dist/api/recall-cli.js +94 -0
  49. package/dist/api/recall-core.js +14 -6
  50. package/dist/api/recall-finish.d.ts +53 -0
  51. package/dist/api/recall-finish.js +30 -0
  52. package/dist/api/recall-history.d.ts +17 -84
  53. package/dist/api/recall-history.js +15 -88
  54. package/dist/api/recall-pipeline.d.ts +2 -3
  55. package/dist/api/recall-pipeline.js +16 -9
  56. package/dist/api/recall-types.d.ts +64 -304
  57. package/dist/api/recall.d.ts +5 -33
  58. package/dist/api/recall.js +59 -60
  59. package/dist/api/refine.d.ts +7 -0
  60. package/dist/api/refine.js +10 -0
  61. package/dist/api/remember-local.d.ts +57 -0
  62. package/dist/api/remember-local.js +90 -0
  63. package/dist/api/remember.d.ts +18 -1
  64. package/dist/api/remember.js +13 -1
  65. package/dist/api/sleep-run.d.ts +1 -3
  66. package/dist/api/sleep-run.js +17 -21
  67. package/dist/api/sleep.d.ts +9 -28
  68. package/dist/api/tokens.d.ts +3 -10
  69. package/dist/api/tokens.js +3 -10
  70. package/dist/api/types.d.ts +6 -29
  71. package/dist/api/types.js +4 -22
  72. package/dist/capture/command.d.ts +4 -12
  73. package/dist/capture/command.js +6 -22
  74. package/dist/capture/compact.d.ts +4 -15
  75. package/dist/capture/compact.js +16 -25
  76. package/dist/capture/compaction-record.js +101 -69
  77. package/dist/capture/compaction-spool.d.ts +1 -1
  78. package/dist/capture/compaction-spool.js +1 -1
  79. package/dist/capture/session-digest.d.ts +1 -1
  80. package/dist/capture/session-digest.js +13 -7
  81. package/dist/capture/transcript.d.ts +2 -10
  82. package/dist/capture/transcript.js +4 -18
  83. package/dist/cli/api-context.d.ts +3 -0
  84. package/dist/cli/api-context.js +6 -0
  85. package/dist/cli/audit-prune.d.ts +6 -39
  86. package/dist/cli/audit-prune.js +6 -39
  87. package/dist/cli/audit.d.ts +1 -1
  88. package/dist/cli/audit.js +33 -34
  89. package/dist/cli/auth.d.ts +2 -2
  90. package/dist/cli/auth.js +57 -39
  91. package/dist/cli/briefs.d.ts +4 -4
  92. package/dist/cli/briefs.js +18 -22
  93. package/dist/cli/card.d.ts +2 -2
  94. package/dist/cli/card.js +31 -32
  95. package/dist/cli/client.d.ts +7 -27
  96. package/dist/cli/client.js +24 -43
  97. package/dist/cli/compact-resume-payload.js +3 -2
  98. package/dist/cli/context.d.ts +1 -2
  99. package/dist/cli/context.js +12 -8
  100. package/dist/cli/continuity.d.ts +6 -6
  101. package/dist/cli/continuity.js +62 -64
  102. package/dist/cli/correction-latency.d.ts +2 -14
  103. package/dist/cli/correction-latency.js +2 -14
  104. package/dist/cli/curate.d.ts +13 -17
  105. package/dist/cli/curate.js +68 -92
  106. package/dist/cli/dag.d.ts +4 -4
  107. package/dist/cli/dag.js +33 -27
  108. package/dist/cli/decisions.d.ts +4 -4
  109. package/dist/cli/decisions.js +33 -47
  110. package/dist/cli/eval.js +15 -13
  111. package/dist/cli/exit.d.ts +6 -0
  112. package/dist/cli/exit.js +11 -0
  113. package/dist/cli/explain.d.ts +1 -2
  114. package/dist/cli/explain.js +6 -4
  115. package/dist/cli/flag-values.d.ts +6 -1
  116. package/dist/cli/flag-values.js +27 -10
  117. package/dist/cli/flags.d.ts +1 -0
  118. package/dist/cli/flags.js +1 -1
  119. package/dist/cli/github.d.ts +14 -0
  120. package/dist/{connectors/github/cli-impl.js → cli/github.js} +43 -71
  121. package/dist/cli/goals.d.ts +2 -2
  122. package/dist/cli/goals.js +46 -50
  123. package/dist/cli/hook-runtime.d.ts +9 -27
  124. package/dist/cli/hook-runtime.js +15 -31
  125. package/dist/cli/init.d.ts +2 -2
  126. package/dist/cli/init.js +6 -12
  127. package/dist/cli/install-steps.js +3 -12
  128. package/dist/cli/last-sleep.d.ts +2 -1
  129. package/dist/cli/last-sleep.js +3 -0
  130. package/dist/cli/maintenance.d.ts +4 -4
  131. package/dist/cli/maintenance.js +14 -19
  132. package/dist/cli/object-verbs.js +4 -3
  133. package/dist/cli/owner-validation.d.ts +5 -28
  134. package/dist/cli/owner-validation.js +5 -28
  135. package/dist/cli/playbooks.d.ts +4 -4
  136. package/dist/cli/playbooks.js +23 -28
  137. package/dist/cli/print.d.ts +2 -5
  138. package/dist/cli/print.js +1 -4
  139. package/dist/cli/projects.d.ts +2 -2
  140. package/dist/cli/projects.js +1 -3
  141. package/dist/cli/provenance-coverage.d.ts +2 -6
  142. package/dist/cli/provenance-coverage.js +2 -6
  143. package/dist/cli/quality-repair-once.js +2 -2
  144. package/dist/cli/recall.d.ts +2 -4
  145. package/dist/cli/recall.js +55 -131
  146. package/dist/cli/refine-llm.d.ts +5 -31
  147. package/dist/cli/refine-llm.js +9 -36
  148. package/dist/cli/remember.d.ts +3 -3
  149. package/dist/cli/remember.js +122 -180
  150. package/dist/cli/scheduler.d.ts +2 -17
  151. package/dist/cli/scheduler.js +12 -18
  152. package/dist/cli/serve.js +21 -12
  153. package/dist/cli/session-hooks.d.ts +10 -18
  154. package/dist/cli/session-hooks.js +112 -113
  155. package/dist/cli/setup.d.ts +4 -4
  156. package/dist/cli/setup.js +19 -21
  157. package/dist/cli/shared.d.ts +9 -23
  158. package/dist/cli/shared.js +9 -32
  159. package/dist/cli/slack.d.ts +2 -2
  160. package/dist/cli/slack.js +19 -23
  161. package/dist/cli/sleep.d.ts +3 -2
  162. package/dist/cli/sleep.js +15 -16
  163. package/dist/cli/status.d.ts +9 -12
  164. package/dist/cli/status.js +55 -98
  165. package/dist/cli/stdin.d.ts +4 -6
  166. package/dist/cli/stdin.js +2 -3
  167. package/dist/cli/transfer.d.ts +9 -9
  168. package/dist/cli/transfer.js +66 -89
  169. package/dist/cli/usage.js +11 -5
  170. package/dist/cli.d.ts +66 -448
  171. package/dist/cli.js +87 -263
  172. package/dist/connectors/github/backfill.d.ts +5 -25
  173. package/dist/connectors/github/backfill.js +14 -49
  174. package/dist/connectors/github/deletion.d.ts +4 -18
  175. package/dist/connectors/github/deletion.js +2 -15
  176. package/dist/connectors/github/dlq.d.ts +8 -33
  177. package/dist/connectors/github/dlq.js +12 -29
  178. package/dist/connectors/github/ingest.d.ts +2 -6
  179. package/dist/connectors/github/ingest.js +4 -10
  180. package/dist/connectors/github/octokit-client.d.ts +4 -16
  181. package/dist/connectors/github/octokit-client.js +27 -24
  182. package/dist/connectors/github/ratelimit.d.ts +3 -14
  183. package/dist/connectors/github/ratelimit.js +3 -14
  184. package/dist/connectors/github/scope.d.ts +3 -5
  185. package/dist/connectors/github/scope.js +3 -5
  186. package/dist/connectors/github/signature.d.ts +4 -26
  187. package/dist/connectors/github/signature.js +4 -26
  188. package/dist/connectors/github/tenant-routing.d.ts +2 -24
  189. package/dist/connectors/github/tenant-routing.js +4 -26
  190. package/dist/connectors/github/transform.js +2 -16
  191. package/dist/connectors/github/types.d.ts +3 -15
  192. package/dist/connectors/github/types.js +2 -9
  193. package/dist/connectors/github/webhook.d.ts +2 -16
  194. package/dist/connectors/github/webhook.js +6 -22
  195. package/dist/connectors/slack/backfill.d.ts +4 -17
  196. package/dist/connectors/slack/backfill.js +4 -13
  197. package/dist/connectors/slack/dlq.d.ts +2 -19
  198. package/dist/connectors/slack/dlq.js +2 -19
  199. package/dist/connectors/slack/ingest.d.ts +2 -3
  200. package/dist/connectors/slack/ingest.js +2 -3
  201. package/dist/connectors/slack/scope.d.ts +2 -8
  202. package/dist/connectors/slack/scope.js +2 -8
  203. package/dist/connectors/slack/signature.d.ts +1 -6
  204. package/dist/connectors/slack/tenant-routing.d.ts +2 -19
  205. package/dist/connectors/slack/tenant-routing.js +2 -21
  206. package/dist/connectors/slack/transform.d.ts +2 -18
  207. package/dist/connectors/slack/transform.js +2 -18
  208. package/dist/connectors/slack/types.d.ts +3 -9
  209. package/dist/connectors/slack/types.js +2 -4
  210. package/dist/connectors/slack/web-client.js +33 -27
  211. package/dist/connectors/slack/webhook.d.ts +2 -19
  212. package/dist/connectors/slack/webhook.js +5 -26
  213. package/dist/connectors/slack/workspaces.d.ts +4 -24
  214. package/dist/connectors/slack/workspaces.js +4 -24
  215. package/dist/consolidate/conflicts.js +6 -14
  216. package/dist/consolidate/dag-summary.d.ts +8 -0
  217. package/dist/consolidate/dag-summary.js +41 -0
  218. package/dist/consolidate/dag.d.ts +5 -28
  219. package/dist/consolidate/dag.js +14 -75
  220. package/dist/consolidate/decay.js +7 -19
  221. package/dist/consolidate/dedupe.d.ts +6 -52
  222. package/dist/consolidate/dedupe.js +13 -71
  223. package/dist/consolidate/flush-units.d.ts +3 -4
  224. package/dist/consolidate/flush-units.js +3 -3
  225. package/dist/consolidate/half-life-migration.d.ts +3 -26
  226. package/dist/consolidate/half-life-migration.js +11 -28
  227. package/dist/consolidate/llm-passes.js +4 -21
  228. package/dist/consolidate/memory-value-weights.d.ts +2 -13
  229. package/dist/consolidate/memory-value-weights.js +2 -13
  230. package/dist/consolidate/memory-value.d.ts +11 -84
  231. package/dist/consolidate/memory-value.js +16 -104
  232. package/dist/consolidate/merge.js +10 -31
  233. package/dist/consolidate/merged-row.js +2 -1
  234. package/dist/consolidate/physics-pass.js +1 -3
  235. package/dist/consolidate/replay.d.ts +6 -38
  236. package/dist/consolidate/replay.js +14 -52
  237. package/dist/consolidate/run.js +1 -1
  238. package/dist/consolidate/sleep.d.ts +1 -8
  239. package/dist/consolidate/sleep.js +5 -17
  240. package/dist/consolidate/trace.d.ts +3 -18
  241. package/dist/consolidate/trace.js +3 -18
  242. package/dist/consolidate/traces.js +6 -22
  243. package/dist/core/ablation.d.ts +4 -91
  244. package/dist/core/ablation.js +4 -91
  245. package/dist/core/ambient.d.ts +1 -8
  246. package/dist/core/ambient.js +1 -8
  247. package/dist/core/capture-contract.d.ts +4 -2
  248. package/dist/core/capture-contract.js +4 -2
  249. package/dist/core/card.d.ts +4 -1
  250. package/dist/core/card.js +8 -0
  251. package/dist/core/compare.d.ts +11 -67
  252. package/dist/core/compare.js +9 -63
  253. package/dist/core/config.d.ts +10 -24
  254. package/dist/core/config.js +13 -14
  255. package/dist/core/handoff.d.ts +1 -7
  256. package/dist/core/handoff.js +1 -7
  257. package/dist/core/memory-quality.js +1 -1
  258. package/dist/core/memory.d.ts +41 -164
  259. package/dist/core/memory.js +51 -221
  260. package/dist/core/package-root.d.ts +3 -0
  261. package/dist/core/package-root.js +5 -0
  262. package/dist/core/physics-config.d.ts +1 -4
  263. package/dist/core/physics-config.js +3 -8
  264. package/dist/core/physics.d.ts +15 -61
  265. package/dist/core/physics.js +59 -122
  266. package/dist/core/project-identity.d.ts +17 -58
  267. package/dist/core/project-identity.js +17 -38
  268. package/dist/core/project-remote.js +13 -2
  269. package/dist/core/raw-append-only.d.ts +5 -0
  270. package/dist/core/raw-append-only.js +7 -0
  271. package/dist/core/salience.d.ts +1 -7
  272. package/dist/core/salience.js +1 -7
  273. package/dist/dashboard/dashboard-actions.js +2 -2
  274. package/dist/dashboard/dashboard-snapshot.d.ts +2 -1
  275. package/dist/dashboard/dashboard-snapshot.js +11 -2
  276. package/dist/dashboard/dashboard-types.d.ts +2 -1
  277. package/dist/dashboard/dashboard.d.ts +1 -0
  278. package/dist/dashboard/dashboard.js +50 -4
  279. package/dist/db/busy.d.ts +1 -1
  280. package/dist/db/busy.js +17 -8
  281. package/dist/db/connect.d.ts +1 -0
  282. package/dist/db/connect.js +3 -3
  283. package/dist/db/migrate.js +3 -3
  284. package/dist/db/migrations/types.d.ts +2 -5
  285. package/dist/db/migrations/v14.js +2 -3
  286. package/dist/db/migrations/v15.js +2 -8
  287. package/dist/db/migrations/v16.js +2 -3
  288. package/dist/db/migrations/v17.js +2 -3
  289. package/dist/db/migrations/v19.js +2 -5
  290. package/dist/db/migrations/v20.js +2 -7
  291. package/dist/db/migrations/v22.js +4 -17
  292. package/dist/db/migrations/v23.js +3 -14
  293. package/dist/db/migrations/v24.js +2 -4
  294. package/dist/db/migrations/v25.js +3 -8
  295. package/dist/db/migrations/v26.js +2 -13
  296. package/dist/db/migrations/v27.js +3 -11
  297. package/dist/db/migrations/v28.js +2 -14
  298. package/dist/db/migrations/v29.js +4 -18
  299. package/dist/db/migrations/v30.js +4 -16
  300. package/dist/db/migrations/v31.js +2 -15
  301. package/dist/db/migrations/v32.js +4 -22
  302. package/dist/db/migrations/v33.js +2 -15
  303. package/dist/db/migrations/v34.js +2 -11
  304. package/dist/db/migrations/v35.js +2 -11
  305. package/dist/db/migrations/v36.js +2 -11
  306. package/dist/db/migrations/v37.js +8 -33
  307. package/dist/db/migrations/v38.js +5 -38
  308. package/dist/db/migrations/v39.js +9 -20
  309. package/dist/db/migrations/v40.js +2 -9
  310. package/dist/db/migrations/v41.js +2 -24
  311. package/dist/db/migrations/v43.js +1 -1
  312. package/dist/db/migrations/v44.js +2 -8
  313. package/dist/db/migrations/v45.js +2 -7
  314. package/dist/db/migrations/v47.js +2 -3
  315. package/dist/db/migrations/v51.js +1 -1
  316. package/dist/db/open.d.ts +2 -0
  317. package/dist/db/open.js +17 -1
  318. package/dist/db/physics-state.d.ts +6 -22
  319. package/dist/db/physics-state.js +25 -36
  320. package/dist/db/raw-archive-mirror-cleanup.d.ts +2 -17
  321. package/dist/db/raw-archive-mirror-cleanup.js +2 -17
  322. package/dist/db/vector-store.d.ts +2 -0
  323. package/dist/db/vector-store.js +8 -1
  324. package/dist/doctor.js +74 -19
  325. package/dist/entry/session-text.js +2 -1
  326. package/dist/eval/eval-stats.d.ts +15 -53
  327. package/dist/eval/eval-stats.js +12 -42
  328. package/dist/eval/eval-suite.d.ts +2 -13
  329. package/dist/eval/eval-suite.js +74 -34
  330. package/dist/eval/eval.d.ts +6 -24
  331. package/dist/eval/eval.js +7 -34
  332. package/dist/eval/judgment.d.ts +0 -3
  333. package/dist/eval/judgment.js +19 -11
  334. package/dist/extensions/openclaw-plugin/index.js +1 -1
  335. package/dist/graph/extract.d.ts +5 -27
  336. package/dist/graph/extract.js +7 -33
  337. package/dist/graph/recall.d.ts +7 -20
  338. package/dist/graph/recall.js +14 -76
  339. package/dist/graph/stream.d.ts +7 -39
  340. package/dist/graph/stream.js +11 -34
  341. package/dist/graph/view.d.ts +9 -35
  342. package/dist/graph/view.js +11 -39
  343. package/dist/hooks/codex-wrapper.js +2 -2
  344. package/dist/hooks/copilot.js +2 -1
  345. package/dist/hooks/hook-blocks.d.ts +6 -2
  346. package/dist/hooks/hook-blocks.js +37 -124
  347. package/dist/hooks/json-hooks.d.ts +4 -36
  348. package/dist/hooks/json-hooks.js +18 -57
  349. package/dist/hooks/opencode.d.ts +0 -38
  350. package/dist/hooks/opencode.js +9 -76
  351. package/dist/hooks/shared.d.ts +8 -17
  352. package/dist/hooks/shared.js +29 -20
  353. package/dist/importers/core.d.ts +12 -37
  354. package/dist/importers/core.js +9 -27
  355. package/dist/importers/markdown-parse.d.ts +8 -22
  356. package/dist/importers/markdown-parse.js +8 -25
  357. package/dist/importers/markdown.js +3 -12
  358. package/dist/importers/sources.js +7 -35
  359. package/dist/importers/vault.d.ts +2 -8
  360. package/dist/importers/vault.js +25 -81
  361. package/dist/index.d.ts +6 -2
  362. package/dist/index.js +6 -2
  363. package/dist/learn/autolearn.d.ts +14 -41
  364. package/dist/learn/autolearn.js +14 -41
  365. package/dist/learn/extract.js +2 -4
  366. package/dist/learn/forward-claim-detector.d.ts +6 -30
  367. package/dist/learn/forward-claim-detector.js +14 -66
  368. package/dist/learn/invalidation.d.ts +6 -18
  369. package/dist/learn/invalidation.js +9 -26
  370. package/dist/mcp/admin-tools.js +3 -5
  371. package/dist/mcp/memory-tools.js +4 -9
  372. package/dist/mcp/protocol.d.ts +8 -26
  373. package/dist/mcp/protocol.js +3 -6
  374. package/dist/mcp/recall-tools.js +3 -3
  375. package/dist/mcp/request.d.ts +3 -11
  376. package/dist/mcp/request.js +10 -26
  377. package/dist/mcp/server.d.ts +3 -9
  378. package/dist/mcp/server.js +5 -16
  379. package/dist/mcp/session-state.d.ts +1 -1
  380. package/dist/mcp/session-state.js +5 -11
  381. package/dist/mcp/stdio.d.ts +2 -6
  382. package/dist/mcp/stdio.js +48 -12
  383. package/dist/mcp/tools.js +5 -3
  384. package/dist/objects/customer-notes.d.ts +7 -42
  385. package/dist/objects/customer-notes.js +7 -48
  386. package/dist/objects/decisions.d.ts +12 -50
  387. package/dist/objects/decisions.js +15 -53
  388. package/dist/objects/incidents.d.ts +7 -38
  389. package/dist/objects/incidents.js +7 -41
  390. package/dist/objects/policies.d.ts +11 -89
  391. package/dist/objects/policies.js +11 -98
  392. package/dist/objects/processes.d.ts +7 -52
  393. package/dist/objects/processes.js +7 -61
  394. package/dist/objects/project-briefs.d.ts +11 -55
  395. package/dist/objects/project-briefs.js +14 -75
  396. package/dist/objects/skills.d.ts +7 -42
  397. package/dist/objects/skills.js +8 -54
  398. package/dist/postinstall.js +6 -19
  399. package/dist/predictions/planning-fallacy.d.ts +11 -34
  400. package/dist/rerankers/clef.js +3 -31
  401. package/dist/rerankers/cross-encoder.js +4 -6
  402. package/dist/rerankers/jev.js +9 -6
  403. package/dist/rerankers/llm.d.ts +2 -11
  404. package/dist/rerankers/llm.js +14 -14
  405. package/dist/rerankers/outage-warning.d.ts +2 -1
  406. package/dist/rerankers/outage-warning.js +2 -1
  407. package/dist/rerankers/remote.d.ts +1 -0
  408. package/dist/rerankers/remote.js +2 -0
  409. package/dist/rerankers/types.d.ts +2 -14
  410. package/dist/search/boosts.d.ts +0 -2
  411. package/dist/search/boosts.js +2 -2
  412. package/dist/search/goal-boost.d.ts +23 -0
  413. package/dist/search/goal-boost.js +90 -0
  414. package/dist/search/hybrid.d.ts +2 -0
  415. package/dist/search/multihop.js +2 -3
  416. package/dist/search/path-context.d.ts +5 -18
  417. package/dist/search/path-context.js +5 -18
  418. package/dist/search/physics-search.js +11 -8
  419. package/dist/search/rrf.d.ts +7 -35
  420. package/dist/search/rrf.js +5 -30
  421. package/dist/search/vector.d.ts +7 -0
  422. package/dist/search/vector.js +35 -5
  423. package/dist/server/auth.d.ts +9 -28
  424. package/dist/server/auth.js +32 -25
  425. package/dist/server/boot.d.ts +2 -21
  426. package/dist/server/boot.js +63 -96
  427. package/dist/server/client-ip.d.ts +3 -19
  428. package/dist/server/client-ip.js +5 -28
  429. package/dist/server/defaults.d.ts +3 -0
  430. package/dist/server/defaults.js +4 -0
  431. package/dist/server/key-check-bounds.d.ts +2 -1
  432. package/dist/server/lifecycle.d.ts +5 -4
  433. package/dist/server/lifecycle.js +19 -4
  434. package/dist/server/mcp-http.js +10 -44
  435. package/dist/server/rate-limit.d.ts +5 -18
  436. package/dist/server/rate-limit.js +4 -13
  437. package/dist/server/request.d.ts +4 -8
  438. package/dist/server/request.js +9 -17
  439. package/dist/server/route-table.js +42 -49
  440. package/dist/server/routes/admin.js +22 -28
  441. package/dist/server/routes/customer-notes.js +7 -12
  442. package/dist/server/routes/decisions.js +10 -17
  443. package/dist/server/routes/incidents.js +12 -20
  444. package/dist/server/routes/memories.js +12 -32
  445. package/dist/server/routes/object-routes.d.ts +0 -5
  446. package/dist/server/routes/object-routes.js +7 -15
  447. package/dist/server/routes/policies.js +10 -18
  448. package/dist/server/routes/predictions.js +13 -25
  449. package/dist/server/routes/processes.js +16 -26
  450. package/dist/server/routes/project-briefs.js +9 -16
  451. package/dist/server/routes/recall.js +10 -35
  452. package/dist/server/routes/skills.js +8 -18
  453. package/dist/server/server-detect.d.ts +9 -53
  454. package/dist/server/server-detect.js +24 -90
  455. package/dist/server/sleep-offload.js +4 -1
  456. package/dist/server/types.d.ts +12 -10
  457. package/dist/server/validation.d.ts +3 -1
  458. package/dist/server/validation.js +10 -23
  459. package/dist/server.d.ts +2 -2
  460. package/dist/server.js +3 -2
  461. package/dist/sharing/global-store.d.ts +19 -0
  462. package/dist/sharing/global-store.js +75 -0
  463. package/dist/sharing/global-sync.d.ts +6 -0
  464. package/dist/sharing/global-sync.js +80 -0
  465. package/dist/sharing/project-merge.d.ts +4 -5
  466. package/dist/sharing/project-merge.js +9 -7
  467. package/dist/sharing/scope.d.ts +4 -11
  468. package/dist/sharing/scope.js +4 -11
  469. package/dist/sharing/search-both.d.ts +60 -0
  470. package/dist/sharing/search-both.js +138 -0
  471. package/dist/sharing/share.d.ts +38 -0
  472. package/dist/sharing/share.js +226 -0
  473. package/dist/store/ambient.js +4 -9
  474. package/dist/store/audit-event.d.ts +4 -12
  475. package/dist/store/audit-event.js +4 -12
  476. package/dist/store/audit.d.ts +2 -5
  477. package/dist/store/audit.js +4 -12
  478. package/dist/store/auth.d.ts +6 -6
  479. package/dist/store/auth.js +10 -9
  480. package/dist/store/candidates.d.ts +20 -3
  481. package/dist/store/candidates.js +77 -48
  482. package/dist/store/card-detail.d.ts +2 -1
  483. package/dist/store/card-detail.js +2 -1
  484. package/dist/store/cards.d.ts +14 -9
  485. package/dist/store/cards.js +72 -126
  486. package/dist/store/conflicts.d.ts +4 -21
  487. package/dist/store/conflicts.js +71 -150
  488. package/dist/store/connectors/github.d.ts +10 -10
  489. package/dist/store/connectors/github.js +10 -10
  490. package/dist/store/dashboard-reads.js +4 -8
  491. package/dist/store/delete-and-batch.d.ts +11 -31
  492. package/dist/store/delete-and-batch.js +48 -64
  493. package/dist/store/delivery-recorder.d.ts +8 -4
  494. package/dist/store/delivery-recorder.js +25 -15
  495. package/dist/store/diagnostics.js +6 -13
  496. package/dist/store/dormant.d.ts +7 -29
  497. package/dist/store/dormant.js +15 -56
  498. package/dist/store/embeddings/index.d.ts +11 -80
  499. package/dist/store/embeddings/index.js +71 -207
  500. package/dist/store/embeddings/local.js +15 -32
  501. package/dist/store/embeddings/provider.d.ts +16 -53
  502. package/dist/store/embeddings/provider.js +41 -69
  503. package/dist/store/entry-reads.d.ts +21 -57
  504. package/dist/store/entry-reads.js +65 -126
  505. package/dist/store/entry-row.d.ts +6 -35
  506. package/dist/store/entry-row.js +9 -37
  507. package/dist/store/entry-writes.d.ts +10 -16
  508. package/dist/store/entry-writes.js +17 -35
  509. package/dist/store/goals.d.ts +3 -40
  510. package/dist/store/goals.js +21 -160
  511. package/dist/store/graph-queue.d.ts +6 -22
  512. package/dist/store/graph-queue.js +14 -45
  513. package/dist/store/graph-reads.d.ts +11 -35
  514. package/dist/store/graph-reads.js +20 -58
  515. package/dist/store/graph-rows.d.ts +3 -6
  516. package/dist/store/graph-rows.js +6 -9
  517. package/dist/store/graph-view-rows.d.ts +2 -1
  518. package/dist/store/graph-view-rows.js +2 -1
  519. package/dist/store/graph-writes.d.ts +6 -31
  520. package/dist/store/graph-writes.js +13 -37
  521. package/dist/store/half-life.d.ts +2 -1
  522. package/dist/store/half-life.js +14 -16
  523. package/dist/store/handoffs.d.ts +5 -11
  524. package/dist/store/handoffs.js +16 -34
  525. package/dist/store/index-and-stats.d.ts +6 -19
  526. package/dist/store/index-and-stats.js +34 -82
  527. package/dist/store/markdown.d.ts +2 -6
  528. package/dist/store/markdown.js +21 -20
  529. package/dist/store/mirrors.d.ts +2 -6
  530. package/dist/store/mirrors.js +14 -23
  531. package/dist/store/open.js +6 -13
  532. package/dist/store/planning-fallacy-evidence.d.ts +2 -30
  533. package/dist/store/planning-fallacy-evidence.js +8 -37
  534. package/dist/store/port.d.ts +82 -79
  535. package/dist/store/predictions.d.ts +11 -51
  536. package/dist/store/predictions.js +38 -119
  537. package/dist/{cli → store}/quality-repair.js +15 -31
  538. package/dist/store/raw-archive.d.ts +4 -16
  539. package/dist/store/raw-archive.js +14 -29
  540. package/dist/store/recall-scope.d.ts +19 -79
  541. package/dist/store/recall-scope.js +21 -82
  542. package/dist/store/recall-trace.d.ts +10 -77
  543. package/dist/store/recall-trace.js +19 -95
  544. package/dist/store/rejected-values.js +7 -19
  545. package/dist/store/rejection.d.ts +12 -58
  546. package/dist/store/rejection.js +13 -65
  547. package/dist/store/report-reads.d.ts +6 -0
  548. package/dist/store/report-reads.js +29 -0
  549. package/dist/store/rows.d.ts +9 -19
  550. package/dist/store/rows.js +36 -34
  551. package/dist/store/rule-sql.d.ts +5 -0
  552. package/dist/store/rule-sql.js +37 -0
  553. package/dist/store/search-rows.d.ts +7 -38
  554. package/dist/store/search-rows.js +14 -50
  555. package/dist/store/sessions.d.ts +10 -47
  556. package/dist/store/sessions.js +17 -73
  557. package/dist/store/sqlite/connector-events-group.js +2 -2
  558. package/dist/store/sqlite/entry-writes-group.js +2 -2
  559. package/dist/store/sqlite/error-codec.js +4 -2
  560. package/dist/store/sqlite/executor.d.ts +2 -1
  561. package/dist/store/sqlite/executor.js +2 -1
  562. package/dist/store/sqlite/local.d.ts +3 -3
  563. package/dist/store/sqlite/local.js +1 -0
  564. package/dist/store/sqlite/object-rows.js +6 -3
  565. package/dist/store/sqlite/objects-group.js +4 -2
  566. package/dist/store/sqlite/quarantine-group.js +2 -2
  567. package/dist/store/sqlite/store.d.ts +1 -4
  568. package/dist/store/sqlite/store.js +2 -3
  569. package/dist/store/sqlite/vector-reads-group.js +2 -2
  570. package/dist/store/sqlite/worker-jobs.js +1 -1
  571. package/dist/store/sqlite/worker-ops.d.ts +13 -2
  572. package/dist/store/sqlite/worker-ops.js +13 -2
  573. package/dist/store/sqlite/worker-store.js +5 -2
  574. package/dist/store/summaries.d.ts +10 -62
  575. package/dist/store/summaries.js +34 -146
  576. package/dist/store/summary-dirty.js +1 -1
  577. package/dist/store/tenant-lookup.d.ts +6 -1
  578. package/dist/store/tenant-lookup.js +7 -0
  579. package/dist/store/tenant.d.ts +2 -16
  580. package/dist/store/tenant.js +4 -19
  581. package/dist/store/token-ledger.d.ts +13 -43
  582. package/dist/store/token-ledger.js +19 -50
  583. package/dist/store/usage-reports.js +5 -13
  584. package/dist/store/vector-index.d.ts +46 -0
  585. package/dist/store/vector-index.js +170 -0
  586. package/dist/store/working-memory.d.ts +6 -25
  587. package/dist/store/working-memory.js +18 -52
  588. package/dist/store/yaml.d.ts +1 -5
  589. package/dist/store/yaml.js +2 -6
  590. package/dist/support-bundle.js +7 -5
  591. package/dist/trust/reject-flow.js +1 -3
  592. package/dist/util/anthropic-messages.js +14 -2
  593. package/dist/util/atomic-write.d.ts +2 -1
  594. package/dist/util/atomic-write.js +35 -4
  595. package/dist/util/capped-json.d.ts +6 -0
  596. package/dist/util/capped-json.js +46 -0
  597. package/dist/util/crash-handlers.d.ts +8 -1
  598. package/dist/util/crash-handlers.js +52 -10
  599. package/dist/util/env.d.ts +13 -6
  600. package/dist/util/env.js +14 -7
  601. package/dist/util/home-path.d.ts +2 -1
  602. package/dist/util/home-path.js +4 -2
  603. package/dist/util/http-retry.d.ts +3 -1
  604. package/dist/util/http-retry.js +26 -5
  605. package/dist/util/log.d.ts +3 -2
  606. package/dist/util/log.js +25 -9
  607. package/dist/util/request-scope.d.ts +2 -1
  608. package/dist/util/request-scope.js +2 -1
  609. package/dist/util/secret-detect.d.ts +5 -30
  610. package/dist/util/secret-detect.js +13 -39
  611. package/dist/util/stored-json.d.ts +1 -1
  612. package/dist/util/stored-json.js +1 -1
  613. package/dist/util/token-text.d.ts +1 -4
  614. package/dist/util/token-text.js +1 -4
  615. package/dist/util/transcript-tail.d.ts +2 -0
  616. package/dist/util/transcript-tail.js +24 -23
  617. package/dist/util/version.d.ts +5 -20
  618. package/dist/util/version.js +5 -20
  619. package/extensions/openclaw-plugin/index.ts +1 -1
  620. package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
  621. package/extensions/openclaw-plugin/package.json +1 -1
  622. package/openclaw.plugin.json +1 -1
  623. package/package.json +1 -1
  624. package/dist/connectors/github/cli-impl.d.ts +0 -25
  625. package/dist/sharing/shared.d.ts +0 -187
  626. package/dist/sharing/shared.js +0 -563
  627. package/dist/store/vector-writes.d.ts +0 -13
  628. package/dist/store/vector-writes.js +0 -89
  629. /package/dist/{cli → store}/quality-repair.d.ts +0 -0
@@ -1,54 +1,20 @@
1
- /**
2
- * Recall-side scope predicates, in a leaf module so shared.ts (which api.ts
3
- * imports) can apply the same default-deny rule to searchBothHybrid's internal
4
- * candidate loads without an import cycle. api.ts imports
5
- * these for its own call sites AND re-exports them for back-compat
6
- * (`api.isPrivateScope`, test imports of `passesScopeFilterForRecall`).
7
- */
1
+ /** Recall-side scope predicates, in a leaf module so search-both.ts can apply the same default-deny rule to searchBothHybrid's candidate loads without an
2
+ * import cycle. src/api/index.ts imports these and re-exports them for back-compat (`api.isPrivateScope`, tests importing `passesScopeFilterForRecall`). */
8
3
  import { BadRequestError, ForbiddenError } from '../core/api-errors.js';
9
4
  import { MAX_ID_LEN } from '../util/http-util.js';
10
- /**
11
- * Literal scopes excluded from recall by default-deny when the
12
- * caller passes no `scope`. The SQL clause in `loadSearchRows` and the JS
13
- * helper `passesScopeFilterForRecall` (src/api/index.ts) both read from this
14
- * constant. Adding a deny scope is a one-place change.
15
- *
16
- * Regex-based denies (e.g. `<source>:private:*`) stay in
17
- * `passesScopeFilterForRecall` as a separate JS step — they don't translate
18
- * cleanly to SQL.
19
- *
20
- * Invariant: never empty. An empty array would silently allow quarantine
21
- * scopes through both paths (SQL clause omitted, JS check vacuous). The
22
- * module-load assertion below pins this loudly.
23
- */
5
+ /** Literal scopes excluded from recall by default-deny when the caller passes no `scope`; read by the SQL clause in `loadSearchRows` and by
6
+ * `passesScopeFilterForRecall`. Invariant: never empty, or quarantine scopes would pass both paths silently (the module-load assertion below pins this). */
24
7
  export const RECALL_DEFAULT_DENY_SCOPES = ['unknown:legacy'];
25
- /**
26
- * @internal Runtime guard against a future maintainer blanking a
27
- * load-bearing literal array. Extracted from the inline guard so the throw
28
- * path is directly testable. `as const` arrays widen via `readonly T[]` at
29
- * the call site so the empty case is reachable at runtime.
30
- */
8
+ /** @internal Runtime guard against blanking a load-bearing literal array; `as const` arrays widen via `readonly T[]` at the call site, so the empty case
9
+ * is reachable and testable. */
31
10
  export function assertNonEmpty(arr, name) {
32
11
  if (arr.length === 0) {
33
12
  throw new Error(`${name} cannot be empty — would silently allow quarantine scopes`);
34
13
  }
35
14
  }
36
15
  assertNonEmpty(RECALL_DEFAULT_DENY_SCOPES, 'RECALL_DEFAULT_DENY_SCOPES');
37
- /**
38
- * Source-agnostic private-scope detector. A scope string is treated
39
- * as private when it has the shape `<lowercase-source>:private:<rest>`.
40
- *
41
- * Examples that match:
42
- * slack:private:Cabc, github:private:owner/repo, jira:private:PROJ-1
43
- * Examples that DO NOT match:
44
- * slack:public:Cgeneral, acme:public:my-private-channel, null, '',
45
- * 'unknown:legacy', 'private' (alone), 'private:foo' (no source prefix).
46
- *
47
- * Used by api.recall, mcp/server.ts (hippo_recall + hippo_context),
48
- * cli.ts (cmdRecall + cmdExplain + continuity), shared.ts (searchBothHybrid
49
- * recall mode). Keep these in sync — the export is the single source of
50
- * truth so connector work cannot drift.
51
- */
16
+ /** Source-agnostic private-scope detector: private means `<lowercase-source>:private:<rest>` (`slack:private:Cabc`; not `slack:public:x`, null, '',
17
+ * 'private:foo'). The single source of truth for api.recall, the MCP server, the CLI and search-both.ts, so connector work cannot drift. */
52
18
  export const PRIVATE_SCOPE_RE = /^[a-z][a-z0-9_-]*:private:/;
53
19
  function isScopeString(value) {
54
20
  return typeof value === 'string';
@@ -89,15 +55,8 @@ export function canTouchScope(actor, scope) {
89
55
  export function ownScopeTouches(ownScope, scope) {
90
56
  return !isPersonalScope(scope) || scope === ownScope;
91
57
  }
92
- /**
93
- * Recall-side scope filter — the canonical JS half of the recall default-deny
94
- * rule (the SQL half lives in `loadSearchRows` via `loadRecallSearchEntries`).
95
- *
96
- * - When `requested` is set and non-empty: exact match required.
97
- * - When `requested` is undefined/empty: default-deny on any
98
- * `<source>:private:*` scope and on the `RECALL_DEFAULT_DENY_SCOPES`
99
- * quarantine buckets. `null` and public scopes pass, and so does `ownScope`, the caller's own personal scope.
100
- */
58
+ /** JS half of the recall default-deny rule (SQL half: `loadSearchRows`). A non-empty `requested` needs an exact match;
59
+ * otherwise `<source>:private:*` and `RECALL_DEFAULT_DENY_SCOPES` buckets are denied, while null, public scopes and the caller's `ownScope` pass. */
101
60
  export function passesScopeFilterForRecall(scope, requested, ownScope) {
102
61
  if (requested !== undefined && requested !== '') {
103
62
  return scope === requested;
@@ -113,40 +72,23 @@ export function scopeAdmitSql(col, ownScope) {
113
72
  // The own arm sits inside the outer parentheses so a caller's `AND ${sql}` cannot split it off.
114
73
  return { sql: `(${admitted} OR ${col}scope = ?)`, params: [...RECALL_DEFAULT_DENY_SCOPES, ownScope] };
115
74
  }
116
- /** SQL twin of canTouchScope, which is also canReadScope for an admin: every row but another person's personal one. LIKE folds ASCII case as isPersonalScope's /i does. */
75
+ /** SQL twin of canTouchScope, which is also canReadScope for an admin: every row but
76
+ * another person's personal one. LIKE folds ASCII case as isPersonalScope's /i does. */
117
77
  export function touchableScopeSql(col, ownScope) {
118
78
  const notPersonal = `${col}scope IS NULL OR ${col}scope NOT LIKE '${PERSONAL_SCOPE_PREFIX}%'`;
119
79
  if (ownScope == null)
120
80
  return { sql: `(${notPersonal})`, params: [] };
121
81
  return { sql: `(${notPersonal} OR ${col}scope = ?)`, params: [ownScope] };
122
82
  }
123
- /**
124
- * The CLI `--scope` variant of the recall filter (JS half of the
125
- * SQL 'default-deny-or-exact' mode in loadSearchRows).
126
- *
127
- * The CLI flag predates the envelope column as a TAG-boost ranking hint
128
- * (`scope:<v>` tags, HIPPO_SCOPE, detectScope()), so an explicit `--scope X`
129
- * UNLOCKS envelope scope X in addition to the default-admitted set — it does
130
- * NOT narrow the result to X (that would return zero rows for every
131
- * tag-scoped workflow, whose envelope scope is NULL). api.recall keeps the
132
- * narrowing 'exact' semantics via `passesScopeFilterForRecall`.
133
- *
134
- * Note the unlock applies to whatever scope was explicitly named — including
135
- * a private scope or a quarantine bucket (`--scope unknown:legacy`). That is
136
- * deliberate owner access, identical in reach to api.recall's exact-match
137
- * for the same input; only NON-requested private/quarantine scopes stay
138
- * denied. A named personal scope never unlocks: the CLI has no caller identity to check it against.
139
- */
83
+ /** CLI `--scope` variant: an explicit `--scope X` UNLOCKS scope X on top of the default-admitted set rather than narrowing to X (api.recall keeps 'exact').
84
+ * Includes private/quarantine scopes (owner access); a named personal scope never unlocks: the CLI has no caller identity. */
140
85
  export function passesCliRecallScopeFilter(scope, requested) {
141
86
  if (requested !== undefined && requested !== '' && !isPersonalScope(requested) && scope === requested) {
142
87
  return true;
143
88
  }
144
89
  return passesScopeFilterForRecall(scope, undefined);
145
90
  }
146
- /**
147
- * Thrown when a caller requests a scope its role may not read. The HTTP layer
148
- * maps it to 403.
149
- */
91
+ /** Thrown when a caller requests a scope its role may not read; the HTTP layer maps it to 403. */
150
92
  export class ScopeForbiddenError extends ForbiddenError {
151
93
  scope;
152
94
  constructor(scope) {
@@ -155,20 +97,17 @@ export class ScopeForbiddenError extends ForbiddenError {
155
97
  this.scope = scope;
156
98
  }
157
99
  }
158
- /**
159
- * True for scopes that default-deny hides: `<source>:private:*` and the
160
- * quarantine buckets. Naming one explicitly is what unlocks it, so naming one
161
- * is the act that needs authorization.
162
- */
100
+ /** True for scopes default-deny hides (`<source>:private:*` and the quarantine buckets); naming one explicitly unlocks it, so naming one needs
101
+ * authorization. */
163
102
  export function isRestrictedScope(scope) {
164
103
  if (!isScopeString(scope))
165
104
  return false;
166
- // SAFETY: RECALL_DEFAULT_DENY_SCOPES is a readonly tuple of string
167
- // literals; widening the array (not the input) lets .includes() take any scope.
168
- // `:private:` anywhere, any case, matches the store's SQL default-deny (store/search-rows.ts) so JS never admits what SQL hides.
105
+ // SAFETY: RECALL_DEFAULT_DENY_SCOPES is a readonly tuple of string literals; widening the array lets .includes() take any scope.
106
+ // `:private:` anywhere, any case, matches the SQL default-deny in src/store/search-rows.ts so JS never admits what SQL hides.
169
107
  return isPrivateScope(scope) || /:private:/i.test(scope) || RECALL_DEFAULT_DENY_SCOPES.includes(scope);
170
108
  }
171
- /** Personal rows answer to their owner alone: role, key grants and resolver scopes never open one. Else admin reads all; a member needs an exact grant on a restricted scope. */
109
+ /** Personal rows answer to their owner alone: role, key grants and resolver scopes never
110
+ * open one. Else admin reads all; a member needs an exact grant on a restricted scope. */
172
111
  export function canReadScope(actor, scope) {
173
112
  if (isPersonalScope(scope))
174
113
  return scope === personalScopeOf(actor);
@@ -1,19 +1,6 @@
1
- /**
2
- * Retrieval-trace persistence.
3
- *
4
- * Single producer for the `recall_traces` / `recall_trace_results` /
5
- * `recall_trace_outcomes` tables (schema v40). Every recall on the three
6
- * wired paths (api.recall, api.getContext, CLI cmdRecall) writes a trace
7
- * row: the ids + ranks + scores actually returned. Outcome events that
8
- * resolve their targets from last-retrieval state link back to the trace
9
- * they judge via `recordTraceOutcome`. This is the (query, shown, outcome)
10
- * training triple every Track LC learned component needs.
11
- *
12
- * All writes here are fail-soft: a broken trace write must never break the
13
- * surrounding recall or outcome call. Failures are logged to stderr and
14
- * swallowed (matches the api.ts ~2843 "audit emit failed" precedent — no
15
- * new debug env var).
16
- */
1
+ /** Retrieval-trace persistence: the single producer for `recall_traces`, `recall_trace_results` and `recall_trace_outcomes`.
2
+ * One trace row per recall on api.recall, api.getContext and CLI cmdRecall: the (query, shown, outcome) triple the learned components train on.
3
+ * All writes are fail-soft: a failed trace write is logged to stderr and swallowed, never breaking the surrounding call. */
17
4
  import { type DatabaseSyncLike } from '../db/index.js';
18
5
  import type { RerankStep } from '../core/search-types.js';
19
6
  import { type DeliveryEventInput } from './delivery-recorder.js';
@@ -31,7 +18,7 @@ export interface RecallTraceInput {
31
18
  sessionId?: string | null;
32
19
  pipeline: 'api' | 'cli' | 'context' | 'mcp';
33
20
  /** Raw query text. NEVER persisted — only its sha256/16 hash + length are
34
- * stored (GDPR Path A / audit convention, cli.ts:1532). */
21
+ * stored (GDPR Path A / audit convention, CLI). */
35
22
  query: string;
36
23
  /** True when the caller ran with explain/--why (per-result rerank steps
37
24
  * may be present). Defaults to false. */
@@ -39,39 +26,11 @@ export interface RecallTraceInput {
39
26
  /** Results in returned rank order (index 0 = rank 1). */
40
27
  results: RecallTraceResultInput[];
41
28
  }
42
- /**
43
- * Insert a `recall_traces` row + its `recall_trace_results` rows in ONE
44
- * transaction, on the connection handed in. Fail-soft: never throws —
45
- * logs to stderr and returns null on any failure.
46
- *
47
- * Connection policy: api.recall and api.getContext reach this through
48
- * `finishRecallAt`, on the handle that recall's other writes use. CLI
49
- * cmdRecall goes through `writeRecallTraceAtRoot` instead, since its audit
50
- * handle is already closed by the time tracing runs.
51
- */
29
+ /** Insert a `recall_traces` row and its results rows in ONE transaction on the given connection. Fail-soft: logs to stderr and returns null on failure.
30
+ * api.recall/getContext reach this via `finishRecallAt` on their own handle; CLI cmdRecall uses `writeRecallTraceAtRoot` (its audit handle is closed). */
52
31
  export declare function writeRecallTrace(db: DatabaseSyncLike, input: RecallTraceInput): number | null;
53
- /**
54
- * Convenience wrapper: opens a fresh short-lived connection at `root`,
55
- * writes the trace, and closes. Returns the new trace id, or null on any
56
- * failure (fail-soft).
57
- *
58
- * Used at CLI cmdRecall, where the block's own convention is per-call
59
- * handles (writeEntry, saveIndex) and the earlier audit handle is already
60
- * closed. NOT used by api.recall, which must reuse the caller's open handle
61
- * (no-side-effects contract, tests/api-recall-no-side-effects.test.ts).
62
- *
63
- * This function does NOT touch the `last_trace_id` meta key: its own connection
64
- * would commit apart from `saveIndex`, so a crash could advance one key alone. LOCKSTEP
65
- * INVARIANT: `last_trace_id` must only ever advance in the SAME write as
66
- * `last_retrieval_ids`. The caller now does: call this function FIRST, set
67
- * `localIndex.last_trace_id` from the returned id, THEN call `saveIndex`
68
- * once — `saveIndex` persists both meta keys in one transaction
69
- * (store.ts). Call sites that trace WITHOUT advancing `last_retrieval_ids`
70
- * (CLI cmdRecall's zero-result path) simply never touch `localIndex` at
71
- * all, so they can't desync by construction.
72
- *
73
- * Fail-soft: never throws, including on connection failure.
74
- */
32
+ /** Short-lived connection at `root`: writes the trace, closes; returns the id or null (fail-soft). For CLI cmdRecall; api.recall must reuse its open handle.
33
+ * LOCKSTEP: never touches `last_trace_id`, which advances only in the same `saveIndex` write as `last_retrieval_ids`; the caller sets it from the id. */
75
34
  export declare function writeRecallTraceAtRoot(root: string, input: RecallTraceInput): number | null;
76
35
  /** Input to `recordTraceOutcome`. */
77
36
  export interface RecordTraceOutcomeInput {
@@ -81,34 +40,8 @@ export interface RecordTraceOutcomeInput {
81
40
  /** Ids actually credited by this outcome event (post tenant-filtering). */
82
41
  memoryIds: string[];
83
42
  }
84
- /**
85
- * Record an outcome event against a trace, linking the (query, shown,
86
- * outcome) triple. Called ONLY where the credited ids actually come from
87
- * the last-retrieval mechanism (api.outcomeForLastRecall and any outcome
88
- * flow that resolves its targets from last-retrieval state) or from an
89
- * SDK caller's explicit `traceId` opt — never unconditionally from
90
- * api.outcome, which would mislink an explicit-id caller to a stale,
91
- * unrelated trace.
92
- *
93
- * Lives in its own append-only table, not audit_log metadata: audit_log is
94
- * pruned by `pruneAuditLog`, and pruning must never erase training data.
95
- *
96
- * Validation: `traceId`/`memoryIds` reach
97
- * this function from caller-side state (`last_trace_id` / applied outcome
98
- * ids) that can go stale relative to the trace it names — a forgotten
99
- * memory, a tenant switch mid-session, or a race between two callers. Two
100
- * checks run before the insert, both skip with one log.warn line
101
- * rather than throw:
102
- * 1. The named trace must exist and belong to `input.tenantId` — a
103
- * tenant mismatch or a dangling id (deleted trace) skips.
104
- * 2. `input.memoryIds` is intersected against the trace's OWN
105
- * `recall_trace_results.memory_id` set — only ids that trace actually
106
- * returned are recorded. An id that was never in this trace's result
107
- * set (stale caller state) is silently dropped rather than recorded
108
- * as a false credit. If the intersection is empty, no row is written.
109
- *
110
- * Fail-soft: never throws.
111
- */
43
+ /** Record an outcome against a trace; call ONLY with ids from last-retrieval state or an SDK `traceId`, never from api.outcome (stale-trace mislink).
44
+ * Skips (log.warn) unless the trace is in `input.tenantId`; keeps only memoryIds it returned. Own table so `pruneAuditLog` cannot erase training data. */
112
45
  export declare function recordTraceOutcome(db: DatabaseSyncLike, input: RecordTraceOutcomeInput): void;
113
46
  /** Pruned on write, counted back from the event's ts capped at the real clock, so a far-future fake time spares real rows. */
114
47
  export declare const DELIVERY_LEDGER_RETENTION_DAYS = 90;
@@ -1,33 +1,13 @@
1
- /**
2
- * Retrieval-trace persistence.
3
- *
4
- * Single producer for the `recall_traces` / `recall_trace_results` /
5
- * `recall_trace_outcomes` tables (schema v40). Every recall on the three
6
- * wired paths (api.recall, api.getContext, CLI cmdRecall) writes a trace
7
- * row: the ids + ranks + scores actually returned. Outcome events that
8
- * resolve their targets from last-retrieval state link back to the trace
9
- * they judge via `recordTraceOutcome`. This is the (query, shown, outcome)
10
- * training triple every Track LC learned component needs.
11
- *
12
- * All writes here are fail-soft: a broken trace write must never break the
13
- * surrounding recall or outcome call. Failures are logged to stderr and
14
- * swallowed (matches the api.ts ~2843 "audit emit failed" precedent — no
15
- * new debug env var).
16
- */
17
- import { createHash } from 'node:crypto';
1
+ /** Retrieval-trace persistence: the single producer for `recall_traces`, `recall_trace_results` and `recall_trace_outcomes`.
2
+ * One trace row per recall on api.recall, api.getContext and CLI cmdRecall: the (query, shown, outcome) triple the learned components train on.
3
+ * All writes are fail-soft: a failed trace write is logged to stderr and swallowed, never breaking the surrounding call. */
18
4
  import { openHippoDb, closeHippoDb, rethrowIfSqliteBlocked, withWriteScope } from '../db/index.js';
19
5
  import { DELIVERY_LEDGER_VERSION, isBoundaryEvent } from './delivery-recorder.js';
20
- import { errorMessage, log } from '../util/log.js';
6
+ import { errorFields, errorMessage, log } from '../util/log.js';
21
7
  import { DAY_MS } from '../util/time.js';
22
- /**
23
- * Strip a RerankStep down to {stage, multiplier, scoreBefore, scoreAfter}
24
- * before persisting. `note` is
25
- * free-form human text — the CLI's goal-boost step embeds matched goal tag
26
- * text there, so persisting it verbatim would leak raw user content into
27
- * training data via `rerank_json`. Only the four structured fields survive;
28
- * any other/future free-form field is dropped by construction (allowlist,
29
- * not a denylist).
30
- */
8
+ import { blockHash } from '../util/token-text.js';
9
+ /** Strip a RerankStep to {stage, multiplier, scoreBefore, scoreAfter}: `note` is free-form (the CLI goal-boost step embeds goal tag text) and would leak
10
+ * user content into `rerank_json`; an allowlist, so any future free-form field is dropped too. */
31
11
  function sanitizeRerankSteps(steps) {
32
12
  return steps.map((s) => ({
33
13
  stage: s.stage,
@@ -36,19 +16,11 @@ function sanitizeRerankSteps(steps) {
36
16
  scoreAfter: s.scoreAfter,
37
17
  }));
38
18
  }
39
- /**
40
- * Insert a `recall_traces` row + its `recall_trace_results` rows in ONE
41
- * transaction, on the connection handed in. Fail-soft: never throws —
42
- * logs to stderr and returns null on any failure.
43
- *
44
- * Connection policy: api.recall and api.getContext reach this through
45
- * `finishRecallAt`, on the handle that recall's other writes use. CLI
46
- * cmdRecall goes through `writeRecallTraceAtRoot` instead, since its audit
47
- * handle is already closed by the time tracing runs.
48
- */
19
+ /** Insert a `recall_traces` row and its results rows in ONE transaction on the given connection. Fail-soft: logs to stderr and returns null on failure.
20
+ * api.recall/getContext reach this via `finishRecallAt` on their own handle; CLI cmdRecall uses `writeRecallTraceAtRoot` (its audit handle is closed). */
49
21
  export function writeRecallTrace(db, input) {
50
22
  try {
51
- const queryHash = createHash('sha256').update(input.query).digest('hex').slice(0, 16);
23
+ const queryHash = blockHash(input.query);
52
24
  const ts = new Date().toISOString();
53
25
  return withWriteScope(db, 'write_recall_trace', () => {
54
26
  const insertTrace = db.prepare(`
@@ -68,32 +40,12 @@ export function writeRecallTrace(db, input) {
68
40
  });
69
41
  }
70
42
  catch (error) {
71
- log.error(`recall trace write failed: ${errorMessage(error)}`);
43
+ log.error(`recall trace write failed: ${errorMessage(error)}`, errorFields(error));
72
44
  return null;
73
45
  }
74
46
  }
75
- /**
76
- * Convenience wrapper: opens a fresh short-lived connection at `root`,
77
- * writes the trace, and closes. Returns the new trace id, or null on any
78
- * failure (fail-soft).
79
- *
80
- * Used at CLI cmdRecall, where the block's own convention is per-call
81
- * handles (writeEntry, saveIndex) and the earlier audit handle is already
82
- * closed. NOT used by api.recall, which must reuse the caller's open handle
83
- * (no-side-effects contract, tests/api-recall-no-side-effects.test.ts).
84
- *
85
- * This function does NOT touch the `last_trace_id` meta key: its own connection
86
- * would commit apart from `saveIndex`, so a crash could advance one key alone. LOCKSTEP
87
- * INVARIANT: `last_trace_id` must only ever advance in the SAME write as
88
- * `last_retrieval_ids`. The caller now does: call this function FIRST, set
89
- * `localIndex.last_trace_id` from the returned id, THEN call `saveIndex`
90
- * once — `saveIndex` persists both meta keys in one transaction
91
- * (store.ts). Call sites that trace WITHOUT advancing `last_retrieval_ids`
92
- * (CLI cmdRecall's zero-result path) simply never touch `localIndex` at
93
- * all, so they can't desync by construction.
94
- *
95
- * Fail-soft: never throws, including on connection failure.
96
- */
47
+ /** Short-lived connection at `root`: writes the trace, closes; returns the id or null (fail-soft). For CLI cmdRecall; api.recall must reuse its open handle.
48
+ * LOCKSTEP: never touches `last_trace_id`, which advances only in the same `saveIndex` write as `last_retrieval_ids`; the caller sets it from the id. */
97
49
  export function writeRecallTraceAtRoot(root, input) {
98
50
  let db;
99
51
  try {
@@ -101,7 +53,7 @@ export function writeRecallTraceAtRoot(root, input) {
101
53
  }
102
54
  catch (error) {
103
55
  rethrowIfSqliteBlocked(error);
104
- log.error(`recall trace connection failed: ${errorMessage(error)}`);
56
+ log.error(`recall trace connection failed: ${errorMessage(error)}`, errorFields(error));
105
57
  return null;
106
58
  }
107
59
  try {
@@ -111,34 +63,8 @@ export function writeRecallTraceAtRoot(root, input) {
111
63
  closeHippoDb(db);
112
64
  }
113
65
  }
114
- /**
115
- * Record an outcome event against a trace, linking the (query, shown,
116
- * outcome) triple. Called ONLY where the credited ids actually come from
117
- * the last-retrieval mechanism (api.outcomeForLastRecall and any outcome
118
- * flow that resolves its targets from last-retrieval state) or from an
119
- * SDK caller's explicit `traceId` opt — never unconditionally from
120
- * api.outcome, which would mislink an explicit-id caller to a stale,
121
- * unrelated trace.
122
- *
123
- * Lives in its own append-only table, not audit_log metadata: audit_log is
124
- * pruned by `pruneAuditLog`, and pruning must never erase training data.
125
- *
126
- * Validation: `traceId`/`memoryIds` reach
127
- * this function from caller-side state (`last_trace_id` / applied outcome
128
- * ids) that can go stale relative to the trace it names — a forgotten
129
- * memory, a tenant switch mid-session, or a race between two callers. Two
130
- * checks run before the insert, both skip with one log.warn line
131
- * rather than throw:
132
- * 1. The named trace must exist and belong to `input.tenantId` — a
133
- * tenant mismatch or a dangling id (deleted trace) skips.
134
- * 2. `input.memoryIds` is intersected against the trace's OWN
135
- * `recall_trace_results.memory_id` set — only ids that trace actually
136
- * returned are recorded. An id that was never in this trace's result
137
- * set (stale caller state) is silently dropped rather than recorded
138
- * as a false credit. If the intersection is empty, no row is written.
139
- *
140
- * Fail-soft: never throws.
141
- */
66
+ /** Record an outcome against a trace; call ONLY with ids from last-retrieval state or an SDK `traceId`, never from api.outcome (stale-trace mislink).
67
+ * Skips (log.warn) unless the trace is in `input.tenantId`; keeps only memoryIds it returned. Own table so `pruneAuditLog` cannot erase training data. */
142
68
  export function recordTraceOutcome(db, input) {
143
69
  try {
144
70
  // SAFETY: row shape matches the single `tenant_id` column named in the
@@ -165,7 +91,7 @@ export function recordTraceOutcome(db, input) {
165
91
  `).run(input.traceId, new Date().toISOString(), input.tenantId, input.outcome, JSON.stringify(credited));
166
92
  }
167
93
  catch (error) {
168
- log.error(`recall trace outcome write failed: ${errorMessage(error)}`);
94
+ log.error(`recall trace outcome write failed: ${errorMessage(error)}`, errorFields(error));
169
95
  }
170
96
  }
171
97
  /** Pruned on write, counted back from the event's ts capped at the real clock, so a far-future fake time spares real rows. */
@@ -258,8 +184,7 @@ export function writeDeliveryEvent(db, input) {
258
184
  });
259
185
  }
260
186
  catch (error) {
261
- // The prompt hook's stderr shows this exact `[hippo] delivery ledger` line, so it stays off the logger's format.
262
- console.error(`[hippo] delivery ledger write failed: ${errorMessage(error)}`);
187
+ log.error(`delivery ledger write failed: ${errorMessage(error)}`);
263
188
  return null;
264
189
  }
265
190
  }
@@ -270,8 +195,7 @@ export function writeDeliveryEventAtRoot(root, input) {
270
195
  db = openHippoDb(root);
271
196
  }
272
197
  catch (error) {
273
- // Same hook stderr line as writeDeliveryEvent above.
274
- console.error(`[hippo] delivery ledger write failed: ${errorMessage(error)}`);
198
+ log.error(`delivery ledger write failed: ${errorMessage(error)}`);
275
199
  return null;
276
200
  }
277
201
  try {
@@ -9,7 +9,7 @@ import { entryRejectRowAt, selectAllEntries } from './entry-reads.js';
9
9
  import { stampOriginProject } from './entry-row.js';
10
10
  import { writeEntryDbOnly, writeEntryMirrors } from './entry-writes.js';
11
11
  import { purgeMirrorBestEffort } from './mirrors.js';
12
- import { openStore } from './open.js';
12
+ import { onHandle, openStore } from './open.js';
13
13
  import { archiveRawMemory, markMirrorCleaned } from './raw-archive.js';
14
14
  import { RejectedValueError, checkRejectionGuard, deleteRejectedValue, insertRejectedValue, listRejectedValues, normalizeValueForRejection, rejectionDigest, } from './rejection.js';
15
15
  function removeLiveRows(db, hippoRoot, rejection, holdsValue, removal) {
@@ -81,8 +81,7 @@ function purgeRemovedMirrors(db, hippoRoot, removal) {
81
81
  * text (live or dormant, whole or inside a merged row) and one reject_value audit row. Markdown mirrors follow the commit. */
82
82
  export function applyRejection(hippoRoot, rejection) {
83
83
  const { tenantId, actor, reason, memoryId } = rejection;
84
- const db = openStore(hippoRoot);
85
- try {
84
+ return onHandle(hippoRoot, (db) => {
86
85
  const content = rejection.textOf(memoryId === undefined ? undefined : entryRejectRowAt(db, memoryId));
87
86
  const digest = rejectionDigest(content);
88
87
  const rejectedAt = new Date().toISOString();
@@ -108,16 +107,12 @@ export function applyRejection(hippoRoot, rejection) {
108
107
  purgeRemovedMirrors(db, hippoRoot, removal);
109
108
  const { removedIds, removedRawIds, successors, dormantSuccessorIds } = removal;
110
109
  return { digest, content, removedIds, removedRawIds, successorIds: successors.map((s) => s.id), dormantSuccessorIds };
111
- }
112
- finally {
113
- closeHippoDb(db);
114
- }
110
+ }, openStore);
115
111
  }
116
112
  /** Deletes the tenant's one rejected value whose digest starts with `digestPrefix` and writes its unreject_value audit row.
117
113
  * No match, or more than one, writes nothing. */
118
114
  export function liftRejection(hippoRoot, tenantId, digestPrefix, actor) {
119
- const db = openStore(hippoRoot);
120
- try {
115
+ return onHandle(hippoRoot, (db) => {
121
116
  const matches = listRejectedValues(db, tenantId).filter((r) => r.digest.startsWith(digestPrefix));
122
117
  const target = matches[0];
123
118
  if (target === undefined)
@@ -127,20 +122,13 @@ export function liftRejection(hippoRoot, tenantId, digestPrefix, actor) {
127
122
  deleteRejectedValue(db, tenantId, target.digest);
128
123
  audit(db, 'unreject_value', { tenantId, actor, targetId: target.sourceMemoryId ?? undefined, metadata: { digest: target.digest, reason: target.reason } });
129
124
  return { status: 'ok', digest: target.digest, reason: target.reason };
130
- }
131
- finally {
132
- closeHippoDb(db);
133
- }
125
+ }, openStore);
134
126
  }
135
127
  /** The tenant's rejected values, newest first. */
136
128
  export function loadRejectedValues(hippoRoot, tenantId) {
137
- const db = openStore(hippoRoot);
138
- try {
129
+ return onHandle(hippoRoot, (db) => {
139
130
  return listRejectedValues(db, tenantId);
140
- }
141
- finally {
142
- closeHippoDb(db);
143
- }
131
+ }, openStore);
144
132
  }
145
133
  /** Whether the write guard would refuse `content` under `entryId`, as a write of that row would find it. Reads on a plain open
146
134
  * and writes nothing, so a dry run counts the values a real run refuses. */
@@ -1,38 +1,14 @@
1
- /**
2
- * Rejected-value tombstone: core invariant.
3
- *
4
- * Exact-normalized-value semantics: a human who rejects a fact can refuse
5
- * byte-stable re-ingestion of the same value across remember/capture/import/
6
- * sync surfaces. Paraphrase/semantic matching is explicitly out of scope
7
- * (documented limitation, plan "Design").
8
- *
9
- * Kept db-agnostic (helpers take a `DatabaseSyncLike` handle) and does NOT
10
- * import from store.ts — store.ts imports from here, and the reverse would
11
- * be a cycle.
12
- */
1
+ /** Rejected-value tombstone: a human can refuse byte-stable re-ingestion of a rejected fact (exact normalized value); paraphrase matching is out of scope.
2
+ * db-agnostic (helpers take a `DatabaseSyncLike`) and imports nothing from the store layer above it, which imports this (the reverse is a cycle). */
13
3
  import type { DatabaseSyncLike } from '../db/index.js';
14
4
  import { BadRequestError } from '../core/api-errors.js';
15
- /**
16
- * Normalize content for rejection-digest comparisons: Unicode NFC →
17
- * lowercase → collapse whitespace runs to a single space → trim. No
18
- * punctuation stripping — over-normalization creates false refusals, which
19
- * are worse than misses (plan §1).
20
- */
5
+ /** Normalize content for rejection digests: NFC, lowercase, collapse whitespace runs, trim. No punctuation stripping: over-normalizing causes false
6
+ * refusals, worse than misses. */
21
7
  export declare function normalizeValueForRejection(content: string): string;
22
- /**
23
- * Full sha256 hex (64 chars) of the normalized content. Reuses the strong-
24
- * identity convention (importers.ts:814 content-hash tag), NOT the privacy-
25
- * lossy 16-char convention (recall-trace query hashing) — a tombstone lookup
26
- * key needs collision resistance, not redaction (plan §1).
27
- */
8
+ /** Full 64-char sha256 hex of the normalized content: a tombstone key needs collision resistance, not the 16-char redaction hash used for query hashing. */
28
9
  export declare function rejectionDigest(content: string): string;
29
- /**
30
- * Thrown by the write-path guard (checkRejectionGuard, called from
31
- * upsertEntryRow) when an incoming write would introduce a value matching a
32
- * tombstoned digest. Carries enough context for the transaction-owner catch
33
- * blocks (writeEntry, api.supersede) to write a post-rollback
34
- * `reject_refusal` audit row via `auditRejectionRefusal` (plan §3).
35
- */
10
+ /** Thrown by the write-path guard (checkRejectionGuard, via upsertEntryRow) when a write would introduce a tombstoned value; carries what the
11
+ * transaction-owner catch blocks (writeEntry, api.supersede) need to write the post-rollback `reject_refusal` audit row via `auditRejectionRefusal`. */
36
12
  export declare class RejectedValueError extends BadRequestError {
37
13
  readonly digest: string;
38
14
  readonly tenantId: string;
@@ -56,15 +32,9 @@ export interface RejectedValueRow {
56
32
  sourceMemoryId: string | null;
57
33
  normalizedChars: number | null;
58
34
  }
59
- /**
60
- * Look up a tombstone by tenant + digest. One indexed point query — the
61
- * guard's common-case cost, a miss ends the guard (plan §3).
62
- */
35
+ /** Look up a tombstone by tenant + digest: one indexed point query, the guard's common-case cost; a miss ends the guard. */
63
36
  export declare function findRejectedValue(db: DatabaseSyncLike, tenantId: string, digest: string): RejectedValueRow | null;
64
- /**
65
- * Insert (or refresh) a tombstone row. Caller owns the transaction — used by
66
- * the `reject` verb and `resolveConflict`'s `rejectLoserValue` path.
67
- */
37
+ /** Insert (or refresh) a tombstone row; the caller owns the transaction (used by the `reject` verb and `resolveConflict`'s `rejectLoserValue`). */
68
38
  export declare function insertRejectedValue(db: DatabaseSyncLike, opts: {
69
39
  tenantId: string;
70
40
  digest: string;
@@ -74,27 +44,11 @@ export declare function insertRejectedValue(db: DatabaseSyncLike, opts: {
74
44
  sourceMemoryId?: string | null;
75
45
  normalizedChars: number;
76
46
  }): void;
77
- /**
78
- * Delete a tombstone by tenant + exact digest: the `unreject` verb, the
79
- * only escape hatch.
80
- */
47
+ /** Delete a tombstone by tenant + exact digest: the `unreject` verb, the only escape hatch. */
81
48
  export declare function deleteRejectedValue(db: DatabaseSyncLike, tenantId: string, digest: string): boolean;
82
49
  /** List tombstones for a tenant, newest first: the `rejections` verb. */
83
50
  export declare function listRejectedValues(db: DatabaseSyncLike, tenantId: string): RejectedValueRow[];
84
- /**
85
- * The write-path guard's check helper, called from `upsertEntryRow`
86
- * (store.ts). Fires when the incoming content's digest matches a tombstone
87
- * AND the write *introduces* that content: the row is new, OR the stored
88
- * row's content digest differs from the incoming one — an UPSERT editing a
89
- * same-id row TO a rejected value is a content introduction and must be
90
- * refused. Unchanged same-id re-persists (recall boost, decay, star toggle)
91
- * are exempt by construction (plan §3).
92
- *
93
- * Ordering minimizes queries on the common (miss) path: (a) caller has
94
- * already computed nothing yet — this does the digest + point lookup first;
95
- * (b) a miss returns immediately (ONE indexed point query); (c) only on a
96
- * tombstone hit does it SELECT the stored row's content to classify
97
- * new-row vs content-introduction (+1 query, rare path).
98
- */
51
+ /** Write-path guard check: fires when the digest matches a tombstone AND the write introduces that content (a new row, or a same-id UPSERT changing it).
52
+ * Unchanged same-id re-persists (recall boost, decay, star toggle) are exempt. A miss costs ONE indexed point query; only a hit SELECTs the stored row. */
99
53
  export declare function checkRejectionGuard(db: DatabaseSyncLike, tenantId: string, entryId: string, content: string): void;
100
54
  //# sourceMappingURL=rejection.d.ts.map