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
@@ -7,32 +7,10 @@ export interface VerifyOpts {
7
7
  previousSecret?: string;
8
8
  }
9
9
  export declare function verifyGitHubSignature(opts: VerifyOpts): boolean;
10
- /**
11
- * Source-aware idempotency key: artifact_ref plus the source-side updated_at.
12
- * A raw-body key would hash a webhook envelope and a REST backfill item of the
13
- * SAME source event differently and ingest it twice. Same artifact + same
14
- * revision = same key, whichever path delivered it; an edit gets a new key,
15
- * which is correct because each edit IS a new memory revision.
16
- *
17
- * Both inputs are upstream-derived from the parsed event, not from the
18
- * unsigned delivery header — replay attacks still cannot bypass dedupe.
19
- *
20
- * Inputs:
21
- * - artifactRef: e.g. 'github://acme/repo/issue/42' or
22
- * 'github://acme/repo/issue/42/comment/123'.
23
- * - updatedAt: source-side ISO timestamp (issue.updated_at,
24
- * comment.updated_at, pull_request.updated_at). Empty string when the
25
- * payload omits it (rare; older REST shapes).
26
- */
10
+ /** Source-aware idempotency key: artifact_ref plus the source-side updated_at, so a webhook and a REST backfill of the SAME event dedupe.
11
+ * An edit gets a new key (a new revision); both inputs come from the parsed event, not the unsigned delivery header, so replays cannot bypass dedupe. */
27
12
  export declare function computeIdempotencyKey(artifactRef: string, updatedAt: string | null | undefined): string;
28
- /**
29
- * Deletion-specific idempotency key: sha256('deleted:' + artifactRef + ':' +
30
- * updatedAt). Distinct namespace from computeIdempotencyKey so an ingest's row
31
- * in github_event_log doesn't make a deletion return 'duplicate' before it
32
- * gets a chance to archive; retries of the SAME deletion still dedupe.
33
- *
34
- * Kept as a separate exported function so the namespace prefix is explicit
35
- * at every call site (server.ts deletion branches, deletion.ts, DLQ replay).
36
- */
13
+ /** Deletion idempotency key: sha256('deleted:' + artifactRef + ':' + updatedAt).
14
+ * A separate namespace so an ingest's event-log row cannot make a deletion return 'duplicate'; retries of the same deletion still dedupe. */
37
15
  export declare function computeDeletionKey(artifactRef: string, updatedAt: string | null | undefined): string;
38
16
  //# sourceMappingURL=signature.d.ts.map
@@ -16,35 +16,13 @@ export function verifyGitHubSignature(opts) {
16
16
  return true;
17
17
  return false;
18
18
  }
19
- /**
20
- * Source-aware idempotency key: artifact_ref plus the source-side updated_at.
21
- * A raw-body key would hash a webhook envelope and a REST backfill item of the
22
- * SAME source event differently and ingest it twice. Same artifact + same
23
- * revision = same key, whichever path delivered it; an edit gets a new key,
24
- * which is correct because each edit IS a new memory revision.
25
- *
26
- * Both inputs are upstream-derived from the parsed event, not from the
27
- * unsigned delivery header — replay attacks still cannot bypass dedupe.
28
- *
29
- * Inputs:
30
- * - artifactRef: e.g. 'github://acme/repo/issue/42' or
31
- * 'github://acme/repo/issue/42/comment/123'.
32
- * - updatedAt: source-side ISO timestamp (issue.updated_at,
33
- * comment.updated_at, pull_request.updated_at). Empty string when the
34
- * payload omits it (rare; older REST shapes).
35
- */
19
+ /** Source-aware idempotency key: artifact_ref plus the source-side updated_at, so a webhook and a REST backfill of the SAME event dedupe.
20
+ * An edit gets a new key (a new revision); both inputs come from the parsed event, not the unsigned delivery header, so replays cannot bypass dedupe. */
36
21
  export function computeIdempotencyKey(artifactRef, updatedAt) {
37
22
  return createHash('sha256').update(`${artifactRef}:${updatedAt ?? ''}`).digest('hex');
38
23
  }
39
- /**
40
- * Deletion-specific idempotency key: sha256('deleted:' + artifactRef + ':' +
41
- * updatedAt). Distinct namespace from computeIdempotencyKey so an ingest's row
42
- * in github_event_log doesn't make a deletion return 'duplicate' before it
43
- * gets a chance to archive; retries of the SAME deletion still dedupe.
44
- *
45
- * Kept as a separate exported function so the namespace prefix is explicit
46
- * at every call site (server.ts deletion branches, deletion.ts, DLQ replay).
47
- */
24
+ /** Deletion idempotency key: sha256('deleted:' + artifactRef + ':' + updatedAt).
25
+ * A separate namespace so an ingest's event-log row cannot make a deletion return 'duplicate'; retries of the same deletion still dedupe. */
48
26
  export function computeDeletionKey(artifactRef, updatedAt) {
49
27
  return createHash('sha256').update(`deleted:${artifactRef}:${updatedAt ?? ''}`).digest('hex');
50
28
  }
@@ -5,29 +5,7 @@ export interface ResolveArgs {
5
5
  /** `repository.full_name` from the webhook envelope, used for PAT-mode multi-tenant routing. */
6
6
  repoFullName?: string | null;
7
7
  }
8
- /**
9
- * Resolve the tenant_id for a GitHub webhook envelope.
10
- *
11
- * Returns:
12
- * - mapped tenant_id when `github_installations` has a row for `installationId`
13
- * (App-mode multi-tenant — primary path)
14
- * - mapped tenant_id when `installation` is absent, `repository.full_name`
15
- * matches a `github_repositories` row (PAT-mode multi-tenant)
16
- * - the deployment's HIPPO_TENANT fallback (or 'default') when BOTH routing
17
- * tables are empty (single-tenant deployment — env fallback is safe)
18
- * - null when:
19
- * - `installationId` is present but unknown AND `github_installations`
20
- * is non-empty (multi-tenant install with foreign installation)
21
- * - `installationId` is missing AND either routing table is non-empty
22
- * AND no `repository.full_name` match (PAT-mode webhook from a foreign
23
- * account)
24
- *
25
- * Escape hatch: `GITHUB_ALLOW_UNKNOWN_INSTALLATION_FALLBACK=1` restores the
26
- * env fallback for emergency rollback only. Mirrors the Slack equivalent
27
- * (`SLACK_ALLOW_UNKNOWN_TEAM_FALLBACK`).
28
- *
29
- * The fail-closed contract lives here so every caller (route handler, CLI
30
- * replay, future MCP) gets identical protection.
31
- */
8
+ /** Resolve a GitHub envelope's tenant_id by installation id, then repository.full_name; the HIPPO_TENANT fallback applies only if both tables are empty.
9
+ * An unknown installation or repo on a multi-tenant deployment returns null (fail closed); GITHUB_ALLOW_UNKNOWN_INSTALLATION_FALLBACK=1 escapes. */
32
10
  export declare function resolveTenantForGitHub(hippoRoot: string, args: ResolveArgs, store?: HippoStore): Promise<string | null>;
33
11
  //# sourceMappingURL=tenant-routing.d.ts.map
@@ -1,32 +1,10 @@
1
- import { envGithubAllowUnknownInstallationFallback, envTenant } from '../../util/env.js';
1
+ import { envGitHubAllowUnknownInstallationFallback, envTenant } from '../../util/env.js';
2
2
  import { requireGroup, storeFor } from '../../store/index.js';
3
- /**
4
- * Resolve the tenant_id for a GitHub webhook envelope.
5
- *
6
- * Returns:
7
- * - mapped tenant_id when `github_installations` has a row for `installationId`
8
- * (App-mode multi-tenant — primary path)
9
- * - mapped tenant_id when `installation` is absent, `repository.full_name`
10
- * matches a `github_repositories` row (PAT-mode multi-tenant)
11
- * - the deployment's HIPPO_TENANT fallback (or 'default') when BOTH routing
12
- * tables are empty (single-tenant deployment — env fallback is safe)
13
- * - null when:
14
- * - `installationId` is present but unknown AND `github_installations`
15
- * is non-empty (multi-tenant install with foreign installation)
16
- * - `installationId` is missing AND either routing table is non-empty
17
- * AND no `repository.full_name` match (PAT-mode webhook from a foreign
18
- * account)
19
- *
20
- * Escape hatch: `GITHUB_ALLOW_UNKNOWN_INSTALLATION_FALLBACK=1` restores the
21
- * env fallback for emergency rollback only. Mirrors the Slack equivalent
22
- * (`SLACK_ALLOW_UNKNOWN_TEAM_FALLBACK`).
23
- *
24
- * The fail-closed contract lives here so every caller (route handler, CLI
25
- * replay, future MCP) gets identical protection.
26
- */
3
+ /** Resolve a GitHub envelope's tenant_id by installation id, then repository.full_name; the HIPPO_TENANT fallback applies only if both tables are empty.
4
+ * An unknown installation or repo on a multi-tenant deployment returns null (fail closed); GITHUB_ALLOW_UNKNOWN_INSTALLATION_FALLBACK=1 escapes. */
27
5
  export async function resolveTenantForGitHub(hippoRoot, args, store) {
28
6
  const envFallback = () => envTenant();
29
- const escapeHatch = envGithubAllowUnknownInstallationFallback();
7
+ const escapeHatch = envGitHubAllowUnknownInstallationFallback();
30
8
  const routing = await requireGroup(storeFor({ hippoRoot, store }), 'connectorEvents').githubRouting(args);
31
9
  if (routing.tenant)
32
10
  return routing.tenant;
@@ -1,20 +1,6 @@
1
1
  import { scopeFromRepository } from './scope.js';
2
- /**
3
- * Convert GitHub webhook events into RememberOpts for api.remember(). Each
4
- * function returns null when the event has no usable body so the webhook
5
- * caller can mark the delivery seen for idempotency and skip the insert.
6
- *
7
- * Contract (mirrors src/connectors/slack/transform.ts):
8
- * - kind is the literal 'raw' (connector boundary, see src/importers.ts).
9
- * - artifact_ref formats are stable; deletion paths look up by these strings.
10
- * - issue: github://<owner/repo>/issue/<number>
11
- * - issue_comment: github://<owner/repo>/issue/<number>/comment/<id>
12
- * - pull_request: github://<owner/repo>/pull/<number>
13
- * - pr_review_comment: github://<owner/repo>/pull/<number>/review_comment/<id>
14
- * - owner is `user:github:<login>`. Required by the provenance gate.
15
- * - scope is derived from repository.private via scopeFromRepository (default
16
- * private when undetermined).
17
- */
2
+ /** Convert GitHub webhook events into RememberOpts; each returns null when the event has no usable body so the caller marks it seen and skips the insert.
3
+ * artifact_ref formats (github://<owner/repo>/issue|pull/<n>[/comment|review_comment/<id>]) are stable because deletion looks rows up by them. */
18
4
  const UNKNOWN_REPO = 'unknown/unknown';
19
5
  export function issueEventToRememberOpts(evt) {
20
6
  const body = evt.issue.body?.trim();
@@ -1,19 +1,7 @@
1
- /**
2
- * GitHub webhook event shapes used by the ingestion connector.
3
- * Spec: https://docs.github.com/en/webhooks/webhook-events-and-payloads
4
- *
5
- * V1 cares about four event types: issues, issue_comment, pull_request,
6
- * pull_request_review_comment. Each guard is gated on the X-GitHub-Event
7
- * header value so a malicious or misrouted payload cannot satisfy a guard
8
- * for the wrong event type.
9
- */
1
+ /** GitHub webhook event shapes for the ingestion connector (https://docs.github.com/en/webhooks/webhook-events-and-payloads).
2
+ * Each guard is gated on the X-GitHub-Event header so a misrouted payload cannot satisfy a guard for the wrong event type. */
10
3
  import { type JsonValue } from '../../util/json.js';
11
- /**
12
- * `private` MUST be optional, not required. The Slack-style
13
- * fail-safe in scope.ts requires an envelope with `private: undefined` to
14
- * map to private; a strict boolean type would reject the payload before
15
- * scope can fail closed.
16
- */
4
+ /** `private` MUST stay optional: scope.ts maps `private: undefined` to private, and a strict boolean would reject the payload before scope can fail closed. */
17
5
  export interface GitHubRepository {
18
6
  full_name: string;
19
7
  private?: boolean;
@@ -1,12 +1,5 @@
1
- /**
2
- * GitHub webhook event shapes used by the ingestion connector.
3
- * Spec: https://docs.github.com/en/webhooks/webhook-events-and-payloads
4
- *
5
- * V1 cares about four event types: issues, issue_comment, pull_request,
6
- * pull_request_review_comment. Each guard is gated on the X-GitHub-Event
7
- * header value so a malicious or misrouted payload cannot satisfy a guard
8
- * for the wrong event type.
9
- */
1
+ /** GitHub webhook event shapes for the ingestion connector (https://docs.github.com/en/webhooks/webhook-events-and-payloads).
2
+ * Each guard is gated on the X-GitHub-Event header so a misrouted payload cannot satisfy a guard for the wrong event type. */
10
3
  import { isJsonString, isJsonNumber } from '../../util/json.js';
11
4
  function isObjectOrArray(x) {
12
5
  return x !== null && typeof x === 'object';
@@ -1,20 +1,6 @@
1
1
  import type { HippoStore } from '../../store/index.js';
2
2
  import { type WebhookRequest } from '../../util/http-util.js';
3
- /**
4
- * GitHub webhook receiver. Mirrors the Slack route shape but with
5
- * GitHub-specific idioms:
6
- * 1. HMAC SHA-256 over the raw body (X-Hub-Signature-256), no timestamp.
7
- * 2. Event type discriminated by the X-GitHub-Event header (not body.type).
8
- * 3. X-GitHub-Delivery is required audit metadata (NOT the dedupe seam - see
9
- * computeIdempotencyKey, which folds the signed body into the key so a
10
- * replayed body with a fresh delivery UUID still dedupes).
11
- * 4. Tenant resolved by installation.id → github_installations, then by
12
- * repository.full_name → github_repositories (PAT-mode multi-tenant).
13
- * 5. ALWAYS ACK 200 on signed envelopes (DLQ included). 401 only on bad
14
- * signature; 404 only when GITHUB_WEBHOOK_SECRET is unset (don't expose
15
- * the route's existence on builds where it's gated off).
16
- *
17
- * Bearer auth is skipped on purpose: server.ts checks isPublicRoute before calling this.
18
- */
3
+ /** GitHub webhook receiver: HMAC SHA-256 over the raw body, event type from the X-GitHub-Event header, tenant by installation.id then repository.full_name.
4
+ * ACKs 200 on signed envelopes (DLQ too); 401 only on a bad signature; 404 when GITHUB_WEBHOOK_SECRET is unset. No Bearer: server.ts checks isPublicRoute. */
19
5
  export declare function handleGitHubEventsWebhook(request: WebhookRequest, store?: HippoStore): Promise<void>;
20
6
  //# sourceMappingURL=webhook.d.ts.map
@@ -1,4 +1,4 @@
1
- import { envGithubWebhookSecret, envGithubWebhookSecretPrevious } from '../../util/env.js';
1
+ import { envGitHubWebhookSecret, envGitHubWebhookSecretPrevious } from '../../util/env.js';
2
2
  import { verifyGitHubSignature } from './signature.js';
3
3
  import { isGitHubWebhookEnvelope, isGitHubIssueEvent, isGitHubIssueCommentEvent, isGitHubPullRequestEvent, isGitHubPullRequestReviewCommentEvent, } from './types.js';
4
4
  import { ingestEvent as ingestGitHubEvent } from './ingest.js';
@@ -9,33 +9,19 @@ import { resolveTenantForGitHub } from './tenant-routing.js';
9
9
  import { computeDeletionKey as computeGitHubDeletionKey } from './signature.js';
10
10
  import { resolveTenantId } from '../../store/tenant.js';
11
11
  import { HttpError, JSON_HEADERS, isHeaderString, closeIfBodyUnread, readWebhookBody, sendJson, } from '../../util/http-util.js';
12
- /**
13
- * GitHub webhook receiver. Mirrors the Slack route shape but with
14
- * GitHub-specific idioms:
15
- * 1. HMAC SHA-256 over the raw body (X-Hub-Signature-256), no timestamp.
16
- * 2. Event type discriminated by the X-GitHub-Event header (not body.type).
17
- * 3. X-GitHub-Delivery is required audit metadata (NOT the dedupe seam - see
18
- * computeIdempotencyKey, which folds the signed body into the key so a
19
- * replayed body with a fresh delivery UUID still dedupes).
20
- * 4. Tenant resolved by installation.id → github_installations, then by
21
- * repository.full_name → github_repositories (PAT-mode multi-tenant).
22
- * 5. ALWAYS ACK 200 on signed envelopes (DLQ included). 401 only on bad
23
- * signature; 404 only when GITHUB_WEBHOOK_SECRET is unset (don't expose
24
- * the route's existence on builds where it's gated off).
25
- *
26
- * Bearer auth is skipped on purpose: server.ts checks isPublicRoute before calling this.
27
- */
12
+ /** GitHub webhook receiver: HMAC SHA-256 over the raw body, event type from the X-GitHub-Event header, tenant by installation.id then repository.full_name.
13
+ * ACKs 200 on signed envelopes (DLQ too); 401 only on a bad signature; 404 when GITHUB_WEBHOOK_SECRET is unset. No Bearer: server.ts checks isPublicRoute. */
28
14
  export async function handleGitHubEventsWebhook(request, store) {
29
15
  const { req, res, opts } = request;
30
16
  // Secret and signature header before the body, so a caller with neither cannot make the server buffer one.
31
- const secret = envGithubWebhookSecret();
17
+ const secret = envGitHubWebhookSecret();
32
18
  if (!secret) {
33
19
  closeIfBodyUnread(request);
34
20
  res.writeHead(404, JSON_HEADERS);
35
21
  res.end(JSON.stringify({ error: 'not found' }));
36
22
  return;
37
23
  }
38
- const previousSecret = envGithubWebhookSecretPrevious();
24
+ const previousSecret = envGitHubWebhookSecretPrevious();
39
25
  const sigHdr = req.headers['x-hub-signature-256'];
40
26
  const eventHdr = req.headers['x-github-event'];
41
27
  const deliveryHdr = req.headers['x-github-delivery'];
@@ -167,9 +153,7 @@ async function dispatchGitHubEvent(d, ctx, body, deliveryId, routing) {
167
153
  if (action === null)
168
154
  return false;
169
155
  if (action.kind === 'manual-review') {
170
- // GitHub does fire issues.deleted (admin-initiated). Don't archive - V1
171
- // policy is to log and let an operator decide. Archive could lose the
172
- // memory if the issue is being moved between accounts.
156
+ // issues.deleted (admin-initiated) is logged, not archived: archiving could lose the memory if the issue moves between accounts.
173
157
  await parkAndAck(d, {
174
158
  ...routing,
175
159
  tenantId: ctx.tenantId,
@@ -9,14 +9,8 @@ export type SlackHistoryFetcher = (args: {
9
9
  channelId: string;
10
10
  /** Slack's opaque pagination token. Null on first page of a backfill run. */
11
11
  cursor: string | null;
12
- /**
13
- * Incremental-resume bound: skip messages with ts <= oldest. Set from
14
- * `slack_cursors.latest_ts` on the FIRST page of a rerun; unused on
15
- * subsequent pages within one run (where `cursor` carries us forward).
16
- * Distinct from `cursor` because Slack treats `cursor` as opaque token
17
- * and `oldest` as a numeric ts — feeding `latest_ts` as `cursor` breaks
18
- * against the live API even though it round-trips through test fetchers.
19
- */
12
+ /** Incremental-resume bound: skip messages with ts <= oldest, set from `slack_cursors.latest_ts` on the first page only.
13
+ * Kept apart from `cursor` because Slack treats `cursor` as an opaque token, so feeding latest_ts as cursor fails on the live API. */
20
14
  oldest?: string;
21
15
  }) => Promise<SlackHistoryPage>;
22
16
  export interface BackfillOpts {
@@ -26,15 +20,8 @@ export interface BackfillOpts {
26
20
  /** Stop after this many messages. Default: unlimited. */
27
21
  maxMessages?: number;
28
22
  }
29
- /**
30
- * Page through `conversations.history` via the injected fetcher and ingest each
31
- * message. The cursor is persisted to `slack_cursors` after every page so a
32
- * crash mid-backfill resumes near where it left off.
33
- *
34
- * Each ingested message uses a synthesized eventId of the form
35
- * `backfill:${teamId}:${channelId}:${ts}`. Reruns dedupe via the
36
- * `slack_event_log` PK so calling `backfillChannel` twice is safe.
37
- */
23
+ /** Page through `conversations.history` and ingest each message, persisting the cursor to `slack_cursors` after every page.
24
+ * The synthesized eventId `backfill:${teamId}:${channelId}:${ts}` makes reruns dedupe via the `slack_event_log` PK. */
38
25
  export declare function backfillChannel(ctx: Context, opts: BackfillOpts): Promise<{
39
26
  ingested: number;
40
27
  pages: number;
@@ -1,19 +1,10 @@
1
1
  import { saveSlackCursor, slackCursor } from '../../store/connectors/slack.js';
2
2
  import { ingestMessage } from './ingest.js';
3
- /**
4
- * Page through `conversations.history` via the injected fetcher and ingest each
5
- * message. The cursor is persisted to `slack_cursors` after every page so a
6
- * crash mid-backfill resumes near where it left off.
7
- *
8
- * Each ingested message uses a synthesized eventId of the form
9
- * `backfill:${teamId}:${channelId}:${ts}`. Reruns dedupe via the
10
- * `slack_event_log` PK so calling `backfillChannel` twice is safe.
11
- */
3
+ /** Page through `conversations.history` and ingest each message, persisting the cursor to `slack_cursors` after every page.
4
+ * The synthesized eventId `backfill:${teamId}:${channelId}:${ts}` makes reruns dedupe via the `slack_event_log` PK. */
12
5
  export async function backfillChannel(ctx, opts) {
13
- // Resume bound from previous run; passed as `oldest` (numeric ts) on the
14
- // first page only. `cursor` starts null — Slack mints the next-page token
15
- // and we feed it back. Mixing the two would feed a numeric ts as an opaque
16
- // cursor and break against the live API on rerun.
6
+ // `oldest` (numeric ts) is the resume bound for the first page only; `cursor` starts null and Slack mints the next-page token.
7
+ // Mixing the two would feed a numeric ts as an opaque cursor and break on rerun.
17
8
  const resumeFrom = slackCursor(ctx.hippoRoot, ctx.tenantId, opts.channel.id);
18
9
  let cursor = null;
19
10
  let ingested = 0;
@@ -14,24 +14,7 @@ export interface ReplayDlqOpts {
14
14
  /** Skew window override for tests. */
15
15
  skewSeconds?: number;
16
16
  }
17
- /**
18
- * Replay a DLQ row through the normal ingest path. Used by `hippo slack dlq
19
- * replay <id> [--force]`.
20
- *
21
- * Behavior:
22
- * 1. SELECT the row.
23
- * 2. If signature + slack_timestamp are present and `signingSecret` is set,
24
- * re-verify with the CURRENT secret (not previous). Failure → bail unless
25
- * --force. Legacy rows from before v19 may have NULL signature; those
26
- * require --force to replay safely.
27
- * 3. Re-parse the raw_payload and dispatch to ingestMessage / handleMessageDeleted.
28
- * 4. On success: mark retried_at, increment retry_count.
29
- * 5. On failure: increment retry_count only, leave the row.
30
- *
31
- * The replay always uses the routing the deployment has NOW (current
32
- * slack_workspaces table + env), not whatever was in effect when the original
33
- * envelope was DLQed. That is intentional: the DLQ exists to be drained after
34
- * the operator fixed the routing.
35
- */
17
+ /** Replay a DLQ row via the normal ingest path (`hippo slack dlq replay <id> [--force]`), re-verifying the signature with the CURRENT secret unless forced.
18
+ * Rows with a NULL signature need --force; replays use today's routing, because the DLQ exists to be drained after the operator fixed routing. */
36
19
  export declare function replayDlqEntry(ctx: Pick<Context, 'hippoRoot'>, id: number, opts?: ReplayDlqOpts): Promise<ReplayResult>;
37
20
  //# sourceMappingURL=dlq.d.ts.map
@@ -12,25 +12,8 @@ export const slackDlq = {
12
12
  letter: (row) => ({ connector: 'slack', ...row }),
13
13
  list: listSlackDlq,
14
14
  };
15
- /**
16
- * Replay a DLQ row through the normal ingest path. Used by `hippo slack dlq
17
- * replay <id> [--force]`.
18
- *
19
- * Behavior:
20
- * 1. SELECT the row.
21
- * 2. If signature + slack_timestamp are present and `signingSecret` is set,
22
- * re-verify with the CURRENT secret (not previous). Failure → bail unless
23
- * --force. Legacy rows from before v19 may have NULL signature; those
24
- * require --force to replay safely.
25
- * 3. Re-parse the raw_payload and dispatch to ingestMessage / handleMessageDeleted.
26
- * 4. On success: mark retried_at, increment retry_count.
27
- * 5. On failure: increment retry_count only, leave the row.
28
- *
29
- * The replay always uses the routing the deployment has NOW (current
30
- * slack_workspaces table + env), not whatever was in effect when the original
31
- * envelope was DLQed. That is intentional: the DLQ exists to be drained after
32
- * the operator fixed the routing.
33
- */
15
+ /** Replay a DLQ row via the normal ingest path (`hippo slack dlq replay <id> [--force]`), re-verifying the signature with the CURRENT secret unless forced.
16
+ * Rows with a NULL signature need --force; replays use today's routing, because the DLQ exists to be drained after the operator fixed routing. */
34
17
  export async function replayDlqEntry(ctx, id, opts = {}) {
35
18
  const row = slackDlqEntry(ctx.hippoRoot, id);
36
19
  if (!row)
@@ -13,8 +13,7 @@ export interface IngestResult {
13
13
  status: IngestStatus;
14
14
  memoryId: string | null;
15
15
  }
16
- /** Ingests a Slack message as a kind='raw' memory, once per event id: Slack redelivers within a minute.
17
- * The pre-check is only the fast path; the store logs the event in the memory's own transaction, which is what holds when two workers race.
18
- * An empty body is logged with no memory, so its replay skips the transform. */
16
+ /** Ingests a Slack message as a kind='raw' memory once per event id (Slack redelivers within a minute); the pre-check is only the fast path,
17
+ * the store logs the event in the memory's own transaction, which holds when two workers race. An empty body is logged with no memory. */
19
18
  export declare function ingestMessage(ctx: Context, input: IngestInput): Promise<IngestResult>;
20
19
  //# sourceMappingURL=ingest.d.ts.map
@@ -2,9 +2,8 @@ import { remember } from '../../api/index.js';
2
2
  import { requireGroup, storeFor } from '../../store/index.js';
3
3
  import { RejectedValueError } from '../../store/rejection.js';
4
4
  import { messageToRememberOpts } from './transform.js';
5
- /** Ingests a Slack message as a kind='raw' memory, once per event id: Slack redelivers within a minute.
6
- * The pre-check is only the fast path; the store logs the event in the memory's own transaction, which is what holds when two workers race.
7
- * An empty body is logged with no memory, so its replay skips the transform. */
5
+ /** Ingests a Slack message as a kind='raw' memory once per event id (Slack redelivers within a minute); the pre-check is only the fast path,
6
+ * the store logs the event in the memory's own transaction, which holds when two workers race. An empty body is logged with no memory. */
8
7
  export async function ingestMessage(ctx, input) {
9
8
  const events = requireGroup(storeFor(ctx), 'connectorEvents');
10
9
  const event = { connector: 'slack', eventId: input.eventId };
@@ -4,13 +4,7 @@ export interface ChannelMeta {
4
4
  is_im?: boolean;
5
5
  is_mpim?: boolean;
6
6
  }
7
- /**
8
- * Map a Slack channel into a hippo scope string.
9
- *
10
- * Default to private when privacy is undetermined. The cost of leaking a
11
- * public channel into private scope (recall returns nothing) is far smaller
12
- * than the cost of leaking a private channel into public scope (data exposed
13
- * to a tenant that should not see it).
14
- */
7
+ /** Map a Slack channel into a hippo scope string, defaulting to private when privacy is undetermined:
8
+ * a public channel leaking into private scope returns nothing, but the reverse exposes data. */
15
9
  export declare function scopeFromChannel(ch: ChannelMeta): string;
16
10
  //# sourceMappingURL=scope.d.ts.map
@@ -1,11 +1,5 @@
1
- /**
2
- * Map a Slack channel into a hippo scope string.
3
- *
4
- * Default to private when privacy is undetermined. The cost of leaking a
5
- * public channel into private scope (recall returns nothing) is far smaller
6
- * than the cost of leaking a private channel into public scope (data exposed
7
- * to a tenant that should not see it).
8
- */
1
+ /** Map a Slack channel into a hippo scope string, defaulting to private when privacy is undetermined:
2
+ * a public channel leaking into private scope returns nothing, but the reverse exposes data. */
9
3
  export function scopeFromChannel(ch) {
10
4
  const isPublic = ch.is_private === false && !ch.is_im && !ch.is_mpim;
11
5
  return isPublic ? `slack:public:${ch.id}` : `slack:private:${ch.id}`;
@@ -3,12 +3,7 @@ export interface VerifyOpts {
3
3
  timestamp: string;
4
4
  signature: string;
5
5
  signingSecret: string;
6
- /**
7
- * Previous signing secret during a rotation. Deploy with
8
- * both `SLACK_SIGNING_SECRET` (new) and `SLACK_SIGNING_SECRET_PREVIOUS` (old)
9
- * set, verify both work, drop previous after rollover. The verifier tries
10
- * `signingSecret` first, then `previousSecret` if that fails.
11
- */
6
+ /** Previous signing secret during rotation (SLACK_SIGNING_SECRET_PREVIOUS); the verifier tries `signingSecret` first, then this. */
12
7
  previousSecret?: string;
13
8
  /** Current unix seconds. Injectable for tests. */
14
9
  now?: number;
@@ -1,22 +1,5 @@
1
- import type { DatabaseSyncLike } from '../../db/index.js';
2
1
  import { type HippoStore } from '../../store/index.js';
3
- /**
4
- * Look up the tenant_id for a Slack team_id.
5
- *
6
- * Returns:
7
- * - mapped tenant_id when slack_workspaces has a row for `teamId`
8
- * - the deployment's HIPPO_TENANT fallback (or 'default') when slack_workspaces
9
- * is empty (single-workspace install — env fallback is safe)
10
- * - null when slack_workspaces is non-empty AND `teamId` is unknown
11
- * (multi-workspace install — fail closed; an unknown team is not the
12
- * deployment's tenant). Escape hatch: SLACK_ALLOW_UNKNOWN_TEAM_FALLBACK=1
13
- * restores the env fallback for emergency rollback only.
14
- *
15
- * The fail-closed contract lives here so every caller (route handler, CLI
16
- * replay, future MCP) gets the same protection against routing a foreign
17
- * workspace's events into the deployment tenant.
18
- */
19
- export declare function resolveTenantForTeam(db: DatabaseSyncLike, teamId: string): string | null;
20
- /** resolveTenantForTeam through `store`, else hippo.db under `hippoRoot`. */
2
+ /** Look up the tenant_id for a Slack team_id; the HIPPO_TENANT fallback applies only when slack_workspaces is empty (single-workspace install).
3
+ * An unknown team on a multi-workspace install returns null (fail closed); SLACK_ALLOW_UNKNOWN_TEAM_FALLBACK=1 is the emergency escape. */
21
4
  export declare function resolveTenantForSlackTeam(hippoRoot: string, teamId: string, store?: HippoStore): Promise<string | null>;
22
5
  //# sourceMappingURL=tenant-routing.d.ts.map
@@ -1,26 +1,7 @@
1
1
  import { envSlackAllowUnknownTeamFallback, envTenant } from '../../util/env.js';
2
2
  import { requireGroup, storeFor } from '../../store/index.js';
3
- import { slackTeamRouteAt } from '../../store/connectors/slack.js';
4
- /**
5
- * Look up the tenant_id for a Slack team_id.
6
- *
7
- * Returns:
8
- * - mapped tenant_id when slack_workspaces has a row for `teamId`
9
- * - the deployment's HIPPO_TENANT fallback (or 'default') when slack_workspaces
10
- * is empty (single-workspace install — env fallback is safe)
11
- * - null when slack_workspaces is non-empty AND `teamId` is unknown
12
- * (multi-workspace install — fail closed; an unknown team is not the
13
- * deployment's tenant). Escape hatch: SLACK_ALLOW_UNKNOWN_TEAM_FALLBACK=1
14
- * restores the env fallback for emergency rollback only.
15
- *
16
- * The fail-closed contract lives here so every caller (route handler, CLI
17
- * replay, future MCP) gets the same protection against routing a foreign
18
- * workspace's events into the deployment tenant.
19
- */
20
- export function resolveTenantForTeam(db, teamId) {
21
- return tenantForRoute(slackTeamRouteAt(db, teamId));
22
- }
23
- /** resolveTenantForTeam through `store`, else hippo.db under `hippoRoot`. */
3
+ /** Look up the tenant_id for a Slack team_id; the HIPPO_TENANT fallback applies only when slack_workspaces is empty (single-workspace install).
4
+ * An unknown team on a multi-workspace install returns null (fail closed); SLACK_ALLOW_UNKNOWN_TEAM_FALLBACK=1 is the emergency escape. */
24
5
  export async function resolveTenantForSlackTeam(hippoRoot, teamId, store) {
25
6
  return tenantForRoute(await requireGroup(storeFor({ hippoRoot, store }), 'connectorEvents').slackTeamRoute(teamId));
26
7
  }
@@ -6,23 +6,7 @@ export interface TransformInput {
6
6
  channel: ChannelMeta;
7
7
  message: SlackMessageEvent;
8
8
  }
9
- /**
10
- * Convert a SlackMessageEvent into RememberOpts for api.remember(). Returns
11
- * null when the message has no usable body (e.g. system events, bot reactions
12
- * without text). Caller treats null as "skip but mark idempotency seen".
13
- *
14
- * Contract:
15
- * - kind is the literal 'raw' (connector boundary, see src/importers.ts).
16
- * - artifact_ref format MUST be exactly `slack://${teamId}/${channelId}/${ts}`;
17
- * the deletion path looks up by this string.
18
- * - owner is non-null whenever a row is written. Required by the
19
- * provenance gate (`hippo provenance --strict`).
20
- * - `user:<slack_user_id>` when the event carries a `user`.
21
- * - `bot:<bot_id>` for the `bot_message` subtype (or any userless+text event
22
- * that supplies bot_id).
23
- * - `bot:unknown` only as a last-resort sentinel so the gate never sees null.
24
- * Skipping userless messages instead would silently drop bot ingestion
25
- * via the "skipped but seen" path in ingest.ts.
26
- */
9
+ /** Convert a SlackMessageEvent into RememberOpts; returns null when the message has no usable body so the caller marks it seen and skips it.
10
+ * artifact_ref MUST be `slack://${teamId}/${channelId}/${ts}` (deletion looks it up); owner is never null: `user:<id>`, `bot:<bot_id>`, else `bot:unknown`. */
27
11
  export declare function messageToRememberOpts(input: TransformInput): RememberOpts | null;
28
12
  //# sourceMappingURL=transform.d.ts.map
@@ -1,22 +1,6 @@
1
1
  import { scopeFromChannel } from './scope.js';
2
- /**
3
- * Convert a SlackMessageEvent into RememberOpts for api.remember(). Returns
4
- * null when the message has no usable body (e.g. system events, bot reactions
5
- * without text). Caller treats null as "skip but mark idempotency seen".
6
- *
7
- * Contract:
8
- * - kind is the literal 'raw' (connector boundary, see src/importers.ts).
9
- * - artifact_ref format MUST be exactly `slack://${teamId}/${channelId}/${ts}`;
10
- * the deletion path looks up by this string.
11
- * - owner is non-null whenever a row is written. Required by the
12
- * provenance gate (`hippo provenance --strict`).
13
- * - `user:<slack_user_id>` when the event carries a `user`.
14
- * - `bot:<bot_id>` for the `bot_message` subtype (or any userless+text event
15
- * that supplies bot_id).
16
- * - `bot:unknown` only as a last-resort sentinel so the gate never sees null.
17
- * Skipping userless messages instead would silently drop bot ingestion
18
- * via the "skipped but seen" path in ingest.ts.
19
- */
2
+ /** Convert a SlackMessageEvent into RememberOpts; returns null when the message has no usable body so the caller marks it seen and skips it.
3
+ * artifact_ref MUST be `slack://${teamId}/${channelId}/${ts}` (deletion looks it up); owner is never null: `user:<id>`, `bot:<bot_id>`, else `bot:unknown`. */
20
4
  export function messageToRememberOpts(input) {
21
5
  const text = input.message.text?.trim();
22
6
  if (!text)
@@ -1,7 +1,5 @@
1
- /**
2
- * Slack Events API envelope shapes used by the ingestion connector.
3
- * Spec: https://api.slack.com/events-api
4
- */
1
+ /** Slack Events API envelope shapes used by the ingestion connector.
2
+ * Spec: https://api.slack.com/events-api */
5
3
  import { type JsonValue } from '../../util/json.js';
6
4
  export interface SlackUrlVerification {
7
5
  type: 'url_verification';
@@ -17,11 +15,7 @@ export interface SlackMessageEvent {
17
15
  text?: string;
18
16
  ts: string;
19
17
  thread_ts?: string;
20
- /**
21
- * Slack `bot_message` subtype carries `bot_id` instead of `user`. The
22
- * provenance gate requires a non-null `owner`, so transform.ts
23
- * derives `owner: bot:<bot_id>` when `user` is absent.
24
- */
18
+ /** The `bot_message` subtype carries `bot_id` instead of `user`; transform.ts derives `owner: bot:<bot_id>` from it. */
25
19
  bot_id?: string;
26
20
  /** Present on subtype='message_deleted'. */
27
21
  deleted_ts?: string;