@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,16 +1,21 @@
1
- import { v, ConvexError } from 'convex/values';
2
- import { normalizeTupleContradictionPolicy, confidenceFromSL, readOpinionFromRecord, mkOpinion } from '@lucern/confidence';
3
1
  import { checkScopeAccess } from '@lucern/access-control/access';
2
+ import { normalizeTupleContradictionPolicy, readOpinionFromRecord, mkOpinion, confidenceFromSL } from '@lucern/confidence';
4
3
  import { permissiveReturn } from '@lucern/contracts/schema-helpers/validators';
5
- import { componentsGeneric, anyApi, queryGeneric, internalMutationGeneric, mutationGeneric } from 'convex/server';
4
+ import { v } from 'convex/values';
5
+ import { unsafeConvexAnyApi } from '@lucern/contracts/convex/unsafeAnyApi';
6
+ import { componentsGeneric, queryGeneric, internalMutationGeneric, mutationGeneric } from 'convex/server';
6
7
  import '@lucern/access-control/audience';
7
8
  import '@lucern/access-control/auth';
9
+ import { throwStructuredMutationError } from '@lucern/access-control/structuredMutationError';
8
10
  import '@lucern/contracts/schema-helpers/spine/tables/epistemicNodes';
9
11
 
10
12
  // src/epistemicBeliefs.backfills.ts
11
- var api = anyApi;
13
+ var unsafeApi = unsafeConvexAnyApi(
14
+ "graph-primitives top-level module bundle lacks a committed Convex _generated/api surface"
15
+ );
16
+ var api = unsafeApi;
12
17
  componentsGeneric();
13
- var internal = anyApi;
18
+ var internal = unsafeApi;
14
19
  var internalMutation = internalMutationGeneric;
15
20
  var mutation = mutationGeneric;
16
21
  var query = queryGeneric;
@@ -171,13 +176,15 @@ function asMappedProjectId(topic) {
171
176
  if (!topic) {
172
177
  return;
173
178
  }
174
- const directLegacyProjectId = normalizeScopeValue(topic[LEGACY_SCOPE_FIELD]);
179
+ const directLegacyProjectId = normalizeScopeValue(
180
+ topic[LEGACY_SCOPE_FIELD]
181
+ );
175
182
  if (directLegacyProjectId) {
176
183
  return directLegacyProjectId;
177
184
  }
178
185
  const metadata = topic.metadata || {};
179
186
  const candidate = metadata[LEGACY_SCOPE_FIELD] || metadata.legacyProjectId || metadata.projectId || metadata.scopeProjectId;
180
- return candidate ? candidate : void 0;
187
+ return typeof candidate === "string" ? normalizeScopeValue(candidate) : void 0;
181
188
  }
182
189
  function normalizeScopeValue(value) {
183
190
  if (typeof value !== "string") {
@@ -202,8 +209,9 @@ function pickPrimaryTopic(candidates) {
202
209
  })[0];
203
210
  }
204
211
  async function findTopicsByScopeAlias(ctx, scopeId) {
212
+ const query2 = ctx.db.query("topics");
205
213
  try {
206
- return await ctx.db.query("topics").withIndex(
214
+ return await query2.withIndex(
207
215
  "by_graph_scope_project",
208
216
  (q) => q.eq(LEGACY_SCOPE_FIELD, scopeId)
209
217
  ).collect();
@@ -215,7 +223,7 @@ async function findTopicsByScopeAlias(ctx, scopeId) {
215
223
  scopeId
216
224
  }
217
225
  );
218
- const topics = await ctx.db.query("topics").collect();
226
+ const topics = await query2.collect();
219
227
  return topics.filter((topic) => {
220
228
  const normalizedGlobalId = normalizeScopeValue(topic.globalId);
221
229
  const mappedProjectId = asMappedProjectId(topic);
@@ -223,20 +231,20 @@ async function findTopicsByScopeAlias(ctx, scopeId) {
223
231
  });
224
232
  }
225
233
  }
226
- async function tryResolveHostTopicById(ctx, topicId) {
234
+ async function tryResolveHostTopicById(ctx, topicId2) {
227
235
  if (typeof ctx.runQuery !== "function") {
228
236
  return null;
229
237
  }
230
238
  try {
231
239
  return await ctx.runQuery(api.topics.get, {
232
- id: topicId
240
+ id: topicId2
233
241
  }) ?? null;
234
242
  } catch (error) {
235
243
  debugGraphPrimitiveFallback(
236
244
  "[topicScope] Failed to resolve topic by host query",
237
245
  {
238
246
  error,
239
- topicId
247
+ topicId: topicId2
240
248
  }
241
249
  );
242
250
  return null;
@@ -271,137 +279,115 @@ async function resolveInheritedWorkspaceScope(ctx, topic) {
271
279
  let current = topic;
272
280
  for (let i = 0; i < MAX_DEPTH && current?.parentTopicId; i++) {
273
281
  current = await ctx.db.get(current.parentTopicId);
274
- if (!current) break;
282
+ if (!current) {
283
+ break;
284
+ }
275
285
  if (!tenantId) {
276
286
  tenantId = normalizeScopeValue(current.tenantId);
277
287
  }
278
288
  if (!workspaceId) {
279
289
  workspaceId = normalizeScopeValue(current.workspaceId);
280
290
  }
281
- if (tenantId && workspaceId) break;
291
+ if (tenantId && workspaceId) {
292
+ break;
293
+ }
282
294
  }
283
295
  return { tenantId, workspaceId };
284
296
  }
285
297
  async function resolveTopicProjectScope(ctx, args) {
286
298
  if (args.topicId) {
287
- let topic = null;
288
- try {
289
- topic = await ctx.db.get(
290
- args.topicId
291
- );
292
- } catch (error) {
293
- debugGraphPrimitiveFallback(
294
- "[topicScope] Failed to load topic by direct id",
295
- {
296
- error,
297
- topicId: args.topicId
298
- }
299
- );
300
- }
301
- if (!topic) {
302
- topic = await tryResolveHostTopicById(ctx, String(args.topicId));
303
- }
304
- if (!topic) {
305
- topic = pickPrimaryTopic(
306
- await findTopicsByScopeAlias(ctx, String(args.topicId))
307
- ) ?? null;
308
- }
309
- if (!topic) {
310
- const nodeScope = await resolveTopicNodeScopeOrNull(
311
- ctx,
312
- String(args.topicId)
313
- );
314
- if (nodeScope) {
315
- return nodeScope;
316
- }
317
- throw new Error(`Topic not found: ${String(args.topicId)}`);
318
- }
319
- const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
320
- const mapped = asMappedProjectId(topic);
321
- if (mapped) {
322
- return {
323
- topicId: topic._id,
324
- projectId: mapped,
325
- tenantId: inherited.tenantId,
326
- workspaceId: inherited.workspaceId,
327
- source: "topic"
328
- };
329
- }
330
- return {
331
- topicId: topic._id,
332
- tenantId: inherited.tenantId,
333
- workspaceId: inherited.workspaceId,
334
- source: "topic"
335
- };
299
+ return await resolveScopeFromTopicId(ctx, args.topicId);
336
300
  }
337
301
  if (args.projectId) {
338
- let directTopic = null;
339
- try {
340
- directTopic = await ctx.db.get(
341
- args.projectId
342
- );
343
- } catch (error) {
344
- debugGraphPrimitiveFallback(
345
- "[topicScope] Failed to load direct project topic",
346
- {
347
- error,
348
- projectId: args.projectId
349
- }
350
- );
351
- }
352
- if (directTopic) {
353
- const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
354
- const mapped = asMappedProjectId(directTopic);
355
- return {
356
- topicId: directTopic._id,
357
- projectId: mapped ?? args.projectId,
358
- tenantId: inherited.tenantId,
359
- workspaceId: inherited.workspaceId,
360
- source: "topic_inferred"
361
- };
362
- }
363
- directTopic = await tryResolveHostTopicByLegacyScope(ctx, args.projectId);
364
- if (directTopic) {
365
- const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
366
- const mapped = asMappedProjectId(directTopic);
367
- return {
368
- topicId: directTopic._id,
369
- projectId: mapped ?? args.projectId,
370
- tenantId: inherited.tenantId,
371
- workspaceId: inherited.workspaceId,
372
- source: "topic_inferred"
373
- };
374
- }
375
- const topics = await findTopicsByScopeAlias(ctx, args.projectId);
376
- const primary = pickPrimaryTopic(topics);
377
- if (primary) {
378
- const inherited = await resolveInheritedWorkspaceScope(ctx, primary);
379
- return {
380
- topicId: primary._id,
381
- projectId: args.projectId,
382
- tenantId: inherited.tenantId,
383
- workspaceId: inherited.workspaceId,
384
- source: "project_mapped_topic"
385
- };
386
- }
387
- const nodeScope = await resolveTopicNodeScopeOrNull(
388
- ctx,
389
- String(args.projectId)
390
- );
391
- if (nodeScope) {
392
- return {
393
- ...nodeScope,
394
- projectId: nodeScope.projectId ?? String(args.projectId)
395
- };
396
- }
397
- throw new Error(
398
- `Legacy project scope ${String(args.projectId)} has no mapped topic.`
399
- );
302
+ return await resolveScopeFromLegacyProjectId(ctx, args.projectId);
400
303
  }
401
304
  throw new Error(
402
305
  "Missing scope: provide topicId (preferred) or legacy projectId alias."
403
306
  );
404
307
  }
308
+ async function resolveScopeFromTopicId(ctx, topicId2) {
309
+ const topic = await resolveTopicDocFromTopicId(ctx, topicId2);
310
+ if (topic) {
311
+ return await buildTopicScope(ctx, topic, "topic");
312
+ }
313
+ const nodeScope = await resolveTopicNodeScopeOrNull(ctx, String(topicId2));
314
+ if (nodeScope) {
315
+ return nodeScope;
316
+ }
317
+ throw new Error(`Topic not found: ${String(topicId2)}`);
318
+ }
319
+ async function resolveTopicDocFromTopicId(ctx, topicId2) {
320
+ const direct = await tryReadTopicDoc(ctx, topicId2, {
321
+ failureLog: "[topicScope] Failed to load topic by direct id",
322
+ idLogKey: "topicId"
323
+ });
324
+ if (direct) {
325
+ return direct;
326
+ }
327
+ const hostTopic = await tryResolveHostTopicById(ctx, String(topicId2));
328
+ if (hostTopic) {
329
+ return hostTopic;
330
+ }
331
+ return pickPrimaryTopic(await findTopicsByScopeAlias(ctx, String(topicId2))) ?? null;
332
+ }
333
+ async function resolveScopeFromLegacyProjectId(ctx, legacyProjectId) {
334
+ const directTopic = await resolveDirectLegacyProjectTopic(
335
+ ctx,
336
+ legacyProjectId
337
+ );
338
+ if (directTopic) {
339
+ return await buildTopicScope(ctx, directTopic, "topic_inferred", {
340
+ fallbackProjectId: legacyProjectId
341
+ });
342
+ }
343
+ const primary = pickPrimaryTopic(
344
+ await findTopicsByScopeAlias(ctx, legacyProjectId)
345
+ );
346
+ if (primary) {
347
+ return await buildTopicScope(ctx, primary, "project_mapped_topic", {
348
+ fallbackProjectId: legacyProjectId
349
+ });
350
+ }
351
+ const nodeScope = await resolveTopicNodeScopeOrNull(ctx, legacyProjectId);
352
+ if (nodeScope) {
353
+ return {
354
+ ...nodeScope,
355
+ projectId: nodeScope.projectId ?? legacyProjectId
356
+ };
357
+ }
358
+ throw new Error(
359
+ `Legacy project scope ${legacyProjectId} has no mapped topic.`
360
+ );
361
+ }
362
+ async function resolveDirectLegacyProjectTopic(ctx, legacyProjectId) {
363
+ const directTopic = await tryReadTopicDoc(ctx, legacyProjectId, {
364
+ failureLog: "[topicScope] Failed to load direct project topic",
365
+ idLogKey: "projectId"
366
+ });
367
+ return directTopic ?? tryResolveHostTopicByLegacyScope(ctx, legacyProjectId);
368
+ }
369
+ async function tryReadTopicDoc(ctx, id, log) {
370
+ try {
371
+ return await ctx.db.get(id);
372
+ } catch (error) {
373
+ debugGraphPrimitiveFallback(log.failureLog, {
374
+ error,
375
+ [log.idLogKey]: id
376
+ });
377
+ return null;
378
+ }
379
+ }
380
+ async function buildTopicScope(ctx, topic, source, options = {}) {
381
+ const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
382
+ const mapped = asMappedProjectId(topic);
383
+ return {
384
+ topicId: topic._id,
385
+ ...mapped || options.fallbackProjectId ? { projectId: mapped ?? options.fallbackProjectId } : {},
386
+ tenantId: inherited.tenantId,
387
+ workspaceId: inherited.workspaceId,
388
+ source
389
+ };
390
+ }
405
391
  var optionalScopeArgs = {
406
392
  projectId: v.optional(v.string()),
407
393
  topicId: v.optional(v.string())
@@ -436,36 +422,125 @@ function nodeMatchesWorkspaceReasoningScope(node, scope) {
436
422
  }
437
423
  return scopeWorkspaceId === nodeWorkspaceId;
438
424
  }
439
-
440
- // src/epistemicBeliefs.helpers.ts
441
425
  v.id("epistemicNodes");
442
426
  var optionalBeliefScopeArgs = optionalScopeArgs;
443
427
  ({
444
428
  tupleContradiction: normalizeTupleContradictionPolicy()
445
429
  });
446
- function throwStructuredMutationError(args) {
447
- const data = {
448
- structuredMutationError: true,
449
- message: args.message,
450
- status: args.status,
451
- code: args.code,
452
- invariantCode: args.invariantCode,
453
- suggestion: args.suggestion,
454
- details: args.details
455
- };
456
- const error = new ConvexError(
457
- data
458
- );
459
- error.status = args.status;
460
- error.code = args.code;
461
- error.invariantCode = args.invariantCode;
462
- error.suggestion = args.suggestion;
463
- error.details = args.details;
464
- throw error;
465
- }
466
430
  function readFiniteNumber(value) {
467
431
  return typeof value === "number" && Number.isFinite(value) ? value : void 0;
468
432
  }
433
+ function isRecord(value) {
434
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
435
+ }
436
+ function readOptionalString(value) {
437
+ return typeof value === "string" && value.trim().length > 0 ? value : void 0;
438
+ }
439
+ function readStringArray(value) {
440
+ if (!Array.isArray(value)) {
441
+ return;
442
+ }
443
+ const strings = value.filter(
444
+ (item) => typeof item === "string" && item.length > 0
445
+ );
446
+ return strings.length === value.length ? strings : void 0;
447
+ }
448
+ function readRecord(value) {
449
+ return isRecord(value) ? value : void 0;
450
+ }
451
+ function readBeliefNodeView(value) {
452
+ if (!isRecord(value)) {
453
+ return null;
454
+ }
455
+ const id = readOptionalString(value._id);
456
+ const nodeType = readOptionalString(value.nodeType);
457
+ if (!(id && nodeType === "belief")) {
458
+ return null;
459
+ }
460
+ const node = {
461
+ _id: id,
462
+ nodeType
463
+ };
464
+ const creationTime = readFiniteNumber(value._creationTime);
465
+ if (creationTime !== void 0) {
466
+ node._creationTime = creationTime;
467
+ }
468
+ const metadata = readRecord(value.metadata);
469
+ if (metadata !== void 0) {
470
+ node.metadata = metadata;
471
+ }
472
+ const opinionA = readFiniteNumber(value.opinion_a);
473
+ if (opinionA !== void 0) {
474
+ node.opinion_a = opinionA;
475
+ }
476
+ const opinionB = readFiniteNumber(value.opinion_b);
477
+ if (opinionB !== void 0) {
478
+ node.opinion_b = opinionB;
479
+ }
480
+ const opinionD = readFiniteNumber(value.opinion_d);
481
+ if (opinionD !== void 0) {
482
+ node.opinion_d = opinionD;
483
+ }
484
+ const opinionU = readFiniteNumber(value.opinion_u);
485
+ if (opinionU !== void 0) {
486
+ node.opinion_u = opinionU;
487
+ }
488
+ const tupleContradicted = typeof value.tupleContradicted === "boolean" ? value.tupleContradicted : void 0;
489
+ if (tupleContradicted !== void 0) {
490
+ node.tupleContradicted = tupleContradicted;
491
+ }
492
+ const stringFields = {
493
+ anonymizationClass: value.anonymizationClass,
494
+ audienceLabel: value.audienceLabel,
495
+ canonicalText: value.canonicalText,
496
+ createdBy: value.createdBy,
497
+ epistemicLayer: value.epistemicLayer,
498
+ exportClass: value.exportClass,
499
+ globalId: value.globalId,
500
+ projectId: value.projectId,
501
+ publicationStatus: value.publicationStatus,
502
+ sensitivityTier: value.sensitivityTier,
503
+ status: value.status,
504
+ tenantId: value.tenantId,
505
+ topicId: value.topicId,
506
+ userId: value.userId,
507
+ workspaceId: value.workspaceId
508
+ };
509
+ for (const [field, fieldValue] of Object.entries(stringFields)) {
510
+ const normalized = readOptionalString(fieldValue);
511
+ if (normalized !== void 0) {
512
+ node[field] = normalized;
513
+ }
514
+ }
515
+ const createdAt = readFiniteNumber(value.createdAt);
516
+ if (createdAt !== void 0) {
517
+ node.createdAt = createdAt;
518
+ }
519
+ const updatedAt = readFiniteNumber(value.updatedAt);
520
+ if (updatedAt !== void 0) {
521
+ node.updatedAt = updatedAt;
522
+ }
523
+ if (value.beliefStatus !== void 0) {
524
+ node.beliefStatus = value.beliefStatus;
525
+ }
526
+ if (value.confidence !== void 0) {
527
+ node.confidence = value.confidence;
528
+ }
529
+ if (value.predictionMeta !== void 0) {
530
+ node.predictionMeta = value.predictionMeta;
531
+ }
532
+ const policyTags = readStringArray(value.policyTags);
533
+ if (policyTags !== void 0) {
534
+ node.policyTags = policyTags;
535
+ }
536
+ return node;
537
+ }
538
+ function readBeliefNodeViews(values) {
539
+ return values.flatMap((value) => {
540
+ const node = readBeliefNodeView(value);
541
+ return node ? [node] : [];
542
+ });
543
+ }
469
544
  function clamp01(value) {
470
545
  return Math.max(0, Math.min(1, value));
471
546
  }
@@ -532,7 +607,7 @@ function deriveSyntheticBackfillOpinion(source) {
532
607
  return mkOpinion(confidence, 1 - confidence, 0, 0.5);
533
608
  }
534
609
  async function resolveBeliefScopeOrNull(ctx, args) {
535
- if (!args.projectId && !args.topicId) {
610
+ if (!(args.projectId || args.topicId)) {
536
611
  return null;
537
612
  }
538
613
  try {
@@ -557,7 +632,8 @@ async function getBeliefNodesForScope(ctx, scope, args) {
557
632
  "by_topic_type",
558
633
  (q) => q.eq("topicId", scope.topicId).eq("nodeType", "belief")
559
634
  );
560
- const nodes = await baseQuery.collect();
635
+ const rows = await baseQuery.collect();
636
+ const nodes = readBeliefNodeViews(rows);
561
637
  const scopedNodes = nodes.filter(
562
638
  (node) => nodeMatchesWorkspaceReasoningScope(node, scope)
563
639
  );
@@ -575,6 +651,340 @@ function resolveBeliefStatus(node, metadata) {
575
651
  }
576
652
 
577
653
  // src/epistemicBeliefs.backfills.ts
654
+ function epistemicNodeId(value) {
655
+ return value;
656
+ }
657
+ function topicId(value) {
658
+ return value;
659
+ }
660
+ function isRecord2(value) {
661
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
662
+ }
663
+ function readConvexId(value) {
664
+ return typeof value === "string" && value.trim().length > 0 ? value : void 0;
665
+ }
666
+ function readOptionalNumber(value) {
667
+ return readFiniteNumber(value);
668
+ }
669
+ function readOptionalString2(value) {
670
+ return typeof value === "string" && value.trim().length > 0 ? value : void 0;
671
+ }
672
+ function readRecord2(value) {
673
+ if (value === null) {
674
+ return null;
675
+ }
676
+ return isRecord2(value) ? value : void 0;
677
+ }
678
+ function readEpistemicNodeBackfillRow(value) {
679
+ if (!isRecord2(value)) {
680
+ return null;
681
+ }
682
+ const id = readConvexId(value._id);
683
+ if (!id) {
684
+ return null;
685
+ }
686
+ const row = { ...value, _id: id };
687
+ const canonicalText = readOptionalString2(value.canonicalText);
688
+ const createdAt = readOptionalNumber(value.createdAt);
689
+ const confidence = readOptionalNumber(value.confidence);
690
+ const globalId = readOptionalString2(value.globalId);
691
+ const metadata = readRecord2(value.metadata);
692
+ const nodeType = readOptionalString2(value.nodeType);
693
+ const projectId = readOptionalString2(value.projectId);
694
+ const status = readOptionalString2(value.status);
695
+ const title = readOptionalString2(value.title);
696
+ const topicIdValue = readOptionalString2(value.topicId);
697
+ const updatedAt = readOptionalNumber(value.updatedAt);
698
+ if (canonicalText !== void 0) {
699
+ row.canonicalText = canonicalText;
700
+ }
701
+ if (createdAt !== void 0) {
702
+ row.createdAt = createdAt;
703
+ }
704
+ if (confidence !== void 0) {
705
+ row.confidence = confidence;
706
+ }
707
+ if (globalId !== void 0) {
708
+ row.globalId = globalId;
709
+ }
710
+ if (metadata !== void 0) {
711
+ row.metadata = metadata;
712
+ }
713
+ if (nodeType !== void 0) {
714
+ row.nodeType = nodeType;
715
+ }
716
+ if (projectId !== void 0) {
717
+ row.projectId = projectId;
718
+ }
719
+ if (status !== void 0) {
720
+ row.status = status;
721
+ }
722
+ if (title !== void 0) {
723
+ row.title = title;
724
+ }
725
+ if (topicIdValue !== void 0) {
726
+ row.topicId = topicIdValue;
727
+ }
728
+ if (updatedAt !== void 0) {
729
+ row.updatedAt = updatedAt;
730
+ }
731
+ return row;
732
+ }
733
+ function readBeliefConfidenceBackfillRow(value) {
734
+ if (!isRecord2(value)) {
735
+ return null;
736
+ }
737
+ const id = readConvexId(value._id);
738
+ const assessedAt = readOptionalNumber(value.assessedAt);
739
+ const assessedBy = readOptionalString2(value.assessedBy);
740
+ const beliefId = readOptionalString2(value.beliefId);
741
+ const confidence = readOptionalNumber(value.confidence);
742
+ const trigger = readOptionalString2(value.trigger);
743
+ if (!(id && assessedAt !== void 0 && assessedBy && beliefId && trigger)) {
744
+ return null;
745
+ }
746
+ const row = {
747
+ ...value,
748
+ _id: id,
749
+ assessedAt,
750
+ assessedBy,
751
+ beliefId,
752
+ confidence: confidence ?? 0.5,
753
+ trigger
754
+ };
755
+ const baseRate = readOptionalNumber(value.baseRate);
756
+ const belief = readOptionalNumber(value.belief);
757
+ const certainty = readOptionalNumber(value.certainty);
758
+ const disbelief = readOptionalNumber(value.disbelief);
759
+ const uncertainty = readOptionalNumber(value.uncertainty);
760
+ const valence = readOptionalNumber(value.valence);
761
+ if (baseRate !== void 0) {
762
+ row.baseRate = baseRate;
763
+ }
764
+ if (belief !== void 0) {
765
+ row.belief = belief;
766
+ }
767
+ if (certainty !== void 0) {
768
+ row.certainty = certainty;
769
+ }
770
+ if (disbelief !== void 0) {
771
+ row.disbelief = disbelief;
772
+ }
773
+ if (uncertainty !== void 0) {
774
+ row.uncertainty = uncertainty;
775
+ }
776
+ if (valence !== void 0) {
777
+ row.valence = valence;
778
+ }
779
+ return row;
780
+ }
781
+ function readEpistemicEdgeBackfillRow(value) {
782
+ if (!isRecord2(value)) {
783
+ return null;
784
+ }
785
+ const id = readConvexId(value._id);
786
+ if (!id) {
787
+ return null;
788
+ }
789
+ const row = { ...value, _id: id };
790
+ const fromNodeId = readOptionalString2(value.fromNodeId);
791
+ const globalId = readOptionalString2(value.globalId);
792
+ const toNodeId = readOptionalString2(value.toNodeId);
793
+ if (fromNodeId !== void 0) {
794
+ row.fromNodeId = fromNodeId;
795
+ }
796
+ if (globalId !== void 0) {
797
+ row.globalId = globalId;
798
+ }
799
+ if (toNodeId !== void 0) {
800
+ row.toNodeId = toNodeId;
801
+ }
802
+ return row;
803
+ }
804
+ function readRowList(values, reader) {
805
+ return values.flatMap((value) => {
806
+ const row = reader(value);
807
+ return row ? [row] : [];
808
+ });
809
+ }
810
+ function hasLegacyOpinionSnapshot(node) {
811
+ return readFiniteNumber(node.opinion_b) !== void 0 || readFiniteNumber(node.opinion_d) !== void 0 || readFiniteNumber(node.opinion_u) !== void 0 || readFiniteNumber(node.opinion_a) !== void 0 || readFiniteNumber(node.confidence) !== void 0;
812
+ }
813
+ function buildSubjectiveOpinionPatch(node, defaultBaseRate) {
814
+ return {
815
+ belief: readFiniteNumber(node.opinion_b) ?? 0,
816
+ disbelief: readFiniteNumber(node.opinion_d) ?? 0,
817
+ uncertainty: readFiniteNumber(node.opinion_u) ?? 1,
818
+ baseRate: readFiniteNumber(node.opinion_a) ?? defaultBaseRate
819
+ };
820
+ }
821
+ function needsSubjectiveOpinionPatch(node) {
822
+ return readFiniteNumber(node.opinion_b) === void 0 || readFiniteNumber(node.opinion_d) === void 0 || readFiniteNumber(node.opinion_u) === void 0 || readFiniteNumber(node.opinion_a) === void 0;
823
+ }
824
+ function buildSubjectiveOpinionNodePatch(opinion) {
825
+ return {
826
+ opinion_b: opinion.belief,
827
+ opinion_d: opinion.disbelief,
828
+ opinion_u: opinion.uncertainty,
829
+ opinion_a: opinion.baseRate,
830
+ updatedAt: Date.now()
831
+ };
832
+ }
833
+ function buildBaseRateHistoryPatch(row, defaultBaseRate) {
834
+ const belief = readFiniteNumber(row.belief) ?? 0;
835
+ const disbelief = readFiniteNumber(row.disbelief) ?? 0;
836
+ const uncertainty = readFiniteNumber(row.uncertainty) ?? 1;
837
+ return {
838
+ baseRate: defaultBaseRate,
839
+ confidence: confidenceFromSL(
840
+ belief,
841
+ disbelief,
842
+ uncertainty,
843
+ defaultBaseRate
844
+ )
845
+ };
846
+ }
847
+ function buildMandatoryPriorAuditRow(args) {
848
+ return {
849
+ entityType: "belief",
850
+ entityId: args.beliefId,
851
+ changeType: "updated",
852
+ changedAt: Date.now(),
853
+ changedBy: "system:lkc-2-prior-backfill",
854
+ isAgent: false,
855
+ previousState: null,
856
+ newState: {
857
+ baseRateBackfilled: true,
858
+ baseRate: args.defaultBaseRate,
859
+ patchedNodeOpinion: args.needsNodePatch,
860
+ patchedHistoryRows: args.rowsMissingBaseRate,
861
+ insertedInitialOpinion: args.insertedInitialRow
862
+ },
863
+ projectId: args.node.projectId,
864
+ topicId: args.node.topicId
865
+ };
866
+ }
867
+ async function backfillMandatoryPriorNode(ctx, args) {
868
+ const beliefId = String(args.node._id);
869
+ const patchedOpinion = buildSubjectiveOpinionPatch(
870
+ args.node,
871
+ args.defaultBaseRate
872
+ );
873
+ const needsNodePatch = needsSubjectiveOpinionPatch(args.node);
874
+ const rowsMissingBaseRate = args.history.filter(
875
+ (row) => readFiniteNumber(row.baseRate) === void 0
876
+ );
877
+ const needsInitialRow = args.history.length === 0;
878
+ if (!needsNodePatch && rowsMissingBaseRate.length === 0 && !needsInitialRow) {
879
+ return {
880
+ auditEntries: 0,
881
+ insertedInitialRows: 0,
882
+ patchedHistoryRows: 0,
883
+ patchedNodes: 0,
884
+ touched: false
885
+ };
886
+ }
887
+ if (needsNodePatch) {
888
+ await ctx.db.patch(
889
+ args.node._id,
890
+ buildSubjectiveOpinionNodePatch(patchedOpinion)
891
+ );
892
+ }
893
+ for (const row of rowsMissingBaseRate) {
894
+ await ctx.db.patch(
895
+ row._id,
896
+ buildBaseRateHistoryPatch(row, args.defaultBaseRate)
897
+ );
898
+ }
899
+ if (needsInitialRow) {
900
+ await ctx.db.insert(
901
+ "beliefConfidence",
902
+ buildBeliefConfidenceRow({
903
+ beliefId: args.node._id,
904
+ belief: patchedOpinion.belief,
905
+ disbelief: patchedOpinion.disbelief,
906
+ uncertainty: patchedOpinion.uncertainty,
907
+ baseRate: patchedOpinion.baseRate,
908
+ trigger: "initial",
909
+ rationale: "LKC-2 backfill: inserted missing initial vacuous opinion with neutral prior.",
910
+ assessedAt: readFiniteNumber(args.node.createdAt) ?? readFiniteNumber(args.node.updatedAt) ?? Date.now(),
911
+ assessedBy: "system:lkc-2-prior-backfill",
912
+ slOperator: "prior_seed"
913
+ })
914
+ );
915
+ }
916
+ await ctx.db.insert(
917
+ "epistemicAudit",
918
+ buildMandatoryPriorAuditRow({
919
+ beliefId,
920
+ defaultBaseRate: args.defaultBaseRate,
921
+ insertedInitialRow: needsInitialRow,
922
+ needsNodePatch,
923
+ node: args.node,
924
+ rowsMissingBaseRate: rowsMissingBaseRate.length
925
+ })
926
+ );
927
+ return {
928
+ auditEntries: 1,
929
+ insertedInitialRows: needsInitialRow ? 1 : 0,
930
+ patchedHistoryRows: rowsMissingBaseRate.length,
931
+ patchedNodes: needsNodePatch ? 1 : 0,
932
+ touched: true
933
+ };
934
+ }
935
+ async function collectConnectedNodeIds(ctx, beliefId) {
936
+ const [rawOutbound, rawInbound] = await Promise.all([
937
+ ctx.db.query("epistemicEdges").withIndex("by_from", (q) => q.eq("fromNodeId", beliefId)).collect(),
938
+ ctx.db.query("epistemicEdges").withIndex("by_to", (q) => q.eq("toNodeId", beliefId)).collect()
939
+ ]);
940
+ const outbound = readRowList(rawOutbound, readEpistemicEdgeBackfillRow);
941
+ const inbound = readRowList(rawInbound, readEpistemicEdgeBackfillRow);
942
+ const connectedNodeIds = /* @__PURE__ */ new Set();
943
+ for (const edge of outbound) {
944
+ if (edge.toNodeId) {
945
+ connectedNodeIds.add(String(edge.toNodeId));
946
+ }
947
+ }
948
+ for (const edge of inbound) {
949
+ if (edge.fromNodeId) {
950
+ connectedNodeIds.add(String(edge.fromNodeId));
951
+ }
952
+ }
953
+ return connectedNodeIds;
954
+ }
955
+ async function reassignConnectedBeliefNeighbors(ctx, args) {
956
+ let connectedReassigned = 0;
957
+ for (const connectedId of args.connectedNodeIds) {
958
+ if (args.movedBeliefIds.has(connectedId) || args.alreadyReassigned.has(connectedId)) {
959
+ continue;
960
+ }
961
+ try {
962
+ const connectedNode = readEpistemicNodeBackfillRow(
963
+ await ctx.db.get(epistemicNodeId(connectedId))
964
+ );
965
+ if (connectedNode?.status !== "active") {
966
+ continue;
967
+ }
968
+ if (connectedNode.topicId && String(connectedNode.topicId) !== String(args.targetTopicId)) {
969
+ await ctx.db.patch(epistemicNodeId(connectedId), {
970
+ topicId: args.targetTopicId,
971
+ updatedAt: args.now
972
+ });
973
+ args.alreadyReassigned.add(connectedId);
974
+ connectedReassigned++;
975
+ }
976
+ } catch (error) {
977
+ debugGraphPrimitiveFallback(
978
+ "[epistemicBeliefs] Failed to reassign connected node",
979
+ {
980
+ error,
981
+ connectedId
982
+ }
983
+ );
984
+ }
985
+ }
986
+ return connectedReassigned;
987
+ }
578
988
  var getRecentConfidenceChanges = query({
579
989
  args: {
580
990
  ...optionalBeliefScopeArgs,
@@ -590,27 +1000,33 @@ var getRecentConfidenceChanges = query({
590
1000
  return [];
591
1001
  }
592
1002
  const scopeId = scope.topicId ? String(scope.topicId) : scope.projectId;
593
- if (!scopeId || !await checkScopeAccess(ctx, scopeId, args.userId)) {
1003
+ if (!(scopeId && await checkScopeAccess(ctx, scopeId, args.userId))) {
594
1004
  return [];
595
1005
  }
596
- const projectBeliefs = await getBeliefNodesForScope(ctx, scope);
1006
+ const projectBeliefs = readRowList(
1007
+ await getBeliefNodesForScope(ctx, scope),
1008
+ readEpistemicNodeBackfillRow
1009
+ );
597
1010
  if (projectBeliefs.length === 0) {
598
1011
  return [];
599
1012
  }
600
1013
  const beliefMap = /* @__PURE__ */ new Map();
601
1014
  for (const belief of projectBeliefs) {
602
1015
  const info = {
603
- id: belief._id,
1016
+ id: String(belief._id),
604
1017
  title: belief.canonicalText || belief.title || "Untitled belief",
605
1018
  currentConfidence: belief.confidence ?? 0.5
606
1019
  };
607
- beliefMap.set(belief._id, info);
1020
+ beliefMap.set(String(belief._id), info);
608
1021
  }
609
- const recentConfidence = await ctx.db.query("beliefConfidence").order("desc").filter((q) => q.gt(q.field("assessedAt"), sevenDaysAgo)).take(200);
1022
+ const recentConfidence = readRowList(
1023
+ await ctx.db.query("beliefConfidence").order("desc").filter((q) => q.gt(q.field("assessedAt"), sevenDaysAgo)).take(200),
1024
+ readBeliefConfidenceBackfillRow
1025
+ );
610
1026
  const changes = [];
611
1027
  const seenBeliefs = /* @__PURE__ */ new Set();
612
1028
  for (const entry of recentConfidence) {
613
- const beliefInfo = beliefMap.get(entry.beliefId);
1029
+ const beliefInfo = beliefMap.get(String(entry.beliefId));
614
1030
  if (!beliefInfo) {
615
1031
  continue;
616
1032
  }
@@ -618,7 +1034,10 @@ var getRecentConfidenceChanges = query({
618
1034
  continue;
619
1035
  }
620
1036
  seenBeliefs.add(beliefInfo.id);
621
- const previousEntries = await ctx.db.query("beliefConfidence").withIndex("by_beliefId", (q) => q.eq("beliefId", entry.beliefId)).order("desc").filter((q) => q.lt(q.field("assessedAt"), entry.assessedAt)).take(1);
1037
+ const previousEntries = readRowList(
1038
+ await ctx.db.query("beliefConfidence").withIndex("by_beliefId", (q) => q.eq("beliefId", entry.beliefId)).order("desc").filter((q) => q.lt(q.field("assessedAt"), entry.assessedAt)).take(1),
1039
+ readBeliefConfidenceBackfillRow
1040
+ );
622
1041
  const previousConfidence = previousEntries[0]?.confidence ?? 0.5;
623
1042
  const delta = entry.confidence - previousConfidence;
624
1043
  if (Math.abs(delta) < 0.05) {
@@ -646,10 +1065,14 @@ var backfillSyntheticOpinionHistory = internalMutation({
646
1065
  returns: permissiveReturn,
647
1066
  handler: async (ctx, args) => {
648
1067
  const limit = Math.max(1, Math.min(args.limit ?? 100, 100));
649
- const [beliefNodes, existingHistory] = await Promise.all([
650
- ctx.db.query("epistemicNodes").withIndex("by_nodeType", (q) => q.eq("nodeType", "belief")).collect(),
651
- ctx.db.query("beliefConfidence").collect()
652
- ]);
1068
+ const beliefNodes = readRowList(
1069
+ await ctx.db.query("epistemicNodes").withIndex("by_nodeType", (q) => q.eq("nodeType", "belief")).collect(),
1070
+ readEpistemicNodeBackfillRow
1071
+ );
1072
+ const existingHistory = readRowList(
1073
+ await ctx.db.query("beliefConfidence").collect(),
1074
+ readBeliefConfidenceBackfillRow
1075
+ );
653
1076
  const beliefsWithHistory = new Set(
654
1077
  existingHistory.map((entry) => String(entry.beliefId))
655
1078
  );
@@ -660,8 +1083,7 @@ var backfillSyntheticOpinionHistory = internalMutation({
660
1083
  if (inserted >= limit) {
661
1084
  break;
662
1085
  }
663
- const hasOpinionSnapshot = readFiniteNumber(node.opinion_b) !== void 0 || readFiniteNumber(node.opinion_d) !== void 0 || readFiniteNumber(node.opinion_u) !== void 0 || readFiniteNumber(node.opinion_a) !== void 0 || readFiniteNumber(node.confidence) !== void 0;
664
- if (!hasOpinionSnapshot) {
1086
+ if (!hasLegacyOpinionSnapshot(node)) {
665
1087
  skippedNoOpinion++;
666
1088
  continue;
667
1089
  }
@@ -669,9 +1091,7 @@ var backfillSyntheticOpinionHistory = internalMutation({
669
1091
  skippedHasHistory++;
670
1092
  continue;
671
1093
  }
672
- const opinion = deriveSyntheticBackfillOpinion(
673
- node
674
- );
1094
+ const opinion = deriveSyntheticBackfillOpinion(node);
675
1095
  await ctx.db.insert(
676
1096
  "beliefConfidence",
677
1097
  buildBeliefConfidenceRow({
@@ -690,10 +1110,9 @@ var backfillSyntheticOpinionHistory = internalMutation({
690
1110
  beliefsWithHistory.add(String(node._id));
691
1111
  inserted++;
692
1112
  }
693
- const remainingCandidates = beliefNodes.filter((node) => {
694
- const hasOpinionSnapshot = readFiniteNumber(node.opinion_b) !== void 0 || readFiniteNumber(node.opinion_d) !== void 0 || readFiniteNumber(node.opinion_u) !== void 0 || readFiniteNumber(node.opinion_a) !== void 0 || readFiniteNumber(node.confidence) !== void 0;
695
- return hasOpinionSnapshot && !beliefsWithHistory.has(String(node._id));
696
- }).length;
1113
+ const remainingCandidates = beliefNodes.filter(
1114
+ (node) => hasLegacyOpinionSnapshot(node) && !beliefsWithHistory.has(String(node._id))
1115
+ ).length;
697
1116
  return {
698
1117
  scanned: beliefNodes.length,
699
1118
  inserted,
@@ -716,10 +1135,14 @@ var backfillMandatoryPriors = internalMutation({
716
1135
  args.defaultBaseRate ?? 0.5,
717
1136
  "defaultBaseRate"
718
1137
  );
719
- const [beliefNodes, historyRows] = await Promise.all([
720
- ctx.db.query("epistemicNodes").withIndex("by_nodeType", (q) => q.eq("nodeType", "belief")).collect(),
721
- ctx.db.query("beliefConfidence").collect()
722
- ]);
1138
+ const beliefNodes = readRowList(
1139
+ await ctx.db.query("epistemicNodes").withIndex("by_nodeType", (q) => q.eq("nodeType", "belief")).collect(),
1140
+ readEpistemicNodeBackfillRow
1141
+ );
1142
+ const historyRows = readRowList(
1143
+ await ctx.db.query("beliefConfidence").collect(),
1144
+ readBeliefConfidenceBackfillRow
1145
+ );
723
1146
  const historyByBeliefId = /* @__PURE__ */ new Map();
724
1147
  for (const row of historyRows) {
725
1148
  const beliefId = String(row.beliefId);
@@ -738,82 +1161,18 @@ var backfillMandatoryPriors = internalMutation({
738
1161
  }
739
1162
  const beliefId = String(node._id);
740
1163
  const history = historyByBeliefId.get(beliefId) ?? [];
741
- const patchedOpinion = {
742
- belief: readFiniteNumber(node.opinion_b) ?? 0,
743
- disbelief: readFiniteNumber(node.opinion_d) ?? 0,
744
- uncertainty: readFiniteNumber(node.opinion_u) ?? 1,
745
- baseRate: readFiniteNumber(node.opinion_a) ?? defaultBaseRate
746
- };
747
- const needsNodePatch = readFiniteNumber(node.opinion_b) === void 0 || readFiniteNumber(node.opinion_d) === void 0 || readFiniteNumber(node.opinion_u) === void 0 || readFiniteNumber(node.opinion_a) === void 0;
748
- const rowsMissingBaseRate = history.filter(
749
- (row) => readFiniteNumber(row.baseRate) === void 0
750
- );
751
- const needsInitialRow = history.length === 0;
752
- if (!needsNodePatch && rowsMissingBaseRate.length === 0 && !needsInitialRow) {
1164
+ const result = await backfillMandatoryPriorNode(ctx, {
1165
+ defaultBaseRate,
1166
+ history,
1167
+ node
1168
+ });
1169
+ if (!result.touched) {
753
1170
  continue;
754
1171
  }
755
- if (needsNodePatch) {
756
- await ctx.db.patch(node._id, {
757
- opinion_b: patchedOpinion.belief,
758
- opinion_d: patchedOpinion.disbelief,
759
- opinion_u: patchedOpinion.uncertainty,
760
- opinion_a: patchedOpinion.baseRate,
761
- updatedAt: Date.now()
762
- });
763
- patchedNodes++;
764
- }
765
- for (const row of rowsMissingBaseRate) {
766
- const belief = readFiniteNumber(row.belief) ?? 0;
767
- const disbelief = readFiniteNumber(row.disbelief) ?? 0;
768
- const uncertainty = readFiniteNumber(row.uncertainty) ?? 1;
769
- await ctx.db.patch(row._id, {
770
- baseRate: defaultBaseRate,
771
- confidence: confidenceFromSL(
772
- belief,
773
- disbelief,
774
- uncertainty,
775
- defaultBaseRate
776
- )
777
- });
778
- patchedHistoryRows++;
779
- }
780
- if (needsInitialRow) {
781
- await ctx.db.insert(
782
- "beliefConfidence",
783
- buildBeliefConfidenceRow({
784
- beliefId: node._id,
785
- belief: patchedOpinion.belief,
786
- disbelief: patchedOpinion.disbelief,
787
- uncertainty: patchedOpinion.uncertainty,
788
- baseRate: patchedOpinion.baseRate,
789
- trigger: "initial",
790
- rationale: "LKC-2 backfill: inserted missing initial vacuous opinion with neutral prior.",
791
- assessedAt: readFiniteNumber(node.createdAt) ?? readFiniteNumber(node.updatedAt) ?? Date.now(),
792
- assessedBy: "system:lkc-2-prior-backfill",
793
- slOperator: "prior_seed"
794
- })
795
- );
796
- insertedInitialRows++;
797
- }
798
- await ctx.db.insert("epistemicAudit", {
799
- entityType: "belief",
800
- entityId: beliefId,
801
- changeType: "updated",
802
- changedAt: Date.now(),
803
- changedBy: "system:lkc-2-prior-backfill",
804
- isAgent: false,
805
- previousState: null,
806
- newState: {
807
- baseRateBackfilled: true,
808
- baseRate: defaultBaseRate,
809
- patchedNodeOpinion: needsNodePatch,
810
- patchedHistoryRows: rowsMissingBaseRate.length,
811
- insertedInitialOpinion: needsInitialRow
812
- },
813
- projectId: node.projectId,
814
- topicId: typeof node.topicId === "string" ? node.topicId : void 0
815
- });
816
- auditEntries++;
1172
+ patchedNodes += result.patchedNodes;
1173
+ patchedHistoryRows += result.patchedHistoryRows;
1174
+ insertedInitialRows += result.insertedInitialRows;
1175
+ auditEntries += result.auditEntries;
817
1176
  touched++;
818
1177
  }
819
1178
  return {
@@ -833,7 +1192,10 @@ var backfillTwoAxisConfidence = internalMutation({
833
1192
  returns: permissiveReturn,
834
1193
  handler: async (ctx, args) => {
835
1194
  const dryRun = args.dryRun ?? false;
836
- const allConfRecords = await ctx.db.query("beliefConfidence").collect();
1195
+ const allConfRecords = readRowList(
1196
+ await ctx.db.query("beliefConfidence").collect(),
1197
+ readBeliefConfidenceBackfillRow
1198
+ );
837
1199
  let confUpdated = 0;
838
1200
  let confSkipped = 0;
839
1201
  for (const record of allConfRecords) {
@@ -849,11 +1211,14 @@ var backfillTwoAxisConfidence = internalMutation({
849
1211
  }
850
1212
  confUpdated++;
851
1213
  }
852
- const allBeliefNodes = await ctx.db.query("epistemicNodes").filter((q) => q.eq(q.field("nodeType"), "belief")).collect();
1214
+ const allBeliefNodes = readRowList(
1215
+ await ctx.db.query("epistemicNodes").filter((q) => q.eq(q.field("nodeType"), "belief")).collect(),
1216
+ readEpistemicNodeBackfillRow
1217
+ );
853
1218
  let nodesUpdated = 0;
854
1219
  let nodesSkipped = 0;
855
1220
  for (const node of allBeliefNodes) {
856
- const meta = node.metadata || {};
1221
+ const meta = node.metadata ?? {};
857
1222
  if (meta.valence !== void 0 && meta.certainty !== void 0) {
858
1223
  nodesSkipped++;
859
1224
  continue;
@@ -891,19 +1256,29 @@ var backfillScoredBeliefEdges = internalMutation({
891
1256
  returns: permissiveReturn,
892
1257
  handler: async (ctx, args) => {
893
1258
  const dryRun = args.dryRun ?? false;
894
- const allBeliefs = await ctx.db.query("epistemicNodes").withIndex(
895
- "by_topic",
896
- (q) => q.eq("topicId", args.topicId || args.projectId)
897
- ).filter((q) => q.eq(q.field("nodeType"), "belief")).collect();
1259
+ const scopeTopicId = args.topicId ?? args.projectId;
1260
+ if (!scopeTopicId) {
1261
+ return {
1262
+ dryRun,
1263
+ scoredBeliefs: 0,
1264
+ themeNodes: 0,
1265
+ edgesCreated: 0,
1266
+ edgesSkipped: 0
1267
+ };
1268
+ }
1269
+ const allBeliefs = readRowList(
1270
+ await ctx.db.query("epistemicNodes").withIndex("by_topic", (q) => q.eq("topicId", scopeTopicId)).filter((q) => q.eq(q.field("nodeType"), "belief")).collect(),
1271
+ readEpistemicNodeBackfillRow
1272
+ );
898
1273
  const scoredBeliefs = allBeliefs.filter((belief) => {
899
- const metadata = belief.metadata || {};
1274
+ const metadata = belief.metadata ?? {};
900
1275
  const lifecycle = resolveBeliefStatus(belief, metadata);
901
1276
  return lifecycle === "active" || lifecycle === "resolved_true";
902
1277
  });
903
- const themeNodes = await ctx.db.query("epistemicNodes").withIndex(
904
- "by_topic",
905
- (q) => q.eq("topicId", args.topicId || args.projectId)
906
- ).filter((q) => q.eq(q.field("nodeType"), "theme")).collect();
1278
+ const themeNodes = readRowList(
1279
+ await ctx.db.query("epistemicNodes").withIndex("by_topic", (q) => q.eq("topicId", scopeTopicId)).filter((q) => q.eq(q.field("nodeType"), "theme")).collect(),
1280
+ readEpistemicNodeBackfillRow
1281
+ );
907
1282
  let created = 0;
908
1283
  let skipped = 0;
909
1284
  for (const belief of scoredBeliefs) {
@@ -929,7 +1304,7 @@ var backfillScoredBeliefEdges = internalMutation({
929
1304
  edgeType: "relates_to_thesis",
930
1305
  weight: belief.confidence ?? 0.5,
931
1306
  createdBy: "backfill:scored_belief_theme",
932
- topicId: String(args.projectId),
1307
+ topicId: String(scopeTopicId),
933
1308
  fromNodeType: "belief",
934
1309
  toNodeType: "theme",
935
1310
  fromLayer: "L3",
@@ -954,16 +1329,14 @@ var backfillBeliefSprintIds = internalMutation({
954
1329
  dryRun: v.optional(v.boolean())
955
1330
  },
956
1331
  returns: permissiveReturn,
957
- handler: async (_ctx, _args) => {
958
- return {
959
- dryRun: true,
960
- message: "backfillBeliefSprintIds removed \u2014 sprints are D-tier legacy. Use worktrees.",
961
- sprintsScanned: 0,
962
- beliefsWithSprints: 0,
963
- updated: 0,
964
- skipped: 0
965
- };
966
- }
1332
+ handler: async (_ctx, _args) => ({
1333
+ dryRun: true,
1334
+ message: "backfillBeliefSprintIds removed \u2014 sprints are D-tier legacy. Use worktrees.",
1335
+ sprintsScanned: 0,
1336
+ beliefsWithSprints: 0,
1337
+ updated: 0,
1338
+ skipped: 0
1339
+ })
967
1340
  });
968
1341
  var getBeliefClusterPositions = query({
969
1342
  args: {
@@ -973,7 +1346,7 @@ var getBeliefClusterPositions = query({
973
1346
  returns: permissiveReturn,
974
1347
  handler: async (ctx, args) => {
975
1348
  const scope = await resolveBeliefScopeOrNull(ctx, args);
976
- if (!scope || !scope.projectId) {
1349
+ if (!scope?.projectId) {
977
1350
  return {
978
1351
  positions: {},
979
1352
  hasClusters: false,
@@ -1021,7 +1394,7 @@ var reassignBeliefsTopic = mutation({
1021
1394
  },
1022
1395
  returns: permissiveReturn,
1023
1396
  handler: async (ctx, args) => {
1024
- const targetTopic = await ctx.db.get(args.targetTopicId);
1397
+ const targetTopic = await ctx.db.get(topicId(args.targetTopicId));
1025
1398
  if (!targetTopic) {
1026
1399
  throw new Error(`Target topic not found: ${args.targetTopicId}`);
1027
1400
  }
@@ -1030,8 +1403,8 @@ var reassignBeliefsTopic = mutation({
1030
1403
  const now = Date.now();
1031
1404
  const movedBeliefIds = /* @__PURE__ */ new Set();
1032
1405
  for (const beliefNodeId of args.beliefNodeIds) {
1033
- const node = await ctx.db.get(beliefNodeId);
1034
- if (!node || node.nodeType !== "belief") {
1406
+ const node = readEpistemicNodeBackfillRow(await ctx.db.get(beliefNodeId));
1407
+ if (node?.nodeType !== "belief") {
1035
1408
  skipped++;
1036
1409
  continue;
1037
1410
  }
@@ -1045,40 +1418,14 @@ var reassignBeliefsTopic = mutation({
1045
1418
  let connectedReassigned = 0;
1046
1419
  const alreadyReassigned = /* @__PURE__ */ new Set();
1047
1420
  for (const beliefId of movedBeliefIds) {
1048
- const outbound = await ctx.db.query("epistemicEdges").withIndex("by_from", (q) => q.eq("fromNodeId", beliefId)).collect();
1049
- const inbound = await ctx.db.query("epistemicEdges").withIndex("by_to", (q) => q.eq("toNodeId", beliefId)).collect();
1050
- const connectedNodeIds = /* @__PURE__ */ new Set();
1051
- for (const edge of outbound) {
1052
- if (edge.toNodeId) connectedNodeIds.add(String(edge.toNodeId));
1053
- }
1054
- for (const edge of inbound) {
1055
- if (edge.fromNodeId) connectedNodeIds.add(String(edge.fromNodeId));
1056
- }
1057
- for (const connectedId of connectedNodeIds) {
1058
- if (movedBeliefIds.has(connectedId) || alreadyReassigned.has(connectedId)) {
1059
- continue;
1060
- }
1061
- try {
1062
- const connectedNode = await ctx.db.get(connectedId);
1063
- if (!connectedNode || connectedNode.status !== "active") continue;
1064
- if (connectedNode.topicId && String(connectedNode.topicId) !== String(args.targetTopicId)) {
1065
- await ctx.db.patch(connectedId, {
1066
- topicId: args.targetTopicId,
1067
- updatedAt: now
1068
- });
1069
- alreadyReassigned.add(connectedId);
1070
- connectedReassigned++;
1071
- }
1072
- } catch (error) {
1073
- debugGraphPrimitiveFallback(
1074
- "[epistemicBeliefs] Failed to reassign connected node",
1075
- {
1076
- error,
1077
- connectedId
1078
- }
1079
- );
1080
- }
1081
- }
1421
+ const connectedNodeIds = await collectConnectedNodeIds(ctx, beliefId);
1422
+ connectedReassigned += await reassignConnectedBeliefNeighbors(ctx, {
1423
+ alreadyReassigned,
1424
+ connectedNodeIds,
1425
+ movedBeliefIds,
1426
+ now,
1427
+ targetTopicId: args.targetTopicId
1428
+ });
1082
1429
  }
1083
1430
  return { reassigned, skipped, connectedReassigned };
1084
1431
  }