@lucern/graph-primitives 1.0.29 → 1.0.31

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 +395 -225
  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 +854 -480
  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 +365 -166
  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 -289
  80. package/dist/epistemicBeliefs.backfills.js.map +1 -1
  81. package/dist/epistemicBeliefs.confidence.d.ts +19 -15
  82. package/dist/epistemicBeliefs.confidence.js +633 -386
  83. package/dist/epistemicBeliefs.confidence.js.map +1 -1
  84. package/dist/epistemicBeliefs.core.d.ts +6 -6
  85. package/dist/epistemicBeliefs.core.js +717 -371
  86. package/dist/epistemicBeliefs.core.js.map +1 -1
  87. package/dist/epistemicBeliefs.d.ts +11 -9
  88. package/dist/epistemicBeliefs.forkEvidence.d.ts +2 -0
  89. package/dist/epistemicBeliefs.forkEvidence.js +8 -8
  90. package/dist/epistemicBeliefs.forkEvidence.js.map +1 -1
  91. package/dist/epistemicBeliefs.helpers.d.ts +68 -49
  92. package/dist/epistemicBeliefs.helpers.js +358 -211
  93. package/dist/epistemicBeliefs.helpers.js.map +1 -1
  94. package/dist/epistemicBeliefs.internal.d.ts +5 -5
  95. package/dist/epistemicBeliefs.internal.js +1248 -1026
  96. package/dist/epistemicBeliefs.internal.js.map +1 -1
  97. package/dist/epistemicBeliefs.js +4942 -3590
  98. package/dist/epistemicBeliefs.js.map +1 -1
  99. package/dist/epistemicBeliefs.lifecycle.d.ts +5 -5
  100. package/dist/epistemicBeliefs.lifecycle.js +1138 -781
  101. package/dist/epistemicBeliefs.lifecycle.js.map +1 -1
  102. package/dist/epistemicBeliefs.links.d.ts +7 -7
  103. package/dist/epistemicBeliefs.links.js +404 -267
  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 +1062 -576
  114. package/dist/epistemicContracts.evaluators.js.map +1 -1
  115. package/dist/epistemicContracts.handlers.d.ts +15 -32
  116. package/dist/epistemicContracts.handlers.js +1829 -1351
  117. package/dist/epistemicContracts.handlers.js.map +1 -1
  118. package/dist/epistemicContracts.js +1131 -636
  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 +1966 -1202
  136. package/dist/epistemicEdges.js.map +1 -1
  137. package/dist/epistemicEdges.mutations.d.ts +7 -7
  138. package/dist/epistemicEdges.mutations.js +956 -579
  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 +933 -532
  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 +840 -692
  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 +700 -504
  180. package/dist/epistemicNodes.js.map +1 -1
  181. package/dist/epistemicNodes.mutations.d.ts +6 -6
  182. package/dist/epistemicNodes.mutations.js +560 -463
  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 +351 -311
  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 +86 -83
  245. package/dist/index.js +16914 -11760
  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,15 +1,16 @@
1
- import { v } from 'convex/values';
2
1
  import { requireScopeWriteAccess, checkScopeAccess } from '@lucern/access-control/access';
3
2
  import { assertSchemaEnumValue } from '@lucern/contracts/schema-helpers/enumValidation';
4
3
  import { permissiveReturn } from '@lucern/contracts/schema-helpers/validators';
5
- import { componentsGeneric, anyApi, mutationGeneric, queryGeneric } from 'convex/server';
6
- import { normalizeTupleContradictionPolicy, createInheritedContractRecord, confidenceFromSL } from '@lucern/confidence';
7
- import { throwStructuredMutationError } from '@lucern/access-control/structuredMutationError';
4
+ import { v } from 'convex/values';
5
+ import { unsafeConvexAnyApi } from '@lucern/contracts/convex/unsafeAnyApi';
6
+ import { componentsGeneric, mutationGeneric, queryGeneric } from 'convex/server';
8
7
  import '@lucern/access-control/audience';
9
8
  import { getCurrentUserId } from '@lucern/access-control/auth';
9
+ import { throwStructuredMutationError } from '@lucern/access-control/structuredMutationError';
10
+ import { normalizeTupleContradictionPolicy, createInheritedContractRecord, confidenceFromSL } from '@lucern/confidence';
10
11
  import { isNodeType, getLayerForNodeType } from '@lucern/contracts/schema-helpers/spine/tables/epistemicNodes';
11
- import { generateGlobalId, assertUuidV7Identity, generateUuidV7, assertStorageEdgeVocabulary, assertUuidShapedEdgeEndpoint } from '@lucern/contracts/ids';
12
12
  import { assertEdgePolicyAllowed, edgePolicyManifest } from '@lucern/contracts';
13
+ import { generateGlobalId, assertUuidV7Identity, generateUuidV7, assertStorageEdgeVocabulary, assertUuidShapedEdgeEndpoint } from '@lucern/contracts/ids';
13
14
 
14
15
  // src/epistemicBeliefs.core.ts
15
16
 
@@ -123,9 +124,12 @@ function resolveBeliefLifecycleStatus(opts) {
123
124
  function isPreValidationBeliefStatus(status) {
124
125
  return status === "assumption" || status === "hypothesis";
125
126
  }
126
- var api = anyApi;
127
+ var unsafeApi = unsafeConvexAnyApi(
128
+ "graph-primitives top-level module bundle lacks a committed Convex _generated/api surface"
129
+ );
130
+ var api = unsafeApi;
127
131
  componentsGeneric();
128
- var internal = anyApi;
132
+ var internal = unsafeApi;
129
133
  var mutation = mutationGeneric;
130
134
  var query = queryGeneric;
131
135
 
@@ -141,6 +145,32 @@ function debugGraphPrimitiveFallback(message, context) {
141
145
  console.debug(message, context ?? {});
142
146
  }
143
147
 
148
+ // src/embeddingTrigger.ts
149
+ var embeddingActionRef = "embeddingActions:generateEpistemicNodeEmbedding";
150
+ async function scheduleEmbeddingGeneration(args) {
151
+ try {
152
+ await args.ctx.scheduler.runAfter(0, embeddingActionRef, {
153
+ nodeId: args.nodeId,
154
+ projectId: args.projectId ? String(args.projectId) : void 0,
155
+ topicId: args.topicId ? String(args.topicId) : void 0,
156
+ createdBy: args.createdBy,
157
+ nodeType: args.nodeType,
158
+ text: args.text.slice(0, 2e4),
159
+ hasAnswer: args.hasAnswer,
160
+ confidence: args.confidence
161
+ });
162
+ } catch (error) {
163
+ debugGraphPrimitiveFallback(
164
+ "[embeddingTrigger] Failed to schedule embedding generation",
165
+ {
166
+ error,
167
+ nodeId: String(args.nodeId),
168
+ nodeType: args.nodeType
169
+ }
170
+ );
171
+ }
172
+ }
173
+
144
174
  // src/topicProjectOverlay.ts
145
175
  var LEGACY_SCOPE_FIELD = "graphScopeProjectId";
146
176
  function readNonEmptyString(value) {
@@ -159,6 +189,10 @@ function readStringArray(value) {
159
189
  function readMetadata(topic) {
160
190
  return topic.metadata && typeof topic.metadata === "object" ? topic.metadata : {};
161
191
  }
192
+ function omitMetadataKey(metadata, key) {
193
+ const { [key]: _omitted, ...rest } = metadata;
194
+ return rest;
195
+ }
162
196
  function readLegacyProjectId(value) {
163
197
  if (!value) {
164
198
  return;
@@ -239,9 +273,12 @@ async function resolveTopicDoc(ctx, scopeId) {
239
273
  );
240
274
  }
241
275
  try {
242
- const topic = await ctx.runQuery(api.topics.getByLegacyScopeId, {
243
- projectId: String(scopeId)
244
- });
276
+ const topic = await ctx.runQuery(
277
+ api.topics.getByLegacyScopeId,
278
+ {
279
+ projectId: String(scopeId)
280
+ }
281
+ );
245
282
  if (topic?.name !== void 0 && topic?.type !== void 0) {
246
283
  return topic;
247
284
  }
@@ -261,8 +298,18 @@ function materializeTopicProjectOverlay(topic, idMode = "legacy") {
261
298
  const outwardId = idMode === "topic" ? topicId : storageProjectId;
262
299
  const visibility = coerceVisibility(topic.visibility) || coerceVisibility(metadata.visibility) || "private";
263
300
  const status = coerceStatus(topic.status) || coerceStatus(metadata.status) || "active";
264
- const createdAt = typeof topic.createdAt === "number" ? topic.createdAt : typeof topic._creationTime === "number" ? topic._creationTime : 0;
265
- const updatedAt = typeof topic.updatedAt === "number" ? topic.updatedAt : typeof metadata.updatedAt === "number" ? metadata.updatedAt : createdAt;
301
+ let createdAt = 0;
302
+ if (typeof topic.createdAt === "number") {
303
+ createdAt = topic.createdAt;
304
+ } else if (typeof topic._creationTime === "number") {
305
+ createdAt = topic._creationTime;
306
+ }
307
+ let updatedAt = createdAt;
308
+ if (typeof topic.updatedAt === "number") {
309
+ updatedAt = topic.updatedAt;
310
+ } else if (typeof metadata.updatedAt === "number") {
311
+ updatedAt = metadata.updatedAt;
312
+ }
266
313
  return {
267
314
  ...metadata,
268
315
  _id: outwardId,
@@ -331,90 +378,113 @@ async function patchTopicProjectOverlay(ctx, scopeId, value) {
331
378
  if (!topic) {
332
379
  return null;
333
380
  }
334
- const nextMetadata = { ...readMetadata(topic) };
335
- const patch = {};
336
- const topicUpdateArgs = {
337
- id: String(topic._id)
381
+ const plan = buildTopicProjectOverlayPatchPlan(topic, value);
382
+ await applyTopicProjectOverlayPatch(ctx, topic, plan);
383
+ return materializeTopicProjectOverlay({
384
+ ...topic,
385
+ ...plan.patch,
386
+ metadata: plan.nextMetadata
387
+ });
388
+ }
389
+ function buildTopicProjectOverlayPatchPlan(topic, value) {
390
+ const plan = {
391
+ nextMetadata: { ...readMetadata(topic) },
392
+ patch: {},
393
+ topicUpdateArgs: {
394
+ id: String(topic._id)
395
+ }
338
396
  };
339
397
  for (const [key, rawValue] of Object.entries(value)) {
340
- switch (key) {
341
- case "_id":
342
- case "projectId":
343
- case "topicId":
344
- case "legacyProjectId":
345
- case "storageProjectId":
346
- break;
347
- case "name":
348
- case "description":
349
- patch[key] = rawValue;
350
- topicUpdateArgs[key] = rawValue;
351
- break;
352
- case "tenantId":
353
- case "workspaceId":
354
- case "ownerId":
355
- throw new Error(
356
- `patchTopicProjectOverlay cannot mutate ${key} via component-owned topics`
357
- );
358
- case "status": {
359
- const status = coerceStatus(rawValue);
360
- if (status) {
361
- patch.status = status;
362
- topicUpdateArgs.status = status;
363
- }
364
- break;
365
- }
366
- case "visibility": {
367
- const visibility = coerceVisibility(rawValue);
368
- if (visibility) {
369
- patch.visibility = visibility;
370
- topicUpdateArgs.visibility = visibility;
371
- }
372
- break;
373
- }
374
- case "type": {
375
- const projectType = readNonEmptyString(rawValue);
376
- if (projectType) {
377
- nextMetadata.projectType = projectType;
378
- } else {
379
- delete nextMetadata.projectType;
380
- }
381
- break;
382
- }
383
- case "updatedAt":
384
- case "createdAt":
385
- break;
386
- default:
387
- if (rawValue === void 0) {
388
- delete nextMetadata[key];
389
- } else {
390
- nextMetadata[key] = rawValue;
391
- }
392
- }
398
+ applyTopicProjectOverlayPatchEntry(plan, key, rawValue);
399
+ }
400
+ plan.patch.updatedAt = Date.now();
401
+ plan.patch.metadata = plan.nextMetadata;
402
+ plan.topicUpdateArgs.metadata = plan.nextMetadata;
403
+ return plan;
404
+ }
405
+ function applyTopicProjectOverlayPatchEntry(plan, key, rawValue) {
406
+ switch (key) {
407
+ case "_id":
408
+ case "projectId":
409
+ case "topicId":
410
+ case "legacyProjectId":
411
+ case "storageProjectId":
412
+ case "updatedAt":
413
+ case "createdAt":
414
+ return;
415
+ case "name":
416
+ case "description":
417
+ plan.patch[key] = rawValue;
418
+ plan.topicUpdateArgs[key] = rawValue;
419
+ return;
420
+ case "tenantId":
421
+ case "workspaceId":
422
+ case "ownerId":
423
+ throw new Error(
424
+ `patchTopicProjectOverlay cannot mutate ${key} via component-owned topics`
425
+ );
426
+ case "status":
427
+ applyTopicStatusPatch(plan, rawValue);
428
+ return;
429
+ case "visibility":
430
+ applyTopicVisibilityPatch(plan, rawValue);
431
+ return;
432
+ case "type":
433
+ applyTopicProjectTypePatch(plan, rawValue);
434
+ return;
435
+ default:
436
+ applyTopicMetadataPatch(plan, key, rawValue);
437
+ }
438
+ }
439
+ function applyTopicStatusPatch(plan, rawValue) {
440
+ const status = coerceStatus(rawValue);
441
+ if (status) {
442
+ plan.patch.status = status;
443
+ plan.topicUpdateArgs.status = status;
444
+ }
445
+ }
446
+ function applyTopicVisibilityPatch(plan, rawValue) {
447
+ const visibility = coerceVisibility(rawValue);
448
+ if (visibility) {
449
+ plan.patch.visibility = visibility;
450
+ plan.topicUpdateArgs.visibility = visibility;
451
+ }
452
+ }
453
+ function applyTopicProjectTypePatch(plan, rawValue) {
454
+ const projectType = readNonEmptyString(rawValue);
455
+ if (projectType) {
456
+ plan.nextMetadata.projectType = projectType;
457
+ return;
458
+ }
459
+ plan.nextMetadata = omitMetadataKey(plan.nextMetadata, "projectType");
460
+ }
461
+ function applyTopicMetadataPatch(plan, key, rawValue) {
462
+ if (rawValue === void 0) {
463
+ plan.nextMetadata = omitMetadataKey(plan.nextMetadata, key);
464
+ return;
393
465
  }
394
- patch.updatedAt = Date.now();
395
- patch.metadata = nextMetadata;
396
- topicUpdateArgs.metadata = nextMetadata;
466
+ plan.nextMetadata[key] = rawValue;
467
+ }
468
+ async function applyTopicProjectOverlayPatch(ctx, topic, plan) {
397
469
  if (typeof ctx.runMutation === "function") {
398
470
  try {
399
- await ctx.runMutation(api.topics.update, topicUpdateArgs);
471
+ await ctx.runMutation(api.topics.update, plan.topicUpdateArgs);
400
472
  } catch (error) {
401
- if (!isMissingLucernChildComponentError(error) || !ctx?.db || typeof ctx.db.patch !== "function") {
473
+ if (!canPatchTopicViaLocalDb(ctx, error)) {
402
474
  throw error;
403
475
  }
404
- await ctx.db.patch(String(topic._id), patch);
476
+ await ctx.db.patch(topic._id, plan.patch);
405
477
  }
406
478
  } else if (ctx?.db && typeof ctx.db.patch === "function") {
407
- await ctx.db.patch(String(topic._id), patch);
479
+ await ctx.db.patch(topic._id, plan.patch);
408
480
  } else {
409
481
  throw new Error(
410
482
  "Cannot patch topic without component adapter (ctx.runMutation unavailable)"
411
483
  );
412
484
  }
413
- return materializeTopicProjectOverlay({
414
- ...topic,
415
- ...patch,
416
- metadata: nextMetadata
417
- });
485
+ }
486
+ function canPatchTopicViaLocalDb(ctx, error) {
487
+ return isMissingLucernChildComponentError(error) && Boolean(ctx?.db) && typeof ctx.db?.patch === "function";
418
488
  }
419
489
 
420
490
  // src/resolvers.ts
@@ -442,7 +512,7 @@ async function patchProjectWithTolerance(ctx, projectId, value) {
442
512
  try {
443
513
  await patchTopicProjectOverlay(ctx, projectId, value);
444
514
  } catch (error) {
445
- if (!isAdvisoryTopicPatch(value) || !isMissingLucernChildComponentError2(error)) {
515
+ if (!(isAdvisoryTopicPatch(value) && isMissingLucernChildComponentError2(error))) {
446
516
  throw error;
447
517
  }
448
518
  console.warn(
@@ -509,13 +579,15 @@ function asMappedProjectId(topic) {
509
579
  if (!topic) {
510
580
  return;
511
581
  }
512
- const directLegacyProjectId = normalizeScopeValue(topic[LEGACY_SCOPE_FIELD2]);
582
+ const directLegacyProjectId = normalizeScopeValue(
583
+ topic[LEGACY_SCOPE_FIELD2]
584
+ );
513
585
  if (directLegacyProjectId) {
514
586
  return directLegacyProjectId;
515
587
  }
516
588
  const metadata = topic.metadata || {};
517
589
  const candidate = metadata[LEGACY_SCOPE_FIELD2] || metadata.legacyProjectId || metadata.projectId || metadata.scopeProjectId;
518
- return candidate ? candidate : void 0;
590
+ return typeof candidate === "string" ? normalizeScopeValue(candidate) : void 0;
519
591
  }
520
592
  function normalizeScopeValue(value) {
521
593
  if (typeof value !== "string") {
@@ -540,8 +612,9 @@ function pickPrimaryTopic(candidates) {
540
612
  })[0];
541
613
  }
542
614
  async function findTopicsByScopeAlias(ctx, scopeId) {
615
+ const query2 = ctx.db.query("topics");
543
616
  try {
544
- return await ctx.db.query("topics").withIndex(
617
+ return await query2.withIndex(
545
618
  "by_graph_scope_project",
546
619
  (q) => q.eq(LEGACY_SCOPE_FIELD2, scopeId)
547
620
  ).collect();
@@ -553,7 +626,7 @@ async function findTopicsByScopeAlias(ctx, scopeId) {
553
626
  scopeId
554
627
  }
555
628
  );
556
- const topics = await ctx.db.query("topics").collect();
629
+ const topics = await query2.collect();
557
630
  return topics.filter((topic) => {
558
631
  const normalizedGlobalId = normalizeScopeValue(topic.globalId);
559
632
  const mappedProjectId = asMappedProjectId(topic);
@@ -609,137 +682,115 @@ async function resolveInheritedWorkspaceScope(ctx, topic) {
609
682
  let current = topic;
610
683
  for (let i = 0; i < MAX_DEPTH && current?.parentTopicId; i++) {
611
684
  current = await ctx.db.get(current.parentTopicId);
612
- if (!current) break;
685
+ if (!current) {
686
+ break;
687
+ }
613
688
  if (!tenantId) {
614
689
  tenantId = normalizeScopeValue(current.tenantId);
615
690
  }
616
691
  if (!workspaceId) {
617
692
  workspaceId = normalizeScopeValue(current.workspaceId);
618
693
  }
619
- if (tenantId && workspaceId) break;
694
+ if (tenantId && workspaceId) {
695
+ break;
696
+ }
620
697
  }
621
698
  return { tenantId, workspaceId };
622
699
  }
623
700
  async function resolveTopicProjectScope(ctx, args) {
624
701
  if (args.topicId) {
625
- let topic = null;
626
- try {
627
- topic = await ctx.db.get(
628
- args.topicId
629
- );
630
- } catch (error) {
631
- debugGraphPrimitiveFallback(
632
- "[topicScope] Failed to load topic by direct id",
633
- {
634
- error,
635
- topicId: args.topicId
636
- }
637
- );
638
- }
639
- if (!topic) {
640
- topic = await tryResolveHostTopicById(ctx, String(args.topicId));
641
- }
642
- if (!topic) {
643
- topic = pickPrimaryTopic(
644
- await findTopicsByScopeAlias(ctx, String(args.topicId))
645
- ) ?? null;
646
- }
647
- if (!topic) {
648
- const nodeScope = await resolveTopicNodeScopeOrNull(
649
- ctx,
650
- String(args.topicId)
651
- );
652
- if (nodeScope) {
653
- return nodeScope;
654
- }
655
- throw new Error(`Topic not found: ${String(args.topicId)}`);
656
- }
657
- const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
658
- const mapped = asMappedProjectId(topic);
659
- if (mapped) {
660
- return {
661
- topicId: topic._id,
662
- projectId: mapped,
663
- tenantId: inherited.tenantId,
664
- workspaceId: inherited.workspaceId,
665
- source: "topic"
666
- };
667
- }
668
- return {
669
- topicId: topic._id,
670
- tenantId: inherited.tenantId,
671
- workspaceId: inherited.workspaceId,
672
- source: "topic"
673
- };
702
+ return await resolveScopeFromTopicId(ctx, args.topicId);
674
703
  }
675
704
  if (args.projectId) {
676
- let directTopic = null;
677
- try {
678
- directTopic = await ctx.db.get(
679
- args.projectId
680
- );
681
- } catch (error) {
682
- debugGraphPrimitiveFallback(
683
- "[topicScope] Failed to load direct project topic",
684
- {
685
- error,
686
- projectId: args.projectId
687
- }
688
- );
689
- }
690
- if (directTopic) {
691
- const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
692
- const mapped = asMappedProjectId(directTopic);
693
- return {
694
- topicId: directTopic._id,
695
- projectId: mapped ?? args.projectId,
696
- tenantId: inherited.tenantId,
697
- workspaceId: inherited.workspaceId,
698
- source: "topic_inferred"
699
- };
700
- }
701
- directTopic = await tryResolveHostTopicByLegacyScope(ctx, args.projectId);
702
- if (directTopic) {
703
- const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
704
- const mapped = asMappedProjectId(directTopic);
705
- return {
706
- topicId: directTopic._id,
707
- projectId: mapped ?? args.projectId,
708
- tenantId: inherited.tenantId,
709
- workspaceId: inherited.workspaceId,
710
- source: "topic_inferred"
711
- };
712
- }
713
- const topics = await findTopicsByScopeAlias(ctx, args.projectId);
714
- const primary = pickPrimaryTopic(topics);
715
- if (primary) {
716
- const inherited = await resolveInheritedWorkspaceScope(ctx, primary);
717
- return {
718
- topicId: primary._id,
719
- projectId: args.projectId,
720
- tenantId: inherited.tenantId,
721
- workspaceId: inherited.workspaceId,
722
- source: "project_mapped_topic"
723
- };
724
- }
725
- const nodeScope = await resolveTopicNodeScopeOrNull(
726
- ctx,
727
- String(args.projectId)
728
- );
729
- if (nodeScope) {
730
- return {
731
- ...nodeScope,
732
- projectId: nodeScope.projectId ?? String(args.projectId)
733
- };
734
- }
735
- throw new Error(
736
- `Legacy project scope ${String(args.projectId)} has no mapped topic.`
737
- );
705
+ return await resolveScopeFromLegacyProjectId(ctx, args.projectId);
738
706
  }
739
707
  throw new Error(
740
708
  "Missing scope: provide topicId (preferred) or legacy projectId alias."
741
709
  );
742
710
  }
711
+ async function resolveScopeFromTopicId(ctx, topicId) {
712
+ const topic = await resolveTopicDocFromTopicId(ctx, topicId);
713
+ if (topic) {
714
+ return await buildTopicScope(ctx, topic, "topic");
715
+ }
716
+ const nodeScope = await resolveTopicNodeScopeOrNull(ctx, String(topicId));
717
+ if (nodeScope) {
718
+ return nodeScope;
719
+ }
720
+ throw new Error(`Topic not found: ${String(topicId)}`);
721
+ }
722
+ async function resolveTopicDocFromTopicId(ctx, topicId) {
723
+ const direct = await tryReadTopicDoc(ctx, topicId, {
724
+ failureLog: "[topicScope] Failed to load topic by direct id",
725
+ idLogKey: "topicId"
726
+ });
727
+ if (direct) {
728
+ return direct;
729
+ }
730
+ const hostTopic = await tryResolveHostTopicById(ctx, String(topicId));
731
+ if (hostTopic) {
732
+ return hostTopic;
733
+ }
734
+ return pickPrimaryTopic(await findTopicsByScopeAlias(ctx, String(topicId))) ?? null;
735
+ }
736
+ async function resolveScopeFromLegacyProjectId(ctx, legacyProjectId) {
737
+ const directTopic = await resolveDirectLegacyProjectTopic(
738
+ ctx,
739
+ legacyProjectId
740
+ );
741
+ if (directTopic) {
742
+ return await buildTopicScope(ctx, directTopic, "topic_inferred", {
743
+ fallbackProjectId: legacyProjectId
744
+ });
745
+ }
746
+ const primary = pickPrimaryTopic(
747
+ await findTopicsByScopeAlias(ctx, legacyProjectId)
748
+ );
749
+ if (primary) {
750
+ return await buildTopicScope(ctx, primary, "project_mapped_topic", {
751
+ fallbackProjectId: legacyProjectId
752
+ });
753
+ }
754
+ const nodeScope = await resolveTopicNodeScopeOrNull(ctx, legacyProjectId);
755
+ if (nodeScope) {
756
+ return {
757
+ ...nodeScope,
758
+ projectId: nodeScope.projectId ?? legacyProjectId
759
+ };
760
+ }
761
+ throw new Error(
762
+ `Legacy project scope ${legacyProjectId} has no mapped topic.`
763
+ );
764
+ }
765
+ async function resolveDirectLegacyProjectTopic(ctx, legacyProjectId) {
766
+ const directTopic = await tryReadTopicDoc(ctx, legacyProjectId, {
767
+ failureLog: "[topicScope] Failed to load direct project topic",
768
+ idLogKey: "projectId"
769
+ });
770
+ return directTopic ?? tryResolveHostTopicByLegacyScope(ctx, legacyProjectId);
771
+ }
772
+ async function tryReadTopicDoc(ctx, id, log) {
773
+ try {
774
+ return await ctx.db.get(id);
775
+ } catch (error) {
776
+ debugGraphPrimitiveFallback(log.failureLog, {
777
+ error,
778
+ [log.idLogKey]: id
779
+ });
780
+ return null;
781
+ }
782
+ }
783
+ async function buildTopicScope(ctx, topic, source, options = {}) {
784
+ const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
785
+ const mapped = asMappedProjectId(topic);
786
+ return {
787
+ topicId: topic._id,
788
+ ...mapped || options.fallbackProjectId ? { projectId: mapped ?? options.fallbackProjectId } : {},
789
+ tenantId: inherited.tenantId,
790
+ workspaceId: inherited.workspaceId,
791
+ source
792
+ };
793
+ }
743
794
  var optionalScopeArgs = {
744
795
  projectId: v.optional(v.string()),
745
796
  topicId: v.optional(v.string())
@@ -804,8 +855,6 @@ function nodeMatchesWorkspaceReasoningScope(node, scope) {
804
855
  }
805
856
  return scopeWorkspaceId === nodeWorkspaceId;
806
857
  }
807
-
808
- // src/epistemicBeliefs.helpers.ts
809
858
  v.id("epistemicNodes");
810
859
  var DEFAULT_PROJECT_BELIEF_LIMIT = 250;
811
860
  var MAX_PROJECT_BELIEF_LIMIT = 1e3;
@@ -897,7 +946,7 @@ function normalizePillar(pillar) {
897
946
  async function markBeliefGraphDirty(ctx, scope) {
898
947
  const projectId = typeof scope.projectId === "string" && scope.projectId.trim().length > 0 ? scope.projectId : void 0;
899
948
  const topicId = typeof scope.topicId === "string" && scope.topicId.trim().length > 0 ? scope.topicId : void 0;
900
- if (!projectId && !topicId) {
949
+ if (!(projectId || topicId)) {
901
950
  return;
902
951
  }
903
952
  if (projectId) {
@@ -914,9 +963,15 @@ async function markBeliefGraphDirty(ctx, scope) {
914
963
  { topicId }
915
964
  );
916
965
  }
966
+ const activityScopeId = topicId ?? projectId;
967
+ if (!activityScopeId) {
968
+ throw new Error(
969
+ "Expected belief graph dirty scope to include a topic or project id."
970
+ );
971
+ }
917
972
  await resolveGraphPrimitivesAppResolvers().patchProject(
918
973
  ctx,
919
- topicId ?? projectId,
974
+ activityScopeId,
920
975
  {
921
976
  lastActivityAt: Date.now()
922
977
  }
@@ -924,7 +979,10 @@ async function markBeliefGraphDirty(ctx, scope) {
924
979
  }
925
980
  async function getActiveConfidencePolicy(ctx) {
926
981
  try {
927
- const activeConfig = await ctx.db.query("logicSprintScoring").withIndex("by_active", (q) => q.eq("isActive", true)).first();
982
+ const activeConfig = await ctx.db.query("logicSprintScoring").withIndex(
983
+ "by_active",
984
+ (q) => q.eq("isActive", true)
985
+ ).first();
928
986
  return {
929
987
  scoringMode: activeConfig?.confidencePolicy === "always" ? "always" : DEFAULT_CONFIDENCE_POLICY.scoringMode,
930
988
  tupleContradiction: normalizeTupleContradictionPolicy(
@@ -969,7 +1027,7 @@ function normalizeForkTriggerRelation(value) {
969
1027
  }
970
1028
  async function resolveForkTriggerEvidence(ctx, args) {
971
1029
  const evidence = await ctx.db.get(args.triggeringEvidenceId);
972
- if (!evidence || evidence.nodeType !== "evidence") {
1030
+ if (evidence?.nodeType !== "evidence") {
973
1031
  throwStructuredMutationError({
974
1032
  message: "Fork requires an existing evidence node.",
975
1033
  status: 400,
@@ -1008,16 +1066,16 @@ async function resolveForkTriggerEvidence(ctx, args) {
1008
1066
  ].filter(Boolean)
1009
1067
  );
1010
1068
  let relation = null;
1011
- const linkedBeliefNodeId = String(
1012
- evidenceMetadata.linkedBeliefNodeId ?? ""
1013
- );
1069
+ const linkedBeliefNodeId = String(evidenceMetadata.linkedBeliefNodeId ?? "");
1014
1070
  if (linkedBeliefNodeId && parentRefs.has(linkedBeliefNodeId)) {
1015
1071
  relation = normalizeForkTriggerRelation(evidenceMetadata.evidenceRelation);
1016
1072
  }
1017
1073
  if (!relation) {
1018
1074
  for (const parentRef of parentRefs) {
1019
1075
  const links = await ctx.db.query("beliefEvidenceLinks").withIndex("by_beliefId", (q) => q.eq("beliefId", parentRef)).collect();
1020
- const matched = links.find((link) => evidenceRefs.has(String(link.insightId)));
1076
+ const matched = links.find(
1077
+ (link) => evidenceRefs.has(String(link.insightId))
1078
+ );
1021
1079
  if (matched) {
1022
1080
  relation = normalizeForkTriggerRelation(matched.relation);
1023
1081
  break;
@@ -1053,13 +1111,16 @@ async function resolveForkTriggerEvidence(ctx, args) {
1053
1111
  }
1054
1112
  return { evidenceNodeId: args.triggeringEvidenceId, relation };
1055
1113
  }
1056
- async function insertEpistemicNode(ctx, doc) {
1114
+ function insertEpistemicNode(ctx, doc) {
1057
1115
  assertUuidV7Identity("epistemicNodes", doc.globalId);
1058
1116
  return ctx.db.insert("epistemicNodes", doc);
1059
1117
  }
1060
1118
  async function assertExistingNodeEndpoint(ctx, endpointRole, endpoint) {
1061
1119
  assertUuidShapedEdgeEndpoint(endpointRole, endpoint);
1062
- const node = await ctx.db.query("epistemicNodes").withIndex("by_globalId", (q) => q.eq("globalId", endpoint)).first();
1120
+ const node = await ctx.db.query("epistemicNodes").withIndex(
1121
+ "by_globalId",
1122
+ (q) => q.eq("globalId", endpoint)
1123
+ ).first();
1063
1124
  if (!node) {
1064
1125
  throw new Error(
1065
1126
  `edge_endpoint_not_canonical: epistemicEdges insert requires ${endpointRole} to be the globalId of an existing epistemicNodes row, received ${endpoint} (no node with that globalId)`
@@ -1125,7 +1186,7 @@ async function resolveRequiredTopicAnchor(ctx, topicRef) {
1125
1186
  if (direct?.nodeType === "topic" && cleanString(direct.globalId)) {
1126
1187
  return direct;
1127
1188
  }
1128
- } catch (_) {
1189
+ } catch {
1129
1190
  }
1130
1191
  const byGlobalId = await ctx.db.query("epistemicNodes").withIndex("by_globalId", (q) => q.eq("globalId", candidate)).first();
1131
1192
  if (byGlobalId?.nodeType === "topic" && cleanString(byGlobalId.globalId)) {
@@ -1210,33 +1271,278 @@ async function createRequiredBeliefTopicEdge(ctx, args) {
1210
1271
  });
1211
1272
  }
1212
1273
 
1213
- // src/embeddingTrigger.ts
1214
- async function scheduleEmbeddingGeneration(args) {
1215
- try {
1216
- await args.ctx.scheduler.runAfter(
1217
- 0,
1218
- "embeddingActions:generateEpistemicNodeEmbedding",
1219
- {
1220
- nodeId: args.nodeId,
1221
- projectId: args.projectId ? String(args.projectId) : void 0,
1222
- topicId: args.topicId ? String(args.topicId) : void 0,
1223
- createdBy: args.createdBy,
1224
- nodeType: args.nodeType,
1225
- text: args.text.slice(0, 2e4),
1226
- hasAnswer: args.hasAnswer,
1227
- confidence: args.confidence
1228
- }
1229
- );
1230
- } catch (error) {
1231
- debugGraphPrimitiveFallback(
1232
- "[embeddingTrigger] Failed to schedule embedding generation",
1233
- {
1234
- error,
1235
- nodeId: String(args.nodeId),
1236
- nodeType: args.nodeType
1237
- }
1238
- );
1274
+ // src/epistemicBeliefs.core.ts
1275
+ var CONTRACT_CONDITION_TYPES = /* @__PURE__ */ new Set(["assertion", "temporal", "evidential", "threshold", "composite"]);
1276
+ var CONTRACT_DIRECTIONS = /* @__PURE__ */ new Set([
1277
+ "confirms",
1278
+ "falsifies"
1279
+ ]);
1280
+ var CONTRACT_LINEAGE_SOURCES = /* @__PURE__ */ new Set(["declared", "inherited"]);
1281
+ var CONTRACT_SCHEDULES = /* @__PURE__ */ new Set([
1282
+ "on_demand",
1283
+ "on_evidence",
1284
+ "periodic",
1285
+ "event_driven"
1286
+ ]);
1287
+ var CONTRACT_STATUSES = /* @__PURE__ */ new Set([
1288
+ "active",
1289
+ "satisfied",
1290
+ "violated",
1291
+ "expired",
1292
+ "suspended",
1293
+ "archived"
1294
+ ]);
1295
+ function isRecord(value) {
1296
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
1297
+ }
1298
+ function readConvexId(value) {
1299
+ return typeof value === "string" && value.trim().length > 0 ? value : void 0;
1300
+ }
1301
+ function readOptionalBoolean(value) {
1302
+ return typeof value === "boolean" ? value : void 0;
1303
+ }
1304
+ function readOptionalNumber(value) {
1305
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
1306
+ }
1307
+ function readOptionalString(value) {
1308
+ return typeof value === "string" && value.trim().length > 0 ? value : void 0;
1309
+ }
1310
+ function readRecord(value) {
1311
+ return isRecord(value) ? value : void 0;
1312
+ }
1313
+ function readStringList(value) {
1314
+ if (!Array.isArray(value)) {
1315
+ return;
1316
+ }
1317
+ const strings = value.filter(
1318
+ (item) => typeof item === "string" && item.length > 0
1319
+ );
1320
+ return strings.length === value.length ? strings : void 0;
1321
+ }
1322
+ function readEnumValue(value, allowed) {
1323
+ return typeof value === "string" && allowed.has(value) ? value : void 0;
1324
+ }
1325
+ function readContractCondition(value) {
1326
+ const record = readRecord(value);
1327
+ const evaluator = readOptionalString(record?.evaluator);
1328
+ const expression = readOptionalString(record?.expression);
1329
+ if (!(record && evaluator && expression)) {
1330
+ return;
1331
+ }
1332
+ return {
1333
+ evaluator,
1334
+ expression,
1335
+ evaluatorConfig: record.evaluatorConfig
1336
+ };
1337
+ }
1338
+ function readContractModulation(value) {
1339
+ const record = readRecord(value);
1340
+ const onConfirmed = readRecord(record?.onConfirmed);
1341
+ const onDisconfirmed = readRecord(record?.onDisconfirmed);
1342
+ const confirmedDelta = readOptionalNumber(onConfirmed?.delta);
1343
+ const disconfirmedDelta = readOptionalNumber(onDisconfirmed?.delta);
1344
+ if (!(record && onConfirmed && onDisconfirmed)) {
1345
+ return;
1346
+ }
1347
+ if (confirmedDelta === void 0 || disconfirmedDelta === void 0) {
1348
+ return;
1349
+ }
1350
+ const modulation = {
1351
+ onConfirmed: { delta: confirmedDelta },
1352
+ onDisconfirmed: { delta: disconfirmedDelta }
1353
+ };
1354
+ const confirmedCeiling = readOptionalNumber(onConfirmed.ceiling);
1355
+ if (confirmedCeiling !== void 0) {
1356
+ modulation.onConfirmed.ceiling = confirmedCeiling;
1357
+ }
1358
+ const disconfirmedFloor = readOptionalNumber(onDisconfirmed.floor);
1359
+ if (disconfirmedFloor !== void 0) {
1360
+ modulation.onDisconfirmed.floor = disconfirmedFloor;
1361
+ }
1362
+ const onExpired = readRecord(record.onExpired);
1363
+ const expiredDelta = readOptionalNumber(onExpired?.delta);
1364
+ if (expiredDelta !== void 0) {
1365
+ modulation.onExpired = { delta: expiredDelta };
1366
+ }
1367
+ const onPartial = readRecord(record.onPartial);
1368
+ const partialDelta = readOptionalNumber(onPartial?.delta);
1369
+ const partialThreshold = readOptionalNumber(onPartial?.threshold);
1370
+ if (partialDelta !== void 0 && partialThreshold !== void 0) {
1371
+ modulation.onPartial = {
1372
+ delta: partialDelta,
1373
+ threshold: partialThreshold
1374
+ };
1375
+ }
1376
+ return modulation;
1377
+ }
1378
+ function readBeliefNodeDoc(value) {
1379
+ if (!isRecord(value)) {
1380
+ return null;
1381
+ }
1382
+ const id = readConvexId(value._id);
1383
+ const nodeType = readOptionalString(value.nodeType);
1384
+ const projectId = readOptionalString(value.projectId);
1385
+ if (!(id && nodeType === "belief" && projectId)) {
1386
+ return null;
1387
+ }
1388
+ const node = { _id: id, nodeType, projectId };
1389
+ const canonicalText = readOptionalString(value.canonicalText);
1390
+ const confidence = readOptionalNumber(value.confidence);
1391
+ const content = readOptionalString(value.content);
1392
+ const epistemicLayer = readOptionalString(value.epistemicLayer);
1393
+ const globalId = readOptionalString(value.globalId);
1394
+ const metadata = readRecord(value.metadata);
1395
+ const predictionMeta = readRecord(value.predictionMeta);
1396
+ const sourceType = readOptionalString(value.sourceType);
1397
+ const status = readOptionalString(value.status);
1398
+ const tenantId = readOptionalString(value.tenantId);
1399
+ const title = readOptionalString(value.title);
1400
+ const topicId = readConvexId(value.topicId);
1401
+ const tupleContradicted = readOptionalBoolean(value.tupleContradicted);
1402
+ const workspaceId = readOptionalString(value.workspaceId);
1403
+ if (canonicalText !== void 0) {
1404
+ node.canonicalText = canonicalText;
1405
+ }
1406
+ if (confidence !== void 0) {
1407
+ node.confidence = confidence;
1408
+ }
1409
+ if (content !== void 0) {
1410
+ node.content = content;
1411
+ }
1412
+ if (epistemicLayer !== void 0) {
1413
+ node.epistemicLayer = epistemicLayer;
1414
+ }
1415
+ if (globalId !== void 0) {
1416
+ node.globalId = globalId;
1417
+ }
1418
+ if (metadata !== void 0) {
1419
+ node.metadata = metadata;
1420
+ }
1421
+ if (predictionMeta !== void 0) {
1422
+ node.predictionMeta = predictionMeta;
1423
+ }
1424
+ if (sourceType !== void 0) {
1425
+ node.sourceType = sourceType;
1426
+ }
1427
+ if (status !== void 0) {
1428
+ node.status = status;
1429
+ }
1430
+ if (tenantId !== void 0) {
1431
+ node.tenantId = tenantId;
1432
+ }
1433
+ if (title !== void 0) {
1434
+ node.title = title;
1435
+ }
1436
+ if (topicId !== void 0) {
1437
+ node.topicId = topicId;
1438
+ }
1439
+ if (tupleContradicted !== void 0) {
1440
+ node.tupleContradicted = tupleContradicted;
1441
+ }
1442
+ if (workspaceId !== void 0) {
1443
+ node.workspaceId = workspaceId;
1444
+ }
1445
+ return node;
1446
+ }
1447
+ function readContractRow(value) {
1448
+ if (!isRecord(value)) {
1449
+ return null;
1450
+ }
1451
+ const beliefNodeId = readConvexId(value.beliefNodeId);
1452
+ const condition = readContractCondition(value.condition);
1453
+ const conditionType = readEnumValue(
1454
+ value.conditionType,
1455
+ CONTRACT_CONDITION_TYPES
1456
+ );
1457
+ const contractId = readOptionalString(value.contractId);
1458
+ const createdAt = readOptionalNumber(value.createdAt);
1459
+ const createdBy = readOptionalString(value.createdBy);
1460
+ const direction = readEnumValue(value.direction, CONTRACT_DIRECTIONS);
1461
+ const evaluationSchedule = readEnumValue(
1462
+ value.evaluationSchedule,
1463
+ CONTRACT_SCHEDULES
1464
+ );
1465
+ const lineageSource = readEnumValue(
1466
+ value.lineageSource,
1467
+ CONTRACT_LINEAGE_SOURCES
1468
+ );
1469
+ const modulation = readContractModulation(value.modulation);
1470
+ const status = readEnumValue(value.status, CONTRACT_STATUSES);
1471
+ const title = readOptionalString(value.title);
1472
+ const updatedAt = readOptionalNumber(value.updatedAt);
1473
+ if (!(beliefNodeId && condition && conditionType && contractId && createdAt !== void 0 && createdBy && direction && evaluationSchedule && lineageSource && modulation && status && title && updatedAt !== void 0)) {
1474
+ return null;
1475
+ }
1476
+ const row = {
1477
+ beliefNodeId,
1478
+ condition,
1479
+ conditionType,
1480
+ contractId,
1481
+ createdAt,
1482
+ createdBy,
1483
+ direction,
1484
+ evaluationSchedule,
1485
+ lineageSource,
1486
+ modulation,
1487
+ status,
1488
+ title,
1489
+ updatedAt
1490
+ };
1491
+ const compositeOf = readStringList(value.compositeOf);
1492
+ if (compositeOf !== void 0) {
1493
+ row.compositeOf = compositeOf;
1494
+ }
1495
+ const compositeOperator = readOptionalString(value.compositeOperator);
1496
+ if (compositeOperator === "all" || compositeOperator === "any" || compositeOperator === "majority") {
1497
+ row.compositeOperator = compositeOperator;
1498
+ }
1499
+ const deadline = readOptionalNumber(value.deadline);
1500
+ if (deadline !== void 0) {
1501
+ row.deadline = deadline;
1502
+ }
1503
+ const description = readOptionalString(value.description);
1504
+ if (description !== void 0) {
1505
+ row.description = description;
1506
+ }
1507
+ const evaluationCount = readOptionalNumber(value.evaluationCount);
1508
+ if (evaluationCount !== void 0) {
1509
+ row.evaluationCount = evaluationCount;
1510
+ }
1511
+ const inheritedAt = readOptionalNumber(value.inheritedAt);
1512
+ if (inheritedAt !== void 0) {
1513
+ row.inheritedAt = inheritedAt;
1514
+ }
1515
+ const inheritedFromBeliefNodeId = readConvexId(
1516
+ value.inheritedFromBeliefNodeId
1517
+ );
1518
+ if (inheritedFromBeliefNodeId !== void 0) {
1519
+ row.inheritedFromBeliefNodeId = inheritedFromBeliefNodeId;
1520
+ }
1521
+ const inheritedFromContractId = readOptionalString(
1522
+ value.inheritedFromContractId
1523
+ );
1524
+ if (inheritedFromContractId !== void 0) {
1525
+ row.inheritedFromContractId = inheritedFromContractId;
1526
+ }
1527
+ const lastEvaluatedAt = readOptionalNumber(value.lastEvaluatedAt);
1528
+ if (lastEvaluatedAt !== void 0) {
1529
+ row.lastEvaluatedAt = lastEvaluatedAt;
1530
+ }
1531
+ const periodicIntervalMs = readOptionalNumber(value.periodicIntervalMs);
1532
+ if (periodicIntervalMs !== void 0) {
1533
+ row.periodicIntervalMs = periodicIntervalMs;
1534
+ }
1535
+ const topicId = readConvexId(value.topicId) ?? readOptionalString(value.topicId);
1536
+ if (topicId !== void 0) {
1537
+ row.topicId = topicId;
1239
1538
  }
1539
+ return row;
1540
+ }
1541
+ function readRowList(values, reader) {
1542
+ return values.flatMap((value) => {
1543
+ const row = reader(value);
1544
+ return row ? [row] : [];
1545
+ });
1240
1546
  }
1241
1547
  var create = mutation({
1242
1548
  args: {
@@ -1287,41 +1593,7 @@ var create = mutation({
1287
1593
  returns: permissiveReturn,
1288
1594
  handler: async (ctx, args) => {
1289
1595
  const authenticatedUserId = await requireAuthenticatedUserId(ctx);
1290
- const topicRef = readTopicNodeRef(args);
1291
- if (!topicRef) {
1292
- throwStructuredMutationError({
1293
- message: "Belief creation requires an explicit topic epistemic node.",
1294
- status: 400,
1295
- code: "INVALID_ARGUMENT",
1296
- invariantCode: "belief.topic_node_required",
1297
- suggestion: "Pass topicGlobalId or topicNodeId for a topic in epistemicNodes before creating a belief.",
1298
- details: {
1299
- topicId: args.topicId,
1300
- topicNodeId: args.topicNodeId,
1301
- topicGlobalId: args.topicGlobalId
1302
- }
1303
- });
1304
- }
1305
- const topicNode = await resolveRequiredTopicAnchor(ctx, topicRef);
1306
- const scope = scopeFromTopicAnchor(topicNode);
1307
- assertWorkspaceScopedEpistemicNodeScope({
1308
- scope,
1309
- nodeType: "belief",
1310
- mutationName: "epistemicBeliefs.create"
1311
- });
1312
- const normalizedBeliefType = await assertSchemaEnumValue(ctx, {
1313
- category: "belief_type",
1314
- value: args.beliefType,
1315
- tenantId: scope.tenantId,
1316
- context: "epistemicBeliefs.create"
1317
- });
1318
- if (scope.projectId) {
1319
- await requireScopeWriteAccess(
1320
- ctx,
1321
- scope.projectId,
1322
- authenticatedUserId
1323
- );
1324
- }
1596
+ const { normalizedBeliefType, scope, topicNode } = await resolveCreateBeliefAdmission(ctx, args, authenticatedUserId);
1325
1597
  const now = Date.now();
1326
1598
  const baseRate = assertBaseRateInRange(args.baseRate ?? 0.5);
1327
1599
  const initialBeliefStatus = args.worktreeId ? "hypothesis" : "assumption";
@@ -1333,7 +1605,7 @@ var create = mutation({
1333
1605
  opinion_a: baseRate
1334
1606
  };
1335
1607
  const pillar = normalizePillar(args.pillar);
1336
- const additionalMeta = args.metadata || {};
1608
+ const additionalMeta = readRecord(args.metadata) ?? {};
1337
1609
  const beliefGlobalId = generateGlobalId();
1338
1610
  const nodeId = await insertEpistemicNode(ctx, {
1339
1611
  globalId: beliefGlobalId,
@@ -1495,6 +1767,44 @@ Rationale: ${args.rationale}` : args.formulation
1495
1767
  return { nodeId };
1496
1768
  }
1497
1769
  });
1770
+ async function resolveCreateBeliefAdmission(ctx, args, authenticatedUserId) {
1771
+ const topicRef = readTopicNodeRef(args);
1772
+ if (!topicRef) {
1773
+ throwStructuredMutationError({
1774
+ message: "Belief creation requires an explicit topic epistemic node.",
1775
+ status: 400,
1776
+ code: "INVALID_ARGUMENT",
1777
+ invariantCode: "belief.topic_node_required",
1778
+ suggestion: "Pass topicGlobalId or topicNodeId for a topic in epistemicNodes before creating a belief.",
1779
+ details: {
1780
+ topicId: args.topicId,
1781
+ topicNodeId: args.topicNodeId,
1782
+ topicGlobalId: args.topicGlobalId
1783
+ }
1784
+ });
1785
+ }
1786
+ const topicNode = await resolveRequiredTopicAnchor(ctx, topicRef);
1787
+ const anchoredScope = scopeFromTopicAnchor(topicNode);
1788
+ const scope = {
1789
+ ...anchoredScope,
1790
+ topicId: anchoredScope.topicId
1791
+ };
1792
+ assertWorkspaceScopedEpistemicNodeScope({
1793
+ scope,
1794
+ nodeType: "belief",
1795
+ mutationName: "epistemicBeliefs.create"
1796
+ });
1797
+ const normalizedBeliefType = await assertSchemaEnumValue(ctx, {
1798
+ category: "belief_type",
1799
+ value: args.beliefType,
1800
+ tenantId: scope.tenantId,
1801
+ context: "epistemicBeliefs.create"
1802
+ });
1803
+ if (scope.projectId) {
1804
+ await requireScopeWriteAccess(ctx, scope.projectId, authenticatedUserId);
1805
+ }
1806
+ return { normalizedBeliefType, scope, topicNode };
1807
+ }
1498
1808
  var getById = query({
1499
1809
  args: {
1500
1810
  nodeId: v.optional(v.id("epistemicNodes")),
@@ -1506,8 +1816,8 @@ var getById = query({
1506
1816
  if (!id) {
1507
1817
  return null;
1508
1818
  }
1509
- const node = await ctx.db.get(id);
1510
- if (!node || node.nodeType !== "belief") {
1819
+ const node = readBeliefNodeDoc(await ctx.db.get(id));
1820
+ if (!node) {
1511
1821
  return null;
1512
1822
  }
1513
1823
  return node;
@@ -1525,48 +1835,8 @@ var refineBelief = mutation({
1525
1835
  handler: async (ctx, args) => {
1526
1836
  const authenticatedUserId = await requireAuthenticatedUserId(ctx);
1527
1837
  const now = Date.now();
1528
- const node = await ctx.db.get(args.nodeId);
1529
- if (!node) {
1530
- throwStructuredMutationError({
1531
- message: "Belief not found.",
1532
- status: 404,
1533
- code: "NOT_FOUND",
1534
- invariantCode: "belief.exists",
1535
- suggestion: "Verify nodeId points to an existing belief before refining.",
1536
- details: { nodeId: args.nodeId }
1537
- });
1538
- }
1539
- if (node.nodeType !== "belief") {
1540
- throwStructuredMutationError({
1541
- message: `refineBelief only applies to belief nodes. Received nodeType "${node.nodeType}".`,
1542
- status: 400,
1543
- code: "INVALID_ARGUMENT",
1544
- invariantCode: "entity.no_refine",
1545
- suggestion: "Use entityLifecycle.updateEntityAttributes for entity mutations.",
1546
- details: { nodeId: args.nodeId, nodeType: node.nodeType }
1547
- });
1548
- }
1549
- if (!node.projectId) {
1550
- throwStructuredMutationError({
1551
- message: "Belief has no project scope.",
1552
- status: 400,
1553
- code: "MISSING_SCOPE",
1554
- invariantCode: "belief.project_required",
1555
- suggestion: "Belief must have a projectId to refine.",
1556
- details: { nodeId: args.nodeId }
1557
- });
1558
- }
1838
+ const node = await requireRefinableBelief(ctx, args.nodeId);
1559
1839
  await requireScopeWriteAccess(ctx, node.projectId, authenticatedUserId);
1560
- if (typeof node.confidence === "number" && Number.isFinite(node.confidence)) {
1561
- throwStructuredMutationError({
1562
- message: "Scored beliefs are immutable. Use forkBelief to evolve a scored belief.",
1563
- status: 409,
1564
- code: "CONFLICT",
1565
- invariantCode: "belief.versioning.scored_immutable",
1566
- suggestion: "Use forkBelief() to create a new version instead of refining in place.",
1567
- details: { nodeId: args.nodeId, confidence: node.confidence }
1568
- });
1569
- }
1570
1840
  const nextText = typeof args.canonicalText === "string" && args.canonicalText.trim().length > 0 ? args.canonicalText.trim() : void 0;
1571
1841
  const nextTitle = typeof args.title === "string" && args.title.trim().length > 0 ? args.title.trim() : void 0;
1572
1842
  const patch = { updatedAt: now };
@@ -1627,6 +1897,110 @@ Rationale: ${args.rationale}` : nextText
1627
1897
  return { nodeId: args.nodeId };
1628
1898
  }
1629
1899
  });
1900
+ async function requireRefinableBelief(ctx, nodeId) {
1901
+ const node = await ctx.db.get(nodeId);
1902
+ if (!node) {
1903
+ throwStructuredMutationError({
1904
+ message: "Belief not found.",
1905
+ status: 404,
1906
+ code: "NOT_FOUND",
1907
+ invariantCode: "belief.exists",
1908
+ suggestion: "Verify nodeId points to an existing belief before refining.",
1909
+ details: { nodeId }
1910
+ });
1911
+ }
1912
+ const nodeType = isRecord(node) ? readOptionalString(node.nodeType) : void 0;
1913
+ if (nodeType !== "belief") {
1914
+ throwStructuredMutationError({
1915
+ message: `refineBelief only applies to belief nodes. Received nodeType "${nodeType}".`,
1916
+ status: 400,
1917
+ code: "INVALID_ARGUMENT",
1918
+ invariantCode: "entity.no_refine",
1919
+ suggestion: "Use entityLifecycle.updateEntityAttributes for entity mutations.",
1920
+ details: { nodeId, nodeType }
1921
+ });
1922
+ }
1923
+ const projectId = isRecord(node) ? readOptionalString(node.projectId) : void 0;
1924
+ if (!projectId) {
1925
+ throwStructuredMutationError({
1926
+ message: "Belief has no project scope.",
1927
+ status: 400,
1928
+ code: "MISSING_SCOPE",
1929
+ invariantCode: "belief.project_required",
1930
+ suggestion: "Belief must have a projectId to refine.",
1931
+ details: { nodeId }
1932
+ });
1933
+ }
1934
+ const confidence = isRecord(node) ? readOptionalNumber(node.confidence) : void 0;
1935
+ if (confidence !== void 0) {
1936
+ throwStructuredMutationError({
1937
+ message: "Scored beliefs are immutable. Use forkBelief to evolve a scored belief.",
1938
+ status: 409,
1939
+ code: "CONFLICT",
1940
+ invariantCode: "belief.versioning.scored_immutable",
1941
+ suggestion: "Use forkBelief() to create a new version instead of refining in place.",
1942
+ details: { nodeId, confidence }
1943
+ });
1944
+ }
1945
+ const beliefNode = readBeliefNodeDoc(node);
1946
+ if (!beliefNode) {
1947
+ throwStructuredMutationError({
1948
+ message: "Belief row is missing required typed fields.",
1949
+ status: 400,
1950
+ code: "MISSING_SCOPE",
1951
+ invariantCode: "belief.typed_row_required",
1952
+ suggestion: "Backfill belief project/topic/global scope before refining.",
1953
+ details: { nodeId }
1954
+ });
1955
+ }
1956
+ return beliefNode;
1957
+ }
1958
+ async function requireForkParentAdmission(ctx, args, authenticatedUserId) {
1959
+ const parentRaw = await ctx.db.get(args.parentNodeId);
1960
+ if (!parentRaw) {
1961
+ throwStructuredMutationError({
1962
+ message: "Parent node not found.",
1963
+ status: 404,
1964
+ code: "NOT_FOUND",
1965
+ invariantCode: "belief.exists",
1966
+ suggestion: "Verify parentNodeId points to an existing node before forking.",
1967
+ details: { parentNodeId: args.parentNodeId }
1968
+ });
1969
+ }
1970
+ const parent = readBeliefNodeDoc(parentRaw);
1971
+ const parentNodeType = isRecord(parentRaw) ? readOptionalString(parentRaw.nodeType) : void 0;
1972
+ if (!parent) {
1973
+ throwStructuredMutationError({
1974
+ message: `forkBelief only applies to fully scoped belief nodes. Received nodeType "${parentNodeType}". Entity nodes (company, person, investor, etc.) are mutable \u2014 use entityLifecycle.updateEntityAttributes instead of forking.`,
1975
+ status: 400,
1976
+ code: "INVALID_ARGUMENT",
1977
+ invariantCode: "entity.no_fork",
1978
+ suggestion: "Use entityLifecycle.updateEntityAttributes for entity mutations. forkBelief is for belief nodes only, and parent beliefs must carry project scope.",
1979
+ details: {
1980
+ parentNodeId: args.parentNodeId,
1981
+ nodeType: parentNodeType
1982
+ }
1983
+ });
1984
+ }
1985
+ const parentGlobalId = parent.globalId;
1986
+ if (!parentGlobalId) {
1987
+ throwStructuredMutationError({
1988
+ message: "Parent belief has no globalId for lineage edge creation.",
1989
+ status: 400,
1990
+ code: "INVALID_ARGUMENT",
1991
+ invariantCode: "belief.global_id_required",
1992
+ suggestion: "Backfill parent belief globalId before forking so Neo4j lineage edges can use canonical endpoints.",
1993
+ details: { parentNodeId: args.parentNodeId }
1994
+ });
1995
+ }
1996
+ await requireScopeWriteAccess(ctx, parent.projectId, authenticatedUserId);
1997
+ return {
1998
+ metadata: parent.metadata,
1999
+ parent,
2000
+ parentGlobalId,
2001
+ parentRaw
2002
+ };
2003
+ }
1630
2004
  var getByProject = query({
1631
2005
  args: {
1632
2006
  ...optionalBeliefScopeArgs,
@@ -1642,7 +2016,7 @@ var getByProject = query({
1642
2016
  },
1643
2017
  returns: permissiveReturn,
1644
2018
  handler: async (ctx, args) => {
1645
- if (!args.projectId && !args.topicId) {
2019
+ if (!(args.projectId || args.topicId)) {
1646
2020
  return [];
1647
2021
  }
1648
2022
  const pageSize = clampBeliefLimit(args.limit);
@@ -1674,11 +2048,14 @@ var getByProject = query({
1674
2048
  return [];
1675
2049
  }
1676
2050
  }
1677
- const query3 = ctx.db.query("epistemicNodes").withIndex(
2051
+ const query2 = ctx.db.query("epistemicNodes").withIndex(
1678
2052
  "by_topic_type",
1679
2053
  (q) => q.eq("topicId", scope.topicId).eq("nodeType", "belief")
1680
2054
  );
1681
- const nodes = await query3.order("desc").take(scanLimit);
2055
+ const nodes = readRowList(
2056
+ await query2.order("desc").take(scanLimit),
2057
+ readBeliefNodeDoc
2058
+ );
1682
2059
  const scopedNodes = nodes.filter(
1683
2060
  (node) => nodeMatchesWorkspaceReasoningScope(node, scope)
1684
2061
  );
@@ -1708,11 +2085,14 @@ var getByTopic = query({
1708
2085
  const scope = await resolveTopicProjectScope(ctx, {
1709
2086
  topicId: args.topicId
1710
2087
  });
1711
- const query3 = ctx.db.query("epistemicNodes").withIndex(
2088
+ const query2 = ctx.db.query("epistemicNodes").withIndex(
1712
2089
  "by_topic_type",
1713
2090
  (q) => q.eq("topicId", args.topicId).eq("nodeType", "belief")
1714
2091
  );
1715
- const nodes = await query3.order("desc").take(scanLimit);
2092
+ const nodes = readRowList(
2093
+ await query2.order("desc").take(scanLimit),
2094
+ readBeliefNodeDoc
2095
+ );
1716
2096
  const scopedNodes = nodes.filter(
1717
2097
  (node) => nodeMatchesWorkspaceReasoningScope(node, {
1718
2098
  tenantId: scope.tenantId,
@@ -1745,44 +2125,12 @@ var forkBelief = mutation({
1745
2125
  const authenticatedUserId = await requireAuthenticatedUserId(ctx);
1746
2126
  const now = Date.now();
1747
2127
  await getActiveConfidencePolicy(ctx);
1748
- const parent = await ctx.db.get(args.parentNodeId);
1749
- if (!parent) {
1750
- throwStructuredMutationError({
1751
- message: "Parent node not found.",
1752
- status: 404,
1753
- code: "NOT_FOUND",
1754
- invariantCode: "belief.exists",
1755
- suggestion: "Verify parentNodeId points to an existing node before forking.",
1756
- details: { parentNodeId: args.parentNodeId }
1757
- });
1758
- }
1759
- if (parent.nodeType !== "belief") {
1760
- throwStructuredMutationError({
1761
- message: `forkBelief only applies to belief nodes. Received nodeType "${parent.nodeType}". Entity nodes (company, person, investor, etc.) are mutable \u2014 use entityLifecycle.updateEntityAttributes instead of forking.`,
1762
- status: 400,
1763
- code: "INVALID_ARGUMENT",
1764
- invariantCode: "entity.no_fork",
1765
- suggestion: "Use entityLifecycle.updateEntityAttributes for entity mutations. forkBelief is for belief nodes only.",
1766
- details: { parentNodeId: args.parentNodeId, nodeType: parent.nodeType }
1767
- });
1768
- }
1769
- if (!parent.projectId) {
1770
- throwStructuredMutationError({
1771
- message: "Parent belief has no project scope.",
1772
- status: 400,
1773
- code: "MISSING_SCOPE",
1774
- invariantCode: "belief.project_required",
1775
- suggestion: "Belief must have a projectId to fork.",
1776
- details: { parentNodeId: args.parentNodeId }
1777
- });
1778
- }
1779
- await requireScopeWriteAccess(ctx, parent.projectId, authenticatedUserId);
1780
- const metadata = parent.metadata;
2128
+ const { metadata, parent, parentGlobalId, parentRaw } = await requireForkParentAdmission(ctx, args, authenticatedUserId);
1781
2129
  const forkBeliefStatus = "hypothesis";
1782
2130
  const forkMode = args.forkMode ?? "supersede";
1783
2131
  const triggerEvidence = await resolveForkTriggerEvidence(ctx, {
1784
2132
  parentNodeId: args.parentNodeId,
1785
- parent,
2133
+ parent: parentRaw,
1786
2134
  triggeringEvidenceId: args.triggeringEvidenceId,
1787
2135
  forkMode
1788
2136
  });
@@ -1829,7 +2177,7 @@ var forkBelief = mutation({
1829
2177
  tupleContradicted: false
1830
2178
  },
1831
2179
  beliefStatus: forkBeliefStatus,
1832
- sourceType: parent.sourceType,
2180
+ sourceType: parent.sourceType ?? "human",
1833
2181
  confidence: void 0,
1834
2182
  tupleContradicted: false,
1835
2183
  verificationStatus: "unverified",
@@ -1861,23 +2209,21 @@ var forkBelief = mutation({
1861
2209
  operation: "upsert"
1862
2210
  });
1863
2211
  }
1864
- const inheritedContracts = await ctx.db.query("epistemicContracts").withIndex(
1865
- "by_belief",
1866
- (q) => q.eq("beliefNodeId", args.parentNodeId)
1867
- ).collect();
2212
+ const inheritedContracts = readRowList(
2213
+ await ctx.db.query("epistemicContracts").withIndex("by_belief", (q) => q.eq("beliefNodeId", args.parentNodeId)).collect(),
2214
+ readContractRow
2215
+ );
1868
2216
  for (const contract of inheritedContracts) {
1869
2217
  if (contract.status === "archived") {
1870
2218
  continue;
1871
2219
  }
1872
- await ctx.db.insert(
1873
- "epistemicContracts",
1874
- createInheritedContractRecord(contract, {
1875
- beliefNodeId: newNodeId,
1876
- topicId: parent.topicId,
1877
- createdBy: authenticatedUserId,
1878
- now
1879
- })
1880
- );
2220
+ const inheritedContract = createInheritedContractRecord(contract, {
2221
+ beliefNodeId: newNodeId,
2222
+ topicId: parent.topicId,
2223
+ createdBy: authenticatedUserId,
2224
+ now
2225
+ });
2226
+ await ctx.db.insert("epistemicContracts", { ...inheritedContract });
1881
2227
  }
1882
2228
  await ctx.scheduler.runAfter(0, internal.neo4jSync.syncNodeToNeo4j, {
1883
2229
  nodeId: newNodeId,
@@ -1886,7 +2232,7 @@ var forkBelief = mutation({
1886
2232
  await ctx.scheduler.runAfter(5e3, internal.neo4jEdgeAPI.createEdge, {
1887
2233
  globalId: generateGlobalId(),
1888
2234
  fromGlobalId: newBeliefGlobalId,
1889
- toGlobalId: parent.globalId,
2235
+ toGlobalId: parentGlobalId,
1890
2236
  edgeType: forkMode === "supersede" ? "supersedes" : "derived_from",
1891
2237
  context: `Fork reason: ${args.forkReason}; triggering evidence: ${triggerEvidence.evidenceNodeId}`,
1892
2238
  createdBy: authenticatedUserId,