@jungjaehoon/mama-core 2.4.1 → 4.1.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 (378) hide show
  1. package/README.md +76 -239
  2. package/db/migrations/030-case-first-memory-substrate.sql +13 -98
  3. package/db/migrations/034-add-connector-event-scope-columns.sql +9 -13
  4. package/db/migrations/039-add-connector-event-operator-ingest-seq.sql +9 -95
  5. package/db/migrations/062-refresh-connector-event-sequences.sql +9 -113
  6. package/db/migrations/063-refresh-legacy-connector-event-updates.sql +9 -32
  7. package/db/migrations/067-add-connector-event-source-entity-id.sql +9 -13
  8. package/db/migrations/069-create-registry-nodes.sql +52 -0
  9. package/db/migrations/070-record-identity.sql +35 -0
  10. package/db/migrations/071-service-operation-origins.sql +187 -0
  11. package/db/migrations/072-observation-versions.sql +29 -0
  12. package/db/migrations/073-registry-corrections.sql +45 -0
  13. package/db/migrations/074-work-graph-ref-kinds.sql +39 -0
  14. package/db/migrations/075-agent-judgments.sql +58 -0
  15. package/db/migrations/076-scoped-checkpoint-bindings.sql +15 -0
  16. package/db/migrations/077-legacy-record-kind.sql +6 -0
  17. package/db/migrations/078-source-ingest-commands.sql +18 -0
  18. package/db/migrations/079-twin-edge-relations.sql +43 -0
  19. package/db/migrations/080-restore-duration-days.sql +7 -0
  20. package/db/migrations/081-mailbox.sql +61 -0
  21. package/db/migrations/082-commitments-row-id.sql +12 -0
  22. package/db/migrations/083-observation-is-the-evidence.sql +49 -0
  23. package/db/migrations/084-scope-kind-is-not-the-cores-to-list.sql +34 -0
  24. package/db/migrations/085-a-migration-has-a-source.sql +37 -0
  25. package/db/migrations/086-the-mailbox-is-generic.sql +110 -0
  26. package/db/migrations/087-mailbox-payload.sql +5 -0
  27. package/db/migrations/088-native-input-journal.sql +14 -0
  28. package/db/migrations/089-native-turn-receipt-lookup.sql +3 -0
  29. package/db/migrations/090-model-run-native-inputs.sql +29 -0
  30. package/db/migrations/091-native-turn-results.sql +11 -0
  31. package/db/migrations/092-restore-decision-fts.sql +34 -0
  32. package/db/migrations/093-native-turn-primary-kind.sql +14 -0
  33. package/db/migrations/094-commitment-run-provenance.sql +9 -0
  34. package/db/migrations/095-model-run-native-input-identity.sql +39 -0
  35. package/db/migrations/096-drop-connector-event-index-fts.sql +9 -0
  36. package/db/migrations/097-native-input-json-validity.sql +37 -0
  37. package/db/migrations/098-workflow-memory-kind.sql +105 -0
  38. package/db/migrations/099-commitment-revision-graph.sql +2 -0
  39. package/dist/action-contracts.d.ts +212 -0
  40. package/dist/action-contracts.js +10 -0
  41. package/dist/api/catalog.d.ts +118 -0
  42. package/dist/api/catalog.js +1756 -0
  43. package/dist/api/dispatch.d.ts +76 -0
  44. package/dist/api/dispatch.js +372 -0
  45. package/dist/canonicalize.d.ts +2 -2
  46. package/dist/canonicalize.js +3 -3
  47. package/dist/client/client.d.ts +33 -0
  48. package/dist/client/client.js +123 -0
  49. package/dist/client/ipc.d.ts +81 -0
  50. package/dist/client/ipc.js +314 -0
  51. package/dist/db-adapter/base-adapter.d.ts +6 -66
  52. package/dist/db-adapter/base-adapter.js +6 -6
  53. package/dist/db-adapter/index.d.ts +5 -5
  54. package/dist/db-adapter/index.js +2 -5
  55. package/dist/db-adapter/node-sqlite-adapter.d.ts +85 -15
  56. package/dist/db-adapter/node-sqlite-adapter.js +1985 -570
  57. package/dist/db-manager.d.ts +53 -97
  58. package/dist/db-manager.js +121 -603
  59. package/dist/embedding/embedder.d.ts +132 -0
  60. package/dist/embedding/embedder.js +299 -0
  61. package/dist/identity/principal-repository.d.ts +2 -2
  62. package/dist/index.d.ts +43 -58
  63. package/dist/index.js +97 -145
  64. package/dist/{context-compile/channel-grant.d.ts → knowledge/access.d.ts} +12 -17
  65. package/dist/knowledge/access.js +663 -0
  66. package/dist/knowledge/case-errors.d.ts +31 -0
  67. package/dist/knowledge/case-errors.js +40 -0
  68. package/dist/{cases/search-rollup.d.ts → knowledge/case-search-rollup.d.ts} +5 -4
  69. package/dist/{cases/search-rollup.js → knowledge/case-search-rollup.js} +6 -8
  70. package/dist/{cases/store.d.ts → knowledge/case-store.d.ts} +3 -6
  71. package/dist/{cases/store.js → knowledge/case-store.js} +7 -42
  72. package/dist/{cases/timeline-range.d.ts → knowledge/case-timeline-range.d.ts} +3 -3
  73. package/dist/{cases/timeline-range.js → knowledge/case-timeline-range.js} +47 -25
  74. package/dist/{cases/types.d.ts → knowledge/case-types.d.ts} +8 -2
  75. package/dist/{cases/types.js → knowledge/case-types.js} +1 -1
  76. package/dist/knowledge/commitment-revision-migration.d.ts +4 -0
  77. package/dist/knowledge/commitment-revision-migration.js +50 -0
  78. package/dist/knowledge/commitments.d.ts +192 -0
  79. package/dist/knowledge/commitments.js +386 -0
  80. package/dist/knowledge/decision-edges.d.ts +70 -0
  81. package/dist/knowledge/decision-edges.js +123 -0
  82. package/dist/{agent-graph/types.d.ts → knowledge/graph-query.d.ts} +80 -70
  83. package/dist/knowledge/graph-query.js +1585 -0
  84. package/dist/knowledge/identity.d.ts +16 -0
  85. package/dist/knowledge/identity.js +22 -0
  86. package/dist/knowledge/index.d.ts +47 -0
  87. package/dist/knowledge/index.js +90 -0
  88. package/dist/knowledge/judgment-edge.d.ts +6 -0
  89. package/dist/knowledge/judgment-edge.js +22 -0
  90. package/dist/knowledge/judgments.d.ts +118 -0
  91. package/dist/knowledge/judgments.js +802 -0
  92. package/dist/knowledge/observations.d.ts +160 -0
  93. package/dist/knowledge/observations.js +449 -0
  94. package/dist/knowledge/question-type.d.ts +34 -0
  95. package/dist/knowledge/question-type.js +70 -0
  96. package/dist/{search → knowledge}/ranker-features.js +1 -1
  97. package/dist/{search → knowledge}/search-quality.d.ts +0 -1
  98. package/dist/knowledge/search.d.ts +38 -0
  99. package/dist/knowledge/search.js +91 -0
  100. package/dist/knowledge/source-ingest.d.ts +65 -0
  101. package/dist/knowledge/source-ingest.js +174 -0
  102. package/dist/{edges/types.d.ts → knowledge/twin-edge-types.d.ts} +31 -4
  103. package/dist/{edges/types.js → knowledge/twin-edge-types.js} +13 -2
  104. package/dist/knowledge/work-dates.d.ts +49 -0
  105. package/dist/knowledge/work-dates.js +120 -0
  106. package/dist/mama-api.d.ts +114 -778
  107. package/dist/mama-api.js +313 -2461
  108. package/dist/memory/api.d.ts +264 -24
  109. package/dist/memory/api.js +1633 -843
  110. package/dist/memory/bootstrap-builder.d.ts +2 -1
  111. package/dist/memory/bootstrap-builder.js +5 -5
  112. package/dist/memory/channel-summary-state-store.d.ts +3 -2
  113. package/dist/memory/channel-summary-state-store.js +53 -51
  114. package/dist/memory/channel-summary-store.d.ts +5 -3
  115. package/dist/memory/channel-summary-store.js +3 -8
  116. package/dist/memory/dashboard-read.d.ts +46 -0
  117. package/dist/memory/dashboard-read.js +94 -0
  118. package/dist/memory/event-store.d.ts +3 -3
  119. package/dist/memory/event-store.js +3 -10
  120. package/dist/memory/finding-store.d.ts +3 -2
  121. package/dist/memory/finding-store.js +2 -7
  122. package/dist/memory/graph-read.d.ts +52 -0
  123. package/dist/memory/graph-read.js +130 -0
  124. package/dist/memory/judgment-types.d.ts +394 -0
  125. package/dist/memory/judgment-types.js +16 -0
  126. package/dist/memory/provenance-audit.d.ts +5 -2
  127. package/dist/memory/provenance-audit.js +8 -14
  128. package/dist/memory/provenance-live.d.ts +141 -0
  129. package/dist/memory/provenance-live.js +409 -0
  130. package/dist/memory/provenance-query.d.ts +5 -4
  131. package/dist/memory/provenance-query.js +21 -29
  132. package/dist/memory/provenance-resolver.d.ts +191 -0
  133. package/dist/memory/provenance-resolver.js +155 -0
  134. package/dist/memory/provenance.d.ts +1 -11
  135. package/dist/memory/provenance.js +2 -33
  136. package/dist/memory/recall-sanitize.d.ts +55 -0
  137. package/dist/memory/recall-sanitize.js +144 -0
  138. package/dist/memory/secret-filter.d.ts +32 -0
  139. package/dist/memory/secret-filter.js +126 -0
  140. package/dist/memory/truth-store.d.ts +2 -1
  141. package/dist/memory/truth-store.js +1 -4
  142. package/dist/memory/types.d.ts +74 -24
  143. package/dist/memory/types.js +75 -5
  144. package/dist/memory/write-adapters.d.ts +98 -0
  145. package/dist/memory/write-adapters.js +242 -0
  146. package/dist/operations/owner-action-effects.d.ts +53 -0
  147. package/dist/operations/owner-action-effects.js +96 -0
  148. package/dist/provenance/source-ref.d.ts +1 -1
  149. package/dist/provenance/source-ref.js +0 -2
  150. package/dist/registry/corrections.d.ts +31 -0
  151. package/dist/registry/corrections.js +332 -0
  152. package/dist/registry/record-identity.d.ts +49 -0
  153. package/dist/registry/record-identity.js +133 -0
  154. package/dist/registry/store.d.ts +101 -0
  155. package/dist/registry/store.js +395 -0
  156. package/dist/registry/types.d.ts +28 -0
  157. package/dist/registry/types.js +5 -0
  158. package/dist/relevance-scorer.js +2 -2
  159. package/dist/runtime/agent-event-bus.d.ts +50 -0
  160. package/dist/runtime/agent-event-bus.js +101 -0
  161. package/dist/runtime/drivers/claude-cli-wrapper.d.ts +152 -0
  162. package/dist/runtime/drivers/claude-cli-wrapper.js +375 -0
  163. package/dist/runtime/drivers/claude-effort.d.ts +4 -0
  164. package/dist/runtime/drivers/claude-effort.js +16 -0
  165. package/dist/runtime/drivers/cli-arg-redaction.d.ts +2 -0
  166. package/dist/runtime/drivers/cli-arg-redaction.js +18 -0
  167. package/dist/runtime/drivers/cli-secret-redaction.d.ts +17 -0
  168. package/dist/runtime/drivers/cli-secret-redaction.js +126 -0
  169. package/dist/runtime/drivers/codex-app-server-process.d.ts +277 -0
  170. package/dist/runtime/drivers/codex-app-server-process.js +2342 -0
  171. package/dist/runtime/drivers/codex-auxiliary-tools.d.ts +17 -0
  172. package/dist/runtime/drivers/codex-auxiliary-tools.js +267 -0
  173. package/dist/runtime/drivers/codex-home.d.ts +20 -0
  174. package/dist/runtime/drivers/codex-home.js +674 -0
  175. package/dist/runtime/drivers/codex-thread-registry.d.ts +63 -0
  176. package/dist/runtime/drivers/codex-thread-registry.js +433 -0
  177. package/dist/runtime/drivers/persistent-cli-adapter.d.ts +160 -0
  178. package/dist/runtime/drivers/persistent-cli-adapter.js +396 -0
  179. package/dist/runtime/drivers/persistent-cli-process.d.ts +425 -0
  180. package/dist/runtime/drivers/persistent-cli-process.js +1529 -0
  181. package/dist/runtime/drivers/types.d.ts +456 -0
  182. package/dist/runtime/drivers/types.js +110 -0
  183. package/dist/runtime/mailbox.d.ts +223 -0
  184. package/dist/runtime/mailbox.js +582 -0
  185. package/dist/runtime/model-run-store.d.ts +28 -0
  186. package/dist/{model-runs/store.js → runtime/model-run-store.js} +81 -41
  187. package/dist/{model-runs/types.d.ts → runtime/model-run-types.d.ts} +33 -4
  188. package/dist/{model-runs/types.js → runtime/model-run-types.js} +1 -1
  189. package/dist/runtime/native-effect-observer.d.ts +22 -0
  190. package/dist/runtime/native-effect-observer.js +103 -0
  191. package/dist/runtime/native-input-journal.d.ts +46 -0
  192. package/dist/runtime/native-input-journal.js +308 -0
  193. package/dist/runtime/native-prompt.d.ts +118 -0
  194. package/dist/runtime/native-prompt.js +496 -0
  195. package/dist/runtime/native-session.d.ts +10 -0
  196. package/dist/{agent-graph/index.js → runtime/native-session.js} +9 -6
  197. package/dist/runtime/native-tool-trace-observer.d.ts +5 -0
  198. package/dist/runtime/native-tool-trace-observer.js +65 -0
  199. package/dist/runtime/native-turn.d.ts +272 -0
  200. package/dist/runtime/native-turn.js +1041 -0
  201. package/dist/runtime/operations.d.ts +236 -0
  202. package/dist/runtime/operations.js +565 -0
  203. package/dist/runtime/post-tool-handler.d.ts +74 -0
  204. package/dist/runtime/post-tool-handler.js +137 -0
  205. package/dist/runtime/prompt-layers.d.ts +126 -0
  206. package/dist/runtime/prompt-layers.js +239 -0
  207. package/dist/runtime/runtime-process.d.ts +102 -0
  208. package/dist/runtime/runtime-process.js +206 -0
  209. package/dist/runtime/runtime.d.ts +278 -0
  210. package/dist/runtime/runtime.js +563 -0
  211. package/dist/runtime/session-pool.d.ts +176 -0
  212. package/dist/runtime/session-pool.js +369 -0
  213. package/dist/runtime/stimulus-payload.d.ts +5 -0
  214. package/dist/runtime/stimulus-payload.js +50 -0
  215. package/dist/runtime/subagent-bridge.d.ts +24 -0
  216. package/dist/{agent-graph/types.js → runtime/subagent-bridge.js} +1 -1
  217. package/dist/runtime/text-completion.d.ts +22 -0
  218. package/dist/{agent-situation/types.js → runtime/text-completion.js} +1 -1
  219. package/dist/runtime/token-estimator.d.ts +25 -0
  220. package/dist/runtime/token-estimator.js +75 -0
  221. package/dist/runtime/tool-trace-store.d.ts +22 -0
  222. package/dist/{model-runs → runtime}/tool-trace-store.js +46 -27
  223. package/dist/runtime/trace-summary.d.ts +5 -0
  224. package/dist/runtime/trace-summary.js +74 -0
  225. package/dist/runtime/turn-text.d.ts +23 -0
  226. package/dist/runtime/turn-text.js +41 -0
  227. package/dist/storage/database.d.ts +67 -0
  228. package/dist/storage/database.js +158 -0
  229. package/package.json +20 -34
  230. package/dist/agent-graph/alias-write.d.ts +0 -3
  231. package/dist/agent-graph/alias-write.js +0 -234
  232. package/dist/agent-graph/entity-resolve.d.ts +0 -3
  233. package/dist/agent-graph/entity-resolve.js +0 -271
  234. package/dist/agent-graph/errors.d.ts +0 -4
  235. package/dist/agent-graph/errors.js +0 -11
  236. package/dist/agent-graph/graph-query.d.ts +0 -5
  237. package/dist/agent-graph/graph-query.js +0 -360
  238. package/dist/agent-graph/index.d.ts +0 -6
  239. package/dist/agent-situation/builder.d.ts +0 -8
  240. package/dist/agent-situation/builder.js +0 -239
  241. package/dist/agent-situation/cache-key.d.ts +0 -4
  242. package/dist/agent-situation/cache-key.js +0 -64
  243. package/dist/agent-situation/index.d.ts +0 -7
  244. package/dist/agent-situation/index.js +0 -28
  245. package/dist/agent-situation/packet-store.d.ts +0 -27
  246. package/dist/agent-situation/packet-store.js +0 -228
  247. package/dist/agent-situation/ranking-policy.d.ts +0 -18
  248. package/dist/agent-situation/ranking-policy.js +0 -75
  249. package/dist/agent-situation/source-readers.d.ts +0 -52
  250. package/dist/agent-situation/source-readers.js +0 -300
  251. package/dist/agent-situation/types.d.ts +0 -195
  252. package/dist/cases/wiki-page-index.d.ts +0 -37
  253. package/dist/cases/wiki-page-index.js +0 -201
  254. package/dist/config-loader.d.ts +0 -68
  255. package/dist/config-loader.js +0 -239
  256. package/dist/connectors/event-index.d.ts +0 -24
  257. package/dist/connectors/event-index.js +0 -245
  258. package/dist/connectors/raw-query.d.ts +0 -40
  259. package/dist/connectors/raw-query.js +0 -412
  260. package/dist/connectors/types.d.ts +0 -117
  261. package/dist/connectors/types.js +0 -3
  262. package/dist/context-compile/boundary-defaults.d.ts +0 -12
  263. package/dist/context-compile/boundary-defaults.js +0 -105
  264. package/dist/context-compile/channel-grant.js +0 -66
  265. package/dist/context-compile/compiler-policy.d.ts +0 -39
  266. package/dist/context-compile/compiler-policy.js +0 -147
  267. package/dist/context-compile/compiler.d.ts +0 -18
  268. package/dist/context-compile/compiler.js +0 -404
  269. package/dist/context-compile/index.d.ts +0 -10
  270. package/dist/context-compile/index.js +0 -26
  271. package/dist/context-compile/packet-store.d.ts +0 -8
  272. package/dist/context-compile/packet-store.js +0 -239
  273. package/dist/context-compile/ref.d.ts +0 -7
  274. package/dist/context-compile/ref.js +0 -102
  275. package/dist/context-compile/source-readers.d.ts +0 -70
  276. package/dist/context-compile/source-readers.js +0 -840
  277. package/dist/context-compile/types.d.ts +0 -155
  278. package/dist/context-compile/types.js +0 -11
  279. package/dist/context-compile/visibility.d.ts +0 -21
  280. package/dist/context-compile/visibility.js +0 -224
  281. package/dist/decision-tracker.d.ts +0 -206
  282. package/dist/decision-tracker.js +0 -481
  283. package/dist/edges/ref-validation.d.ts +0 -7
  284. package/dist/edges/ref-validation.js +0 -321
  285. package/dist/edges/store.d.ts +0 -8
  286. package/dist/edges/store.js +0 -129
  287. package/dist/embedding-client.d.ts +0 -28
  288. package/dist/embedding-client.js +0 -53
  289. package/dist/embedding-server/index.d.ts +0 -67
  290. package/dist/embedding-server/index.js +0 -405
  291. package/dist/embedding-server/mobile/auth.d.ts +0 -44
  292. package/dist/embedding-server/mobile/auth.js +0 -150
  293. package/dist/embedding-server/mobile/daemon.d.ts +0 -129
  294. package/dist/embedding-server/mobile/daemon.js +0 -313
  295. package/dist/embedding-server/mobile/output-parser.d.ts +0 -115
  296. package/dist/embedding-server/mobile/output-parser.js +0 -241
  297. package/dist/embedding-server/mobile/session-api.d.ts +0 -57
  298. package/dist/embedding-server/mobile/session-api.js +0 -261
  299. package/dist/embedding-server/mobile/session-manager.d.ts +0 -138
  300. package/dist/embedding-server/mobile/session-manager.js +0 -378
  301. package/dist/embedding-server/mobile/websocket-handler.d.ts +0 -137
  302. package/dist/embedding-server/mobile/websocket-handler.js +0 -486
  303. package/dist/embeddings.d.ts +0 -68
  304. package/dist/embeddings.js +0 -244
  305. package/dist/entities/audit-metrics.d.ts +0 -68
  306. package/dist/entities/audit-metrics.js +0 -124
  307. package/dist/entities/candidate-generator.d.ts +0 -8
  308. package/dist/entities/candidate-generator.js +0 -24
  309. package/dist/entities/entity-linked-decision-counts.d.ts +0 -2
  310. package/dist/entities/entity-linked-decision-counts.js +0 -29
  311. package/dist/entities/entity-list.d.ts +0 -22
  312. package/dist/entities/entity-list.js +0 -3
  313. package/dist/entities/entity-orphan-list.d.ts +0 -17
  314. package/dist/entities/entity-orphan-list.js +0 -3
  315. package/dist/entities/entity-search.d.ts +0 -20
  316. package/dist/entities/entity-search.js +0 -3
  317. package/dist/entities/errors.d.ts +0 -55
  318. package/dist/entities/errors.js +0 -100
  319. package/dist/entities/lineage-store.d.ts +0 -28
  320. package/dist/entities/lineage-store.js +0 -204
  321. package/dist/entities/normalization.d.ts +0 -14
  322. package/dist/entities/normalization.js +0 -63
  323. package/dist/entities/policy-store.d.ts +0 -8
  324. package/dist/entities/policy-store.js +0 -75
  325. package/dist/entities/policy-types.d.ts +0 -72
  326. package/dist/entities/policy-types.js +0 -59
  327. package/dist/entities/projection.d.ts +0 -8
  328. package/dist/entities/projection.js +0 -82
  329. package/dist/entities/provenance-query.d.ts +0 -32
  330. package/dist/entities/provenance-query.js +0 -3
  331. package/dist/entities/read-identity.d.ts +0 -31
  332. package/dist/entities/read-identity.js +0 -264
  333. package/dist/entities/recall-bridge.d.ts +0 -5
  334. package/dist/entities/recall-bridge.js +0 -171
  335. package/dist/entities/resolution-engine.d.ts +0 -8
  336. package/dist/entities/resolution-engine.js +0 -3
  337. package/dist/entities/rollback-preview.d.ts +0 -35
  338. package/dist/entities/rollback-preview.js +0 -3
  339. package/dist/entities/source-locator.d.ts +0 -3
  340. package/dist/entities/source-locator.js +0 -32
  341. package/dist/entities/store.d.ts +0 -69
  342. package/dist/entities/store.js +0 -544
  343. package/dist/entities/types.d.ts +0 -166
  344. package/dist/entities/types.js +0 -30
  345. package/dist/memory/extraction-prompt.d.ts +0 -4
  346. package/dist/memory/extraction-prompt.js +0 -89
  347. package/dist/memory/scope-backfill.d.ts +0 -14
  348. package/dist/memory/scope-backfill.js +0 -3
  349. package/dist/memory/scope-store.d.ts +0 -4
  350. package/dist/memory/scope-store.js +0 -9
  351. package/dist/memory-store.d.ts +0 -87
  352. package/dist/memory-store.js +0 -78
  353. package/dist/model-runs/store.d.ts +0 -13
  354. package/dist/model-runs/tool-trace-store.d.ts +0 -8
  355. package/dist/notification-manager.d.ts +0 -7
  356. package/dist/notification-manager.js +0 -12
  357. package/dist/outcome-tracker.d.ts +0 -151
  358. package/dist/outcome-tracker.js +0 -271
  359. package/dist/query-intent.d.ts +0 -23
  360. package/dist/query-intent.js +0 -114
  361. package/dist/runtime/trusted-provenance.d.ts +0 -3
  362. package/dist/runtime/trusted-provenance.js +0 -6
  363. package/dist/search/question-type.d.ts +0 -5
  364. package/dist/search/question-type.js +0 -41
  365. package/dist/test-utils.d.ts +0 -80
  366. package/dist/test-utils.js +0 -218
  367. package/dist/tier-validator.d.ts +0 -43
  368. package/dist/tier-validator.js +0 -159
  369. package/dist/time-formatter.d.ts +0 -25
  370. package/dist/time-formatter.js +0 -93
  371. /package/dist/{search → knowledge}/feedback-store.d.ts +0 -0
  372. /package/dist/{search → knowledge}/feedback-store.js +0 -0
  373. /package/dist/{search → knowledge}/ranker-features.d.ts +0 -0
  374. /package/dist/{search → knowledge}/ranker-rescore.d.ts +0 -0
  375. /package/dist/{search → knowledge}/ranker-rescore.js +0 -0
  376. /package/dist/{search → knowledge}/ranker-trainer.d.ts +0 -0
  377. /package/dist/{search → knowledge}/ranker-trainer.js +0 -0
  378. /package/dist/{search → knowledge}/search-quality.js +0 -0
@@ -0,0 +1,663 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TwinRefNotVisibleError = void 0;
4
+ exports.visibleTwinRefKeys = visibleTwinRefKeys;
5
+ exports.visibleTwinRefKeysRecursive = visibleTwinRefKeysRecursive;
6
+ exports.assertTwinRefsVisible = assertTwinRefsVisible;
7
+ exports.listVisibleTwinEdgesForRefs = listVisibleTwinEdgesForRefs;
8
+ exports.isChannelGranted = isChannelGranted;
9
+ exports.channelGrantClause = channelGrantClause;
10
+ const observations_js_1 = require("../knowledge/observations.js");
11
+ const judgments_js_1 = require("./judgments.js");
12
+ const TABLE_COLUMN_PRAGMAS = {
13
+ decisions: 'PRAGMA table_info(decisions)',
14
+ case_truth: 'PRAGMA table_info(case_truth)',
15
+ };
16
+ const tableColumnCache = new WeakMap();
17
+ // Keep memory-truth quarantine semantics excluded for legacy/backcompat rows even though the
18
+ // decisions.status terminal states: 'superseded' is history a caller holding
19
+ // scope may read under includeReplaced; the rest are holds excluded always.
20
+ const RETIRED_MEMORY_STATUSES = new Set(['quarantined', 'contradicted', 'stale']);
21
+ class TwinRefNotVisibleError extends Error {
22
+ constructor(ref) {
23
+ super(`Twin ref is not visible to requested visibility: ${ref.kind}:${ref.id}`);
24
+ this.name = 'TwinRefNotVisibleError';
25
+ }
26
+ }
27
+ exports.TwinRefNotVisibleError = TwinRefNotVisibleError;
28
+ function scopeKey(scope) {
29
+ return `${scope.kind}\0${scope.id}`;
30
+ }
31
+ function hasScopes(scopes) {
32
+ return Array.isArray(scopes) && scopes.length > 0;
33
+ }
34
+ function hasProjectRefs(projectRefs) {
35
+ return Array.isArray(projectRefs) && projectRefs.length > 0;
36
+ }
37
+ function asOfMs(visibility) {
38
+ return typeof visibility.asOfMs === 'number' ? visibility.asOfMs : null;
39
+ }
40
+ function startMs(visibility) {
41
+ return typeof visibility.startMs === 'number' ? visibility.startMs : null;
42
+ }
43
+ function isWithinVisibilityTime(value, visibility) {
44
+ const start = startMs(visibility);
45
+ const asOf = asOfMs(visibility);
46
+ if (start === null && asOf === null) {
47
+ return true;
48
+ }
49
+ return (typeof value === 'number' &&
50
+ (start === null || value >= start) &&
51
+ (asOf === null || value <= asOf));
52
+ }
53
+ function parseTimestamp(value) {
54
+ if (typeof value === 'number' && Number.isFinite(value)) {
55
+ return Math.floor(value);
56
+ }
57
+ if (typeof value === 'string') {
58
+ const trimmed = value.trim();
59
+ if (trimmed.length === 0) {
60
+ return null;
61
+ }
62
+ const numeric = Number(trimmed);
63
+ if (Number.isFinite(numeric)) {
64
+ return Math.floor(numeric);
65
+ }
66
+ const parsed = Date.parse(trimmed);
67
+ return Number.isFinite(parsed) ? parsed : null;
68
+ }
69
+ return null;
70
+ }
71
+ function tableColumns(adapter, table) {
72
+ const pragma = TABLE_COLUMN_PRAGMAS[table];
73
+ if (!pragma) {
74
+ throw new Error(`Unsupported table for column introspection: ${table}`);
75
+ }
76
+ let adapterCache = tableColumnCache.get(adapter);
77
+ if (!adapterCache) {
78
+ adapterCache = new Map();
79
+ tableColumnCache.set(adapter, adapterCache);
80
+ }
81
+ const cached = adapterCache.get(table);
82
+ if (cached) {
83
+ return cached;
84
+ }
85
+ const rows = adapter.prepare(pragma).all();
86
+ const columns = new Set(rows.map((row) => row.name));
87
+ adapterCache.set(table, columns);
88
+ return columns;
89
+ }
90
+ function isMemoryVisible(adapter, id, visibility) {
91
+ const columns = tableColumns(adapter, 'decisions');
92
+ const statusSelect = columns.has('status') ? 'status' : 'NULL AS status';
93
+ const supersededBySelect = columns.has('superseded_by')
94
+ ? 'superseded_by'
95
+ : 'NULL AS superseded_by';
96
+ const row = adapter
97
+ .prepare(`
98
+ SELECT created_at, event_datetime, ${statusSelect}, ${supersededBySelect}
99
+ FROM decisions
100
+ WHERE id = ?
101
+ LIMIT 1
102
+ `)
103
+ .get(id);
104
+ if (!row) {
105
+ return false;
106
+ }
107
+ const status = typeof row.status === 'string' ? row.status : 'active';
108
+ const replaced = status === 'superseded' ||
109
+ (typeof row.superseded_by === 'string' && row.superseded_by.length > 0);
110
+ if (RETIRED_MEMORY_STATUSES.has(status) || (replaced && !visibility.includeReplaced)) {
111
+ return false;
112
+ }
113
+ if (!isWithinVisibilityTime(row.event_datetime ?? row.created_at, visibility)) {
114
+ return false;
115
+ }
116
+ const scopes = visibility.scopes;
117
+ if (!hasScopes(scopes)) {
118
+ return true;
119
+ }
120
+ const scopeClauses = scopes.map(() => '(ms.kind = ? AND ms.external_id = ?)').join(' OR ');
121
+ const params = scopes.flatMap((scope) => [scope.kind, scope.id]);
122
+ const bindingRow = adapter
123
+ .prepare(`
124
+ SELECT 1 AS ok
125
+ FROM memory_scope_bindings msb
126
+ JOIN memory_scopes ms ON ms.id = msb.scope_id
127
+ WHERE msb.memory_id = ?
128
+ AND (${scopeClauses})
129
+ LIMIT 1
130
+ `)
131
+ .get(id, ...params);
132
+ if (bindingRow?.ok) {
133
+ return true;
134
+ }
135
+ if (columns.has('memory_scope_kind') && columns.has('memory_scope_id')) {
136
+ const row = adapter
137
+ .prepare(`
138
+ SELECT 1 AS ok
139
+ FROM decisions
140
+ WHERE id = ?
141
+ AND (${scopes.map(() => '(memory_scope_kind = ? AND memory_scope_id = ?)').join(' OR ')})
142
+ LIMIT 1
143
+ `)
144
+ .get(id, ...params);
145
+ return Boolean(row?.ok);
146
+ }
147
+ return false;
148
+ }
149
+ function parseCaseScopeRefs(scopeRefs) {
150
+ if (typeof scopeRefs !== 'string' || scopeRefs.length === 0) {
151
+ return [];
152
+ }
153
+ try {
154
+ const parsed = JSON.parse(scopeRefs);
155
+ if (!Array.isArray(parsed)) {
156
+ return [];
157
+ }
158
+ return parsed.filter((item) => item !== null &&
159
+ typeof item === 'object' &&
160
+ typeof item.kind === 'string' &&
161
+ typeof item.id === 'string');
162
+ }
163
+ catch {
164
+ return [];
165
+ }
166
+ }
167
+ function isCaseVisible(adapter, id, visibility) {
168
+ const row = adapter.prepare('SELECT * FROM case_truth WHERE case_id = ? LIMIT 1').get(id);
169
+ if (!row) {
170
+ return false;
171
+ }
172
+ const timestamp = parseTimestamp(row.last_activity_at) ?? parseTimestamp(row.updated_at);
173
+ if (!isWithinVisibilityTime(timestamp, visibility)) {
174
+ return false;
175
+ }
176
+ const scopes = visibility.scopes;
177
+ if (!hasScopes(scopes)) {
178
+ return true;
179
+ }
180
+ const requested = new Set(scopes.map(scopeKey));
181
+ const scopeRefs = parseCaseScopeRefs(row.scope_refs);
182
+ if (scopeRefs.some((scope) => requested.has(scopeKey(scope)))) {
183
+ return true;
184
+ }
185
+ const columns = tableColumns(adapter, 'case_truth');
186
+ if (columns.has('memory_scope_kind') && columns.has('memory_scope_id')) {
187
+ return scopes.some((scope) => row.memory_scope_kind === scope.kind && row.memory_scope_id === scope.id);
188
+ }
189
+ return false;
190
+ }
191
+ /** Current rows use immutable observation capture time; valid legacy rows use source time. */
192
+ function isRawWithinTime(row, visibility) {
193
+ const maxSourceMs = visibility.maxSourceMs ?? null;
194
+ if (maxSourceMs !== null) {
195
+ if (!Number.isSafeInteger(maxSourceMs) || maxSourceMs < 0) {
196
+ throw new Error('Raw source ceiling must be a nonnegative epoch-millisecond integer');
197
+ }
198
+ const sourceAt = parseTimestamp(row.source_at);
199
+ if (sourceAt === null || sourceAt > maxSourceMs)
200
+ return false;
201
+ }
202
+ const rawTs = row.observation_observed_at ?? row.event_datetime ?? row.source_timestamp_ms;
203
+ if (rawTs === null || rawTs === undefined || (typeof rawTs === 'string' && rawTs.trim() === '')) {
204
+ return false;
205
+ }
206
+ const eventTsMs = parseTimestamp(rawTs);
207
+ return eventTsMs !== null && eventTsMs >= 0 && isWithinVisibilityTime(eventTsMs, visibility);
208
+ }
209
+ /**
210
+ * A `raw` ref resolves against observations, the same as an `observation` ref.
211
+ *
212
+ * There is one evidence space in the core. `raw` was the spelling from when the
213
+ * connector event index WAS the substrate -- the schema still shows it, allowing
214
+ * `raw` as an edge object and never as a subject, while `observation` is allowed
215
+ * on both sides. A ref that does not name an observation does not name evidence
216
+ * this core can vouch for, and is not visible.
217
+ */
218
+ function isRawVisible(adapter, id, visibility) {
219
+ const row = adapter
220
+ .prepare(`SELECT source, channel, project_id, tenant_id, memory_scope_kind, memory_scope_id, source_at,
221
+ observed_at AS observation_observed_at
222
+ FROM observation_versions
223
+ WHERE observation_id = ?
224
+ LIMIT 1`)
225
+ .get(id);
226
+ return row ? isRawRowVisible(row, visibility) : false;
227
+ }
228
+ /** One observation row, judged against the caller's window. */
229
+ function isRawRowVisible(row, visibility) {
230
+ if (Array.isArray(visibility.connectors) && !visibility.connectors.includes(String(row.source))) {
231
+ return false;
232
+ }
233
+ if (visibility.connectorWideRead?.includes(String(row.source))) {
234
+ return isRawWithinTime(row, visibility);
235
+ }
236
+ // The grant decides, and it decides the same way here as in the reader - one rule, taken
237
+ // from one place. The scope/project/tenant clauses below are the pre-grant rule and are
238
+ // skipped when a grant is present, exactly as the reader skips them, because applying
239
+ // both would make a cited ref satisfy a stricter test than a read one.
240
+ if (visibility.channels) {
241
+ return (isChannelGranted(String(row.source), typeof row.channel === 'string' ? row.channel : null, visibility.channels) && isRawWithinTime(row, visibility));
242
+ }
243
+ if (hasProjectRefs(visibility.projectRefs) &&
244
+ !visibility.projectRefs.some((project) => project.id === row.project_id)) {
245
+ return false;
246
+ }
247
+ if (typeof visibility.tenantId === 'string' &&
248
+ visibility.tenantId.length > 0 &&
249
+ row.tenant_id !== visibility.tenantId) {
250
+ return false;
251
+ }
252
+ if (!isRawWithinTime(row, visibility)) {
253
+ return false;
254
+ }
255
+ if (!hasScopes(visibility.scopes)) {
256
+ return true;
257
+ }
258
+ return visibility.scopes.some((scope) => row.memory_scope_kind === scope.kind && row.memory_scope_id === scope.id);
259
+ }
260
+ function refVisibilityKey(ref) {
261
+ return `${ref.kind}\0${ref.id}`;
262
+ }
263
+ function placeholders(count) {
264
+ if (count < 1) {
265
+ throw new Error('Visibility batch requires at least one identifier');
266
+ }
267
+ return Array.from({ length: count }, () => '?').join(', ');
268
+ }
269
+ function visibleTwinRefKeys(adapter, refs, visibility) {
270
+ const unique = [...new Map(refs.map((ref) => [refVisibilityKey(ref), ref])).values()];
271
+ const visible = new Set();
272
+ const ids = (kind) => unique.filter((ref) => ref.kind === kind).map((ref) => ref.id);
273
+ const rawIds = ids('raw');
274
+ if (rawIds.length > 0) {
275
+ const rows = adapter
276
+ .prepare(`SELECT observation_id, source, channel, project_id, tenant_id,
277
+ memory_scope_kind, memory_scope_id, source_at,
278
+ observed_at AS observation_observed_at
279
+ FROM observation_versions
280
+ WHERE observation_id IN (${placeholders(rawIds.length)})`)
281
+ .all(...rawIds);
282
+ for (const row of rows) {
283
+ if (isRawRowVisible(row, visibility)) {
284
+ visible.add(refVisibilityKey({ kind: 'raw', id: String(row.observation_id) }));
285
+ }
286
+ }
287
+ }
288
+ const observationIds = ids('observation');
289
+ if (observationIds.length > 0) {
290
+ const rows = adapter
291
+ .prepare(`SELECT observation_id, source, scope_json, observed_at, source_at
292
+ FROM observation_versions
293
+ WHERE observation_id IN (${placeholders(observationIds.length)})`)
294
+ .all(...observationIds);
295
+ for (const row of rows) {
296
+ if (isWithinVisibilityTime(row.observed_at, visibility) &&
297
+ (0, observations_js_1.isObservationVisibilityRowVisible)(row, {
298
+ principalId: visibility.principalId,
299
+ agentId: visibility.agentId,
300
+ scopes: visibility.scopes,
301
+ connectors: visibility.connectors,
302
+ connectorWideRead: visibility.connectorWideRead,
303
+ channels: visibility.channels,
304
+ maxSourceMs: visibility.maxSourceMs,
305
+ })) {
306
+ visible.add(refVisibilityKey({ kind: 'observation', id: row.observation_id }));
307
+ }
308
+ }
309
+ }
310
+ const caseIds = ids('case');
311
+ if (caseIds.length > 0) {
312
+ const rows = adapter
313
+ .prepare(`SELECT * FROM case_truth WHERE case_id IN (${placeholders(caseIds.length)})`)
314
+ .all(...caseIds);
315
+ for (const row of rows) {
316
+ const timestamp = parseTimestamp(row.last_activity_at) ?? parseTimestamp(row.updated_at);
317
+ const scopeVisible = !hasScopes(visibility.scopes) ||
318
+ parseCaseScopeRefs(row.scope_refs).some((scope) => new Set(visibility.scopes?.map(scopeKey) ?? []).has(scopeKey(scope))) ||
319
+ visibility.scopes.some((scope) => row.memory_scope_kind === scope.kind && row.memory_scope_id === scope.id);
320
+ if (typeof row.case_id === 'string' &&
321
+ isWithinVisibilityTime(timestamp, visibility) &&
322
+ scopeVisible) {
323
+ visible.add(refVisibilityKey({ kind: 'case', id: row.case_id }));
324
+ }
325
+ }
326
+ }
327
+ const memoryIds = ids('memory');
328
+ if (memoryIds.length > 0) {
329
+ const columns = tableColumns(adapter, 'decisions');
330
+ const rows = adapter
331
+ .prepare(`SELECT * FROM decisions WHERE id IN (${placeholders(memoryIds.length)})`)
332
+ .all(...memoryIds);
333
+ const admittedBindings = new Set();
334
+ if (hasScopes(visibility.scopes)) {
335
+ const scopeClauses = visibility.scopes
336
+ .map(() => '(ms.kind = ? AND ms.external_id = ?)')
337
+ .join(' OR ');
338
+ const bindings = adapter
339
+ .prepare(`SELECT msb.memory_id FROM memory_scope_bindings msb
340
+ JOIN memory_scopes ms ON ms.id = msb.scope_id
341
+ WHERE msb.memory_id IN (${placeholders(memoryIds.length)})
342
+ AND (${scopeClauses})`)
343
+ .all(...memoryIds, ...visibility.scopes.flatMap((scope) => [scope.kind, scope.id]));
344
+ bindings.forEach((row) => admittedBindings.add(row.memory_id));
345
+ }
346
+ for (const row of rows) {
347
+ const id = String(row.id);
348
+ const status = typeof row.status === 'string' ? row.status : 'active';
349
+ const replaced = status === 'superseded' ||
350
+ (typeof row.superseded_by === 'string' && row.superseded_by.length > 0);
351
+ const retired = RETIRED_MEMORY_STATUSES.has(status) || (replaced && !visibility.includeReplaced);
352
+ const scopeVisible = !hasScopes(visibility.scopes) ||
353
+ admittedBindings.has(id) ||
354
+ (columns.has('memory_scope_kind') &&
355
+ columns.has('memory_scope_id') &&
356
+ visibility.scopes.some((scope) => row.memory_scope_kind === scope.kind && row.memory_scope_id === scope.id));
357
+ if (!retired &&
358
+ isWithinVisibilityTime(parseTimestamp(row.event_datetime) ?? parseTimestamp(row.created_at), visibility) &&
359
+ scopeVisible) {
360
+ visible.add(refVisibilityKey({ kind: 'memory', id }));
361
+ }
362
+ }
363
+ }
364
+ const registryIds = ids('registry');
365
+ if (registryIds.length > 0) {
366
+ // `created_at` is read, not just `id`: a registry ref must have existed at the requested
367
+ // `as_of`, the same rule memory, raw and observation refs obey. The entity branch this
368
+ // replaced applied it (`isWithinVisibilityTime(row.created_at, visibility)`) and the
369
+ // replacement dropped it, so a packet could cite a node created after the boundary.
370
+ //
371
+ // A merged-away node is NOT excluded. Merging redirects identity, it does not retire the
372
+ // node, and the graph projection's contract is to keep the ORIGINAL ref citable while
373
+ // resolving the current one beside it (design section 4.1, original/corrected references).
374
+ // Filtering on `merged_into IS NULL` here broke exactly that - caught by
375
+ // agent-graph.test.ts.
376
+ const rows = adapter
377
+ .prepare(`SELECT id, created_at FROM registry_nodes
378
+ WHERE id IN (${placeholders(registryIds.length)})`)
379
+ .all(...registryIds);
380
+ const admitted = new Set();
381
+ if (hasScopes(visibility.scopes)) {
382
+ const scopeClauses = visibility.scopes
383
+ .map(() => '(scope_kind = ? AND scope_id = ?)')
384
+ .join(' OR ');
385
+ const bindings = adapter
386
+ .prepare(`SELECT DISTINCT node_id FROM registry_scope_bindings
387
+ WHERE node_id IN (${placeholders(registryIds.length)}) AND (${scopeClauses})`)
388
+ .all(...registryIds, ...visibility.scopes.flatMap((scope) => [scope.kind, scope.id]));
389
+ bindings.forEach((row) => admitted.add(row.node_id));
390
+ }
391
+ for (const row of rows) {
392
+ if (isWithinVisibilityTime(row.created_at, visibility) &&
393
+ (!hasScopes(visibility.scopes) || admitted.has(row.id))) {
394
+ visible.add(refVisibilityKey({ kind: 'registry', id: row.id }));
395
+ }
396
+ }
397
+ }
398
+ for (const ref of unique) {
399
+ if (ref.kind === 'report' && !hasScopes(visibility.scopes)) {
400
+ visible.add(refVisibilityKey(ref));
401
+ }
402
+ }
403
+ return visible;
404
+ }
405
+ function preloadRecursiveEdgeVisibility(adapter, refs, visibility) {
406
+ const edgeCache = new Map();
407
+ const rootEdgeIds = [...new Set(refs.filter((ref) => ref.kind === 'edge').map((ref) => ref.id))];
408
+ const nestedRefs = refs.filter((ref) => ref.kind !== 'edge');
409
+ if (rootEdgeIds.length > 0) {
410
+ const rows = adapter
411
+ .prepare(`WITH RECURSIVE edge_tree(edge_id) AS (
412
+ SELECT CAST(value AS TEXT)
413
+ FROM json_each(?)
414
+ UNION
415
+ SELECT CAST(child.value AS TEXT)
416
+ FROM edge_tree tree
417
+ JOIN twin_edges parent ON parent.edge_id = tree.edge_id
418
+ JOIN json_each(json_array(
419
+ CASE WHEN parent.subject_kind = 'edge' THEN parent.subject_id END,
420
+ CASE WHEN parent.object_kind = 'edge' THEN parent.object_id END
421
+ )) child
422
+ WHERE child.value IS NOT NULL
423
+ )
424
+ SELECT edge.*
425
+ FROM edge_tree
426
+ JOIN twin_edges edge ON edge.edge_id = edge_tree.edge_id`)
427
+ .all(JSON.stringify(rootEdgeIds));
428
+ for (const row of rows) {
429
+ const edge = (0, judgments_js_1.mapTwinEdgeRow)(row);
430
+ edgeCache.set(edge.edge_id, edge);
431
+ if (edge.subject_ref.kind !== 'edge') {
432
+ nestedRefs.push(edge.subject_ref);
433
+ }
434
+ if (edge.object_ref.kind !== 'edge') {
435
+ nestedRefs.push(edge.object_ref);
436
+ }
437
+ }
438
+ for (const edgeId of rootEdgeIds) {
439
+ if (!edgeCache.has(edgeId)) {
440
+ edgeCache.set(edgeId, null);
441
+ }
442
+ }
443
+ }
444
+ return {
445
+ edgeCache,
446
+ edgeVisibility: new Map(),
447
+ precomputed: visibleTwinRefKeys(adapter, nestedRefs, visibility),
448
+ };
449
+ }
450
+ function visibleTwinRefKeysRecursive(adapter, refs, visibility) {
451
+ const { edgeCache, edgeVisibility, precomputed } = preloadRecursiveEdgeVisibility(adapter, refs, visibility);
452
+ const visible = new Set();
453
+ for (const ref of refs) {
454
+ if (isTwinRefVisible(adapter, ref, visibility, new Set(), edgeCache, edgeVisibility, precomputed)) {
455
+ visible.add(refVisibilityKey(ref));
456
+ }
457
+ }
458
+ return visible;
459
+ }
460
+ function isTwinRefVisible(adapter, ref, visibility, edgesInProgress, edgeCache, edgeVisibility, precomputed) {
461
+ if (precomputed && ref.kind !== 'edge') {
462
+ return precomputed.has(refVisibilityKey(ref));
463
+ }
464
+ if (ref.kind === 'report') {
465
+ return !hasScopes(visibility.scopes);
466
+ }
467
+ if (ref.kind === 'memory') {
468
+ return isMemoryVisible(adapter, ref.id, visibility);
469
+ }
470
+ if (ref.kind === 'case') {
471
+ return isCaseVisible(adapter, ref.id, visibility);
472
+ }
473
+ if (ref.kind === 'raw') {
474
+ return isRawVisible(adapter, ref.id, visibility);
475
+ }
476
+ if (ref.kind === 'registry') {
477
+ const node = adapter
478
+ .prepare('SELECT created_at FROM registry_nodes WHERE id = ?')
479
+ .get(ref.id);
480
+ if (!node || !isWithinVisibilityTime(node.created_at, visibility)) {
481
+ return false;
482
+ }
483
+ if (!hasScopes(visibility.scopes)) {
484
+ return true;
485
+ }
486
+ return visibility.scopes.some((scope) => Boolean(adapter
487
+ .prepare('SELECT 1 FROM registry_scope_bindings WHERE node_id = ? AND scope_kind = ? AND scope_id = ?')
488
+ .get(ref.id, scope.kind, scope.id)));
489
+ }
490
+ if (ref.kind === 'observation') {
491
+ const row = adapter
492
+ .prepare('SELECT scope_json, observed_at, source_at FROM observation_versions WHERE observation_id = ?')
493
+ .get(ref.id);
494
+ if (!row || !isWithinVisibilityTime(row.observed_at, visibility)) {
495
+ return false;
496
+ }
497
+ return (0, observations_js_1.isObservationVersionVisible)(adapter, ref.id, {
498
+ principalId: visibility.principalId,
499
+ agentId: visibility.agentId,
500
+ scopes: visibility.scopes,
501
+ connectors: visibility.connectors,
502
+ connectorWideRead: visibility.connectorWideRead,
503
+ channels: visibility.channels,
504
+ maxSourceMs: visibility.maxSourceMs,
505
+ });
506
+ }
507
+ if (ref.kind !== 'edge') {
508
+ throw new Error(`UNSUPPORTED_REFERENCE_KIND: ${ref.kind}`);
509
+ }
510
+ // An edge met again while it is being decided lies on a cycle through itself: never visible.
511
+ // Every edge on such a cycle is invisible from any root, so a finished answer is memoized.
512
+ if (edgesInProgress.has(ref.id)) {
513
+ return false;
514
+ }
515
+ const decided = edgeVisibility.get(ref.id);
516
+ if (decided !== undefined) {
517
+ return decided;
518
+ }
519
+ let edge = edgeCache.get(ref.id);
520
+ if (edge === undefined) {
521
+ edge = (0, judgments_js_1.getTwinEdge)(adapter, ref.id);
522
+ edgeCache.set(ref.id, edge);
523
+ }
524
+ if (!edge || !isWithinVisibilityTime(edge.created_at, visibility)) {
525
+ edgeVisibility.set(ref.id, false);
526
+ return false;
527
+ }
528
+ edgesInProgress.add(ref.id);
529
+ const visible = isTwinRefVisible(adapter, edge.subject_ref, visibility, edgesInProgress, edgeCache, edgeVisibility, precomputed) &&
530
+ isTwinRefVisible(adapter, edge.object_ref, visibility, edgesInProgress, edgeCache, edgeVisibility, precomputed);
531
+ edgesInProgress.delete(ref.id);
532
+ edgeVisibility.set(ref.id, visible);
533
+ return visible;
534
+ }
535
+ function assertTwinRefsVisible(adapter, refs, visibility = {}) {
536
+ const supportedKinds = new Set([
537
+ 'memory',
538
+ 'case',
539
+ 'report',
540
+ 'edge',
541
+ 'raw',
542
+ 'registry',
543
+ 'observation',
544
+ ]);
545
+ for (const ref of refs) {
546
+ if (!supportedKinds.has(ref.kind)) {
547
+ throw new Error(`UNSUPPORTED_REFERENCE_KIND: ${ref.kind}`);
548
+ }
549
+ }
550
+ const { edgeCache, edgeVisibility, precomputed } = preloadRecursiveEdgeVisibility(adapter, refs, visibility);
551
+ for (const ref of refs) {
552
+ if (!isTwinRefVisible(adapter, ref, visibility, new Set(), edgeCache, edgeVisibility, precomputed)) {
553
+ throw new TwinRefNotVisibleError(ref);
554
+ }
555
+ }
556
+ }
557
+ function listVisibleTwinEdgesForRefs(adapter, refs, options = {}) {
558
+ const edgeTypes = normalizeEdgeTypes(options.edgeTypes);
559
+ const limit = typeof options.limit === 'number' && Number.isFinite(options.limit)
560
+ ? Math.max(0, Math.floor(options.limit))
561
+ : null;
562
+ if (limit === 0) {
563
+ return [];
564
+ }
565
+ if (limit !== null) {
566
+ const pageSize = Math.min(2000, Math.max(128, limit * 2));
567
+ const admitted = [];
568
+ let after;
569
+ while (admitted.length < limit) {
570
+ const candidates = (0, judgments_js_1.listTwinEdgesForRefs)(adapter, refs, {
571
+ newest: true,
572
+ limit: pageSize,
573
+ ...(after ? { after } : {}),
574
+ ...(edgeTypes.size > 0 ? { edgeTypes: [...edgeTypes] } : {}),
575
+ startMs: options.startMs,
576
+ asOfMs: options.asOfMs,
577
+ });
578
+ if (candidates.length === 0) {
579
+ break;
580
+ }
581
+ const { edgeCache, edgeVisibility, precomputed } = preloadRecursiveEdgeVisibility(adapter, candidates.flatMap((edge) => [edge.subject_ref, edge.object_ref]), options);
582
+ for (const edge of candidates) {
583
+ if (isTwinRefVisible(adapter, edge.subject_ref, options, new Set(), edgeCache, edgeVisibility, precomputed) &&
584
+ isTwinRefVisible(adapter, edge.object_ref, options, new Set(), edgeCache, edgeVisibility, precomputed)) {
585
+ admitted.push(edge);
586
+ if (admitted.length === limit) {
587
+ return admitted;
588
+ }
589
+ }
590
+ }
591
+ if (candidates.length < pageSize) {
592
+ break;
593
+ }
594
+ const last = candidates[candidates.length - 1];
595
+ after = { createdAt: last.created_at, edgeId: last.edge_id };
596
+ }
597
+ return admitted;
598
+ }
599
+ const candidateEdges = (0, judgments_js_1.listTwinEdgesForRefs)(adapter, refs);
600
+ const { edgeCache, edgeVisibility, precomputed } = preloadRecursiveEdgeVisibility(adapter, candidateEdges.flatMap((edge) => [edge.subject_ref, edge.object_ref]), options);
601
+ const edges = candidateEdges.filter((edge) => (edgeTypes.size === 0 || edgeTypes.has(edge.edge_type)) &&
602
+ (typeof options.startMs !== 'number' || edge.created_at >= options.startMs) &&
603
+ (typeof options.asOfMs !== 'number' || edge.created_at <= options.asOfMs) &&
604
+ isTwinRefVisible(adapter, edge.subject_ref, options, new Set(), edgeCache, edgeVisibility, precomputed) &&
605
+ isTwinRefVisible(adapter, edge.object_ref, options, new Set(), edgeCache, edgeVisibility, precomputed));
606
+ const sortedEdges = [...edges].sort((left, right) => {
607
+ const createdDiff = right.created_at - left.created_at;
608
+ return createdDiff !== 0 ? createdDiff : left.edge_id.localeCompare(right.edge_id);
609
+ });
610
+ return sortedEdges;
611
+ }
612
+ function normalizeEdgeTypes(edgeTypes) {
613
+ if (!Array.isArray(edgeTypes) || edgeTypes.length === 0) {
614
+ return new Set();
615
+ }
616
+ return new Set(edgeTypes);
617
+ }
618
+ /**
619
+ * The rule: an event is visible when its connector is granted and its channel is one of
620
+ * the channels granted for that connector.
621
+ *
622
+ * A connector absent from the grant is denied. A connector present with an empty list is
623
+ * also denied - "granted the connector but no channel of it" is not a useful state, and
624
+ * reading it as "all channels" is how a grant becomes a wildcard.
625
+ */
626
+ function isChannelGranted(connector, channel, grant) {
627
+ if (typeof channel !== 'string' || channel.length === 0)
628
+ return false;
629
+ const channels = grant[connector];
630
+ return Array.isArray(channels) && channels.includes(channel);
631
+ }
632
+ /**
633
+ * The same rule as a SQL predicate.
634
+ *
635
+ * Returns null when nothing is readable, which callers must treat as "select nothing"
636
+ * rather than "no filter" - an empty WHERE is how a visibility rule turns into a full scan
637
+ * at the exact moment it should have refused.
638
+ *
639
+ * `requestedConnectors` narrows further: a connector the caller did not ask for is not read
640
+ * even though it is granted. The grant is a ceiling, never an instruction.
641
+ */
642
+ function channelGrantClause(grant, requestedConnectors, columns) {
643
+ const pairs = [];
644
+ const params = [];
645
+ for (const [connector, channels] of Object.entries(grant)) {
646
+ if (Array.isArray(requestedConnectors) && !requestedConnectors.includes(connector))
647
+ continue;
648
+ // Array.isArray, not `?? []`: the boolean form denies a malformed grant quietly, so
649
+ // this one must not throw on it. Two forms of a rule that disagree on bad input have
650
+ // already started to be two rules.
651
+ if (!Array.isArray(channels))
652
+ continue;
653
+ const unique = [
654
+ ...new Set(channels.filter((channel) => typeof channel === 'string' && channel.length > 0)),
655
+ ];
656
+ if (unique.length === 0)
657
+ continue;
658
+ pairs.push(`(${columns.connector} = ? AND ${columns.channel} IN (${unique.map(() => '?').join(', ')}))`);
659
+ params.push(connector, ...unique);
660
+ }
661
+ return pairs.length === 0 ? null : { sql: `(${pairs.join(' OR ')})`, params };
662
+ }
663
+ //# sourceMappingURL=access.js.map
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Case errors.
3
+ *
4
+ * `CaseMergeChainCycleError` used to live in `entities/errors.ts` and extend
5
+ * that module's `EntityError`. Nothing about a cycle in `case_truth` belongs to
6
+ * the entity substrate; it sat there because the two subsystems were written
7
+ * together. It carries its own shape now.
8
+ *
9
+ * @module cases/errors
10
+ */
11
+ export interface CaseErrorEnvelope {
12
+ error: {
13
+ code: string;
14
+ message: string;
15
+ hint: string;
16
+ doc_url: string;
17
+ };
18
+ }
19
+ export declare class CaseMergeChainCycleError extends Error {
20
+ readonly code = "case.merge_chain_cycle";
21
+ readonly doc_section = "#case-merge-chain-cycle";
22
+ readonly context: Record<string, unknown>;
23
+ readonly hint: string;
24
+ constructor(context: {
25
+ case_id: string;
26
+ chain: string[];
27
+ detected_at_depth: number;
28
+ });
29
+ toErrorEnvelope(): CaseErrorEnvelope;
30
+ }
31
+ //# sourceMappingURL=case-errors.d.ts.map