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,20 +1,9 @@
1
- /**
2
- * Memory-as-Physics engine for Hippo.
3
- *
4
- * Pure math module: forces, Velocity Verlet integration, physics-based scoring,
5
- * and cluster amplification. No I/O — all state is passed in and returned.
6
- *
7
- * Memories are particles on the unit hypersphere in embedding space (384-dim).
8
- * Forces act on them: query gravity (retrieval), inter-memory attraction,
9
- * conflict repulsion, and drag (consolidation). Nearby high-scoring memories
10
- * amplify each other via constructive interference.
11
- */
1
+ /** Memory-as-Physics engine: pure math (forces, Velocity Verlet integration, physics-based scoring, cluster amplification), no I/O.
2
+ * Memories are particles on the unit hypersphere in embedding space (384-dim); query gravity, attraction, conflict repulsion and drag act on them,
3
+ * and nearby high-scoring memories amplify each other. */
12
4
  import { isRecallBoostAblated } from './ablation.js';
13
5
  import { FALLBACK_HALF_LIFE_DAYS } from './memory.js';
14
6
  import { comparePhysicsResultsBy } from './compare.js';
15
- // ---------------------------------------------------------------------------
16
- // Vector math (hot path — kept inline for performance)
17
- // ---------------------------------------------------------------------------
18
7
  export function vecDot(a, b) {
19
8
  let sum = 0;
20
9
  for (let i = 0; i < a.length; i++)
@@ -25,25 +14,25 @@ export function vecNorm(v) {
25
14
  return Math.sqrt(vecDot(v, v));
26
15
  }
27
16
  export function vecScale(v, s) {
28
- const out = new Array(v.length);
17
+ const out = v.slice();
29
18
  for (let i = 0; i < v.length; i++)
30
19
  out[i] = v[i] * s;
31
20
  return out;
32
21
  }
33
22
  export function vecAdd(a, b) {
34
- const out = new Array(a.length);
23
+ const out = a.slice();
35
24
  for (let i = 0; i < a.length; i++)
36
25
  out[i] = a[i] + b[i];
37
26
  return out;
38
27
  }
39
28
  export function vecSub(a, b) {
40
- const out = new Array(a.length);
29
+ const out = a.slice();
41
30
  for (let i = 0; i < a.length; i++)
42
31
  out[i] = a[i] - b[i];
43
32
  return out;
44
33
  }
45
34
  export function vecZero(dim) {
46
- return new Array(dim).fill(0);
35
+ return Array(dim).fill(0);
47
36
  }
48
37
  /** Normalize to unit length. Returns zero vector if magnitude < epsilon. */
49
38
  export function vecNormalize(v) {
@@ -70,9 +59,6 @@ function cosine(a, b) {
70
59
  return 0;
71
60
  return Math.min(1, Math.max(-1, dot / (na * nb)));
72
61
  }
73
- // ---------------------------------------------------------------------------
74
- // Property derivation from memory attributes
75
- // ---------------------------------------------------------------------------
76
62
  const CHARGE_MAP = {
77
63
  neutral: 0,
78
64
  positive: 0.3,
@@ -80,9 +66,8 @@ const CHARGE_MAP = {
80
66
  critical: -1.0,
81
67
  };
82
68
  export function computeMass(strength, retrievalCount) {
83
- // EVAL-ONLY ablation (see ablation.ts): under the recall-boost flag mass ignores retrieval history, since
84
- // query gravity ranks by mass and prior counts would leak strengthening into the ablated arm's
85
- // physics-pool rankings. Covers both the init and refresh callers in physics-state.ts.
69
+ // EVAL-ONLY ablation (ablation.ts): under the recall-boost flag mass ignores retrieval history, which would otherwise leak strengthening into the ablated
70
+ // arm's physics-pool rankings (query gravity ranks by mass). Covers both init and refresh callers in physics-state.ts.
86
71
  const effectiveCount = isRecallBoostAblated() ? 0 : retrievalCount;
87
72
  return Math.max(0.01, strength * (1 + 0.1 * Math.log2(effectiveCount + 1)));
88
73
  }
@@ -92,23 +77,12 @@ export function computeCharge(valence) {
92
77
  export function computeTemperature(ageDays, temperatureDecay) {
93
78
  return 1 / (ageDays * temperatureDecay + 1);
94
79
  }
95
- // ---------------------------------------------------------------------------
96
- // Force computations
97
- // ---------------------------------------------------------------------------
98
- /**
99
- * Query gravity (retrieval-time, virtual — does not update position).
100
- * Returns scalar force magnitude for ranking.
101
- *
102
- * F_query(i) = G_Q * mass(i) * max(0, cosine(pos_i, query))^2
103
- */
80
+ /** Query gravity (retrieval-time, virtual: does not move the particle): scalar ranking magnitude F = G_Q * mass * max(0, cosine(pos, query))^2. */
104
81
  export function queryGravityMagnitude(particle, queryEmbedding, G_query) {
105
82
  const cos = cosine(particle.position, queryEmbedding);
106
83
  return G_query * particle.mass * Math.pow(Math.max(0, cos), 2);
107
84
  }
108
- /**
109
- * Momentum bonus: how aligned is the particle's velocity with the query direction?
110
- * Returns a value in [0, 1].
111
- */
85
+ /** Momentum bonus in [0, 1]: how aligned the particle's velocity is with the query direction. */
112
86
  export function velocityAlignmentBonus(particle, queryEmbedding) {
113
87
  if (particle.velocity.length === 0 || particle.velocity.length !== queryEmbedding.length)
114
88
  return 0;
@@ -119,31 +93,25 @@ export function velocityAlignmentBonus(particle, queryEmbedding) {
119
93
  const alignment = vecDot(particle.velocity, queryEmbedding) / (velMag * qNorm);
120
94
  return Math.max(0, alignment);
121
95
  }
122
- /**
123
- * Inter-memory attraction force vector (consolidation-time).
124
- * Attractive force from particle j on particle i.
125
- *
126
- * F_attract(i,j) = G_M * m_i * m_j * max(0, cosine(i,j))^3 * direction(j→i in embedding space)
127
- *
128
- * Direction is computed as the component of (pos_j - pos_i) that lies tangent to the
129
- * unit sphere at pos_i (since we normalize positions back to the sphere after integration).
130
- */
131
- export function attractionForce(pi, pj, G_memory) {
96
+ /** Attraction force on particle i from j (consolidation-time): G_M m_i m_j max(0, cosine)^3, directed along (pos_j - pos_i) projected tangent to the unit
97
+ * sphere at pos_i (positions are re-normalized to the sphere after integration). Adds into `out` (a fresh zero vector by default) using `diff` as scratch. */
98
+ export function attractionForce(pi, pj, G_memory, out = vecZero(pi.position.length), diff = vecZero(pi.position.length)) {
132
99
  const cos = cosine(pi.position, pj.position);
133
100
  if (cos <= 0)
134
- return vecZero(pi.position.length);
101
+ return out;
135
102
  const magnitude = G_memory * pi.mass * pj.mass * Math.pow(cos, 3);
136
103
  // Direction: from i toward j (tangent projection handled by normalization after integration)
137
- const direction = vecNormalize(vecSub(pj.position, pi.position));
138
- return vecScale(direction, magnitude);
104
+ for (let k = 0; k < out.length; k++)
105
+ diff[k] = pj.position[k] - pi.position[k];
106
+ const norm = vecNorm(diff);
107
+ if (norm < 1e-10)
108
+ return out;
109
+ const inv = 1 / norm;
110
+ for (let k = 0; k < out.length; k++)
111
+ out[k] += diff[k] * inv * magnitude;
112
+ return out;
139
113
  }
140
- /**
141
- * Conflict repulsion force vector (consolidation-time).
142
- * Repulsive force pushing i away from j.
143
- *
144
- * F_repel(i,j) = K_R * m_i * m_j / max(0.01, cosine_distance(i,j))^2
145
- * where cosine_distance = 1 - cosine_similarity
146
- */
114
+ /** Conflict repulsion on i away from j (consolidation-time): K_R * m_i * m_j / max(0.01, cosine_distance)^2, where cosine_distance = 1 - cosine_similarity. */
147
115
  export function repulsionForce(pi, pj, K_repulsion) {
148
116
  const cos = cosine(pi.position, pj.position);
149
117
  const dist = Math.max(0.01, 1 - cos);
@@ -152,46 +120,44 @@ export function repulsionForce(pi, pj, K_repulsion) {
152
120
  const direction = vecNormalize(vecSub(pi.position, pj.position));
153
121
  return vecScale(direction, magnitude);
154
122
  }
155
- /**
156
- * Drag force vector (consolidation-time).
157
- * F_drag(i) = -drag * velocity(i) / max(1, effective_half_life(i))
158
- *
159
- * effectiveHalfLife should be passed in from the memory's current half_life_days.
160
- */
123
+ /** Drag force (consolidation-time): -drag * velocity / max(1, effectiveHalfLife), with effectiveHalfLife from the memory's current half_life_days. */
161
124
  export function dragForce(particle, drag, effectiveHalfLife) {
162
125
  const damping = drag / Math.max(1, effectiveHalfLife);
163
126
  return vecScale(particle.velocity, -damping);
164
127
  }
165
- /**
166
- * Compute net force on particle i from all other particles + drag.
167
- */
168
- function computeNetForce(i, particles, ctx) {
128
+ function addInto(net, force) {
129
+ for (let k = 0; k < net.length; k++)
130
+ net[k] += force[k];
131
+ }
132
+ /** The net force on particle i, accumulated into one new array; `diff` is the caller's scratch for pair directions. */
133
+ function computeNetForce(i, particles, ctx, diff) {
169
134
  const pi = particles[i];
170
135
  const dim = pi.position.length;
171
- let net = vecZero(dim);
136
+ const net = vecZero(dim);
172
137
  const conflicts = ctx.conflictPairs.get(pi.memoryId);
173
138
  for (let j = 0; j < particles.length; j++) {
174
139
  if (i === j)
175
140
  continue;
176
141
  const pj = particles[j];
177
142
  // Attraction (all pairs)
178
- const fa = attractionForce(pi, pj, ctx.config.G_memory);
179
- net = vecAdd(net, fa);
143
+ attractionForce(pi, pj, ctx.config.G_memory, net, diff);
180
144
  // Repulsion (conflict pairs only)
181
- if (conflicts?.has(pj.memoryId)) {
182
- const fr = repulsionForce(pi, pj, ctx.config.K_repulsion);
183
- net = vecAdd(net, fr);
184
- }
145
+ if (conflicts?.has(pj.memoryId))
146
+ addInto(net, repulsionForce(pi, pj, ctx.config.K_repulsion));
185
147
  }
186
148
  // Drag
187
- const fd = dragForce(pi, ctx.config.drag, ctx.halfLives.get(pi.memoryId) ?? FALLBACK_HALF_LIFE_DAYS);
188
- net = vecAdd(net, fd);
149
+ addInto(net, dragForce(pi, ctx.config.drag, ctx.halfLives.get(pi.memoryId) ?? FALLBACK_HALF_LIFE_DAYS));
189
150
  return net;
190
151
  }
191
- /**
192
- * Run one Velocity Verlet integration step for all particles.
193
- * Mutates particles in place for performance.
194
- */
152
+ /** Acceleration of particle i: its net force divided by mass, scaled in place. */
153
+ function computeAcceleration(i, particles, ctx, diff) {
154
+ const accel = computeNetForce(i, particles, ctx, diff);
155
+ const inv = 1 / Math.max(0.01, particles[i].mass);
156
+ for (let k = 0; k < accel.length; k++)
157
+ accel[k] *= inv;
158
+ return accel;
159
+ }
160
+ /** One Velocity Verlet step for all particles; mutates in place for performance. */
195
161
  function verletStep(particles, accelerations, ctx) {
196
162
  const dt = ctx.config.dt;
197
163
  const maxVel = ctx.config.max_velocity;
@@ -203,11 +169,10 @@ function verletStep(particles, accelerations, ctx) {
203
169
  p.position = vecAdd(vecAdd(p.position, velDt), accelDt2);
204
170
  }
205
171
  // Compute new accelerations
172
+ const diff = vecZero(particles[0].position.length);
206
173
  const newAccelerations = [];
207
- for (let i = 0; i < particles.length; i++) {
208
- const force = computeNetForce(i, particles, ctx);
209
- newAccelerations.push(vecScale(force, 1 / Math.max(0.01, particles[i].mass)));
210
- }
174
+ for (let i = 0; i < particles.length; i++)
175
+ newAccelerations.push(computeAcceleration(i, particles, ctx, diff));
211
176
  // Velocity update: vel += 0.5*(accel_old + accel_new)*dt
212
177
  for (let i = 0; i < particles.length; i++) {
213
178
  const p = particles[i];
@@ -222,10 +187,7 @@ function verletStep(particles, accelerations, ctx) {
222
187
  accelerations[i] = newAccelerations[i];
223
188
  }
224
189
  }
225
- /**
226
- * Run the full physics simulation for one sleep cycle.
227
- * Mutates particles in place. Returns simulation statistics.
228
- */
190
+ /** Full physics simulation for one sleep cycle; mutates particles in place and returns simulation statistics. */
229
191
  export function simulate(particles, ctx) {
230
192
  if (particles.length === 0) {
231
193
  return {
@@ -237,10 +199,8 @@ export function simulate(particles, ctx) {
237
199
  };
238
200
  }
239
201
  // Initial accelerations
240
- const accelerations = particles.map((_, i) => {
241
- const force = computeNetForce(i, particles, ctx);
242
- return vecScale(force, 1 / Math.max(0.01, particles[i].mass));
243
- });
202
+ const diff = vecZero(particles[0].position.length);
203
+ const accelerations = particles.map((_, i) => computeAcceleration(i, particles, ctx, diff));
244
204
  // Run substeps
245
205
  for (let step = 0; step < ctx.config.substeps; step++) {
246
206
  verletStep(particles, accelerations, ctx);
@@ -268,9 +228,6 @@ export function simulate(particles, ctx) {
268
228
  substepsRun: ctx.config.substeps,
269
229
  };
270
230
  }
271
- // ---------------------------------------------------------------------------
272
- // System energy (health monitoring)
273
- // ---------------------------------------------------------------------------
274
231
  export function computeSystemEnergy(particles, G_memory) {
275
232
  let kinetic = 0;
276
233
  let potential = 0;
@@ -286,18 +243,10 @@ export function computeSystemEnergy(particles, G_memory) {
286
243
  }
287
244
  return { kinetic, potential, total: kinetic + potential };
288
245
  }
289
- // ---------------------------------------------------------------------------
290
- // Physics-based scoring (retrieval-time)
291
- // ---------------------------------------------------------------------------
292
- /**
293
- * Score all particles against a query embedding using physics-based ranking.
294
- * Does NOT modify particle positions (virtual force computation).
295
- */
246
+ /** Scores all particles against a query embedding; virtual force computation, so it does NOT modify particle positions. */
296
247
  export function physicsScore(particles, queryEmbedding, config,
297
- /** Cross-ingest-stable tie key per memoryId (typically the memory's
298
- * content, supplied by the caller which has entries in scope). Without
299
- * it ties fall to memoryId -- per-instance only, which lets the
300
- * cluster_top_k amplification set vary across fresh ingests. */
248
+ /** Cross-ingest-stable tie key per memoryId (typically the memory content, from a caller with entries in scope); without it ties fall to memoryId,
249
+ * which is per-instance only and lets the cluster_top_k amplification set vary across fresh ingests. */
301
250
  tieKeyOf) {
302
251
  if (particles.length === 0 || queryEmbedding.length === 0)
303
252
  return [];
@@ -312,10 +261,8 @@ tieKeyOf) {
312
261
  finalScore: gravity + momentum,
313
262
  };
314
263
  });
315
- // Sort by base score for top-K selection: score desc -> tie key asc.
316
- // The tie order here picks the cluster_top_k amplification SET (which
317
- // mutates scores), so it must be cross-ingest-stable when the caller
318
- // supplies a content tie key. See compare.ts comparePhysicsResultsBy.
264
+ // Base-score order picks the cluster_top_k amplification SET (which mutates scores), so ties must be cross-ingest-stable
265
+ // when the caller supplies a content tie key (see comparePhysicsResultsBy in compare.ts).
319
266
  const tie = tieKeyOf ? (r) => tieKeyOf(r.memoryId) : undefined;
320
267
  results.sort(comparePhysicsResultsBy((r) => r.baseScore, tie));
321
268
  // Pass 2: cluster amplification on top K
@@ -324,10 +271,7 @@ tieKeyOf) {
324
271
  results.sort(comparePhysicsResultsBy((r) => r.finalScore, tie));
325
272
  return results;
326
273
  }
327
- /**
328
- * Cluster amplification: nearby high-scoring memories reinforce each other.
329
- * Mutates results in place.
330
- */
274
+ /** Cluster amplification: nearby high-scoring memories reinforce each other; mutates results in place. */
331
275
  function applyClusterAmplification(results, particles, config) {
332
276
  const topK = Math.min(config.cluster_top_k, results.length);
333
277
  if (topK < 2)
@@ -358,14 +302,7 @@ function applyClusterAmplification(results, particles, config) {
358
302
  top[i].finalScore = top[i].baseScore * amplification;
359
303
  }
360
304
  }
361
- // ---------------------------------------------------------------------------
362
- // Outcome feedback (micro-nudge)
363
- // ---------------------------------------------------------------------------
364
- /**
365
- * Nudge a particle's position toward (good outcome) or away from (bad outcome)
366
- * the query embedding. Respects temperature: new memories respond more.
367
- * Mutates particle in place.
368
- */
305
+ /** Nudges a particle toward (good outcome) or away from (bad outcome) the query embedding; new memories respond more (temperature). Mutates in place. */
369
306
  export function applyOutcomeFeedback(particle, queryEmbedding, good, feedbackAlpha) {
370
307
  if (particle.position.length === 0 || particle.position.length !== queryEmbedding.length)
371
308
  return;
@@ -1,22 +1,5 @@
1
- /**
2
- * Project identity resolution for memory scope isolation.
3
- *
4
- * Resolution rules:
5
- * - The nearest ancestor of cwd (including cwd itself) containing a `.hippo`
6
- * directory is the project root; if none exists, the nearest ancestor
7
- * containing `.git` (directory or worktree file).
8
- * - The user home directory is NEVER a project, even though it contains the
9
- * global store at `~/.hippo`. Reaching home or the temp root (inside home on Windows) ends the walk.
10
- * - A directory with no marker anywhere up the walk is NOT a project: it
11
- * resolves to the user-global identity (empty name), so memories written
12
- * there stay injectable everywhere (matches pre-isolation behavior).
13
- * - A project's name is its id: `.hippo-project.json` at the root, else the
14
- * checkout's normalised `origin` remote, else the folder rule (legacyName),
15
- * so two repos in folders of one name stay apart.
16
- *
17
- * NOTE: this module must stay free of imports from shared.ts / store.ts /
18
- * api.ts so any of them can import it without creating a cycle.
19
- */
1
+ /** Project = nearest ancestor of cwd with `.hippo` (else `.git`); home and the temp root never are, and no marker means user-global (empty name).
2
+ * Name: `.hippo-project.json`, else the normalised `origin`, else the folder name. Must not import shared.ts / store.ts / api/index.ts (cycle). */
20
3
  /** The project a working directory belongs to. */
21
4
  export interface ProjectIdentity {
22
5
  /** Realpath-resolved root directory of the project (the start dir when not in a project). */
@@ -25,26 +8,21 @@ export interface ProjectIdentity {
25
8
  name: string;
26
9
  /** The folder rule rows written before ids carry: the root's lowercased basename, or its repo's for a linked worktree with no `.hippo`. */
27
10
  legacyName: string;
28
- /** Every other name this root resolves to (the project file id, the origin remote even with the rule off, legacyName), so rows written under an earlier id stay readable. */
11
+ /** Every other name this root resolves to (the project file id, the origin remote even
12
+ * with the rule off, legacyName), so rows written under an earlier id stay readable. */
29
13
  aliases?: readonly string[];
30
14
  /** True when the directory resolves to the user home working set. */
31
15
  isHome: boolean;
32
16
  }
33
- /**
34
- * Options for resolveProjectIdentity. Both fields are test seams; results are
35
- * not cached when either is set. stopDir bounds the upward walk so tests in a
36
- * temp sandbox never escape it and hit the host machine's real markers.
37
- */
17
+ /** Options for resolveProjectIdentity. Both fields are test seams and disable caching;
18
+ * stopDir bounds the upward walk so tests in a temp sandbox never reach the host's real markers. */
38
19
  export interface ResolveProjectIdentityOpts {
39
20
  homeDir?: string;
40
21
  stopDir?: string;
41
22
  }
42
23
  /** Clear the per-process identity cache and the remote switch it read (test seam). */
43
24
  export declare function clearProjectIdentityCache(): void;
44
- /**
45
- * Resolve the project identity for a working directory.
46
- * Defaults to process.cwd(). Results are cached per resolved input path.
47
- */
25
+ /** Resolves the project identity for a working directory (default process.cwd()); results are cached per resolved input path. */
48
26
  export declare function resolveProjectIdentity(cwd?: string, opts?: ResolveProjectIdentityOpts): ProjectIdentity;
49
27
  /** Nearest ancestor `.hippo` below home and the temp root (never projects; on Windows the temp root sits inside home).
50
28
  * Everything is realpath'd so a symlinked temp root or cwd still matches its bound. */
@@ -57,44 +35,25 @@ export declare function projectId(project: ProjectRef): string;
57
35
  export declare function projectNames(project: ProjectRef): readonly string[];
58
36
  export declare const MAX_PROJECT_ALIASES = 10;
59
37
  export declare const MCP_PROJECT_SCOPED_HEADER = "X-Hippo-Project-Scoped";
60
- /** Refuses a caller's project that is blank (it would stamp user-global), past the caps, or unlike the resolver's ids: rows match verbatim, so a rewrite would split a project. Inner spaces pass, since a checkout with no remote is named by its folder. */
38
+ /** Refuses a caller's project that is blank (it would stamp user-global), past the caps, or unlike the resolver's ids: rows match
39
+ * verbatim, so a rewrite would split a project. Inner spaces pass, since a checkout with no remote is named by its folder. */
61
40
  export declare function assertCallerProject(project: {
62
41
  readonly name: string;
63
42
  readonly aliases?: readonly string[];
64
43
  }): void;
65
44
  /** `origin_project IN (?, ...)` with one placeholder per name; an empty list matches nothing. */
66
45
  export declare function originInSql(names: readonly string[], column?: string): string;
67
- /**
68
- * v39 memory scope isolation: classify a memory's origin_project against the
69
- * active project. An empty current id means the session is not in a project
70
- * (home dir or markerless cwd) - everything is in scope there, matching
71
- * pre-isolation behavior. NULL/undefined origin means no known project (a legacy
72
- * row, or a shared-store write that named none) and is treated as cross-project
73
- * (deny by default) - the safe direction for a security partition.
74
- */
46
+ /** Classifies a memory's origin_project against the active project. An empty current id (home or markerless cwd) puts everything in scope;
47
+ * NULL/undefined origin (legacy row, or a shared-store write naming none) counts as cross-project: deny by default for a security partition. */
75
48
  export declare function classifyOriginProject(origin: string | null | undefined, current: ProjectRef): 'project' | 'user-global' | 'cross-project';
76
- /**
77
- * The global Hippo store directory, resolved the same way shared.ts does:
78
- * $HIPPO_HOME > $XDG_DATA_HOME/hippo > ~/.hippo. Lives here (leaf module) so
79
- * db.ts migrations can use it without importing shared.ts (store.ts cycle);
80
- * shared.getGlobalRoot delegates to this.
81
- */
49
+ /** The global Hippo store directory ($HIPPO_HOME > $XDG_DATA_HOME/hippo > ~/.hippo); getGlobalRoot (sharing/global-store.ts) returns it.
50
+ * Leaf module so store migrations can use it without importing sharing/ (store cycle). */
82
51
  export declare function resolveGlobalRootDir(): string;
83
- /**
84
- * True when `p` IS the global store root. Used by the v39 migration so a
85
- * global store whose parent chain happens to contain `.git`/`.hippo`
86
- * (git-managed HIPPO_HOME, dotfiles setups) still backfills as user-global
87
- * ('') instead of being stamped with the surrounding repo's name - which
88
- * would hide the user's entire global corpus from every project.
89
- */
52
+ /** True when `p` IS the global store root, so a global store whose parent chain contains `.git`/`.hippo` (git-managed HIPPO_HOME) still backfills as
53
+ * user-global ('') instead of being stamped with the surrounding repo's name, which would hide the global corpus from every project. */
90
54
  export declare function isGlobalStoreRoot(p: string): boolean;
91
- /**
92
- * Parse a memory's origin from its provenance `source` string, mirroring the
93
- * v39 migration's evidence rules: `shared:<project>:<ts>` and
94
- * `promoted:<localRoot>` identify the owning project; the user home dir's
95
- * basename maps to '' (user-global). Returns null when the source carries no
96
- * origin evidence. Pure string logic - recorded paths may no longer exist.
97
- */
55
+ /** Parses a memory's origin from its provenance `source`: `shared:<project>:<ts>` and `promoted:<localRoot>` name the owning project; the home dir basename
56
+ * maps to '' (user-global). Returns null without origin evidence. Pure string logic, since recorded paths may no longer exist. */
98
57
  export declare function originFromSource(source: string | null | undefined, homeName?: string): string | null;
99
58
  /** The origin to stamp on a memory written from cwd: its project name, or '' (user-global, injectable everywhere) outside a project.
100
59
  * NULL means no known project: a legacy row with no evidence, or a write to a shared store that named none; ambient context treats it as deny. */
@@ -23,7 +23,8 @@ function remoteRuleOn() {
23
23
  remoteSwitch = { globalRoot, on: loadConfig(globalRoot).projectIdentity.remote };
24
24
  return remoteSwitch.on;
25
25
  }
26
- /** The id a root names itself by plus every rung that resolves; only the root's own `.git` is read, so a store nested in another checkout keeps its folder name. */
26
+ /** The id a root names itself by plus every rung that resolves; only the root's own
27
+ * `.git` is read, so a store nested in another checkout keeps its folder name. */
27
28
  function namesAt(root, legacyName) {
28
29
  const fileId = projectFileId(root);
29
30
  const remoteId = originRemoteId(root);
@@ -48,9 +49,8 @@ function isUnder(child, parent) {
48
49
  }
49
50
  return false;
50
51
  }
51
- /** A `.hippo` marker must be a DIRECTORY (a store) - a stray file named
52
- * `.hippo` must not turn its parent into a project. `.git` stays existsSync
53
- * because worktrees legitimately use a `.git` FILE. */
52
+ /** A `.hippo` marker must be a DIRECTORY (a store), so a stray file named `.hippo` cannot make its parent a project;
53
+ * `.git` stays existsSync because worktrees use a `.git` FILE. */
54
54
  function isDirectoryAt(p) {
55
55
  try {
56
56
  return fs.statSync(p).isDirectory();
@@ -60,10 +60,7 @@ function isDirectoryAt(p) {
60
60
  return false;
61
61
  }
62
62
  }
63
- /**
64
- * Resolve the project identity for a working directory.
65
- * Defaults to process.cwd(). Results are cached per resolved input path.
66
- */
63
+ /** Resolves the project identity for a working directory (default process.cwd()); results are cached per resolved input path. */
67
64
  export function resolveProjectIdentity(cwd, opts) {
68
65
  const startInput = path.resolve(cwd ?? process.cwd());
69
66
  const cacheable = !opts?.homeDir && !opts?.stopDir;
@@ -96,7 +93,8 @@ export function resolveProjectIdentity(cwd, opts) {
96
93
  identityCache.set(startInput, identity);
97
94
  return identity;
98
95
  }
99
- /** The repo name a linked worktree shares with its main checkout (`repo.git` or `repo/.bare` for a bare repo), so one repo is one project; null for any other checkout. */
96
+ /** The repo name a linked worktree shares with its main checkout (`repo.git` or
97
+ * `repo/.bare` for a bare repo), so one repo is one project; null for any other checkout. */
100
98
  function linkedWorktreeRepoName(gitRoot, home) {
101
99
  const marker = path.join(gitRoot, '.git');
102
100
  if (!fs.existsSync(marker) || isDirectoryAt(marker))
@@ -172,7 +170,8 @@ export function projectNames(project) {
172
170
  // Each project name is matched against every candidate row, so the caller's list stays short.
173
171
  export const MAX_PROJECT_ALIASES = 10;
174
172
  export const MCP_PROJECT_SCOPED_HEADER = 'X-Hippo-Project-Scoped';
175
- /** Refuses a caller's project that is blank (it would stamp user-global), past the caps, or unlike the resolver's ids: rows match verbatim, so a rewrite would split a project. Inner spaces pass, since a checkout with no remote is named by its folder. */
173
+ /** Refuses a caller's project that is blank (it would stamp user-global), past the caps, or unlike the resolver's ids: rows match
174
+ * verbatim, so a rewrite would split a project. Inner spaces pass, since a checkout with no remote is named by its folder. */
176
175
  export function assertCallerProject(project) {
177
176
  const { name, aliases = [] } = project;
178
177
  if (name.trim() === '')
@@ -190,14 +189,8 @@ export function assertCallerProject(project) {
190
189
  export function originInSql(names, column = 'origin_project') {
191
190
  return names.length === 0 ? '0' : `${column} IN (${names.map(() => '?').join(', ')})`;
192
191
  }
193
- /**
194
- * v39 memory scope isolation: classify a memory's origin_project against the
195
- * active project. An empty current id means the session is not in a project
196
- * (home dir or markerless cwd) - everything is in scope there, matching
197
- * pre-isolation behavior. NULL/undefined origin means no known project (a legacy
198
- * row, or a shared-store write that named none) and is treated as cross-project
199
- * (deny by default) - the safe direction for a security partition.
200
- */
192
+ /** Classifies a memory's origin_project against the active project. An empty current id (home or markerless cwd) puts everything in scope;
193
+ * NULL/undefined origin (legacy row, or a shared-store write naming none) counts as cross-project: deny by default for a security partition. */
201
194
  export function classifyOriginProject(origin, current) {
202
195
  if (projectId(current) === '')
203
196
  return 'project';
@@ -207,12 +200,8 @@ export function classifyOriginProject(origin, current) {
207
200
  return 'user-global';
208
201
  return projectNames(current).includes(origin) ? 'project' : 'cross-project';
209
202
  }
210
- /**
211
- * The global Hippo store directory, resolved the same way shared.ts does:
212
- * $HIPPO_HOME > $XDG_DATA_HOME/hippo > ~/.hippo. Lives here (leaf module) so
213
- * db.ts migrations can use it without importing shared.ts (store.ts cycle);
214
- * shared.getGlobalRoot delegates to this.
215
- */
203
+ /** The global Hippo store directory ($HIPPO_HOME > $XDG_DATA_HOME/hippo > ~/.hippo); getGlobalRoot (sharing/global-store.ts) returns it.
204
+ * Leaf module so store migrations can use it without importing sharing/ (store cycle). */
216
205
  export function resolveGlobalRootDir() {
217
206
  const hippoHome = envHippoHome();
218
207
  if (hippoHome)
@@ -222,23 +211,13 @@ export function resolveGlobalRootDir() {
222
211
  return path.join(xdgData, 'hippo');
223
212
  return path.join(os.homedir(), '.hippo');
224
213
  }
225
- /**
226
- * True when `p` IS the global store root. Used by the v39 migration so a
227
- * global store whose parent chain happens to contain `.git`/`.hippo`
228
- * (git-managed HIPPO_HOME, dotfiles setups) still backfills as user-global
229
- * ('') instead of being stamped with the surrounding repo's name - which
230
- * would hide the user's entire global corpus from every project.
231
- */
214
+ /** True when `p` IS the global store root, so a global store whose parent chain contains `.git`/`.hippo` (git-managed HIPPO_HOME) still backfills as
215
+ * user-global ('') instead of being stamped with the surrounding repo's name, which would hide the global corpus from every project. */
232
216
  export function isGlobalStoreRoot(p) {
233
217
  return samePath(realpathOrResolve(path.resolve(p)), realpathOrResolve(resolveGlobalRootDir()));
234
218
  }
235
- /**
236
- * Parse a memory's origin from its provenance `source` string, mirroring the
237
- * v39 migration's evidence rules: `shared:<project>:<ts>` and
238
- * `promoted:<localRoot>` identify the owning project; the user home dir's
239
- * basename maps to '' (user-global). Returns null when the source carries no
240
- * origin evidence. Pure string logic - recorded paths may no longer exist.
241
- */
219
+ /** Parses a memory's origin from its provenance `source`: `shared:<project>:<ts>` and `promoted:<localRoot>` name the owning project; the home dir basename
220
+ * maps to '' (user-global). Returns null without origin evidence. Pure string logic, since recorded paths may no longer exist. */
242
221
  export function originFromSource(source, homeName) {
243
222
  if (!source)
244
223
  return null;
@@ -7,9 +7,10 @@ import { errorMessage, log } from '../util/log.js';
7
7
  export function gitConfigPath(gitRoot) {
8
8
  const marker = path.join(gitRoot, '.git');
9
9
  try {
10
- if (fs.statSync(marker).isDirectory())
10
+ const pointer = gitFilePointer(marker);
11
+ if (pointer === null)
11
12
  return path.join(marker, 'config');
12
- const gitDir = /^gitdir:\s*(.+)$/m.exec(fs.readFileSync(marker, 'utf8'))?.[1]?.trim();
13
+ const gitDir = /^gitdir:\s*(.+)$/m.exec(pointer)?.[1]?.trim();
13
14
  if (!gitDir)
14
15
  return null;
15
16
  const linkDir = path.resolve(gitRoot, gitDir);
@@ -23,6 +24,16 @@ export function gitConfigPath(gitRoot) {
23
24
  return null;
24
25
  }
25
26
  }
27
+ /** The text of a `.git` file, or null when `.git` is a folder; one descriptor answers both, so the path cannot change in between. */
28
+ function gitFilePointer(marker) {
29
+ const fd = fs.openSync(marker, 'r');
30
+ try {
31
+ return fs.fstatSync(fd).isDirectory() ? null : fs.readFileSync(fd, 'utf8');
32
+ }
33
+ finally {
34
+ fs.closeSync(fd);
35
+ }
36
+ }
26
37
  /** One config value with git's quoting: `"` toggles quoting, backslash escapes, and an unquoted `#` or `;` starts a comment. */
27
38
  function configValue(raw) {
28
39
  let out = '';
@@ -0,0 +1,5 @@
1
+ /** The refusal a delete of a raw row gets; a plain Error subclass, so it joins no HTTP status family. */
2
+ export declare class RawAppendOnlyError extends Error {
3
+ constructor(cause: Error);
4
+ }
5
+ //# sourceMappingURL=raw-append-only.d.ts.map
@@ -0,0 +1,7 @@
1
+ /** The refusal a delete of a raw row gets; a plain Error subclass, so it joins no HTTP status family. */
2
+ export class RawAppendOnlyError extends Error {
3
+ constructor(cause) {
4
+ super('raw is append-only', { cause });
5
+ }
6
+ }
7
+ //# sourceMappingURL=raw-append-only.js.map
@@ -1,10 +1,4 @@
1
- /**
2
- * Salience gate — decides at memory creation time whether content is worth
3
- * storing at full strength, should start weakened, or should be skipped.
4
- *
5
- * Inspired by the biological salience network (anterior insula + dACC):
6
- * not everything that enters working memory deserves long-term storage.
7
- */
1
+ /** Salience gate: decides at memory creation whether content is stored at full strength, starts weakened, or is skipped. */
8
2
  import type { MemoryEntry } from './memory.js';
9
3
  export type SalienceDecision = 'store' | 'skip' | 'start_weak';
10
4
  export interface SalienceResult {
@@ -1,10 +1,4 @@
1
- /**
2
- * Salience gate — decides at memory creation time whether content is worth
3
- * storing at full strength, should start weakened, or should be skipped.
4
- *
5
- * Inspired by the biological salience network (anterior insula + dACC):
6
- * not everything that enters working memory deserves long-term storage.
7
- */
1
+ /** Salience gate: decides at memory creation whether content is stored at full strength, starts weakened, or is skipped. */
8
2
  import { textOverlap } from '../util/tokenize.js';
9
3
  import { duplicateKey, heldTextKeys } from '../util/same-text.js';
10
4
  // Each store or skip reason carries a score; a novel memory adds bonuses for structure and length.
@@ -1,6 +1,7 @@
1
1
  // The four dashboard writes, each a thin call into an existing store or api function; the router owns HTTP and the cache.
2
2
  import * as api from '../api/index.js';
3
3
  import { NotFoundError } from '../core/api-errors.js';
4
+ import { RawAppendOnlyError } from '../core/raw-append-only.js';
4
5
  import { listTouchableConflicts, resolveConflict } from '../store/conflicts.js';
5
6
  import { readEntry } from '../store/entry-reads.js';
6
7
  import { writeEntry } from '../store/entry-writes.js';
@@ -52,8 +53,7 @@ export function forgetMemory(hippoRoot, tenantId, rawId) {
52
53
  catch (err) {
53
54
  if (err instanceof NotFoundError)
54
55
  return notFound();
55
- // Same match as cmdForget: the append-only trigger names itself in the message.
56
- if (err instanceof Error && /append-only/i.test(err.message)) {
56
+ if (err instanceof RawAppendOnlyError) {
57
57
  const error = `Cannot forget ${id}: it is a raw, append-only memory. Archive it instead: hippo forget ${id} --archive --reason "<why>"`;
58
58
  return { status: 409, body: { error }, changed: false };
59
59
  }