@lucern/graph-primitives 1.0.28 → 1.0.30

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 (319) hide show
  1. package/dist/{beliefDecay-DZ6tkLYq.d.ts → beliefDecay-BmkEk5OJ.d.ts} +3 -3
  2. package/dist/beliefDecay.d.ts +1 -1
  3. package/dist/beliefDecay.js +448 -314
  4. package/dist/beliefDecay.js.map +1 -1
  5. package/dist/{beliefEvidenceLinks-CWOXxxJg.d.ts → beliefEvidenceLinks-BzfjON_6.d.ts} +13 -13
  6. package/dist/beliefEvidenceLinks.d.ts +1 -1
  7. package/dist/beliefEvidenceLinks.js +843 -624
  8. package/dist/beliefEvidenceLinks.js.map +1 -1
  9. package/dist/beliefEvidenceLinks.operational.d.ts +7 -5
  10. package/dist/beliefEvidenceLinks.operational.js +91 -18
  11. package/dist/beliefEvidenceLinks.operational.js.map +1 -1
  12. package/dist/beliefLifecycle.js.map +1 -1
  13. package/dist/confidencePropagationDispatch.d.ts +28 -27
  14. package/dist/confidencePropagationDispatch.js +157 -99
  15. package/dist/confidencePropagationDispatch.js.map +1 -1
  16. package/dist/{contradictions-51VLsESq.d.ts → contradictions-BATPuZTL.d.ts} +10 -10
  17. package/dist/contradictions.d.ts +1 -1
  18. package/dist/contradictions.js +398 -228
  19. package/dist/contradictions.js.map +1 -1
  20. package/dist/convex.d.ts +65 -30
  21. package/dist/convex.js +7 -3
  22. package/dist/convex.js.map +1 -1
  23. package/dist/debug.js.map +1 -1
  24. package/dist/edgeValidation.js +293 -85
  25. package/dist/edgeValidation.js.map +1 -1
  26. package/dist/edges/contains.d.ts +1 -1
  27. package/dist/edges/contains.js.map +1 -1
  28. package/dist/edges/contradicts.d.ts +1 -1
  29. package/dist/edges/contradicts.js.map +1 -1
  30. package/dist/edges/{dependsOn.d.ts → depends-on.d.ts} +1 -1
  31. package/dist/edges/{dependsOn.js → depends-on.js} +4 -4
  32. package/dist/edges/depends-on.js.map +1 -0
  33. package/dist/edges/{derivedFrom.d.ts → derived-from.d.ts} +1 -1
  34. package/dist/edges/{derivedFrom.js → derived-from.js} +3 -3
  35. package/dist/edges/derived-from.js.map +1 -0
  36. package/dist/edges/elaborates.d.ts +1 -1
  37. package/dist/edges/elaborates.js.map +1 -1
  38. package/dist/edges/index.d.ts +7 -3
  39. package/dist/edges/index.js +7 -4
  40. package/dist/edges/index.js.map +1 -1
  41. package/dist/edges/informs.d.ts +1 -1
  42. package/dist/edges/informs.js.map +1 -1
  43. package/dist/edges/{propagationTypes.d.ts → propagation-types.d.ts} +14 -14
  44. package/dist/edges/{propagationTypes.js → propagation-types.js} +3 -3
  45. package/dist/edges/propagation-types.js.map +1 -0
  46. package/dist/edges/refutes.d.ts +1 -1
  47. package/dist/edges/refutes.js.map +1 -1
  48. package/dist/edges/supports.d.ts +1 -1
  49. package/dist/edges/supports.js.map +1 -1
  50. package/dist/edges/tests.d.ts +1 -1
  51. package/dist/edges/tests.js.map +1 -1
  52. package/dist/edges/utils.d.ts +1 -1
  53. package/dist/edges/utils.js.map +1 -1
  54. package/dist/embeddingTrigger.d.ts +14 -6
  55. package/dist/embeddingTrigger.js +11 -14
  56. package/dist/embeddingTrigger.js.map +1 -1
  57. package/dist/{entityBridge-DMaKooYn.d.ts → entityBridge-BhVDM3pc.d.ts} +5 -5
  58. package/dist/entityBridge.d.ts +1 -1
  59. package/dist/entityBridge.js +602 -225
  60. package/dist/entityBridge.js.map +1 -1
  61. package/dist/entityCanonicalMatch.d.ts +14 -12
  62. package/dist/entityCanonicalMatch.js.map +1 -1
  63. package/dist/{entityLifecycle-CvgSK5FV.d.ts → entityLifecycle-BsfCz9pS.d.ts} +5 -9
  64. package/dist/entityLifecycle.d.ts +1 -1
  65. package/dist/entityLifecycle.js +857 -515
  66. package/dist/entityLifecycle.js.map +1 -1
  67. package/dist/{entityValidation-KLZ_Xl2D.d.ts → entityValidation-B1yNEHJx.d.ts} +7 -6
  68. package/dist/entityValidation.d.ts +3 -1
  69. package/dist/entityValidation.js +60 -8
  70. package/dist/entityValidation.js.map +1 -1
  71. package/dist/{epistemicAnswers-C5ib4z6_.d.ts → epistemicAnswers-f47YMu9U.d.ts} +6 -6
  72. package/dist/epistemicAnswers.d.ts +1 -1
  73. package/dist/epistemicAnswers.js +587 -545
  74. package/dist/epistemicAnswers.js.map +1 -1
  75. package/dist/epistemicBeliefs.admin.d.ts +8 -8
  76. package/dist/epistemicBeliefs.admin.js +366 -203
  77. package/dist/epistemicBeliefs.admin.js.map +1 -1
  78. package/dist/epistemicBeliefs.backfills.d.ts +8 -8
  79. package/dist/epistemicBeliefs.backfills.js +655 -308
  80. package/dist/epistemicBeliefs.backfills.js.map +1 -1
  81. package/dist/epistemicBeliefs.confidence.d.ts +19 -14
  82. package/dist/epistemicBeliefs.confidence.js +634 -423
  83. package/dist/epistemicBeliefs.confidence.js.map +1 -1
  84. package/dist/epistemicBeliefs.core.d.ts +6 -6
  85. package/dist/epistemicBeliefs.core.js +719 -411
  86. package/dist/epistemicBeliefs.core.js.map +1 -1
  87. package/dist/epistemicBeliefs.d.ts +11 -8
  88. package/dist/epistemicBeliefs.forkEvidence.d.ts +2 -0
  89. package/dist/epistemicBeliefs.forkEvidence.js +8 -28
  90. package/dist/epistemicBeliefs.forkEvidence.js.map +1 -1
  91. package/dist/epistemicBeliefs.helpers.d.ts +69 -74
  92. package/dist/epistemicBeliefs.helpers.js +359 -248
  93. package/dist/epistemicBeliefs.helpers.js.map +1 -1
  94. package/dist/epistemicBeliefs.internal.d.ts +5 -5
  95. package/dist/epistemicBeliefs.internal.js +1246 -1044
  96. package/dist/epistemicBeliefs.internal.js.map +1 -1
  97. package/dist/epistemicBeliefs.js +4922 -3608
  98. package/dist/epistemicBeliefs.js.map +1 -1
  99. package/dist/epistemicBeliefs.lifecycle.d.ts +5 -5
  100. package/dist/epistemicBeliefs.lifecycle.js +1137 -818
  101. package/dist/epistemicBeliefs.lifecycle.js.map +1 -1
  102. package/dist/epistemicBeliefs.links.d.ts +7 -7
  103. package/dist/epistemicBeliefs.links.js +408 -307
  104. package/dist/epistemicBeliefs.links.js.map +1 -1
  105. package/dist/epistemicBeliefs.queries.d.ts +4 -4
  106. package/dist/epistemicBeliefs.queries.js +175 -20
  107. package/dist/epistemicBeliefs.queries.js.map +1 -1
  108. package/dist/epistemicBeliefs.topicAnchor.d.ts +6 -4
  109. package/dist/epistemicBeliefs.topicAnchor.js +12 -5
  110. package/dist/epistemicBeliefs.topicAnchor.js.map +1 -1
  111. package/dist/epistemicContracts.d.ts +28 -3
  112. package/dist/epistemicContracts.evaluators.d.ts +2 -0
  113. package/dist/epistemicContracts.evaluators.js +1063 -613
  114. package/dist/epistemicContracts.evaluators.js.map +1 -1
  115. package/dist/epistemicContracts.handlers.d.ts +15 -32
  116. package/dist/epistemicContracts.handlers.js +2086 -1644
  117. package/dist/epistemicContracts.handlers.js.map +1 -1
  118. package/dist/epistemicContracts.js +1131 -672
  119. package/dist/epistemicContracts.js.map +1 -1
  120. package/dist/epistemicContracts.metrics.d.ts +2 -0
  121. package/dist/epistemicContracts.metrics.js +375 -158
  122. package/dist/epistemicContracts.metrics.js.map +1 -1
  123. package/dist/epistemicContracts.types.d.ts +87 -81
  124. package/dist/epistemicEdgeCreation.d.ts +2 -0
  125. package/dist/epistemicEdgeCreation.js +87 -16
  126. package/dist/epistemicEdgeCreation.js.map +1 -1
  127. package/dist/{epistemicEdges-BF-cn4i3.d.ts → epistemicEdges-BGBh0QSP.d.ts} +4 -7
  128. package/dist/epistemicEdges.d.ts +6 -5
  129. package/dist/epistemicEdges.handlers.d.ts +3 -3
  130. package/dist/epistemicEdges.handlers.js +129 -24
  131. package/dist/epistemicEdges.handlers.js.map +1 -1
  132. package/dist/epistemicEdges.helpers.d.ts +6 -4
  133. package/dist/epistemicEdges.helpers.js +37 -2
  134. package/dist/epistemicEdges.helpers.js.map +1 -1
  135. package/dist/epistemicEdges.js +1969 -1205
  136. package/dist/epistemicEdges.js.map +1 -1
  137. package/dist/epistemicEdges.mutations.d.ts +7 -7
  138. package/dist/epistemicEdges.mutations.js +960 -583
  139. package/dist/epistemicEdges.mutations.js.map +1 -1
  140. package/dist/epistemicEdges.queries.d.ts +16 -16
  141. package/dist/epistemicEdges.queries.js +639 -367
  142. package/dist/epistemicEdges.queries.js.map +1 -1
  143. package/dist/epistemicEdges.types.d.ts +10 -8
  144. package/dist/epistemicEvidence.d.ts +4 -1
  145. package/dist/epistemicEvidence.js +937 -536
  146. package/dist/epistemicEvidence.js.map +1 -1
  147. package/dist/epistemicEvidenceHelpers.d.ts +26 -10
  148. package/dist/epistemicEvidenceHelpers.js +239 -200
  149. package/dist/epistemicEvidenceHelpers.js.map +1 -1
  150. package/dist/epistemicEvidenceMutations.d.ts +8 -8
  151. package/dist/epistemicEvidenceMutations.js +844 -696
  152. package/dist/epistemicEvidenceMutations.js.map +1 -1
  153. package/dist/epistemicEvidenceQueries.d.ts +8 -8
  154. package/dist/epistemicEvidenceQueries.js +514 -238
  155. package/dist/epistemicEvidenceQueries.js.map +1 -1
  156. package/dist/epistemicHelpers.d.ts +4 -2
  157. package/dist/epistemicHelpers.js +308 -134
  158. package/dist/epistemicHelpers.js.map +1 -1
  159. package/dist/epistemicInsert.d.ts +16 -4
  160. package/dist/epistemicInsert.js +6 -3
  161. package/dist/epistemicInsert.js.map +1 -1
  162. package/dist/epistemicLayerRules.d.ts +10 -8
  163. package/dist/epistemicLayerRules.js +1 -5
  164. package/dist/epistemicLayerRules.js.map +1 -1
  165. package/dist/{epistemicLinking-CfE00tHJ.d.ts → epistemicLinking-CsCDv2cN.d.ts} +3 -3
  166. package/dist/epistemicLinking.d.ts +1 -1
  167. package/dist/epistemicLinking.js +177 -100
  168. package/dist/epistemicLinking.js.map +1 -1
  169. package/dist/epistemicNodeCreation.d.ts +2 -0
  170. package/dist/epistemicNodeCreation.js +203 -40
  171. package/dist/epistemicNodeCreation.js.map +1 -1
  172. package/dist/{epistemicNodes-BCQxpYx_.d.ts → epistemicNodes-CokAgBHg.d.ts} +3 -3
  173. package/dist/epistemicNodes.d.ts +3 -3
  174. package/dist/epistemicNodes.helpers.d.ts +24 -15
  175. package/dist/epistemicNodes.helpers.js.map +1 -1
  176. package/dist/epistemicNodes.internal.d.ts +6 -6
  177. package/dist/epistemicNodes.internal.js +389 -319
  178. package/dist/epistemicNodes.internal.js.map +1 -1
  179. package/dist/epistemicNodes.js +704 -508
  180. package/dist/epistemicNodes.js.map +1 -1
  181. package/dist/epistemicNodes.mutations.d.ts +6 -6
  182. package/dist/epistemicNodes.mutations.js +564 -467
  183. package/dist/epistemicNodes.mutations.js.map +1 -1
  184. package/dist/epistemicNodes.queries.d.ts +8 -8
  185. package/dist/epistemicNodes.queries.js +311 -314
  186. package/dist/epistemicNodes.queries.js.map +1 -1
  187. package/dist/epistemicNodes.validators.d.ts +2 -2
  188. package/dist/epistemicNodes.validators.js.map +1 -1
  189. package/dist/epistemicQuestions.conviction.d.ts +8 -8
  190. package/dist/epistemicQuestions.conviction.js +665 -484
  191. package/dist/epistemicQuestions.conviction.js.map +1 -1
  192. package/dist/epistemicQuestions.create.d.ts +4 -4
  193. package/dist/epistemicQuestions.create.js +640 -612
  194. package/dist/epistemicQuestions.create.js.map +1 -1
  195. package/dist/epistemicQuestions.d.ts +8 -5
  196. package/dist/epistemicQuestions.evidence.d.ts +2 -2
  197. package/dist/epistemicQuestions.evidence.js +475 -383
  198. package/dist/epistemicQuestions.evidence.js.map +1 -1
  199. package/dist/epistemicQuestions.helpers.d.ts +125 -24
  200. package/dist/epistemicQuestions.helpers.js +240 -209
  201. package/dist/epistemicQuestions.helpers.js.map +1 -1
  202. package/dist/epistemicQuestions.js +3474 -2823
  203. package/dist/epistemicQuestions.js.map +1 -1
  204. package/dist/epistemicQuestions.lifecycle.d.ts +2 -2
  205. package/dist/epistemicQuestions.lifecycle.js +607 -546
  206. package/dist/epistemicQuestions.lifecycle.js.map +1 -1
  207. package/dist/epistemicQuestions.queries.d.ts +12 -7
  208. package/dist/epistemicQuestions.queries.js +305 -244
  209. package/dist/epistemicQuestions.queries.js.map +1 -1
  210. package/dist/epistemicQuestions.sprint.d.ts +2 -2
  211. package/dist/epistemicQuestions.sprint.js +600 -394
  212. package/dist/epistemicQuestions.sprint.js.map +1 -1
  213. package/dist/epistemicQuestions.tail.d.ts +6 -6
  214. package/dist/epistemicQuestions.tail.js +572 -433
  215. package/dist/epistemicQuestions.tail.js.map +1 -1
  216. package/dist/{epistemicSources-dlKj58Jp.d.ts → epistemicSources-DQtaEkWs.d.ts} +4 -4
  217. package/dist/epistemicSources.d.ts +1 -1
  218. package/dist/epistemicSources.js +352 -312
  219. package/dist/epistemicSources.js.map +1 -1
  220. package/dist/evaluators/index.d.ts +8 -6
  221. package/dist/evaluators/index.js +399 -167
  222. package/dist/evaluators/index.js.map +1 -1
  223. package/dist/evaluators/lint-checker-evaluator.d.ts +16 -0
  224. package/dist/evaluators/{lintCheckerEvaluator.js → lint-checker-evaluator.js} +10 -5
  225. package/dist/evaluators/lint-checker-evaluator.js.map +1 -0
  226. package/dist/evaluators/{sentryCheckerEvaluator.d.ts → sentry-checker-evaluator.d.ts} +7 -2
  227. package/dist/evaluators/{sentryCheckerEvaluator.js → sentry-checker-evaluator.js} +3 -3
  228. package/dist/evaluators/sentry-checker-evaluator.js.map +1 -0
  229. package/dist/evaluators/shared.d.ts +2 -2
  230. package/dist/evaluators/shared.js +3 -1
  231. package/dist/evaluators/shared.js.map +1 -1
  232. package/dist/evaluators/{testRunnerEvaluator.d.ts → test-runner-evaluator.d.ts} +6 -1
  233. package/dist/evaluators/{testRunnerEvaluator.js → test-runner-evaluator.js} +6 -4
  234. package/dist/evaluators/test-runner-evaluator.js.map +1 -0
  235. package/dist/evaluators/tsc-checker-evaluator.d.ts +16 -0
  236. package/dist/evaluators/{tscCheckerEvaluator.js → tsc-checker-evaluator.js} +10 -5
  237. package/dist/evaluators/tsc-checker-evaluator.js.map +1 -0
  238. package/dist/graphTypes.js +6 -2
  239. package/dist/graphTypes.js.map +1 -1
  240. package/dist/helpers.d.ts +2 -0
  241. package/dist/helpers.js +313 -93
  242. package/dist/helpers.js.map +1 -1
  243. package/dist/{index-C-Kyd7hD.d.ts → index-DZxyC9Pb.d.ts} +7 -6
  244. package/dist/index.d.ts +87 -83
  245. package/dist/index.js +15677 -10594
  246. package/dist/index.js.map +1 -1
  247. package/dist/invariantEnforcement.d.ts +3 -3
  248. package/dist/invariantEnforcement.js.map +1 -1
  249. package/dist/logicalRoleInference.d.ts +2 -0
  250. package/dist/logicalRoleInference.js +1 -1
  251. package/dist/logicalRoleInference.js.map +1 -1
  252. package/dist/matcherFeedbackUtils.d.ts +2 -2
  253. package/dist/matcherFeedbackUtils.js.map +1 -1
  254. package/dist/{ontology-matching-C6rrz2VP.d.ts → ontology-matching-C-mYFrir.d.ts} +16 -16
  255. package/dist/ontology-matching.d.ts +1 -1
  256. package/dist/{ontologyApproval-CFYmqKmk.d.ts → ontologyApproval-BVt0feJi.d.ts} +10 -10
  257. package/dist/ontologyApproval.d.ts +1 -1
  258. package/dist/ontologyApproval.js +7 -1
  259. package/dist/ontologyApproval.js.map +1 -1
  260. package/dist/ontologyDefinitions.d.ts +14 -24
  261. package/dist/ontologyDefinitions.js +269 -34
  262. package/dist/ontologyDefinitions.js.map +1 -1
  263. package/dist/ontologyHelpers.d.ts +13 -13
  264. package/dist/ontologyHelpers.js.map +1 -1
  265. package/dist/{ontologyRegistry-B67rPJ16.d.ts → ontologyRegistry-CljS-ENv.d.ts} +2 -2
  266. package/dist/ontologyRegistry.d.ts +1 -1
  267. package/dist/ontologyRegistry.js +34 -6
  268. package/dist/ontologyRegistry.js.map +1 -1
  269. package/dist/{projectionReconciliation-jww2fBI0.d.ts → projectionReconciliation-DnrSgHSQ.d.ts} +4 -4
  270. package/dist/projectionReconciliation.d.ts +1 -1
  271. package/dist/projectionReconciliation.js +57 -10
  272. package/dist/projectionReconciliation.js.map +1 -1
  273. package/dist/{projectionStaleness-CmdbpjVK.d.ts → projectionStaleness-C8ImQ2zP.d.ts} +17 -17
  274. package/dist/projectionStaleness.d.ts +1 -1
  275. package/dist/projectionStaleness.js +8 -2
  276. package/dist/projectionStaleness.js.map +1 -1
  277. package/dist/proof-attestation.json +1 -1
  278. package/dist/{questionEvidenceLinks-DFlyPpAj.d.ts → questionEvidenceLinks-_nPRa-LY.d.ts} +10 -10
  279. package/dist/questionEvidenceLinks.d.ts +1 -1
  280. package/dist/questionEvidenceLinks.js +564 -347
  281. package/dist/questionEvidenceLinks.js.map +1 -1
  282. package/dist/{resolverTypes-CC8Ea2E2.d.ts → resolverTypes-BOXPxLET.d.ts} +8 -7
  283. package/dist/resolverTypes.d.ts +4 -2
  284. package/dist/{resolvers-Br1a6eLV.d.ts → resolvers-B1TIBmRO.d.ts} +3 -1
  285. package/dist/resolvers.d.ts +5 -3
  286. package/dist/resolvers.js +121 -77
  287. package/dist/resolvers.js.map +1 -1
  288. package/dist/scopeResolverCompat.d.ts +10 -7
  289. package/dist/scopeResolverCompat.js +106 -123
  290. package/dist/scopeResolverCompat.js.map +1 -1
  291. package/dist/{text-matching-DNg4M5Wd.d.ts → text-matching-DzFooju6.d.ts} +7 -7
  292. package/dist/text-matching.d.ts +1 -1
  293. package/dist/topicOntologyResolver.d.ts +22 -21
  294. package/dist/topicOntologyResolver.js +54 -32
  295. package/dist/topicOntologyResolver.js.map +1 -1
  296. package/dist/topicProjectOverlay.d.ts +30 -20
  297. package/dist/topicProjectOverlay.js +120 -76
  298. package/dist/topicProjectOverlay.js.map +1 -1
  299. package/dist/{topicScope-7zhyeGl7.d.ts → topicScope-DJVa0mLa.d.ts} +22 -7
  300. package/dist/topicScope.d.ts +3 -1
  301. package/dist/topicScope.js +104 -119
  302. package/dist/topicScope.js.map +1 -1
  303. package/dist/workflowBridge.d.ts +26 -15
  304. package/dist/workflowBridge.js +140 -144
  305. package/dist/workflowBridge.js.map +1 -1
  306. package/dist/workspaceIsolation.d.ts +14 -12
  307. package/dist/workspaceIsolation.js +108 -122
  308. package/dist/workspaceIsolation.js.map +1 -1
  309. package/package.json +4 -4
  310. package/dist/edges/dependsOn.js.map +0 -1
  311. package/dist/edges/derivedFrom.js.map +0 -1
  312. package/dist/edges/propagationTypes.js.map +0 -1
  313. package/dist/evaluators/lintCheckerEvaluator.d.ts +0 -11
  314. package/dist/evaluators/lintCheckerEvaluator.js.map +0 -1
  315. package/dist/evaluators/sentryCheckerEvaluator.js.map +0 -1
  316. package/dist/evaluators/testRunnerEvaluator.js.map +0 -1
  317. package/dist/evaluators/tscCheckerEvaluator.d.ts +0 -11
  318. package/dist/evaluators/tscCheckerEvaluator.js.map +0 -1
  319. package/dist/{epistemicQuestions-bwHd2FWE.d.ts → epistemicQuestions-Do1fhYm5.d.ts} +4 -4
@@ -1,81 +1,25 @@
1
- import { v, ConvexError } from 'convex/values';
1
+ import { requireScopeWriteAccess } from '@lucern/access-control/access';
2
2
  import { permissiveReturn } from '@lucern/contracts/schema-helpers/validators';
3
- import { componentsGeneric, anyApi, mutationGeneric, queryGeneric } from 'convex/server';
4
- import { generateGlobalId, assertUuidV7Identity, assertStorageEdgeVocabulary, assertUuidShapedEdgeEndpoint } from '@lucern/contracts/ids';
5
- import { normalizeTupleContradictionPolicy } from '@lucern/confidence';
6
- import { checkProjectAccess } from '@lucern/access-control/access';
3
+ import { v } from 'convex/values';
4
+ import { unsafeConvexAnyApi } from '@lucern/contracts/convex/unsafeAnyApi';
5
+ import { componentsGeneric, mutationGeneric, queryGeneric } from 'convex/server';
7
6
  import '@lucern/access-control/audience';
8
7
  import { getCurrentUserId } from '@lucern/access-control/auth';
8
+ import { throwStructuredMutationError } from '@lucern/access-control/structuredMutationError';
9
+ import { normalizeTupleContradictionPolicy } from '@lucern/confidence';
9
10
  import { assertEdgePolicyAllowed, edgePolicyManifest } from '@lucern/contracts';
11
+ import { generateGlobalId, assertUuidV7Identity, assertStorageEdgeVocabulary, assertUuidShapedEdgeEndpoint } from '@lucern/contracts/ids';
10
12
 
11
13
  // src/epistemicBeliefs.links.ts
12
- var api = anyApi;
14
+ var unsafeApi = unsafeConvexAnyApi(
15
+ "graph-primitives top-level module bundle lacks a committed Convex _generated/api surface"
16
+ );
17
+ var api = unsafeApi;
13
18
  componentsGeneric();
14
- var internal = anyApi;
19
+ var internal = unsafeApi;
15
20
  var mutation = mutationGeneric;
16
21
  var query = queryGeneric;
17
22
 
18
- // src/logicalRoleInference.ts
19
- var PILLAR_IMPORTANCE = {
20
- market: 1,
21
- competition: 2,
22
- product: 3,
23
- team: 4,
24
- financials: 5,
25
- timing: 6,
26
- other: 10
27
- };
28
- async function computeLogicalRole(ctx, evidenceId, beliefId) {
29
- const belief = await ctx.db.get(beliefId);
30
- if (!belief || belief.nodeType !== "belief") {
31
- return "contributory";
32
- }
33
- const beliefMetadata = belief.metadata;
34
- const pillar = beliefMetadata?.pillar || "other";
35
- const pillarRank = PILLAR_IMPORTANCE[pillar] ?? 10;
36
- const isSynthesized = await checkIfSynthesizedHypothesis(ctx, beliefId);
37
- const testingQuestions = await getTestingQuestionsForBelief(ctx, beliefId);
38
- const answeredQuestions = await getQuestionsAnsweredByEvidence(
39
- ctx,
40
- evidenceId
41
- );
42
- const directlyTests = testingQuestions.filter(
43
- (questionId) => answeredQuestions.includes(questionId)
44
- );
45
- if (directlyTests.length === 0) {
46
- return "contributory";
47
- }
48
- if (isSynthesized && pillarRank <= 2) {
49
- return directlyTests.length > 1 ? "necessary_sufficient" : "necessary";
50
- }
51
- if (isSynthesized) {
52
- return "necessary";
53
- }
54
- return directlyTests.length > 1 ? "necessary" : "contributory";
55
- }
56
- async function checkIfSynthesizedHypothesis(ctx, beliefId) {
57
- const belief = await ctx.db.get(beliefId);
58
- if (!belief) {
59
- return false;
60
- }
61
- const metadata = belief.metadata;
62
- return metadata?.isSynthesized === true || metadata?.beliefStatus === "hypothesis";
63
- }
64
- async function getTestingQuestionsForBelief(ctx, beliefId) {
65
- const testEdges = await ctx.db.query("epistemicEdges").withIndex(
66
- "by_to_type",
67
- (q) => q.eq("toNodeId", beliefId).eq("edgeType", "tests")
68
- ).collect();
69
- return testEdges.map((edge) => edge.fromNodeId).filter((id) => id !== void 0);
70
- }
71
- async function getQuestionsAnsweredByEvidence(ctx, evidenceId) {
72
- const answerEdges = await ctx.db.query("epistemicEdges").withIndex(
73
- "by_from_type",
74
- (q) => q.eq("fromNodeId", evidenceId).eq("edgeType", "derived_from")
75
- ).collect();
76
- return answerEdges.map((edge) => edge.toNodeId).filter((id) => id !== void 0);
77
- }
78
-
79
23
  // src/debug.ts
80
24
  function isGraphPrimitiveDebugEnabled() {
81
25
  const env = globalThis.process?.env;
@@ -121,13 +65,15 @@ function asMappedProjectId(topic) {
121
65
  if (!topic) {
122
66
  return;
123
67
  }
124
- const directLegacyProjectId = normalizeScopeValue(topic[LEGACY_SCOPE_FIELD]);
68
+ const directLegacyProjectId = normalizeScopeValue(
69
+ topic[LEGACY_SCOPE_FIELD]
70
+ );
125
71
  if (directLegacyProjectId) {
126
72
  return directLegacyProjectId;
127
73
  }
128
74
  const metadata = topic.metadata || {};
129
75
  const candidate = metadata[LEGACY_SCOPE_FIELD] || metadata.legacyProjectId || metadata.projectId || metadata.scopeProjectId;
130
- return candidate ? candidate : void 0;
76
+ return typeof candidate === "string" ? normalizeScopeValue(candidate) : void 0;
131
77
  }
132
78
  function normalizeScopeValue(value) {
133
79
  if (typeof value !== "string") {
@@ -152,8 +98,9 @@ function pickPrimaryTopic(candidates) {
152
98
  })[0];
153
99
  }
154
100
  async function findTopicsByScopeAlias(ctx, scopeId) {
101
+ const query2 = ctx.db.query("topics");
155
102
  try {
156
- return await ctx.db.query("topics").withIndex(
103
+ return await query2.withIndex(
157
104
  "by_graph_scope_project",
158
105
  (q) => q.eq(LEGACY_SCOPE_FIELD, scopeId)
159
106
  ).collect();
@@ -165,7 +112,7 @@ async function findTopicsByScopeAlias(ctx, scopeId) {
165
112
  scopeId
166
113
  }
167
114
  );
168
- const topics = await ctx.db.query("topics").collect();
115
+ const topics = await query2.collect();
169
116
  return topics.filter((topic) => {
170
117
  const normalizedGlobalId = normalizeScopeValue(topic.globalId);
171
118
  const mappedProjectId = asMappedProjectId(topic);
@@ -221,168 +168,124 @@ async function resolveInheritedWorkspaceScope(ctx, topic) {
221
168
  let current = topic;
222
169
  for (let i = 0; i < MAX_DEPTH && current?.parentTopicId; i++) {
223
170
  current = await ctx.db.get(current.parentTopicId);
224
- if (!current) break;
171
+ if (!current) {
172
+ break;
173
+ }
225
174
  if (!tenantId) {
226
175
  tenantId = normalizeScopeValue(current.tenantId);
227
176
  }
228
177
  if (!workspaceId) {
229
178
  workspaceId = normalizeScopeValue(current.workspaceId);
230
179
  }
231
- if (tenantId && workspaceId) break;
180
+ if (tenantId && workspaceId) {
181
+ break;
182
+ }
232
183
  }
233
184
  return { tenantId, workspaceId };
234
185
  }
235
186
  async function resolveTopicProjectScope(ctx, args) {
236
187
  if (args.topicId) {
237
- let topic = null;
238
- try {
239
- topic = await ctx.db.get(
240
- args.topicId
241
- );
242
- } catch (error) {
243
- debugGraphPrimitiveFallback(
244
- "[topicScope] Failed to load topic by direct id",
245
- {
246
- error,
247
- topicId: args.topicId
248
- }
249
- );
250
- }
251
- if (!topic) {
252
- topic = await tryResolveHostTopicById(ctx, String(args.topicId));
253
- }
254
- if (!topic) {
255
- topic = pickPrimaryTopic(
256
- await findTopicsByScopeAlias(ctx, String(args.topicId))
257
- ) ?? null;
258
- }
259
- if (!topic) {
260
- const nodeScope = await resolveTopicNodeScopeOrNull(
261
- ctx,
262
- String(args.topicId)
263
- );
264
- if (nodeScope) {
265
- return nodeScope;
266
- }
267
- throw new Error(`Topic not found: ${String(args.topicId)}`);
268
- }
269
- const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
270
- const mapped = asMappedProjectId(topic);
271
- if (mapped) {
272
- return {
273
- topicId: topic._id,
274
- projectId: mapped,
275
- tenantId: inherited.tenantId,
276
- workspaceId: inherited.workspaceId,
277
- source: "topic"
278
- };
279
- }
280
- return {
281
- topicId: topic._id,
282
- tenantId: inherited.tenantId,
283
- workspaceId: inherited.workspaceId,
284
- source: "topic"
285
- };
188
+ return await resolveScopeFromTopicId(ctx, args.topicId);
286
189
  }
287
190
  if (args.projectId) {
288
- let directTopic = null;
289
- try {
290
- directTopic = await ctx.db.get(
291
- args.projectId
292
- );
293
- } catch (error) {
294
- debugGraphPrimitiveFallback(
295
- "[topicScope] Failed to load direct project topic",
296
- {
297
- error,
298
- projectId: args.projectId
299
- }
300
- );
301
- }
302
- if (directTopic) {
303
- const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
304
- const mapped = asMappedProjectId(directTopic);
305
- return {
306
- topicId: directTopic._id,
307
- projectId: mapped ?? args.projectId,
308
- tenantId: inherited.tenantId,
309
- workspaceId: inherited.workspaceId,
310
- source: "topic_inferred"
311
- };
312
- }
313
- directTopic = await tryResolveHostTopicByLegacyScope(ctx, args.projectId);
314
- if (directTopic) {
315
- const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
316
- const mapped = asMappedProjectId(directTopic);
317
- return {
318
- topicId: directTopic._id,
319
- projectId: mapped ?? args.projectId,
320
- tenantId: inherited.tenantId,
321
- workspaceId: inherited.workspaceId,
322
- source: "topic_inferred"
323
- };
324
- }
325
- const topics = await findTopicsByScopeAlias(ctx, args.projectId);
326
- const primary = pickPrimaryTopic(topics);
327
- if (primary) {
328
- const inherited = await resolveInheritedWorkspaceScope(ctx, primary);
329
- return {
330
- topicId: primary._id,
331
- projectId: args.projectId,
332
- tenantId: inherited.tenantId,
333
- workspaceId: inherited.workspaceId,
334
- source: "project_mapped_topic"
335
- };
336
- }
337
- const nodeScope = await resolveTopicNodeScopeOrNull(
338
- ctx,
339
- String(args.projectId)
340
- );
341
- if (nodeScope) {
342
- return {
343
- ...nodeScope,
344
- projectId: nodeScope.projectId ?? String(args.projectId)
345
- };
346
- }
347
- throw new Error(
348
- `Legacy project scope ${String(args.projectId)} has no mapped topic.`
349
- );
191
+ return await resolveScopeFromLegacyProjectId(ctx, args.projectId);
350
192
  }
351
193
  throw new Error(
352
194
  "Missing scope: provide topicId (preferred) or legacy projectId alias."
353
195
  );
354
196
  }
197
+ async function resolveScopeFromTopicId(ctx, topicId) {
198
+ const topic = await resolveTopicDocFromTopicId(ctx, topicId);
199
+ if (topic) {
200
+ return await buildTopicScope(ctx, topic, "topic");
201
+ }
202
+ const nodeScope = await resolveTopicNodeScopeOrNull(ctx, String(topicId));
203
+ if (nodeScope) {
204
+ return nodeScope;
205
+ }
206
+ throw new Error(`Topic not found: ${String(topicId)}`);
207
+ }
208
+ async function resolveTopicDocFromTopicId(ctx, topicId) {
209
+ const direct = await tryReadTopicDoc(ctx, topicId, {
210
+ failureLog: "[topicScope] Failed to load topic by direct id",
211
+ idLogKey: "topicId"
212
+ });
213
+ if (direct) {
214
+ return direct;
215
+ }
216
+ const hostTopic = await tryResolveHostTopicById(ctx, String(topicId));
217
+ if (hostTopic) {
218
+ return hostTopic;
219
+ }
220
+ return pickPrimaryTopic(await findTopicsByScopeAlias(ctx, String(topicId))) ?? null;
221
+ }
222
+ async function resolveScopeFromLegacyProjectId(ctx, legacyProjectId) {
223
+ const directTopic = await resolveDirectLegacyProjectTopic(
224
+ ctx,
225
+ legacyProjectId
226
+ );
227
+ if (directTopic) {
228
+ return await buildTopicScope(ctx, directTopic, "topic_inferred", {
229
+ fallbackProjectId: legacyProjectId
230
+ });
231
+ }
232
+ const primary = pickPrimaryTopic(
233
+ await findTopicsByScopeAlias(ctx, legacyProjectId)
234
+ );
235
+ if (primary) {
236
+ return await buildTopicScope(ctx, primary, "project_mapped_topic", {
237
+ fallbackProjectId: legacyProjectId
238
+ });
239
+ }
240
+ const nodeScope = await resolveTopicNodeScopeOrNull(ctx, legacyProjectId);
241
+ if (nodeScope) {
242
+ return {
243
+ ...nodeScope,
244
+ projectId: nodeScope.projectId ?? legacyProjectId
245
+ };
246
+ }
247
+ throw new Error(
248
+ `Legacy project scope ${legacyProjectId} has no mapped topic.`
249
+ );
250
+ }
251
+ async function resolveDirectLegacyProjectTopic(ctx, legacyProjectId) {
252
+ const directTopic = await tryReadTopicDoc(ctx, legacyProjectId, {
253
+ failureLog: "[topicScope] Failed to load direct project topic",
254
+ idLogKey: "projectId"
255
+ });
256
+ return directTopic ?? tryResolveHostTopicByLegacyScope(ctx, legacyProjectId);
257
+ }
258
+ async function tryReadTopicDoc(ctx, id, log) {
259
+ try {
260
+ return await ctx.db.get(id);
261
+ } catch (error) {
262
+ debugGraphPrimitiveFallback(log.failureLog, {
263
+ error,
264
+ [log.idLogKey]: id
265
+ });
266
+ return null;
267
+ }
268
+ }
269
+ async function buildTopicScope(ctx, topic, source, options = {}) {
270
+ const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
271
+ const mapped = asMappedProjectId(topic);
272
+ return {
273
+ topicId: topic._id,
274
+ ...mapped || options.fallbackProjectId ? { projectId: mapped ?? options.fallbackProjectId } : {},
275
+ tenantId: inherited.tenantId,
276
+ workspaceId: inherited.workspaceId,
277
+ source
278
+ };
279
+ }
355
280
  var optionalScopeArgs = {
356
281
  projectId: v.optional(v.string()),
357
282
  topicId: v.optional(v.string())
358
283
  };
359
-
360
- // src/epistemicBeliefs.helpers.ts
361
284
  var insightIdUnion = v.id("epistemicNodes");
362
285
  var optionalBeliefScopeArgs = optionalScopeArgs;
363
286
  ({
364
287
  tupleContradiction: normalizeTupleContradictionPolicy()
365
288
  });
366
- function throwStructuredMutationError(args) {
367
- const data = {
368
- structuredMutationError: true,
369
- message: args.message,
370
- status: args.status,
371
- code: args.code,
372
- invariantCode: args.invariantCode,
373
- suggestion: args.suggestion,
374
- details: args.details
375
- };
376
- const error = new ConvexError(
377
- data
378
- );
379
- error.status = args.status;
380
- error.code = args.code;
381
- error.invariantCode = args.invariantCode;
382
- error.suggestion = args.suggestion;
383
- error.details = args.details;
384
- throw error;
385
- }
386
289
  function buildBeliefStatusSuccessResult() {
387
290
  return { success: true };
388
291
  }
@@ -393,7 +296,7 @@ function buildBeliefEvidenceNotFoundResult() {
393
296
  return result;
394
297
  }
395
298
  async function resolveBeliefScopeOrNull(ctx, args) {
396
- if (!args.projectId && !args.topicId) {
299
+ if (!(args.projectId || args.topicId)) {
397
300
  return null;
398
301
  }
399
302
  try {
@@ -428,26 +331,12 @@ async function requireAuthenticatedUserId(ctx) {
428
331
  }
429
332
  return userId;
430
333
  }
431
- async function requireProjectWriteAccess(ctx, projectId, userId) {
432
- const hasAccess = await checkProjectAccess(
433
- ctx,
434
- projectId,
435
- userId
436
- );
437
- if (!hasAccess) {
438
- throwStructuredMutationError({
439
- message: `Project write access denied for topic ${projectId}.`,
440
- status: 403,
441
- code: "PROJECT_ACCESS_DENIED",
442
- invariantCode: "policy.scope_required",
443
- suggestion: "The acting principal lacks project-write access to this topic. Request a topic grant (or, if the principal created this topic, run the creator-grant backfill) and retry.",
444
- details: { topicId: projectId, principalId: userId }
445
- });
446
- }
447
- }
448
334
  async function assertExistingNodeEndpoint(ctx, endpointRole, endpoint) {
449
335
  assertUuidShapedEdgeEndpoint(endpointRole, endpoint);
450
- const node = await ctx.db.query("epistemicNodes").withIndex("by_globalId", (q) => q.eq("globalId", endpoint)).first();
336
+ const node = await ctx.db.query("epistemicNodes").withIndex(
337
+ "by_globalId",
338
+ (q) => q.eq("globalId", endpoint)
339
+ ).first();
451
340
  if (!node) {
452
341
  throw new Error(
453
342
  `edge_endpoint_not_canonical: epistemicEdges insert requires ${endpointRole} to be the globalId of an existing epistemicNodes row, received ${endpoint} (no node with that globalId)`
@@ -488,7 +377,193 @@ async function insertEpistemicEdge(ctx, doc) {
488
377
  return ctx.db.insert("epistemicEdges", doc);
489
378
  }
490
379
 
380
+ // src/logicalRoleInference.ts
381
+ var PILLAR_IMPORTANCE = {
382
+ market: 1,
383
+ competition: 2,
384
+ product: 3,
385
+ team: 4,
386
+ financials: 5,
387
+ timing: 6,
388
+ other: 10
389
+ };
390
+ async function computeLogicalRole(ctx, evidenceId, beliefId) {
391
+ const belief = await ctx.db.get(beliefId);
392
+ if (belief?.nodeType !== "belief") {
393
+ return "contributory";
394
+ }
395
+ const beliefMetadata = belief.metadata;
396
+ const pillar = beliefMetadata?.pillar || "other";
397
+ const pillarRank = PILLAR_IMPORTANCE[pillar] ?? 10;
398
+ const isSynthesized = await checkIfSynthesizedHypothesis(ctx, beliefId);
399
+ const testingQuestions = await getTestingQuestionsForBelief(ctx, beliefId);
400
+ const answeredQuestions = await getQuestionsAnsweredByEvidence(
401
+ ctx,
402
+ evidenceId
403
+ );
404
+ const directlyTests = testingQuestions.filter(
405
+ (questionId) => answeredQuestions.includes(questionId)
406
+ );
407
+ if (directlyTests.length === 0) {
408
+ return "contributory";
409
+ }
410
+ if (isSynthesized && pillarRank <= 2) {
411
+ return directlyTests.length > 1 ? "necessary_sufficient" : "necessary";
412
+ }
413
+ if (isSynthesized) {
414
+ return "necessary";
415
+ }
416
+ return directlyTests.length > 1 ? "necessary" : "contributory";
417
+ }
418
+ async function checkIfSynthesizedHypothesis(ctx, beliefId) {
419
+ const belief = await ctx.db.get(beliefId);
420
+ if (!belief) {
421
+ return false;
422
+ }
423
+ const metadata = belief.metadata;
424
+ return metadata?.isSynthesized === true || metadata?.beliefStatus === "hypothesis";
425
+ }
426
+ async function getTestingQuestionsForBelief(ctx, beliefId) {
427
+ const testEdges = await ctx.db.query("epistemicEdges").withIndex(
428
+ "by_to_type",
429
+ (q) => q.eq("toNodeId", beliefId).eq("edgeType", "tests")
430
+ ).collect();
431
+ return testEdges.map((edge) => edge.fromNodeId).filter((id) => id !== void 0);
432
+ }
433
+ async function getQuestionsAnsweredByEvidence(ctx, evidenceId) {
434
+ const answerEdges = await ctx.db.query("epistemicEdges").withIndex(
435
+ "by_from_type",
436
+ (q) => q.eq("fromNodeId", evidenceId).eq("edgeType", "derived_from")
437
+ ).collect();
438
+ return answerEdges.map((edge) => edge.toNodeId).filter((id) => id !== void 0);
439
+ }
440
+
491
441
  // src/epistemicBeliefs.links.ts
442
+ function isRecord(value) {
443
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
444
+ }
445
+ function readOptionalNumber(value) {
446
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
447
+ }
448
+ function readOptionalString(value) {
449
+ return typeof value === "string" && value.trim().length > 0 ? value : void 0;
450
+ }
451
+ function readRecord(value) {
452
+ return isRecord(value) ? value : void 0;
453
+ }
454
+ function readConvexId(value) {
455
+ const normalized = readOptionalString(value);
456
+ return normalized;
457
+ }
458
+ function readEpistemicNodeRow(value) {
459
+ if (!isRecord(value)) {
460
+ return null;
461
+ }
462
+ const id = readConvexId(value._id);
463
+ const nodeType = readOptionalString(value.nodeType);
464
+ if (!(id && nodeType)) {
465
+ return null;
466
+ }
467
+ const row = { _id: id, nodeType };
468
+ const globalId = readOptionalString(value.globalId);
469
+ if (globalId !== void 0) {
470
+ row.globalId = globalId;
471
+ }
472
+ const metadata = readRecord(value.metadata);
473
+ if (metadata !== void 0) {
474
+ row.metadata = metadata;
475
+ }
476
+ const projectId = readOptionalString(value.projectId);
477
+ if (projectId !== void 0) {
478
+ row.projectId = projectId;
479
+ }
480
+ const status = readOptionalString(value.status);
481
+ if (status !== void 0) {
482
+ row.status = status;
483
+ }
484
+ const topicId = readOptionalString(value.topicId);
485
+ if (topicId !== void 0) {
486
+ row.topicId = topicId;
487
+ }
488
+ return row;
489
+ }
490
+ function requireEpistemicNodeRow(value, nodeType, message) {
491
+ const node = readEpistemicNodeRow(value);
492
+ if (!node || node.nodeType !== nodeType) {
493
+ throw new Error(message);
494
+ }
495
+ return node;
496
+ }
497
+ function requireNodeGlobalId(node, context) {
498
+ if (!node.globalId) {
499
+ throw new Error(
500
+ `${context} requires node.globalId for canonical edge endpoints`
501
+ );
502
+ }
503
+ return node.globalId;
504
+ }
505
+ function readEpistemicEdgeRow(value) {
506
+ if (!isRecord(value)) {
507
+ return null;
508
+ }
509
+ const id = readConvexId(value._id);
510
+ const globalId = readOptionalString(value.globalId);
511
+ if (!(id && globalId)) {
512
+ return null;
513
+ }
514
+ const row = { _id: id, globalId };
515
+ const edgeType = readOptionalString(value.edgeType);
516
+ if (edgeType !== void 0) {
517
+ row.edgeType = edgeType;
518
+ }
519
+ const fromGlobalId = readOptionalString(value.fromGlobalId);
520
+ if (fromGlobalId !== void 0) {
521
+ row.fromGlobalId = fromGlobalId;
522
+ }
523
+ const fromNodeId = readOptionalString(value.fromNodeId);
524
+ if (fromNodeId !== void 0) {
525
+ row.fromNodeId = fromNodeId;
526
+ }
527
+ const fromNodeType = readOptionalString(value.fromNodeType);
528
+ if (fromNodeType !== void 0) {
529
+ row.fromNodeType = fromNodeType;
530
+ }
531
+ const fromUuid = readOptionalString(value.fromUuid);
532
+ if (fromUuid !== void 0) {
533
+ row.fromUuid = fromUuid;
534
+ }
535
+ const sourceGlobalId = readOptionalString(value.sourceGlobalId);
536
+ if (sourceGlobalId !== void 0) {
537
+ row.sourceGlobalId = sourceGlobalId;
538
+ }
539
+ const targetGlobalId = readOptionalString(value.targetGlobalId);
540
+ if (targetGlobalId !== void 0) {
541
+ row.targetGlobalId = targetGlobalId;
542
+ }
543
+ const toGlobalId = readOptionalString(value.toGlobalId);
544
+ if (toGlobalId !== void 0) {
545
+ row.toGlobalId = toGlobalId;
546
+ }
547
+ const toNodeId = readOptionalString(value.toNodeId);
548
+ if (toNodeId !== void 0) {
549
+ row.toNodeId = toNodeId;
550
+ }
551
+ const toUuid = readOptionalString(value.toUuid);
552
+ if (toUuid !== void 0) {
553
+ row.toUuid = toUuid;
554
+ }
555
+ const weight = readOptionalNumber(value.weight);
556
+ if (weight !== void 0) {
557
+ row.weight = weight;
558
+ }
559
+ return row;
560
+ }
561
+ function readEpistemicEdgeRows(values) {
562
+ return values.flatMap((value) => {
563
+ const row = readEpistemicEdgeRow(value);
564
+ return row ? [row] : [];
565
+ });
566
+ }
492
567
  function assertSignedImpactScore(value, context) {
493
568
  if (typeof value !== "number" || !Number.isFinite(value) || value === 0 || value < -1 || value > 1) {
494
569
  throw new Error(`${context} requires explicit nonzero weight in [-1, 1]`);
@@ -519,20 +594,21 @@ var updatePillar = mutation({
519
594
  handler: async (ctx, args) => {
520
595
  const authenticatedUserId = await requireAuthenticatedUserId(ctx);
521
596
  const now = Date.now();
522
- const existingNode = await ctx.db.get(args.nodeId);
523
- if (!existingNode || existingNode.nodeType !== "belief") {
524
- throw new Error("Belief not found");
525
- }
597
+ const existingNode = requireEpistemicNodeRow(
598
+ await ctx.db.get(args.nodeId),
599
+ "belief",
600
+ "Belief not found"
601
+ );
526
602
  if (!existingNode.projectId) {
527
603
  throw new Error("Belief has no project scope");
528
604
  }
529
- await requireProjectWriteAccess(
605
+ await requireScopeWriteAccess(
530
606
  ctx,
531
607
  existingNode.projectId,
532
608
  authenticatedUserId
533
609
  );
534
610
  let previousPillar = null;
535
- const metadata = existingNode.metadata || {};
611
+ const metadata = existingNode.metadata ?? {};
536
612
  previousPillar = metadata.pillar;
537
613
  await ctx.db.patch(args.nodeId, {
538
614
  metadata: {
@@ -548,7 +624,7 @@ var updatePillar = mutation({
548
624
  });
549
625
  await ctx.db.insert("epistemicAudit", {
550
626
  entityType: "belief",
551
- entityId: args.nodeId,
627
+ entityId: String(args.nodeId),
552
628
  changeType: "pillar_changed",
553
629
  projectId: existingNode.projectId,
554
630
  changedBy: authenticatedUserId,
@@ -574,10 +650,13 @@ var getCountByStatus = query({
574
650
  if (!scope) {
575
651
  return { active: 0, superseded: 0, archived: 0, total: 0 };
576
652
  }
577
- const nodes = await ctx.db.query("epistemicNodes").withIndex(
653
+ const nodes = (await ctx.db.query("epistemicNodes").withIndex(
578
654
  "by_topic_type",
579
655
  (q) => q.eq("topicId", scope.topicId).eq("nodeType", "belief")
580
- ).collect();
656
+ ).collect()).flatMap((row) => {
657
+ const node = readEpistemicNodeRow(row);
658
+ return node?.nodeType === "belief" ? [node] : [];
659
+ });
581
660
  const counts = {
582
661
  active: 0,
583
662
  superseded: 0,
@@ -618,31 +697,31 @@ var linkBeliefs = mutation({
618
697
  returns: permissiveReturn,
619
698
  handler: async (ctx, args) => {
620
699
  const authenticatedUserId = await requireAuthenticatedUserId(ctx);
621
- const fromNode = await ctx.db.get(args.fromNodeId);
622
- const toNode = await ctx.db.get(args.toNodeId);
623
- if (!fromNode || !toNode) {
624
- throw new Error("One or both belief nodes not found");
625
- }
626
- if (fromNode.nodeType !== "belief" || toNode.nodeType !== "belief") {
627
- throw new Error("Both nodes must be beliefs");
628
- }
700
+ const fromNode = requireEpistemicNodeRow(
701
+ await ctx.db.get(args.fromNodeId),
702
+ "belief",
703
+ "One or both belief nodes not found"
704
+ );
705
+ const toNode = requireEpistemicNodeRow(
706
+ await ctx.db.get(args.toNodeId),
707
+ "belief",
708
+ "One or both belief nodes not found"
709
+ );
629
710
  if (fromNode.projectId !== toNode.projectId) {
630
711
  throw new Error("Cannot link beliefs across different projects");
631
712
  }
632
713
  if (!fromNode.projectId) {
633
714
  throw new Error("Belief has no project scope");
634
715
  }
635
- await requireProjectWriteAccess(
636
- ctx,
637
- fromNode.projectId,
638
- authenticatedUserId
639
- );
716
+ await requireScopeWriteAccess(ctx, fromNode.projectId, authenticatedUserId);
717
+ const fromGlobalId = requireNodeGlobalId(fromNode, "Belief link");
718
+ const toGlobalId = requireNodeGlobalId(toNode, "Belief link");
640
719
  const now = Date.now();
641
720
  const edgeGlobalId = generateGlobalId();
642
721
  await ctx.scheduler.runAfter(0, internal.neo4jEdgeAPI.createEdge, {
643
722
  globalId: edgeGlobalId,
644
- fromGlobalId: fromNode.globalId,
645
- toGlobalId: toNode.globalId,
723
+ fromGlobalId,
724
+ toGlobalId,
646
725
  edgeType: args.edgeType,
647
726
  weight: args.weight ?? 1,
648
727
  context: args.context,
@@ -681,23 +760,26 @@ var linkEvidence = mutation({
681
760
  returns: permissiveReturn,
682
761
  handler: async (ctx, args) => {
683
762
  const authenticatedUserId = await requireAuthenticatedUserId(ctx);
684
- const belief = await ctx.db.get(args.beliefNodeId);
685
- if (!belief || belief.nodeType !== "belief") {
686
- throw new Error("Belief not found");
687
- }
763
+ const belief = requireEpistemicNodeRow(
764
+ await ctx.db.get(args.beliefNodeId),
765
+ "belief",
766
+ "Belief not found"
767
+ );
688
768
  if (!belief.projectId) {
689
769
  throw new Error("Belief has no project scope");
690
770
  }
691
- await requireProjectWriteAccess(ctx, belief.projectId, authenticatedUserId);
692
- const insight = await ctx.db.get(args.insightId);
693
- if (!insight || insight.nodeType !== "evidence") {
694
- throw new Error("Insight not found");
695
- }
696
- if ("projectId" in insight && insight.projectId && insight.projectId !== belief.projectId) {
771
+ await requireScopeWriteAccess(ctx, belief.projectId, authenticatedUserId);
772
+ const insight = requireEpistemicNodeRow(
773
+ await ctx.db.get(args.insightId),
774
+ "evidence",
775
+ "Insight not found"
776
+ );
777
+ if (insight.projectId && insight.projectId !== belief.projectId) {
697
778
  throw new Error("Insight belongs to a different project");
698
779
  }
699
780
  const evidenceNodeId = insight._id;
700
- const evidenceGlobalId = insight.globalId;
781
+ const evidenceGlobalId = requireNodeGlobalId(insight, "Evidence link");
782
+ const beliefGlobalId = requireNodeGlobalId(belief, "Evidence link");
701
783
  const weight = assertSignedImpactScore(args.weight, "Evidence link");
702
784
  if (args.type === "supporting" && weight < 0) {
703
785
  throw new Error("Supporting evidence links require positive weight");
@@ -713,9 +795,9 @@ var linkEvidence = mutation({
713
795
  globalId: edgeGlobalId,
714
796
  // C2-RR.4 Defect E — canonical UUIDv7 endpoints, not Convex doc ids.
715
797
  fromNodeId: evidenceGlobalId,
716
- toNodeId: belief.globalId,
798
+ toNodeId: beliefGlobalId,
717
799
  sourceGlobalId: evidenceGlobalId,
718
- targetGlobalId: belief.globalId,
800
+ targetGlobalId: beliefGlobalId,
719
801
  edgeType,
720
802
  weight,
721
803
  confidence,
@@ -743,7 +825,7 @@ var linkEvidence = mutation({
743
825
  await ctx.scheduler.runAfter(0, internal.neo4jEdgeAPI.createEdge, {
744
826
  globalId: edgeGlobalId,
745
827
  fromGlobalId: evidenceGlobalId,
746
- toGlobalId: belief.globalId,
828
+ toGlobalId: beliefGlobalId,
747
829
  edgeType,
748
830
  weight,
749
831
  confidence,
@@ -772,29 +854,38 @@ var unlinkEvidence = mutation({
772
854
  handler: async (ctx, args) => {
773
855
  const authenticatedUserId = await requireAuthenticatedUserId(ctx);
774
856
  const now = Date.now();
775
- const evidenceNode = await ctx.db.get(args.insightId);
776
- if (!evidenceNode || evidenceNode.nodeType !== "evidence") {
857
+ const evidenceNodeRaw = await ctx.db.get(args.insightId);
858
+ const evidenceNode = readEpistemicNodeRow(evidenceNodeRaw);
859
+ if (evidenceNode?.nodeType !== "evidence") {
777
860
  return buildBeliefEvidenceNotFoundResult();
778
861
  }
779
862
  if (!evidenceNode.projectId) {
780
863
  throw new Error("Evidence has no project scope");
781
864
  }
782
- await requireProjectWriteAccess(
865
+ await requireScopeWriteAccess(
783
866
  ctx,
784
867
  evidenceNode.projectId,
785
868
  authenticatedUserId
786
869
  );
787
- const beliefNode = await ctx.db.get(args.beliefNodeId);
788
- if (!beliefNode || beliefNode.nodeType !== "belief") {
789
- throw new Error("Belief not found");
790
- }
870
+ const beliefNode = requireEpistemicNodeRow(
871
+ await ctx.db.get(args.beliefNodeId),
872
+ "belief",
873
+ "Belief not found"
874
+ );
791
875
  if (beliefNode.projectId !== evidenceNode.projectId) {
792
876
  throw new Error("Belief and evidence belong to different projects");
793
877
  }
794
- const edge = await ctx.db.query("epistemicEdges").withIndex(
795
- "by_from_to",
796
- (q) => q.eq("fromNodeId", evidenceNode._id).eq("toNodeId", args.beliefNodeId)
797
- ).first();
878
+ const evidenceGlobalId = requireNodeGlobalId(
879
+ evidenceNode,
880
+ "Evidence unlink"
881
+ );
882
+ const beliefGlobalId = requireNodeGlobalId(beliefNode, "Evidence unlink");
883
+ const edge = readEpistemicEdgeRow(
884
+ await ctx.db.query("epistemicEdges").withIndex(
885
+ "by_from_to",
886
+ (q) => q.eq("fromNodeId", evidenceGlobalId).eq("toNodeId", beliefGlobalId)
887
+ ).first()
888
+ );
798
889
  if (edge) {
799
890
  await ctx.scheduler.runAfter(0, internal.neo4jEdgeAPI.deleteEdge, {
800
891
  globalId: edge.globalId
@@ -824,25 +915,31 @@ var getWithEvidence = query({
824
915
  },
825
916
  returns: permissiveReturn,
826
917
  handler: async (ctx, args) => {
827
- const belief = await ctx.db.get(args.nodeId);
828
- if (!belief || belief.nodeType !== "belief") {
918
+ const belief = readEpistemicNodeRow(await ctx.db.get(args.nodeId));
919
+ if (belief?.nodeType !== "belief") {
829
920
  return null;
830
921
  }
831
- const incomingEdges = await ctx.db.query("epistemicEdges").withIndex(
832
- "by_to_type",
833
- (q) => q.eq("toNodeId", args.nodeId).eq("edgeType", "informs")
834
- ).collect();
835
- const evidenceNodeIds = incomingEdges.filter((e) => e.fromNodeType === "evidence").map((e) => e.fromNodeId);
836
- const evidenceNodes = await Promise.all(
837
- evidenceNodeIds.map((id) => ctx.db.get(id))
922
+ const beliefGlobalId = requireNodeGlobalId(belief, "Belief evidence read");
923
+ const incomingEdges = readEpistemicEdgeRows(
924
+ await ctx.db.query("epistemicEdges").withIndex(
925
+ "by_to_type",
926
+ (q) => q.eq("toNodeId", beliefGlobalId).eq("edgeType", "informs")
927
+ ).collect()
838
928
  );
839
929
  const supporting = [];
840
930
  const contradicting = [];
841
- for (let i = 0; i < evidenceNodes.length; i++) {
842
- const node = evidenceNodes[i];
843
- const edge = incomingEdges[i];
844
- if (node) {
845
- if ((edge.weight || 0) >= 0) {
931
+ for (const edge of incomingEdges.filter(
932
+ (incomingEdge) => incomingEdge.fromNodeType === "evidence"
933
+ )) {
934
+ const node = readEpistemicNodeRow(
935
+ await resolveRelationshipEndpoint(
936
+ ctx,
937
+ edge.fromNodeId,
938
+ edge.sourceGlobalId ?? edge.fromGlobalId ?? edge.fromUuid
939
+ )
940
+ );
941
+ if (node?.nodeType === "evidence") {
942
+ if ((edge.weight ?? 0) >= 0) {
846
943
  supporting.push(node);
847
944
  } else {
848
945
  contradicting.push(node);
@@ -870,13 +967,13 @@ async function collectRelationshipNodeRefs(ctx, nodeId) {
870
967
  }
871
968
  function endpointMatches(q, fields, refs) {
872
969
  return q.or(
873
- ...fields.flatMap(
874
- (field) => refs.map((ref) => q.eq(q.field(field), ref))
875
- )
970
+ ...fields.flatMap((field) => refs.map((ref) => q.eq(q.field(field), ref)))
876
971
  );
877
972
  }
878
973
  async function resolveRelationshipEndpoint(ctx, endpointId, globalEndpointId) {
879
- const candidates = [endpointId, globalEndpointId].map((value) => typeof value === "string" ? value.trim() : "").filter((value, index, values) => value.length > 0 && values.indexOf(value) === index);
974
+ const candidates = [endpointId, globalEndpointId].map((value) => typeof value === "string" ? value.trim() : "").filter(
975
+ (value, index, values) => value.length > 0 && values.indexOf(value) === index
976
+ );
880
977
  for (const candidate of candidates) {
881
978
  try {
882
979
  const direct = await ctx.db.get(candidate);
@@ -908,13 +1005,15 @@ var getRelationships = query({
908
1005
  };
909
1006
  const nodeRefs = await collectRelationshipNodeRefs(ctx, args.nodeId);
910
1007
  if (direction === "in" || direction === "both") {
911
- const inEdges = await ctx.db.query("epistemicEdges").filter(
912
- (q) => endpointMatches(
913
- q,
914
- ["toNodeId", "targetGlobalId", "toGlobalId", "toUuid"],
915
- nodeRefs
916
- )
917
- ).collect();
1008
+ const inEdges = readEpistemicEdgeRows(
1009
+ await ctx.db.query("epistemicEdges").filter(
1010
+ (q) => endpointMatches(
1011
+ q,
1012
+ ["toNodeId", "targetGlobalId", "toGlobalId", "toUuid"],
1013
+ nodeRefs
1014
+ )
1015
+ ).collect()
1016
+ );
918
1017
  for (const edge of inEdges) {
919
1018
  const sourceNode = await resolveRelationshipEndpoint(
920
1019
  ctx,
@@ -925,13 +1024,15 @@ var getRelationships = query({
925
1024
  }
926
1025
  }
927
1026
  if (direction === "out" || direction === "both") {
928
- const outEdges = await ctx.db.query("epistemicEdges").filter(
929
- (q) => endpointMatches(
930
- q,
931
- ["fromNodeId", "sourceGlobalId", "fromGlobalId", "fromUuid"],
932
- nodeRefs
933
- )
934
- ).collect();
1027
+ const outEdges = readEpistemicEdgeRows(
1028
+ await ctx.db.query("epistemicEdges").filter(
1029
+ (q) => endpointMatches(
1030
+ q,
1031
+ ["fromNodeId", "sourceGlobalId", "fromGlobalId", "fromUuid"],
1032
+ nodeRefs
1033
+ )
1034
+ ).collect()
1035
+ );
935
1036
  for (const edge of outEdges) {
936
1037
  const targetNode = await resolveRelationshipEndpoint(
937
1038
  ctx,