@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,14 +1,37 @@
1
- import { v, ConvexError } from 'convex/values';
2
- import { normalizeTupleContradictionPolicy, mkOpinion, conditionalDeduction, project, dampedDependencyCascade, hasProjectedOpinionChanged, confidenceFromSL, detectTupleContradiction, evaluateTupleContradictionTransition, deriveContractModulationPlan, deriveContractStatus, trustDiscount, applyNegativeSupport, cumulativeFusion, applyNegativeEvidence, readOpinionFromRecord, parseEvidentialEvaluatorConfig, compareMetricValue, buildEvidentialRationale, parseMetricCheckerConfig, getEvaluatorInputRecord, pickFiniteNumber, resolveComparisonResult, buildComparisonRationale, parseReferenceCheckCounterConfig, parseTemporalDeadlineConfig, parseMarketIndexComparatorConfig, createInheritedContractRecord } from '@lucern/confidence';
3
- import { checkProjectAccess } from '@lucern/access-control/access';
1
+ import { unsafeConvexAnyApi } from '@lucern/contracts/convex/unsafeAnyApi';
2
+ import { componentsGeneric, internalMutationGeneric, queryGeneric, mutationGeneric } from 'convex/server';
4
3
  import '@lucern/access-control/audience';
5
4
  import { getCurrentUserId } from '@lucern/access-control/auth';
6
- import { componentsGeneric, internalMutationGeneric, anyApi, queryGeneric, mutationGeneric } from 'convex/server';
5
+ import { throwStructuredMutationError } from '@lucern/access-control/structuredMutationError';
6
+ import { normalizeTupleContradictionPolicy, mkOpinion, conditionalDeduction, project, dampedDependencyCascade, deriveContractModulationPlan, deriveContractStatus, trustDiscount, applyNegativeSupport, cumulativeFusion, applyNegativeEvidence, confidenceFromSL, detectTupleContradiction, evaluateTupleContradictionTransition, readOpinionFromRecord, parseEvidentialEvaluatorConfig, compareMetricValue, resolveComparisonResult, buildEvidentialRationale, parseMetricCheckerConfig, getEvaluatorInputRecord, pickFiniteNumber, buildComparisonRationale, parseReferenceCheckCounterConfig, parseTemporalDeadlineConfig, parseMarketIndexComparatorConfig, hasProjectedOpinionChanged, createInheritedContractRecord } from '@lucern/confidence';
7
+ import { v } from 'convex/values';
7
8
  import '@lucern/contracts/schema-helpers/spine/tables/epistemicNodes';
9
+ import { checkProjectAccess, requireScopeWriteAccess } from '@lucern/access-control/access';
8
10
  import { permissiveReturn } from '@lucern/contracts/schema-helpers/validators';
9
11
  import { generateGlobalId } from '@lucern/contracts/ids';
10
12
 
11
- // src/epistemicBeliefs.helpers.ts
13
+ // src/convex.ts
14
+ var unsafeApi = unsafeConvexAnyApi(
15
+ "graph-primitives top-level module bundle lacks a committed Convex _generated/api surface"
16
+ );
17
+ var api = unsafeApi;
18
+ componentsGeneric();
19
+ var internal = unsafeApi;
20
+ var internalMutation = internalMutationGeneric;
21
+ var mutation = mutationGeneric;
22
+ var query = queryGeneric;
23
+
24
+ // src/debug.ts
25
+ function isGraphPrimitiveDebugEnabled() {
26
+ const env = globalThis.process?.env;
27
+ return env?.LUCERN_COMPAT_FALLBACK_DEBUG === "1" || env?.LUCERN_GRAPH_DEBUG === "1";
28
+ }
29
+ function debugGraphPrimitiveFallback(message, context) {
30
+ if (!isGraphPrimitiveDebugEnabled()) {
31
+ return;
32
+ }
33
+ console.debug(message, context ?? {});
34
+ }
12
35
 
13
36
  // src/beliefLifecycle.ts
14
37
  var BELIEF_STATUS_VALUES = [
@@ -130,24 +153,6 @@ function promoteBeliefStatusAfterScoring(status, opts) {
130
153
  }
131
154
  return status;
132
155
  }
133
- var api = anyApi;
134
- componentsGeneric();
135
- var internal = anyApi;
136
- var internalMutation = internalMutationGeneric;
137
- var mutation = mutationGeneric;
138
- var query = queryGeneric;
139
-
140
- // src/debug.ts
141
- function isGraphPrimitiveDebugEnabled() {
142
- const env = globalThis.process?.env;
143
- return env?.LUCERN_COMPAT_FALLBACK_DEBUG === "1" || env?.LUCERN_GRAPH_DEBUG === "1";
144
- }
145
- function debugGraphPrimitiveFallback(message, context) {
146
- if (!isGraphPrimitiveDebugEnabled()) {
147
- return;
148
- }
149
- console.debug(message, context ?? {});
150
- }
151
156
  var LEGACY_SCOPE_FIELD = "graphScopeProjectId";
152
157
  async function resolveTopicNodeScopeOrNull(ctx, ref) {
153
158
  if (!ctx?.db || typeof ctx.db.query !== "function") {
@@ -182,13 +187,15 @@ function asMappedProjectId(topic) {
182
187
  if (!topic) {
183
188
  return;
184
189
  }
185
- const directLegacyProjectId = normalizeScopeValue(topic[LEGACY_SCOPE_FIELD]);
190
+ const directLegacyProjectId = normalizeScopeValue(
191
+ topic[LEGACY_SCOPE_FIELD]
192
+ );
186
193
  if (directLegacyProjectId) {
187
194
  return directLegacyProjectId;
188
195
  }
189
196
  const metadata = topic.metadata || {};
190
197
  const candidate = metadata[LEGACY_SCOPE_FIELD] || metadata.legacyProjectId || metadata.projectId || metadata.scopeProjectId;
191
- return candidate ? candidate : void 0;
198
+ return typeof candidate === "string" ? normalizeScopeValue(candidate) : void 0;
192
199
  }
193
200
  function normalizeScopeValue(value) {
194
201
  if (typeof value !== "string") {
@@ -213,8 +220,9 @@ function pickPrimaryTopic(candidates) {
213
220
  })[0];
214
221
  }
215
222
  async function findTopicsByScopeAlias(ctx, scopeId) {
223
+ const query2 = ctx.db.query("topics");
216
224
  try {
217
- return await ctx.db.query("topics").withIndex(
225
+ return await query2.withIndex(
218
226
  "by_graph_scope_project",
219
227
  (q) => q.eq(LEGACY_SCOPE_FIELD, scopeId)
220
228
  ).collect();
@@ -226,7 +234,7 @@ async function findTopicsByScopeAlias(ctx, scopeId) {
226
234
  scopeId
227
235
  }
228
236
  );
229
- const topics = await ctx.db.query("topics").collect();
237
+ const topics = await query2.collect();
230
238
  return topics.filter((topic) => {
231
239
  const normalizedGlobalId = normalizeScopeValue(topic.globalId);
232
240
  const mappedProjectId = asMappedProjectId(topic);
@@ -282,137 +290,115 @@ async function resolveInheritedWorkspaceScope(ctx, topic) {
282
290
  let current = topic;
283
291
  for (let i = 0; i < MAX_DEPTH && current?.parentTopicId; i++) {
284
292
  current = await ctx.db.get(current.parentTopicId);
285
- if (!current) break;
293
+ if (!current) {
294
+ break;
295
+ }
286
296
  if (!tenantId) {
287
297
  tenantId = normalizeScopeValue(current.tenantId);
288
298
  }
289
299
  if (!workspaceId) {
290
300
  workspaceId = normalizeScopeValue(current.workspaceId);
291
301
  }
292
- if (tenantId && workspaceId) break;
302
+ if (tenantId && workspaceId) {
303
+ break;
304
+ }
293
305
  }
294
306
  return { tenantId, workspaceId };
295
307
  }
296
308
  async function resolveTopicProjectScope(ctx, args) {
297
309
  if (args.topicId) {
298
- let topic = null;
299
- try {
300
- topic = await ctx.db.get(
301
- args.topicId
302
- );
303
- } catch (error) {
304
- debugGraphPrimitiveFallback(
305
- "[topicScope] Failed to load topic by direct id",
306
- {
307
- error,
308
- topicId: args.topicId
309
- }
310
- );
311
- }
312
- if (!topic) {
313
- topic = await tryResolveHostTopicById(ctx, String(args.topicId));
314
- }
315
- if (!topic) {
316
- topic = pickPrimaryTopic(
317
- await findTopicsByScopeAlias(ctx, String(args.topicId))
318
- ) ?? null;
319
- }
320
- if (!topic) {
321
- const nodeScope = await resolveTopicNodeScopeOrNull(
322
- ctx,
323
- String(args.topicId)
324
- );
325
- if (nodeScope) {
326
- return nodeScope;
327
- }
328
- throw new Error(`Topic not found: ${String(args.topicId)}`);
329
- }
330
- const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
331
- const mapped = asMappedProjectId(topic);
332
- if (mapped) {
333
- return {
334
- topicId: topic._id,
335
- projectId: mapped,
336
- tenantId: inherited.tenantId,
337
- workspaceId: inherited.workspaceId,
338
- source: "topic"
339
- };
340
- }
341
- return {
342
- topicId: topic._id,
343
- tenantId: inherited.tenantId,
344
- workspaceId: inherited.workspaceId,
345
- source: "topic"
346
- };
310
+ return await resolveScopeFromTopicId(ctx, args.topicId);
347
311
  }
348
312
  if (args.projectId) {
349
- let directTopic = null;
350
- try {
351
- directTopic = await ctx.db.get(
352
- args.projectId
353
- );
354
- } catch (error) {
355
- debugGraphPrimitiveFallback(
356
- "[topicScope] Failed to load direct project topic",
357
- {
358
- error,
359
- projectId: args.projectId
360
- }
361
- );
362
- }
363
- if (directTopic) {
364
- const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
365
- const mapped = asMappedProjectId(directTopic);
366
- return {
367
- topicId: directTopic._id,
368
- projectId: mapped ?? args.projectId,
369
- tenantId: inherited.tenantId,
370
- workspaceId: inherited.workspaceId,
371
- source: "topic_inferred"
372
- };
373
- }
374
- directTopic = await tryResolveHostTopicByLegacyScope(ctx, args.projectId);
375
- if (directTopic) {
376
- const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
377
- const mapped = asMappedProjectId(directTopic);
378
- return {
379
- topicId: directTopic._id,
380
- projectId: mapped ?? args.projectId,
381
- tenantId: inherited.tenantId,
382
- workspaceId: inherited.workspaceId,
383
- source: "topic_inferred"
384
- };
385
- }
386
- const topics = await findTopicsByScopeAlias(ctx, args.projectId);
387
- const primary = pickPrimaryTopic(topics);
388
- if (primary) {
389
- const inherited = await resolveInheritedWorkspaceScope(ctx, primary);
390
- return {
391
- topicId: primary._id,
392
- projectId: args.projectId,
393
- tenantId: inherited.tenantId,
394
- workspaceId: inherited.workspaceId,
395
- source: "project_mapped_topic"
396
- };
397
- }
398
- const nodeScope = await resolveTopicNodeScopeOrNull(
399
- ctx,
400
- String(args.projectId)
401
- );
402
- if (nodeScope) {
403
- return {
404
- ...nodeScope,
405
- projectId: nodeScope.projectId ?? String(args.projectId)
406
- };
407
- }
408
- throw new Error(
409
- `Legacy project scope ${String(args.projectId)} has no mapped topic.`
410
- );
313
+ return await resolveScopeFromLegacyProjectId(ctx, args.projectId);
411
314
  }
412
315
  throw new Error(
413
316
  "Missing scope: provide topicId (preferred) or legacy projectId alias."
414
317
  );
415
318
  }
319
+ async function resolveScopeFromTopicId(ctx, topicId) {
320
+ const topic = await resolveTopicDocFromTopicId(ctx, topicId);
321
+ if (topic) {
322
+ return await buildTopicScope(ctx, topic, "topic");
323
+ }
324
+ const nodeScope = await resolveTopicNodeScopeOrNull(ctx, String(topicId));
325
+ if (nodeScope) {
326
+ return nodeScope;
327
+ }
328
+ throw new Error(`Topic not found: ${String(topicId)}`);
329
+ }
330
+ async function resolveTopicDocFromTopicId(ctx, topicId) {
331
+ const direct = await tryReadTopicDoc(ctx, topicId, {
332
+ failureLog: "[topicScope] Failed to load topic by direct id",
333
+ idLogKey: "topicId"
334
+ });
335
+ if (direct) {
336
+ return direct;
337
+ }
338
+ const hostTopic = await tryResolveHostTopicById(ctx, String(topicId));
339
+ if (hostTopic) {
340
+ return hostTopic;
341
+ }
342
+ return pickPrimaryTopic(await findTopicsByScopeAlias(ctx, String(topicId))) ?? null;
343
+ }
344
+ async function resolveScopeFromLegacyProjectId(ctx, legacyProjectId) {
345
+ const directTopic = await resolveDirectLegacyProjectTopic(
346
+ ctx,
347
+ legacyProjectId
348
+ );
349
+ if (directTopic) {
350
+ return await buildTopicScope(ctx, directTopic, "topic_inferred", {
351
+ fallbackProjectId: legacyProjectId
352
+ });
353
+ }
354
+ const primary = pickPrimaryTopic(
355
+ await findTopicsByScopeAlias(ctx, legacyProjectId)
356
+ );
357
+ if (primary) {
358
+ return await buildTopicScope(ctx, primary, "project_mapped_topic", {
359
+ fallbackProjectId: legacyProjectId
360
+ });
361
+ }
362
+ const nodeScope = await resolveTopicNodeScopeOrNull(ctx, legacyProjectId);
363
+ if (nodeScope) {
364
+ return {
365
+ ...nodeScope,
366
+ projectId: nodeScope.projectId ?? legacyProjectId
367
+ };
368
+ }
369
+ throw new Error(
370
+ `Legacy project scope ${legacyProjectId} has no mapped topic.`
371
+ );
372
+ }
373
+ async function resolveDirectLegacyProjectTopic(ctx, legacyProjectId) {
374
+ const directTopic = await tryReadTopicDoc(ctx, legacyProjectId, {
375
+ failureLog: "[topicScope] Failed to load direct project topic",
376
+ idLogKey: "projectId"
377
+ });
378
+ return directTopic ?? tryResolveHostTopicByLegacyScope(ctx, legacyProjectId);
379
+ }
380
+ async function tryReadTopicDoc(ctx, id, log) {
381
+ try {
382
+ return await ctx.db.get(id);
383
+ } catch (error) {
384
+ debugGraphPrimitiveFallback(log.failureLog, {
385
+ error,
386
+ [log.idLogKey]: id
387
+ });
388
+ return null;
389
+ }
390
+ }
391
+ async function buildTopicScope(ctx, topic, source, options = {}) {
392
+ const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
393
+ const mapped = asMappedProjectId(topic);
394
+ return {
395
+ topicId: topic._id,
396
+ ...mapped || options.fallbackProjectId ? { projectId: mapped ?? options.fallbackProjectId } : {},
397
+ tenantId: inherited.tenantId,
398
+ workspaceId: inherited.workspaceId,
399
+ source
400
+ };
401
+ }
416
402
  ({
417
403
  projectId: v.optional(v.string()),
418
404
  topicId: v.optional(v.string())
@@ -480,9 +466,10 @@ async function resolveNodeScopeForWorkspaceIsolation(ctx, node) {
480
466
  if (resolved.tenantId || resolved.workspaceId) {
481
467
  return resolved;
482
468
  }
483
- if (node.topicId) {
469
+ const topicId = normalizeScopeValue2(node.topicId);
470
+ if (topicId) {
484
471
  const topicScope = await resolveTopicProjectScope(ctx, {
485
- topicId: node.topicId
472
+ topicId
486
473
  });
487
474
  return {
488
475
  ...resolved,
@@ -502,33 +489,11 @@ async function resolveNodeScopeForWorkspaceIsolation(ctx, node) {
502
489
  }
503
490
  return resolved;
504
491
  }
505
-
506
- // src/epistemicBeliefs.helpers.ts
507
492
  v.id("epistemicNodes");
508
493
  var DEFAULT_CONFIDENCE_POLICY = {
509
494
  scoringMode: "after_worktree",
510
495
  tupleContradiction: normalizeTupleContradictionPolicy()
511
496
  };
512
- function throwStructuredMutationError(args) {
513
- const data = {
514
- structuredMutationError: true,
515
- message: args.message,
516
- status: args.status,
517
- code: args.code,
518
- invariantCode: args.invariantCode,
519
- suggestion: args.suggestion,
520
- details: args.details
521
- };
522
- const error = new ConvexError(
523
- data
524
- );
525
- error.status = args.status;
526
- error.code = args.code;
527
- error.invariantCode = args.invariantCode;
528
- error.suggestion = args.suggestion;
529
- error.details = args.details;
530
- throw error;
531
- }
532
497
  function buildBeliefConfidenceRow(args) {
533
498
  return {
534
499
  beliefId: args.beliefId,
@@ -603,7 +568,10 @@ function resolveBeliefStatus(node, metadata) {
603
568
  });
604
569
  }
605
570
  async function hasCompletedWorktreeForBelief(ctx, beliefNodeId) {
606
- const clusterMembership = await ctx.db.query("worktreeBeliefCluster").withIndex("by_belief", (q) => q.eq("beliefId", beliefNodeId)).collect();
571
+ const clusterMembership = await ctx.db.query("worktreeBeliefCluster").withIndex(
572
+ "by_belief",
573
+ (q) => q.eq("beliefId", beliefNodeId)
574
+ ).collect();
607
575
  for (const membership of clusterMembership) {
608
576
  const worktree = await ctx.db.get(membership.worktreeId);
609
577
  if (worktree?.status === "completed" || worktree?.status === "merged") {
@@ -614,7 +582,10 @@ async function hasCompletedWorktreeForBelief(ctx, beliefNodeId) {
614
582
  }
615
583
  async function getActiveConfidencePolicy(ctx) {
616
584
  try {
617
- const activeConfig = await ctx.db.query("logicSprintScoring").withIndex("by_active", (q) => q.eq("isActive", true)).first();
585
+ const activeConfig = await ctx.db.query("logicSprintScoring").withIndex(
586
+ "by_active",
587
+ (q) => q.eq("isActive", true)
588
+ ).first();
618
589
  return {
619
590
  scoringMode: activeConfig?.confidencePolicy === "always" ? "always" : DEFAULT_CONFIDENCE_POLICY.scoringMode,
620
591
  tupleContradiction: normalizeTupleContradictionPolicy(
@@ -631,23 +602,6 @@ async function getActiveConfidencePolicy(ctx) {
631
602
  return DEFAULT_CONFIDENCE_POLICY;
632
603
  }
633
604
  }
634
- async function requireProjectWriteAccess(ctx, projectId, userId) {
635
- const hasAccess = await checkProjectAccess(
636
- ctx,
637
- projectId,
638
- userId
639
- );
640
- if (!hasAccess) {
641
- throwStructuredMutationError({
642
- message: `Project write access denied for topic ${projectId}.`,
643
- status: 403,
644
- code: "PROJECT_ACCESS_DENIED",
645
- invariantCode: "policy.scope_required",
646
- suggestion: "The acting principal lacks project-write access to this topic. Request a topic grant (or, if the principal created this topic, run the creator-grant backfill) and retry.",
647
- details: { topicId: projectId, principalId: userId }
648
- });
649
- }
650
- }
651
605
 
652
606
  // src/edges/contains.ts
653
607
  var containsPropagationSpec = {
@@ -784,7 +738,7 @@ var dependsOnPropagationSpec = {
784
738
  description: "Structural gating. Textbook conditional deduction when edge conditionals exist, otherwise damped dependency cascade through downstream chains."
785
739
  };
786
740
 
787
- // src/edges/derivedFrom.ts
741
+ // src/edges/derived-from.ts
788
742
  var derivedFromPropagationSpec = {
789
743
  edgeType: "derived_from",
790
744
  direction: "incoming",
@@ -837,7 +791,7 @@ var informsPropagationSpec = {
837
791
  description: "Evidence-bearing influence. Informs can chain through the graph with light per-hop damping."
838
792
  };
839
793
 
840
- // src/edges/propagationTypes.ts
794
+ // src/edges/propagation-types.ts
841
795
  function isPropagationTraversalDirection(direction) {
842
796
  return direction === "outgoing" || direction === "incoming";
843
797
  }
@@ -910,6 +864,9 @@ var testsPropagationSpec = {
910
864
  };
911
865
 
912
866
  // src/edges/index.ts
867
+ var canContinueTransitively2 = canContinueTransitively;
868
+ var canTraverseHop2 = canTraverseHop;
869
+ var isPropagationTraversalDirection2 = isPropagationTraversalDirection;
913
870
  var EDGE_PROPAGATION_SPECS = [
914
871
  supportsPropagationSpec,
915
872
  informsPropagationSpec,
@@ -926,16 +883,15 @@ function getEdgePropagationSpecs() {
926
883
  return EDGE_PROPAGATION_SPECS;
927
884
  }
928
885
  function getTraversalDirections(direction) {
929
- if (isPropagationTraversalDirection(direction)) {
886
+ if (isPropagationTraversalDirection2(direction)) {
930
887
  return [direction];
931
888
  }
932
889
  return ["outgoing", "incoming"];
933
890
  }
934
891
 
935
892
  // src/confidencePropagationDispatch.ts
936
- function resolveTraversalTargetNodeId(edge, direction) {
937
- const targetNodeId = direction === "outgoing" ? edge.toNodeId : edge.fromNodeId;
938
- return targetNodeId ?? void 0;
893
+ function nodeIdToCacheKey(nodeId) {
894
+ return String(nodeId);
939
895
  }
940
896
  function readNodeOpinion(node) {
941
897
  const metadata = node.metadata ?? {};
@@ -951,118 +907,354 @@ function readNodeOpinion(node) {
951
907
  return mkOpinion(0, 0, 1, 0.5);
952
908
  }
953
909
  }
910
+ function resolveTraversalTargetNodeId(edge, direction) {
911
+ const targetNodeId = direction === "outgoing" ? edge.toNodeId : edge.fromNodeId;
912
+ return targetNodeId ?? void 0;
913
+ }
914
+ function buildInitialState(sourceNodeId, sourceOpinion) {
915
+ return {
916
+ nodeId: sourceNodeId,
917
+ opinion: sourceOpinion,
918
+ hop: 0,
919
+ visitedNodeIds: /* @__PURE__ */ new Set([nodeIdToCacheKey(sourceNodeId)])
920
+ };
921
+ }
922
+ function extendVisited(currentVisited, targetNodeId) {
923
+ return /* @__PURE__ */ new Set([...currentVisited, nodeIdToCacheKey(targetNodeId)]);
924
+ }
925
+ function makeTransitiveState(current, targetNodeId, projectedOpinion, nextHop) {
926
+ return {
927
+ nodeId: targetNodeId,
928
+ opinion: projectedOpinion,
929
+ hop: nextHop,
930
+ visitedNodeIds: extendVisited(current.visitedNodeIds, targetNodeId)
931
+ };
932
+ }
933
+ function makeDispatchRecord(targetNodeId, spec, direction, edge, projectedOpinion, nextHop, result, existingDispatch) {
934
+ return {
935
+ targetNodeId,
936
+ edgeType: spec.edgeType,
937
+ traversedDirection: direction,
938
+ weight: edge.weight ?? 1,
939
+ opinion: projectedOpinion,
940
+ operator: result.operator,
941
+ rationale: existingDispatch ? `${existingDispatch.rationale}; ${result.rationale}` : result.rationale,
942
+ hop: nextHop
943
+ };
944
+ }
945
+ async function loadCachedNode(scope, nodeId) {
946
+ const cacheKey = nodeIdToCacheKey(nodeId);
947
+ if (!scope.nodeCache.has(cacheKey)) {
948
+ scope.nodeCache.set(cacheKey, await scope.args.getNode(nodeId));
949
+ }
950
+ return scope.nodeCache.get(cacheKey) ?? null;
951
+ }
952
+ async function collectTargetDispatch(state, nextHop, spec, direction, edge, queue, scope) {
953
+ const sourceScope = scope.args.sourceScope;
954
+ if (sourceScope && !edgeMatchesWorkspaceReasoningScope(edge, sourceScope)) {
955
+ return;
956
+ }
957
+ const targetNodeId = resolveTraversalTargetNodeId(edge, direction);
958
+ if (!targetNodeId) {
959
+ return;
960
+ }
961
+ const targetNodeIdKey = nodeIdToCacheKey(targetNodeId);
962
+ if (state.visitedNodeIds.has(targetNodeIdKey)) {
963
+ return;
964
+ }
965
+ const targetNode = await loadCachedNode(scope, targetNodeId);
966
+ if (targetNode?.nodeType !== "belief") {
967
+ return;
968
+ }
969
+ if (sourceScope && !nodeMatchesWorkspaceReasoningScope(targetNode, sourceScope)) {
970
+ return;
971
+ }
972
+ const targetOpinion = scope.opinionCache.get(targetNodeIdKey) ?? readNodeOpinion(targetNode);
973
+ const result = spec.operator(state.opinion, targetOpinion, edge, {
974
+ hop: nextHop,
975
+ sourceNodeId: state.nodeId,
976
+ targetNodeId,
977
+ traversedDirection: direction,
978
+ spec
979
+ });
980
+ if (!(result && hasProjectedOpinionChanged(targetOpinion, result.opinion))) {
981
+ return;
982
+ }
983
+ const projectedOpinion = mkOpinion(
984
+ result.opinion.b,
985
+ result.opinion.d,
986
+ result.opinion.u,
987
+ result.opinion.a
988
+ );
989
+ scope.opinionCache.set(targetNodeIdKey, projectedOpinion);
990
+ const existingDispatch = scope.dispatchesByTargetId.get(targetNodeIdKey);
991
+ scope.dispatchesByTargetId.set(
992
+ targetNodeIdKey,
993
+ makeDispatchRecord(
994
+ targetNodeId,
995
+ spec,
996
+ direction,
997
+ edge,
998
+ projectedOpinion,
999
+ nextHop,
1000
+ result,
1001
+ existingDispatch
1002
+ )
1003
+ );
1004
+ if (canContinueTransitively2(spec, nextHop)) {
1005
+ queue.push(
1006
+ makeTransitiveState(state, targetNodeId, projectedOpinion, nextHop)
1007
+ );
1008
+ }
1009
+ }
1010
+ async function processTraversalSpec(state, nextHop, spec, queue, scope) {
1011
+ const sourceNodeId = state.nodeId;
1012
+ for (const direction of getTraversalDirections(spec.direction)) {
1013
+ const edges = await scope.args.queryEdges({
1014
+ nodeId: sourceNodeId,
1015
+ spec,
1016
+ direction,
1017
+ hop: nextHop
1018
+ });
1019
+ for (const edge of edges) {
1020
+ await collectTargetDispatch(
1021
+ state,
1022
+ nextHop,
1023
+ spec,
1024
+ direction,
1025
+ edge,
1026
+ queue,
1027
+ scope
1028
+ );
1029
+ }
1030
+ }
1031
+ }
1032
+ async function processQueuedState(state, queue, scope) {
1033
+ const nextHop = state.hop + 1;
1034
+ for (const spec of scope.traversalSpecs) {
1035
+ if (!canTraverseHop2(spec, nextHop)) {
1036
+ continue;
1037
+ }
1038
+ await processTraversalSpec(state, nextHop, spec, queue, scope);
1039
+ }
1040
+ }
1041
+ function sortDispatches(dispatches) {
1042
+ return Array.from(dispatches).sort((left, right) => {
1043
+ if (left.hop !== right.hop) {
1044
+ return left.hop - right.hop;
1045
+ }
1046
+ return String(left.targetNodeId).localeCompare(String(right.targetNodeId));
1047
+ });
1048
+ }
954
1049
  async function collectConfidencePropagationDispatches(args) {
955
1050
  const dispatchesByTargetId = /* @__PURE__ */ new Map();
956
1051
  const opinionCache = /* @__PURE__ */ new Map();
957
1052
  const nodeCache = /* @__PURE__ */ new Map();
958
1053
  const traversalSpecs = args.traversalSpecs ?? getEdgePropagationSpecs();
1054
+ const scope = {
1055
+ args,
1056
+ dispatchesByTargetId,
1057
+ opinionCache,
1058
+ nodeCache,
1059
+ traversalSpecs
1060
+ };
959
1061
  const queue = [
960
- {
961
- nodeId: args.sourceNodeId,
962
- opinion: args.sourceOpinion,
963
- hop: 0,
964
- visitedNodeIds: /* @__PURE__ */ new Set([String(args.sourceNodeId)])
965
- }
1062
+ buildInitialState(args.sourceNodeId, args.sourceOpinion)
966
1063
  ];
967
- const loadNode = async (nodeId) => {
968
- const cacheKey = String(nodeId);
969
- if (!nodeCache.has(cacheKey)) {
970
- nodeCache.set(cacheKey, await args.getNode(nodeId));
971
- }
972
- return nodeCache.get(cacheKey) ?? null;
973
- };
974
1064
  while (queue.length > 0) {
975
1065
  const state = queue.shift();
976
1066
  if (!state) {
977
1067
  continue;
978
1068
  }
979
- for (const spec of traversalSpecs) {
980
- const nextHop = state.hop + 1;
981
- if (!canTraverseHop(spec, nextHop)) {
982
- continue;
983
- }
984
- for (const direction of getTraversalDirections(spec.direction)) {
985
- const edges = await args.queryEdges({
986
- nodeId: state.nodeId,
987
- spec,
988
- direction,
989
- hop: nextHop
990
- });
991
- for (const edge of edges) {
992
- if (args.sourceScope && !edgeMatchesWorkspaceReasoningScope(edge, args.sourceScope)) {
993
- continue;
994
- }
995
- const targetNodeId = resolveTraversalTargetNodeId(edge, direction);
996
- if (!targetNodeId) {
997
- continue;
998
- }
999
- if (state.visitedNodeIds.has(String(targetNodeId))) {
1000
- continue;
1001
- }
1002
- const targetNode = await loadNode(targetNodeId);
1003
- if (!targetNode || targetNode.nodeType !== "belief") {
1004
- continue;
1005
- }
1006
- if (args.sourceScope && !nodeMatchesWorkspaceReasoningScope(targetNode, args.sourceScope)) {
1007
- continue;
1008
- }
1009
- const cacheKey = String(targetNodeId);
1010
- const targetOpinion = opinionCache.get(cacheKey) ?? readNodeOpinion(targetNode);
1011
- const result = spec.operator(state.opinion, targetOpinion, edge, {
1012
- hop: nextHop,
1013
- sourceNodeId: state.nodeId,
1014
- targetNodeId,
1015
- traversedDirection: direction,
1016
- spec
1017
- });
1018
- if (!result || !hasProjectedOpinionChanged(targetOpinion, result.opinion)) {
1019
- continue;
1020
- }
1021
- const projectedOpinion = mkOpinion(
1022
- result.opinion.b,
1023
- result.opinion.d,
1024
- result.opinion.u,
1025
- result.opinion.a
1026
- );
1027
- opinionCache.set(cacheKey, projectedOpinion);
1028
- const existingDispatch = dispatchesByTargetId.get(cacheKey);
1029
- dispatchesByTargetId.set(cacheKey, {
1030
- targetNodeId,
1031
- edgeType: spec.edgeType,
1032
- traversedDirection: direction,
1033
- weight: edge.weight ?? 1,
1034
- opinion: projectedOpinion,
1035
- operator: result.operator,
1036
- rationale: existingDispatch ? `${existingDispatch.rationale}; ${result.rationale}` : result.rationale,
1037
- hop: nextHop
1038
- });
1039
- if (canContinueTransitively(spec, nextHop)) {
1040
- queue.push({
1041
- nodeId: targetNodeId,
1042
- opinion: projectedOpinion,
1043
- hop: nextHop,
1044
- visitedNodeIds: /* @__PURE__ */ new Set([
1045
- ...state.visitedNodeIds,
1046
- String(targetNodeId)
1047
- ])
1048
- });
1049
- }
1050
- }
1051
- }
1052
- }
1069
+ await processQueuedState(state, queue, scope);
1053
1070
  }
1054
- return Array.from(dispatchesByTargetId.values()).sort((left, right) => {
1055
- if (left.hop !== right.hop) {
1056
- return left.hop - right.hop;
1057
- }
1058
- return String(left.targetNodeId).localeCompare(String(right.targetNodeId));
1059
- });
1071
+ return sortDispatches(dispatchesByTargetId.values());
1060
1072
  }
1061
1073
 
1062
1074
  // src/epistemicBeliefs.confidence.ts
1075
+ function isRecord(value) {
1076
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
1077
+ }
1078
+ function readConvexId(value) {
1079
+ return typeof value === "string" && value.trim().length > 0 ? value : void 0;
1080
+ }
1081
+ function readOptionalBoolean(value) {
1082
+ return typeof value === "boolean" ? value : void 0;
1083
+ }
1084
+ function readOptionalNumber(value) {
1085
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
1086
+ }
1087
+ function readOptionalString(value) {
1088
+ return typeof value === "string" && value.trim().length > 0 ? value : void 0;
1089
+ }
1090
+ function readRecord(value) {
1091
+ return isRecord(value) ? value : void 0;
1092
+ }
1093
+ function readConfidenceBeliefNode(value) {
1094
+ if (!isRecord(value)) {
1095
+ return null;
1096
+ }
1097
+ const id = readConvexId(value._id);
1098
+ const nodeType = readOptionalString(value.nodeType);
1099
+ const projectId = readOptionalString(value.projectId);
1100
+ if (!(id && nodeType === "belief" && projectId)) {
1101
+ return null;
1102
+ }
1103
+ const node = {
1104
+ _id: id,
1105
+ nodeType,
1106
+ projectId
1107
+ };
1108
+ const confidence = readOptionalNumber(value.confidence);
1109
+ const epistemicLayer = readOptionalString(value.epistemicLayer);
1110
+ const globalId = readOptionalString(value.globalId);
1111
+ const metadata = readRecord(value.metadata);
1112
+ const opinionA = readOptionalNumber(value.opinion_a);
1113
+ const opinionB = readOptionalNumber(value.opinion_b);
1114
+ const opinionD = readOptionalNumber(value.opinion_d);
1115
+ const opinionU = readOptionalNumber(value.opinion_u);
1116
+ const predictionMeta = readRecord(value.predictionMeta);
1117
+ const publicationStatus = readOptionalString(value.publicationStatus);
1118
+ const status = readOptionalString(value.status);
1119
+ const tenantId = readOptionalString(value.tenantId);
1120
+ const topicId = readOptionalString(value.topicId);
1121
+ const tupleContradicted = readOptionalBoolean(value.tupleContradicted);
1122
+ const workspaceId = readOptionalString(value.workspaceId);
1123
+ if (confidence !== void 0) {
1124
+ node.confidence = confidence;
1125
+ }
1126
+ if (epistemicLayer !== void 0) {
1127
+ node.epistemicLayer = epistemicLayer;
1128
+ }
1129
+ if (globalId !== void 0) {
1130
+ node.globalId = globalId;
1131
+ }
1132
+ if (metadata !== void 0) {
1133
+ node.metadata = metadata;
1134
+ }
1135
+ if (opinionA !== void 0) {
1136
+ node.opinion_a = opinionA;
1137
+ }
1138
+ if (opinionB !== void 0) {
1139
+ node.opinion_b = opinionB;
1140
+ }
1141
+ if (opinionD !== void 0) {
1142
+ node.opinion_d = opinionD;
1143
+ }
1144
+ if (opinionU !== void 0) {
1145
+ node.opinion_u = opinionU;
1146
+ }
1147
+ if (predictionMeta !== void 0) {
1148
+ node.predictionMeta = predictionMeta;
1149
+ }
1150
+ if (publicationStatus !== void 0) {
1151
+ node.publicationStatus = publicationStatus;
1152
+ }
1153
+ if (status !== void 0) {
1154
+ node.status = status;
1155
+ }
1156
+ if (tenantId !== void 0) {
1157
+ node.tenantId = tenantId;
1158
+ }
1159
+ if (topicId !== void 0) {
1160
+ node.topicId = topicId;
1161
+ }
1162
+ if (tupleContradicted !== void 0) {
1163
+ node.tupleContradicted = tupleContradicted;
1164
+ }
1165
+ if (workspaceId !== void 0) {
1166
+ node.workspaceId = workspaceId;
1167
+ }
1168
+ return node;
1169
+ }
1170
+ function readPropagationEdge(value) {
1171
+ if (!isRecord(value)) {
1172
+ return null;
1173
+ }
1174
+ const edgeType = readOptionalString(value.edgeType);
1175
+ if (!edgeType) {
1176
+ return null;
1177
+ }
1178
+ const edge = { edgeType };
1179
+ const fromNodeId = readConvexId(value.fromNodeId);
1180
+ const tenantId = readOptionalString(value.tenantId);
1181
+ const toNodeId = readConvexId(value.toNodeId);
1182
+ const weight = readOptionalNumber(value.weight);
1183
+ const workspaceId = readOptionalString(value.workspaceId);
1184
+ if (fromNodeId !== void 0) {
1185
+ edge.fromNodeId = fromNodeId;
1186
+ }
1187
+ if (tenantId !== void 0) {
1188
+ edge.tenantId = tenantId;
1189
+ }
1190
+ if (toNodeId !== void 0) {
1191
+ edge.toNodeId = toNodeId;
1192
+ }
1193
+ if (weight !== void 0) {
1194
+ edge.weight = weight;
1195
+ }
1196
+ if (workspaceId !== void 0) {
1197
+ edge.workspaceId = workspaceId;
1198
+ }
1199
+ return edge;
1200
+ }
1201
+ function readRowList(values, reader) {
1202
+ return values.flatMap((value) => {
1203
+ const row = reader(value);
1204
+ return row ? [row] : [];
1205
+ });
1206
+ }
1063
1207
  async function applyBeliefConfidenceChange(ctx, args) {
1064
1208
  const now = Date.now();
1065
- const node = await ctx.db.get(args.nodeId);
1209
+ const node = await requireConfidenceBeliefNode(ctx, args);
1210
+ const state = await buildConfidenceChangeState(ctx, node, args);
1211
+ await assertConfidenceScoringPolicySatisfied(ctx, args, state);
1212
+ const tupleContradictionId = await createTupleContradictionIfNeeded(
1213
+ ctx,
1214
+ args,
1215
+ node,
1216
+ state
1217
+ );
1218
+ await patchBeliefConfidenceState(ctx, args, state);
1219
+ await scheduleFirstScoringThemeEdges(ctx, args, node, state);
1220
+ const beliefConfidenceId = await insertBeliefConfidenceRecord(
1221
+ ctx,
1222
+ args,
1223
+ state,
1224
+ tupleContradictionId,
1225
+ now
1226
+ );
1227
+ await ctx.scheduler.runAfter(0, internal.neo4jSync.syncNodeToNeo4j, {
1228
+ nodeId: args.nodeId,
1229
+ operation: "upsert"
1230
+ });
1231
+ await insertConfidenceAudit(
1232
+ ctx,
1233
+ args,
1234
+ node,
1235
+ state,
1236
+ tupleContradictionId,
1237
+ now
1238
+ );
1239
+ await insertTupleTransitionAuditIfNeeded(
1240
+ ctx,
1241
+ args,
1242
+ node,
1243
+ state,
1244
+ tupleContradictionId,
1245
+ now
1246
+ );
1247
+ await scheduleConfidenceFollowups(ctx, args, node, state);
1248
+ return {
1249
+ nodeId: args.nodeId,
1250
+ previousConfidence: state.previousConfidence,
1251
+ newConfidence: state.derivedConfidence,
1252
+ opinion: state.nextOpinion,
1253
+ beliefConfidenceId
1254
+ };
1255
+ }
1256
+ async function requireConfidenceBeliefNode(ctx, args) {
1257
+ const node = readConfidenceBeliefNode(await ctx.db.get(args.nodeId));
1066
1258
  if (!node) {
1067
1259
  throwStructuredMutationError({
1068
1260
  message: "Node not found.",
@@ -1073,59 +1265,28 @@ async function applyBeliefConfidenceChange(ctx, args) {
1073
1265
  details: { nodeId: args.nodeId }
1074
1266
  });
1075
1267
  }
1076
- if (node.nodeType !== "belief") {
1077
- throwStructuredMutationError({
1078
- message: `appendSlScoring only applies to belief nodes. Received nodeType "${node.nodeType}". Entity nodes (company, person, investor, etc.) do not have confidence \u2014 use entityLifecycle.updateEntityAttributes for mutable entity data.`,
1079
- status: 400,
1080
- code: "INVALID_ARGUMENT",
1081
- invariantCode: "entity.no_confidence",
1082
- suggestion: "Use entityLifecycle.updateEntityAttributes for entity mutations. appendSlScoring is for belief nodes only.",
1083
- details: { nodeId: args.nodeId, nodeType: node.nodeType }
1084
- });
1085
- }
1086
- if (!node.projectId) {
1087
- throwStructuredMutationError({
1088
- message: "Belief has no project scope.",
1089
- status: 400,
1090
- code: "MISSING_SCOPE",
1091
- invariantCode: "belief.project_required",
1092
- suggestion: "Belief must have a projectId before SL scoring can be appended.",
1093
- details: { nodeId: args.nodeId }
1094
- });
1095
- }
1096
- await requireProjectWriteAccess(
1097
- ctx,
1098
- node.projectId,
1099
- args.authenticatedUserId
1100
- );
1101
- const existingMetadata = node.metadata || {};
1268
+ await requireScopeWriteAccess(ctx, node.projectId, args.authenticatedUserId);
1269
+ return node;
1270
+ }
1271
+ async function buildConfidenceChangeState(ctx, node, args) {
1272
+ const existingMetadata = readNodeMetadata(node);
1102
1273
  const currentBeliefStatus = resolveBeliefStatus(node, existingMetadata);
1103
1274
  const confidencePolicy = await getActiveConfidencePolicy(ctx);
1104
- if (confidencePolicy.scoringMode === "after_worktree" && isPreValidationBeliefStatus(currentBeliefStatus)) {
1105
- const hasCompletedWorktree = await hasCompletedWorktreeForBelief(
1106
- ctx,
1107
- args.nodeId
1108
- );
1109
- if (!hasCompletedWorktree) {
1110
- throwStructuredMutationError({
1111
- message: "Cannot score belief before worktree completion. Complete a worktree that tests this belief first.",
1112
- status: 409,
1113
- code: "CONFLICT",
1114
- invariantCode: "belief.confidence_append_only",
1115
- suggestion: "Complete a worktree linked to this belief before recording SL scoring.",
1116
- details: { nodeId: args.nodeId }
1117
- });
1118
- }
1119
- }
1120
1275
  const previousConfidence = node.confidence || 0.5;
1121
1276
  const predictionMeta = node.predictionMeta || existingMetadata.predictionMeta;
1122
1277
  const previousOpinion = readBeliefOpinionSnapshot(node, existingMetadata);
1123
- const slB = args.belief;
1124
- const slD = args.disbelief;
1125
- const slU = args.uncertainty;
1126
- const slA = args.baseRate ?? 0.5;
1127
- const nextOpinion = { b: slB, d: slD, u: slU, a: slA };
1128
- const derivedConfidence = confidenceFromSL(slB, slD, slU, slA);
1278
+ const nextOpinion = {
1279
+ b: args.belief,
1280
+ d: args.disbelief,
1281
+ u: args.uncertainty,
1282
+ a: args.baseRate ?? 0.5
1283
+ };
1284
+ const derivedConfidence = confidenceFromSL(
1285
+ nextOpinion.b,
1286
+ nextOpinion.d,
1287
+ nextOpinion.u,
1288
+ nextOpinion.a
1289
+ );
1129
1290
  const isFirstScoring = typeof node.confidence !== "number" || !Number.isFinite(node.confidence);
1130
1291
  const previousTupleContradicted = readTupleContradictedFlag(node.tupleContradicted) ?? readTupleContradictedFlag(existingMetadata.tupleContradicted) ?? detectTupleContradiction(
1131
1292
  previousOpinion,
@@ -1146,79 +1307,121 @@ async function applyBeliefConfidenceChange(ctx, args) {
1146
1307
  predictionMeta,
1147
1308
  metadata: existingMetadata
1148
1309
  });
1149
- let tupleContradictionId;
1150
- if (tupleTransition.crossedIntoTupleContradiction) {
1151
- tupleContradictionId = await ctx.runMutation(
1152
- "contradictions:create",
1153
- {
1154
- projectId: node.projectId,
1155
- topicId: node.topicId,
1156
- beliefId: args.nodeId,
1157
- beliefBId: args.nodeId,
1158
- supportingInsightIds: [],
1159
- contradictingInsightIds: [],
1160
- severity: deriveTupleContradictionSeverity(node),
1161
- source: "tuple_space",
1162
- detectionMethod: "agent",
1163
- description: tupleContradictionDescription,
1164
- createdBy: args.authenticatedUserId
1165
- }
1166
- );
1310
+ const storedRationale = args.rationale ?? `Confidence changed from ${previousConfidence.toFixed(2)} (nodeId: ${args.nodeId})`;
1311
+ return {
1312
+ confidencePolicy,
1313
+ currentBeliefStatus,
1314
+ derivedConfidence,
1315
+ existingMetadata,
1316
+ isFirstScoring,
1317
+ newBeliefStatus,
1318
+ nextOpinion,
1319
+ previousConfidence,
1320
+ previousTupleContradicted,
1321
+ storedRationale,
1322
+ tupleContradictionDescription,
1323
+ tupleTransition
1324
+ };
1325
+ }
1326
+ function readNodeMetadata(node) {
1327
+ return node.metadata ?? {};
1328
+ }
1329
+ async function assertConfidenceScoringPolicySatisfied(ctx, args, state) {
1330
+ if (state.confidencePolicy.scoringMode !== "after_worktree" || !isPreValidationBeliefStatus(state.currentBeliefStatus)) {
1331
+ return;
1332
+ }
1333
+ const hasCompletedWorktree = await hasCompletedWorktreeForBelief(
1334
+ ctx,
1335
+ args.nodeId
1336
+ );
1337
+ if (hasCompletedWorktree) {
1338
+ return;
1339
+ }
1340
+ throwStructuredMutationError({
1341
+ message: "Cannot score belief before worktree completion. Complete a worktree that tests this belief first.",
1342
+ status: 409,
1343
+ code: "CONFLICT",
1344
+ invariantCode: "belief.confidence_append_only",
1345
+ suggestion: "Complete a worktree linked to this belief before recording SL scoring.",
1346
+ details: { nodeId: args.nodeId }
1347
+ });
1348
+ }
1349
+ async function createTupleContradictionIfNeeded(ctx, args, node, state) {
1350
+ if (!state.tupleTransition.crossedIntoTupleContradiction) {
1351
+ return;
1167
1352
  }
1353
+ return await ctx.runMutation("contradictions:create", {
1354
+ projectId: node.projectId,
1355
+ topicId: node.topicId,
1356
+ beliefId: args.nodeId,
1357
+ beliefBId: args.nodeId,
1358
+ supportingInsightIds: [],
1359
+ contradictingInsightIds: [],
1360
+ severity: deriveTupleContradictionSeverity(node),
1361
+ source: "tuple_space",
1362
+ detectionMethod: "agent",
1363
+ description: state.tupleContradictionDescription,
1364
+ createdBy: args.authenticatedUserId
1365
+ });
1366
+ }
1367
+ async function patchBeliefConfidenceState(ctx, args, state) {
1168
1368
  await ctx.db.patch(args.nodeId, {
1169
- confidence: derivedConfidence,
1170
- beliefStatus: newBeliefStatus,
1171
- tupleContradicted: tupleTransition.tupleContradicted,
1172
- updatedAt: now,
1173
- // Store SL opinion fields at node level for fast access
1174
- opinion_b: slB,
1175
- opinion_d: slD,
1176
- opinion_u: slU,
1177
- opinion_a: slA,
1369
+ confidence: state.derivedConfidence,
1370
+ beliefStatus: state.newBeliefStatus,
1371
+ tupleContradicted: state.tupleTransition.tupleContradicted,
1372
+ updatedAt: Date.now(),
1373
+ opinion_b: state.nextOpinion.b,
1374
+ opinion_d: state.nextOpinion.d,
1375
+ opinion_u: state.nextOpinion.u,
1376
+ opinion_a: state.nextOpinion.a,
1178
1377
  metadata: {
1179
- ...existingMetadata,
1180
- beliefStatus: newBeliefStatus,
1181
- slBelief: slB,
1182
- slDisbelief: slD,
1183
- slUncertainty: slU,
1184
- slBaseRate: slA,
1185
- tupleContradicted: tupleTransition.tupleContradicted
1378
+ ...state.existingMetadata,
1379
+ beliefStatus: state.newBeliefStatus,
1380
+ slBelief: state.nextOpinion.b,
1381
+ slDisbelief: state.nextOpinion.d,
1382
+ slUncertainty: state.nextOpinion.u,
1383
+ slBaseRate: state.nextOpinion.a,
1384
+ tupleContradicted: state.tupleTransition.tupleContradicted
1186
1385
  }
1187
1386
  });
1188
- if (isFirstScoring) {
1189
- const nodeTopicId = node.topicId;
1190
- const themeNodes = await ctx.db.query("epistemicNodes").withIndex(
1191
- "by_topic",
1192
- (q) => q.eq("topicId", nodeTopicId || node.projectId)
1193
- ).filter((q) => q.eq(q.field("nodeType"), "theme")).collect();
1194
- for (const theme of themeNodes) {
1195
- if (theme.globalId && node.globalId) {
1196
- await ctx.scheduler.runAfter(0, internal.neo4jEdgeAPI.createEdge, {
1197
- globalId: `edge-${node.globalId}-relates_to_thesis-${theme.globalId}`,
1198
- fromGlobalId: node.globalId,
1199
- toGlobalId: theme.globalId,
1200
- edgeType: "relates_to_thesis",
1201
- weight: derivedConfidence,
1202
- createdBy: args.authenticatedUserId,
1203
- topicId: String(node.projectId),
1204
- fromNodeType: "belief",
1205
- toNodeType: "theme",
1206
- fromLayer: "L3",
1207
- toLayer: "L3"
1208
- });
1209
- }
1387
+ }
1388
+ async function scheduleFirstScoringThemeEdges(ctx, args, node, state) {
1389
+ if (!state.isFirstScoring) {
1390
+ return;
1391
+ }
1392
+ const themeNodes = await ctx.db.query("epistemicNodes").withIndex(
1393
+ "by_topic",
1394
+ (q) => q.eq("topicId", node.topicId || node.projectId)
1395
+ ).filter((q) => q.eq(q.field("nodeType"), "theme")).collect();
1396
+ for (const theme of themeNodes) {
1397
+ if (!(theme.globalId && node.globalId)) {
1398
+ continue;
1210
1399
  }
1400
+ await ctx.scheduler.runAfter(0, internal.neo4jEdgeAPI.createEdge, {
1401
+ globalId: `edge-${node.globalId}-relates_to_thesis-${theme.globalId}`,
1402
+ fromGlobalId: node.globalId,
1403
+ toGlobalId: theme.globalId,
1404
+ edgeType: "relates_to_thesis",
1405
+ weight: state.derivedConfidence,
1406
+ createdBy: args.authenticatedUserId,
1407
+ topicId: String(node.projectId),
1408
+ fromNodeType: "belief",
1409
+ toNodeType: "theme",
1410
+ fromLayer: "L3",
1411
+ toLayer: "L3"
1412
+ });
1211
1413
  }
1212
- const storedRationale = args.rationale ?? `Confidence changed from ${previousConfidence.toFixed(2)} (nodeId: ${args.nodeId})`;
1213
- const beliefConfidenceId = await ctx.db.insert("beliefConfidence", {
1414
+ }
1415
+ async function insertBeliefConfidenceRecord(ctx, args, state, tupleContradictionId, now) {
1416
+ return await ctx.db.insert("beliefConfidence", {
1214
1417
  ...buildBeliefConfidenceRow({
1215
1418
  beliefId: args.nodeId,
1216
- belief: slB,
1217
- disbelief: slD,
1218
- uncertainty: slU,
1219
- baseRate: slA,
1419
+ belief: state.nextOpinion.b,
1420
+ disbelief: state.nextOpinion.d,
1421
+ uncertainty: state.nextOpinion.u,
1422
+ baseRate: state.nextOpinion.a,
1220
1423
  trigger: args.trigger,
1221
- rationale: storedRationale,
1424
+ rationale: state.storedRationale,
1222
1425
  assessedBy: args.authenticatedUserId,
1223
1426
  assessedAt: now,
1224
1427
  slOperator: args.slOperator,
@@ -1227,25 +1430,23 @@ async function applyBeliefConfidenceChange(ctx, args) {
1227
1430
  triggeringWorktreeId: args.triggeringWorktreeId
1228
1431
  })
1229
1432
  });
1230
- await ctx.scheduler.runAfter(0, internal.neo4jSync.syncNodeToNeo4j, {
1231
- nodeId: args.nodeId,
1232
- operation: "upsert"
1233
- });
1433
+ }
1434
+ async function insertConfidenceAudit(ctx, args, node, state, tupleContradictionId, now) {
1234
1435
  await ctx.db.insert("epistemicAudit", {
1235
1436
  entityType: "belief",
1236
1437
  entityId: args.nodeId,
1237
1438
  changeType: "confidence_changed",
1238
1439
  previousState: {
1239
- confidence: previousConfidence,
1240
- tupleContradicted: previousTupleContradicted
1440
+ confidence: state.previousConfidence,
1441
+ tupleContradicted: state.previousTupleContradicted
1241
1442
  },
1242
1443
  newState: {
1243
- opinion: nextOpinion,
1244
- confidence: derivedConfidence,
1444
+ opinion: state.nextOpinion,
1445
+ confidence: state.derivedConfidence,
1245
1446
  trigger: args.trigger,
1246
- rationale: storedRationale,
1247
- tupleContradicted: tupleTransition.tupleContradicted,
1248
- tupleContradictionPolicy: tupleTransition.policy,
1447
+ rationale: state.storedRationale,
1448
+ tupleContradicted: state.tupleTransition.tupleContradicted,
1449
+ tupleContradictionPolicy: state.tupleTransition.policy,
1249
1450
  ...tupleContradictionId ? { tupleContradictionId: String(tupleContradictionId) } : {}
1250
1451
  },
1251
1452
  changedBy: args.authenticatedUserId,
@@ -1254,28 +1455,39 @@ async function applyBeliefConfidenceChange(ctx, args) {
1254
1455
  projectId: node.projectId,
1255
1456
  topicId: node.topicId
1256
1457
  });
1257
- if (tupleTransition.crossedIntoTupleContradiction || tupleTransition.crossedOutOfTupleContradiction) {
1258
- await ctx.db.insert("epistemicAudit", {
1259
- entityType: "belief",
1260
- entityId: args.nodeId,
1261
- changeType: "updated",
1262
- previousState: { tupleContradicted: previousTupleContradicted },
1263
- newState: {
1264
- tupleContradicted: tupleTransition.tupleContradicted,
1265
- action: tupleTransition.crossedIntoTupleContradiction ? "tuple_contradiction_detected" : "tuple_contradiction_cleared",
1266
- opinion: nextOpinion,
1267
- tupleContradictionPolicy: tupleTransition.policy,
1268
- ...tupleContradictionId ? { tupleContradictionId: String(tupleContradictionId) } : {}
1269
- },
1270
- rationale: tupleTransition.crossedIntoTupleContradiction ? tupleContradictionDescription : `Tuple-space contradiction cleared: b=${nextOpinion.b.toFixed(2)}, d=${nextOpinion.d.toFixed(2)} no longer exceed the configured policy thresholds.`,
1271
- changedBy: args.authenticatedUserId,
1272
- isAgent: false,
1273
- changedAt: now,
1274
- projectId: node.projectId,
1275
- topicId: node.topicId
1276
- });
1458
+ }
1459
+ async function insertTupleTransitionAuditIfNeeded(ctx, args, node, state, tupleContradictionId, now) {
1460
+ if (!(state.tupleTransition.crossedIntoTupleContradiction || state.tupleTransition.crossedOutOfTupleContradiction)) {
1461
+ return;
1462
+ }
1463
+ await ctx.db.insert("epistemicAudit", {
1464
+ entityType: "belief",
1465
+ entityId: args.nodeId,
1466
+ changeType: "updated",
1467
+ previousState: { tupleContradicted: state.previousTupleContradicted },
1468
+ newState: {
1469
+ tupleContradicted: state.tupleTransition.tupleContradicted,
1470
+ action: state.tupleTransition.crossedIntoTupleContradiction ? "tuple_contradiction_detected" : "tuple_contradiction_cleared",
1471
+ opinion: state.nextOpinion,
1472
+ tupleContradictionPolicy: state.tupleTransition.policy,
1473
+ ...tupleContradictionId ? { tupleContradictionId: String(tupleContradictionId) } : {}
1474
+ },
1475
+ rationale: tupleAuditRationale(state),
1476
+ changedBy: args.authenticatedUserId,
1477
+ isAgent: false,
1478
+ changedAt: now,
1479
+ projectId: node.projectId,
1480
+ topicId: node.topicId
1481
+ });
1482
+ }
1483
+ function tupleAuditRationale(state) {
1484
+ if (state.tupleTransition.crossedIntoTupleContradiction) {
1485
+ return state.tupleContradictionDescription;
1277
1486
  }
1278
- if (Math.abs(derivedConfidence - previousConfidence) >= 0.15) {
1487
+ return `Tuple-space contradiction cleared: b=${state.nextOpinion.b.toFixed(2)}, d=${state.nextOpinion.d.toFixed(2)} no longer exceed the configured policy thresholds.`;
1488
+ }
1489
+ async function scheduleConfidenceFollowups(ctx, args, node, state) {
1490
+ if (Math.abs(state.derivedConfidence - state.previousConfidence) >= 0.15) {
1279
1491
  await ctx.scheduler.runAfter(
1280
1492
  5e3,
1281
1493
  internal.bi.contradictionSemanticDetector.scanAffectedBeliefs,
@@ -1292,13 +1504,6 @@ async function applyBeliefConfidenceChange(ctx, args) {
1292
1504
  { nodeId: args.nodeId }
1293
1505
  );
1294
1506
  }
1295
- return {
1296
- nodeId: args.nodeId,
1297
- previousConfidence,
1298
- newConfidence: derivedConfidence,
1299
- opinion: { b: slB, d: slD, u: slU, a: slA },
1300
- beliefConfidenceId
1301
- };
1302
1507
  }
1303
1508
  function propagationPressureLabel(edgeType, weight) {
1304
1509
  if (edgeType === "contradicts" || edgeType === "refutes") {
@@ -1326,7 +1531,7 @@ internalMutation({
1326
1531
  args.opinion_u,
1327
1532
  args.opinion_a
1328
1533
  );
1329
- const sourceNode = await ctx.db.get(args.nodeId);
1534
+ const sourceNode = readConfidenceBeliefNode(await ctx.db.get(args.nodeId));
1330
1535
  const sourceScope = await resolveNodeScopeForWorkspaceIsolation(
1331
1536
  ctx,
1332
1537
  sourceNode
@@ -1335,16 +1540,20 @@ internalMutation({
1335
1540
  sourceNodeId: args.nodeId,
1336
1541
  sourceOpinion,
1337
1542
  sourceScope,
1338
- queryEdges: async ({ nodeId, spec, direction }) => {
1339
- return await ctx.db.query("epistemicEdges").withIndex(
1543
+ queryEdges: async ({ nodeId, spec, direction }) => readRowList(
1544
+ await ctx.db.query("epistemicEdges").withIndex(
1340
1545
  direction === "outgoing" ? "by_from_type" : "by_to_type",
1341
1546
  (q) => direction === "outgoing" ? q.eq("fromNodeId", nodeId).eq("edgeType", spec.edgeType) : q.eq("toNodeId", nodeId).eq("edgeType", spec.edgeType)
1342
- ).collect();
1343
- },
1344
- getNode: async (nodeId) => await ctx.db.get(nodeId)
1547
+ ).collect(),
1548
+ readPropagationEdge
1549
+ ),
1550
+ getNode: async (nodeId) => readConfidenceBeliefNode(await ctx.db.get(nodeId))
1345
1551
  });
1346
1552
  for (const dispatch of dispatches) {
1347
- const pressureLabel = propagationPressureLabel(dispatch.edgeType, dispatch.weight);
1553
+ const pressureLabel = propagationPressureLabel(
1554
+ dispatch.edgeType,
1555
+ dispatch.weight
1556
+ );
1348
1557
  await applyBeliefConfidenceChange(ctx, {
1349
1558
  nodeId: dispatch.targetNodeId,
1350
1559
  belief: dispatch.opinion.b,
@@ -1374,9 +1583,7 @@ var ACTIVE_CONTRADICTION_STATUSES = /* @__PURE__ */ new Set([
1374
1583
  "investigating",
1375
1584
  "accepted_as_permanent"
1376
1585
  ]);
1377
- var DEPENDENT_EDGE_TYPES = /* @__PURE__ */ new Set([
1378
- "depends_on"
1379
- ]);
1586
+ var DEPENDENT_EDGE_TYPES = /* @__PURE__ */ new Set(["depends_on"]);
1380
1587
  function classifyContradictionStatus(status) {
1381
1588
  if (typeof status !== "string") {
1382
1589
  return "active";
@@ -1389,6 +1596,99 @@ function classifyContradictionStatus(status) {
1389
1596
  }
1390
1597
  return "resolved";
1391
1598
  }
1599
+ function isRecord2(value) {
1600
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
1601
+ }
1602
+ function readOptionalNumber2(value) {
1603
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
1604
+ }
1605
+ function readOptionalString2(value) {
1606
+ return typeof value === "string" && value.trim().length > 0 ? value : void 0;
1607
+ }
1608
+ function readConvexId2(value) {
1609
+ const normalized = readOptionalString2(value);
1610
+ return normalized;
1611
+ }
1612
+ function readMetricNodeDoc(value) {
1613
+ if (!isRecord2(value)) {
1614
+ return null;
1615
+ }
1616
+ const id = readConvexId2(value._id);
1617
+ const nodeType = readOptionalString2(value.nodeType);
1618
+ if (!(id && nodeType)) {
1619
+ return null;
1620
+ }
1621
+ const node = { _id: id, nodeType };
1622
+ const globalId = readOptionalString2(value.globalId);
1623
+ if (globalId !== void 0) {
1624
+ node.globalId = globalId;
1625
+ }
1626
+ if ("metadata" in value) {
1627
+ node.metadata = value.metadata;
1628
+ }
1629
+ const status = readOptionalString2(value.status);
1630
+ if (status !== void 0) {
1631
+ node.status = status;
1632
+ }
1633
+ return node;
1634
+ }
1635
+ function readIncomingEdgeRow(value) {
1636
+ if (!isRecord2(value)) {
1637
+ return null;
1638
+ }
1639
+ const fromNodeId = readOptionalString2(value.fromNodeId);
1640
+ if (!fromNodeId) {
1641
+ return null;
1642
+ }
1643
+ const edge = { fromNodeId };
1644
+ const id = readConvexId2(value._id);
1645
+ if (id !== void 0) {
1646
+ edge._id = id;
1647
+ }
1648
+ const edgeType = readOptionalString2(value.edgeType);
1649
+ if (edgeType !== void 0) {
1650
+ edge.edgeType = edgeType;
1651
+ }
1652
+ const fromGlobalId = readOptionalString2(value.fromGlobalId);
1653
+ if (fromGlobalId !== void 0) {
1654
+ edge.fromGlobalId = fromGlobalId;
1655
+ }
1656
+ const fromUuid = readOptionalString2(value.fromUuid);
1657
+ if (fromUuid !== void 0) {
1658
+ edge.fromUuid = fromUuid;
1659
+ }
1660
+ const sourceGlobalId = readOptionalString2(value.sourceGlobalId);
1661
+ if (sourceGlobalId !== void 0) {
1662
+ edge.sourceGlobalId = sourceGlobalId;
1663
+ }
1664
+ const targetGlobalId = readOptionalString2(value.targetGlobalId);
1665
+ if (targetGlobalId !== void 0) {
1666
+ edge.targetGlobalId = targetGlobalId;
1667
+ }
1668
+ const toGlobalId = readOptionalString2(value.toGlobalId);
1669
+ if (toGlobalId !== void 0) {
1670
+ edge.toGlobalId = toGlobalId;
1671
+ }
1672
+ const toNodeId = readOptionalString2(value.toNodeId);
1673
+ if (toNodeId !== void 0) {
1674
+ edge.toNodeId = toNodeId;
1675
+ }
1676
+ const toUuid = readOptionalString2(value.toUuid);
1677
+ if (toUuid !== void 0) {
1678
+ edge.toUuid = toUuid;
1679
+ }
1680
+ const weight = readOptionalNumber2(value.weight);
1681
+ if (weight !== void 0) {
1682
+ edge.weight = weight;
1683
+ }
1684
+ for (const timestampField of ["_creationTime", "createdAt", "updatedAt"]) {
1685
+ const timestamp = readOptionalNumber2(value[timestampField]);
1686
+ if (timestamp !== void 0) {
1687
+ edge[timestampField] = timestamp;
1688
+ }
1689
+ }
1690
+ return edge;
1691
+ }
1392
1692
  function getEdgeTimestamp(edge) {
1393
1693
  if (typeof edge.updatedAt === "number") {
1394
1694
  return edge.updatedAt;
@@ -1401,22 +1701,86 @@ function getEdgeTimestamp(edge) {
1401
1701
  }
1402
1702
  return null;
1403
1703
  }
1704
+ async function collectNodeEndpointRefs(ctx, nodeId) {
1705
+ const refs = /* @__PURE__ */ new Set([String(nodeId)]);
1706
+ const node = readMetricNodeDoc(await ctx.db.get(nodeId));
1707
+ if (node?.globalId) {
1708
+ refs.add(node.globalId);
1709
+ }
1710
+ return [...refs];
1711
+ }
1712
+ async function collectIncomingEdgeRows(ctx, nodeId, edgeType) {
1713
+ const refs = await collectNodeEndpointRefs(ctx, nodeId);
1714
+ const seen = /* @__PURE__ */ new Set();
1715
+ const edges = [];
1716
+ for (const ref of refs) {
1717
+ const rows = edgeType === void 0 ? await ctx.db.query("epistemicEdges").withIndex("by_to", (q) => q.eq("toNodeId", ref)).collect() : await ctx.db.query("epistemicEdges").withIndex(
1718
+ "by_to_type",
1719
+ (q) => q.eq("toNodeId", ref).eq("edgeType", edgeType)
1720
+ ).collect();
1721
+ for (const row of rows) {
1722
+ const edge = readIncomingEdgeRow(row);
1723
+ if (!edge) {
1724
+ continue;
1725
+ }
1726
+ if (edgeType !== void 0 && edge.edgeType !== edgeType) {
1727
+ continue;
1728
+ }
1729
+ const key = edge._id === void 0 ? `${edge.fromNodeId}->${edge.toNodeId ?? ref}:${edge.edgeType ?? ""}` : String(edge._id);
1730
+ if (seen.has(key)) {
1731
+ continue;
1732
+ }
1733
+ seen.add(key);
1734
+ edges.push(edge);
1735
+ }
1736
+ }
1737
+ return edges;
1738
+ }
1739
+ function sourceEndpointRefs(edge) {
1740
+ return [
1741
+ edge.fromNodeId,
1742
+ edge.sourceGlobalId,
1743
+ edge.fromGlobalId,
1744
+ edge.fromUuid
1745
+ ].filter((value) => value !== void 0);
1746
+ }
1747
+ async function resolveEndpointNode(ctx, refs) {
1748
+ const candidates = refs.map((value) => value.trim()).filter(
1749
+ (value, index, values) => value.length > 0 && values.indexOf(value) === index
1750
+ );
1751
+ for (const candidate of candidates) {
1752
+ try {
1753
+ const direct = readMetricNodeDoc(
1754
+ await ctx.db.get(candidate)
1755
+ );
1756
+ if (direct) {
1757
+ return direct;
1758
+ }
1759
+ } catch {
1760
+ }
1761
+ const byGlobalId = readMetricNodeDoc(
1762
+ await ctx.db.query("epistemicNodes").withIndex("by_globalId", (q) => q.eq("globalId", candidate)).first()
1763
+ );
1764
+ if (byGlobalId) {
1765
+ return byGlobalId;
1766
+ }
1767
+ }
1768
+ return null;
1769
+ }
1404
1770
  async function getEvidenceLinks(ctx, beliefNodeId) {
1405
- const edges = await ctx.db.query("epistemicEdges").withIndex(
1406
- "by_to_type",
1407
- (q) => q.eq("toNodeId", beliefNodeId).eq("edgeType", "informs")
1408
- ).collect();
1771
+ const edges = await collectIncomingEdgeRows(ctx, beliefNodeId, "informs");
1409
1772
  if (edges.length === 0) {
1410
1773
  return [];
1411
1774
  }
1412
- const nodes = await Promise.all(edges.map((edge) => ctx.db.get(edge.fromNodeId)));
1413
- return edges.flatMap((edge, index) => {
1414
- const node = nodes[index];
1415
- if (!node || node.nodeType !== "evidence" || node.status === "archived") {
1416
- return [];
1775
+ const links = [];
1776
+ for (const edge of edges) {
1777
+ const node = await resolveEndpointNode(ctx, sourceEndpointRefs(edge));
1778
+ if (node?.nodeType !== "evidence" || node.status === "archived") {
1779
+ continue;
1417
1780
  }
1418
- return [{ edge, node }];
1419
- });
1781
+ links.push({ edge, node });
1782
+ }
1783
+ return links;
1420
1784
  }
1421
1785
  function getEvidenceTags(node) {
1422
1786
  const metadata = node.metadata && typeof node.metadata === "object" ? node.metadata : null;
@@ -1442,7 +1806,8 @@ async function computeTaggedEvidenceCount(args) {
1442
1806
  };
1443
1807
  }
1444
1808
  async function computeContradictionCounts(ctx, beliefNodeId) {
1445
- const contradictions = await ctx.db.query("contradictions").withIndex("by_beliefId", (q) => q.eq("beliefId", beliefNodeId)).collect();
1809
+ const contradictionDb = ctx.db;
1810
+ const contradictions = await contradictionDb.query("contradictions").withIndex("by_beliefId", (q) => q.eq("beliefId", beliefNodeId)).collect();
1446
1811
  return contradictions.reduce(
1447
1812
  (counts, contradiction) => {
1448
1813
  const status = contradiction.resolutionStatus ?? contradiction.status ?? "unresolved";
@@ -1478,18 +1843,16 @@ async function computeEvidenceFreshness(ctx, beliefNodeId, now = Date.now()) {
1478
1843
  };
1479
1844
  }
1480
1845
  async function computeDependentBeliefCount(ctx, beliefNodeId) {
1481
- const incomingEdges = await ctx.db.query("epistemicEdges").withIndex("by_to", (q) => q.eq("toNodeId", beliefNodeId)).collect();
1846
+ const incomingEdges = await collectIncomingEdgeRows(ctx, beliefNodeId);
1482
1847
  const dependencyEdges = incomingEdges.filter(
1483
- (edge) => DEPENDENT_EDGE_TYPES.has(edge.edgeType)
1848
+ (edge) => edge.edgeType ? DEPENDENT_EDGE_TYPES.has(edge.edgeType) : false
1484
1849
  );
1485
1850
  if (dependencyEdges.length === 0) {
1486
1851
  return 0;
1487
1852
  }
1488
- const dependentBeliefs = await Promise.all(
1489
- dependencyEdges.map((edge) => ctx.db.get(edge.fromNodeId))
1490
- );
1491
1853
  const uniqueBeliefIds = /* @__PURE__ */ new Set();
1492
- for (const node of dependentBeliefs) {
1854
+ for (const edge of dependencyEdges) {
1855
+ const node = await resolveEndpointNode(ctx, sourceEndpointRefs(edge));
1493
1856
  if (node && node.nodeType === "belief" && node.status !== "archived" && node.status !== "deleted") {
1494
1857
  uniqueBeliefIds.add(String(node._id));
1495
1858
  }
@@ -1499,7 +1862,10 @@ async function computeDependentBeliefCount(ctx, beliefNodeId) {
1499
1862
  async function snapshotEvidentialMetric(args) {
1500
1863
  switch (args.metric) {
1501
1864
  case "evidence_count": {
1502
- const count = await computeEvidenceCountMetric(args.ctx, args.beliefNodeId);
1865
+ const count = await computeEvidenceCountMetric(
1866
+ args.ctx,
1867
+ args.beliefNodeId
1868
+ );
1503
1869
  return {
1504
1870
  metric: args.metric,
1505
1871
  value: count,
@@ -1507,7 +1873,10 @@ async function snapshotEvidentialMetric(args) {
1507
1873
  };
1508
1874
  }
1509
1875
  case "contradiction_status": {
1510
- const counts = await computeContradictionCounts(args.ctx, args.beliefNodeId);
1876
+ const counts = await computeContradictionCounts(
1877
+ args.ctx,
1878
+ args.beliefNodeId
1879
+ );
1511
1880
  return {
1512
1881
  metric: args.metric,
1513
1882
  value: counts.activeCount,
@@ -1527,7 +1896,10 @@ async function snapshotEvidentialMetric(args) {
1527
1896
  };
1528
1897
  }
1529
1898
  case "dependent_count": {
1530
- const count = await computeDependentBeliefCount(args.ctx, args.beliefNodeId);
1899
+ const count = await computeDependentBeliefCount(
1900
+ args.ctx,
1901
+ args.beliefNodeId
1902
+ );
1531
1903
  return {
1532
1904
  metric: args.metric,
1533
1905
  value: count,
@@ -1543,7 +1915,9 @@ async function snapshotEvidentialMetric(args) {
1543
1915
  }
1544
1916
  }
1545
1917
  async function evaluateBuiltInEvidentialContract(args) {
1546
- const config = parseEvidentialEvaluatorConfig(args.contract.condition.evaluatorConfig);
1918
+ const config = parseEvidentialEvaluatorConfig(
1919
+ args.contract.condition.evaluatorConfig
1920
+ );
1547
1921
  const snapshot = await snapshotEvidentialMetric({
1548
1922
  ctx: args.ctx,
1549
1923
  beliefNodeId: args.belief._id,
@@ -1551,7 +1925,10 @@ async function evaluateBuiltInEvidentialContract(args) {
1551
1925
  now: args.now
1552
1926
  });
1553
1927
  const comparisonSatisfied = snapshot.value !== null && compareMetricValue(config.operator, snapshot.value, config.threshold);
1554
- const result = args.contract.direction === "falsifies" ? comparisonSatisfied ? "disconfirmed" : "confirmed" : comparisonSatisfied ? "confirmed" : "disconfirmed";
1928
+ const result = resolveComparisonResult(
1929
+ args.contract.direction,
1930
+ comparisonSatisfied
1931
+ );
1555
1932
  return {
1556
1933
  result,
1557
1934
  rationale: buildEvidentialRationale({
@@ -1571,57 +1948,66 @@ async function evaluateBuiltInEvidentialContract(args) {
1571
1948
  }
1572
1949
  };
1573
1950
  }
1574
- async function evaluateMetricCheckerContract(args) {
1575
- const config = parseMetricCheckerConfig(args.contract.condition.evaluatorConfig);
1576
- const input = getEvaluatorInputRecord(args.inputData, "metricData");
1577
- const metric = typeof input.metric === "string" && input.metric.length > 0 ? input.metric : config.metric;
1578
- const observedValue = pickFiniteNumber(input, [
1579
- "observedValue",
1580
- "currentValue",
1581
- "metricValue",
1582
- "value"
1583
- ]) ?? config.observedValue ?? config.currentValue ?? config.metricValue ?? null;
1584
- if (observedValue === null) {
1951
+ function evaluateMetricCheckerContract(args) {
1952
+ return Promise.resolve().then(() => {
1953
+ const config = parseMetricCheckerConfig(
1954
+ args.contract.condition.evaluatorConfig
1955
+ );
1956
+ const input = getEvaluatorInputRecord(args.inputData, "metricData");
1957
+ const metric = typeof input.metric === "string" && input.metric.length > 0 ? input.metric : config.metric;
1958
+ const observedValue = pickFiniteNumber(input, [
1959
+ "observedValue",
1960
+ "currentValue",
1961
+ "metricValue",
1962
+ "value"
1963
+ ]) ?? config.observedValue ?? config.currentValue ?? config.metricValue ?? null;
1964
+ if (observedValue === null) {
1965
+ return {
1966
+ result: "inconclusive",
1967
+ rationale: `metric_checker is awaiting data for ${metric ?? args.contract.condition.expression}.`,
1968
+ data: {
1969
+ metric,
1970
+ observedValue: null,
1971
+ operator: config.operator,
1972
+ threshold: config.threshold,
1973
+ unit: config.unit
1974
+ }
1975
+ };
1976
+ }
1977
+ const comparisonSatisfied = compareMetricValue(
1978
+ config.operator,
1979
+ observedValue,
1980
+ config.threshold
1981
+ );
1982
+ const result = resolveComparisonResult(
1983
+ args.contract.direction,
1984
+ comparisonSatisfied
1985
+ );
1585
1986
  return {
1586
- result: "inconclusive",
1587
- rationale: `metric_checker is awaiting data for ${metric ?? args.contract.condition.expression}.`,
1987
+ result,
1988
+ rationale: buildComparisonRationale({
1989
+ label: metric ?? "metric",
1990
+ observedValue,
1991
+ operator: config.operator,
1992
+ threshold: config.threshold,
1993
+ comparisonSatisfied,
1994
+ result,
1995
+ unit: config.unit
1996
+ }),
1588
1997
  data: {
1589
1998
  metric,
1590
- observedValue: null,
1999
+ observedValue,
1591
2000
  operator: config.operator,
1592
2001
  threshold: config.threshold,
1593
2002
  unit: config.unit
1594
2003
  }
1595
2004
  };
1596
- }
1597
- const comparisonSatisfied = compareMetricValue(
1598
- config.operator,
1599
- observedValue,
1600
- config.threshold
1601
- );
1602
- const result = resolveComparisonResult(args.contract.direction, comparisonSatisfied);
1603
- return {
1604
- result,
1605
- rationale: buildComparisonRationale({
1606
- label: metric ?? "metric",
1607
- observedValue,
1608
- operator: config.operator,
1609
- threshold: config.threshold,
1610
- comparisonSatisfied,
1611
- result,
1612
- unit: config.unit
1613
- }),
1614
- data: {
1615
- metric,
1616
- observedValue,
1617
- operator: config.operator,
1618
- threshold: config.threshold,
1619
- unit: config.unit
1620
- }
1621
- };
2005
+ });
1622
2006
  }
1623
2007
  async function evaluateReferenceCheckCounterContract(args) {
1624
- const config = parseReferenceCheckCounterConfig(args.contract.condition.evaluatorConfig);
2008
+ const config = parseReferenceCheckCounterConfig(
2009
+ args.contract.condition.evaluatorConfig
2010
+ );
1625
2011
  const input = getEvaluatorInputRecord(args.inputData, "referenceCheckData");
1626
2012
  const tag = typeof input.tag === "string" && input.tag.trim().length > 0 ? input.tag.trim() : config.tag;
1627
2013
  const snapshot = await computeTaggedEvidenceCount({
@@ -1635,7 +2021,10 @@ async function evaluateReferenceCheckCounterContract(args) {
1635
2021
  snapshot.count,
1636
2022
  config.threshold
1637
2023
  );
1638
- const result = resolveComparisonResult(args.contract.direction, comparisonSatisfied);
2024
+ const result = resolveComparisonResult(
2025
+ args.contract.direction,
2026
+ comparisonSatisfied
2027
+ );
1639
2028
  return {
1640
2029
  result,
1641
2030
  rationale: buildComparisonRationale({
@@ -1657,130 +2046,167 @@ async function evaluateReferenceCheckCounterContract(args) {
1657
2046
  }
1658
2047
  };
1659
2048
  }
1660
- async function evaluateTemporalDeadlineContract(args) {
1661
- if (typeof args.contract.deadline !== "number" || !Number.isFinite(args.contract.deadline)) {
1662
- throw new Error(
1663
- "temporal_deadline requires contract.deadline to be set to a finite timestamp."
1664
- );
1665
- }
1666
- const config = parseTemporalDeadlineConfig(args.contract.condition.evaluatorConfig);
1667
- const input = getEvaluatorInputRecord(args.inputData, "temporalData");
1668
- const label = (typeof input.label === "string" && input.label.length > 0 ? input.label : config.label) ?? args.contract.title ?? args.contract.condition.expression;
1669
- const completedAt = pickFiniteNumber(input, [
1670
- "completedAt",
1671
- "observedAt",
1672
- "satisfiedAt",
1673
- "achievedAt"
1674
- ]) ?? config.completedAt ?? config.observedAt ?? config.satisfiedAt ?? config.achievedAt;
1675
- const completed = input.completed === true || config.completed === true || completedAt !== void 0;
1676
- if (completed) {
1677
- if (completedAt !== void 0 && completedAt > args.contract.deadline) {
1678
- return {
1679
- result: "expired",
1680
- rationale: `${label} completed at ${completedAt}, after deadline ${args.contract.deadline}.`,
1681
- data: {
1682
- label,
1683
- deadline: args.contract.deadline,
1684
- completed: true,
1685
- completedAt,
1686
- missedDeadline: true,
1687
- overdueByMs: completedAt - args.contract.deadline
1688
- }
1689
- };
1690
- }
1691
- const result = args.contract.direction === "falsifies" ? "disconfirmed" : "confirmed";
2049
+ function resolveCompletedTemporalDeadlineResult(args) {
2050
+ const { completedAt, context, deadline, label } = args;
2051
+ if (completedAt !== void 0 && completedAt > deadline) {
1692
2052
  return {
1693
- result,
1694
- rationale: `${label} completed before deadline ${args.contract.deadline}.`,
2053
+ result: "expired",
2054
+ rationale: `${label} completed at ${completedAt}, after deadline ${deadline}.`,
1695
2055
  data: {
1696
2056
  label,
1697
- deadline: args.contract.deadline,
2057
+ deadline,
1698
2058
  completed: true,
1699
- completedAt: completedAt ?? null,
1700
- missedDeadline: false
2059
+ completedAt,
2060
+ missedDeadline: true,
2061
+ overdueByMs: completedAt - deadline
1701
2062
  }
1702
2063
  };
1703
2064
  }
1704
- if (args.now > args.contract.deadline) {
2065
+ const result = context.contract.direction === "falsifies" ? "disconfirmed" : "confirmed";
2066
+ return {
2067
+ result,
2068
+ rationale: `${label} completed before deadline ${deadline}.`,
2069
+ data: {
2070
+ label,
2071
+ deadline,
2072
+ completed: true,
2073
+ completedAt: completedAt ?? null,
2074
+ missedDeadline: false
2075
+ }
2076
+ };
2077
+ }
2078
+ function resolveOpenTemporalDeadlineResult(args) {
2079
+ const { context, deadline, label } = args;
2080
+ if (context.now > deadline) {
1705
2081
  return {
1706
2082
  result: "expired",
1707
- rationale: `${label} missed deadline ${args.contract.deadline}; temporal contract expired.`,
2083
+ rationale: `${label} missed deadline ${deadline}; temporal contract expired.`,
1708
2084
  data: {
1709
2085
  label,
1710
- deadline: args.contract.deadline,
2086
+ deadline,
1711
2087
  completed: false,
1712
- overdueByMs: args.now - args.contract.deadline
2088
+ overdueByMs: context.now - deadline
1713
2089
  }
1714
2090
  };
1715
2091
  }
1716
2092
  return {
1717
2093
  result: "inconclusive",
1718
- rationale: `${label} is still before deadline ${args.contract.deadline}; awaiting outcome.`,
2094
+ rationale: `${label} is still before deadline ${deadline}; awaiting outcome.`,
1719
2095
  data: {
1720
2096
  label,
1721
- deadline: args.contract.deadline,
2097
+ deadline,
1722
2098
  completed: false,
1723
- timeRemainingMs: args.contract.deadline - args.now
2099
+ timeRemainingMs: deadline - context.now
1724
2100
  }
1725
2101
  };
1726
2102
  }
1727
- async function evaluateMarketIndexComparatorContract(args) {
1728
- const config = parseMarketIndexComparatorConfig(args.contract.condition.evaluatorConfig);
1729
- const input = getEvaluatorInputRecord(args.inputData, "marketIndexData");
1730
- const subject = typeof input.subject === "string" && input.subject.length > 0 ? input.subject : config.subject;
1731
- const benchmark = typeof input.benchmark === "string" && input.benchmark.length > 0 ? input.benchmark : config.benchmark;
1732
- const subjectValue = pickFiniteNumber(input, ["subjectValue", "primaryValue", "leftValue"]) ?? config.subjectValue ?? config.primaryValue ?? null;
1733
- const benchmarkValue = pickFiniteNumber(input, ["benchmarkValue", "comparisonValue", "rightValue"]) ?? config.benchmarkValue ?? config.comparisonValue ?? null;
1734
- if (subjectValue === null || benchmarkValue === null) {
2103
+ function evaluateTemporalDeadlineContract(args) {
2104
+ return Promise.resolve().then(() => {
2105
+ if (typeof args.contract.deadline !== "number" || !Number.isFinite(args.contract.deadline)) {
2106
+ throw new Error(
2107
+ "temporal_deadline requires contract.deadline to be set to a finite timestamp."
2108
+ );
2109
+ }
2110
+ const deadline = args.contract.deadline;
2111
+ const config = parseTemporalDeadlineConfig(
2112
+ args.contract.condition.evaluatorConfig
2113
+ );
2114
+ const input = getEvaluatorInputRecord(args.inputData, "temporalData");
2115
+ const label = (typeof input.label === "string" && input.label.length > 0 ? input.label : config.label) ?? args.contract.title ?? args.contract.condition.expression;
2116
+ const completedAt = pickFiniteNumber(input, [
2117
+ "completedAt",
2118
+ "observedAt",
2119
+ "satisfiedAt",
2120
+ "achievedAt"
2121
+ ]) ?? config.completedAt ?? config.observedAt ?? config.satisfiedAt ?? config.achievedAt;
2122
+ const completed = input.completed === true || config.completed === true || completedAt !== void 0;
2123
+ if (completed) {
2124
+ return resolveCompletedTemporalDeadlineResult({
2125
+ completedAt,
2126
+ context: args,
2127
+ deadline,
2128
+ label
2129
+ });
2130
+ }
2131
+ return resolveOpenTemporalDeadlineResult({
2132
+ context: args,
2133
+ deadline,
2134
+ label
2135
+ });
2136
+ });
2137
+ }
2138
+ function evaluateMarketIndexComparatorContract(args) {
2139
+ return Promise.resolve().then(() => {
2140
+ const config = parseMarketIndexComparatorConfig(
2141
+ args.contract.condition.evaluatorConfig
2142
+ );
2143
+ const input = getEvaluatorInputRecord(args.inputData, "marketIndexData");
2144
+ const subject = typeof input.subject === "string" && input.subject.length > 0 ? input.subject : config.subject;
2145
+ const benchmark = typeof input.benchmark === "string" && input.benchmark.length > 0 ? input.benchmark : config.benchmark;
2146
+ const subjectValue = pickFiniteNumber(input, ["subjectValue", "primaryValue", "leftValue"]) ?? config.subjectValue ?? config.primaryValue ?? null;
2147
+ const benchmarkValue = pickFiniteNumber(input, [
2148
+ "benchmarkValue",
2149
+ "comparisonValue",
2150
+ "rightValue"
2151
+ ]) ?? config.benchmarkValue ?? config.comparisonValue ?? null;
2152
+ if (subjectValue === null || benchmarkValue === null) {
2153
+ return {
2154
+ result: "inconclusive",
2155
+ rationale: "market_index_comparator is awaiting both subject and benchmark values.",
2156
+ data: {
2157
+ subject,
2158
+ subjectValue,
2159
+ benchmark,
2160
+ benchmarkValue,
2161
+ operator: config.operator,
2162
+ threshold: config.threshold
2163
+ }
2164
+ };
2165
+ }
2166
+ if (benchmarkValue === 0) {
2167
+ throw new Error(
2168
+ "market_index_comparator cannot compare against a zero benchmark value."
2169
+ );
2170
+ }
2171
+ const differentialPercent = (subjectValue - benchmarkValue) / Math.abs(benchmarkValue) * 100;
2172
+ const comparisonSatisfied = compareMetricValue(
2173
+ config.operator,
2174
+ differentialPercent,
2175
+ config.threshold
2176
+ );
2177
+ const result = resolveComparisonResult(
2178
+ args.contract.direction,
2179
+ comparisonSatisfied
2180
+ );
1735
2181
  return {
1736
- result: "inconclusive",
1737
- rationale: "market_index_comparator is awaiting both subject and benchmark values.",
2182
+ result,
2183
+ rationale: buildComparisonRationale({
2184
+ label: `${subject ?? "subject"} vs ${benchmark ?? "benchmark"} differential`,
2185
+ observedValue: differentialPercent,
2186
+ operator: config.operator,
2187
+ threshold: config.threshold,
2188
+ comparisonSatisfied,
2189
+ result,
2190
+ unit: "%"
2191
+ }),
1738
2192
  data: {
1739
2193
  subject,
1740
2194
  subjectValue,
1741
2195
  benchmark,
1742
2196
  benchmarkValue,
2197
+ differentialPercent,
1743
2198
  operator: config.operator,
1744
2199
  threshold: config.threshold
1745
2200
  }
1746
2201
  };
1747
- }
1748
- if (benchmarkValue === 0) {
1749
- throw new Error(
1750
- "market_index_comparator cannot compare against a zero benchmark value."
1751
- );
1752
- }
1753
- const differentialPercent = (subjectValue - benchmarkValue) / Math.abs(benchmarkValue) * 100;
1754
- const comparisonSatisfied = compareMetricValue(
1755
- config.operator,
1756
- differentialPercent,
1757
- config.threshold
1758
- );
1759
- const result = resolveComparisonResult(args.contract.direction, comparisonSatisfied);
1760
- return {
1761
- result,
1762
- rationale: buildComparisonRationale({
1763
- label: `${subject ?? "subject"} vs ${benchmark ?? "benchmark"} differential`,
1764
- observedValue: differentialPercent,
1765
- operator: config.operator,
1766
- threshold: config.threshold,
1767
- comparisonSatisfied,
1768
- result,
1769
- unit: "%"
1770
- }),
1771
- data: {
1772
- subject,
1773
- subjectValue,
1774
- benchmark,
1775
- benchmarkValue,
1776
- differentialPercent,
1777
- operator: config.operator,
1778
- threshold: config.threshold
1779
- }
1780
- };
2202
+ });
1781
2203
  }
1782
2204
  var METRIC_COMPARATOR_EVALUATOR_NAMES = {
1783
- evidentialAliases: /* @__PURE__ */ new Set(["evidential", "built_in_evidential", "builtin_evidential"]),
2205
+ evidentialAliases: /* @__PURE__ */ new Set([
2206
+ "evidential",
2207
+ "built_in_evidential",
2208
+ "builtin_evidential"
2209
+ ]),
1784
2210
  metricChecker: "metric_checker",
1785
2211
  referenceCheckCounter: "reference_check_counter",
1786
2212
  temporalDeadline: "temporal_deadline",
@@ -1788,6 +2214,8 @@ var METRIC_COMPARATOR_EVALUATOR_NAMES = {
1788
2214
  };
1789
2215
 
1790
2216
  // src/evaluators/shared.ts
2217
+ var WINDOWS_PATH_SEPARATORS = /\\/g;
2218
+ var LEADING_DOT_SLASH = /^\.\//;
1791
2219
  function asArray(value) {
1792
2220
  return Array.isArray(value) ? value : [];
1793
2221
  }
@@ -1829,7 +2257,7 @@ function extractTextCandidates(value) {
1829
2257
  return Array.from(new Set(candidates));
1830
2258
  }
1831
2259
  function normalizeFilePath(value) {
1832
- return value.replace(/\\/g, "/").replace(/^\.\//, "");
2260
+ return value.replace(WINDOWS_PATH_SEPARATORS, "/").replace(LEADING_DOT_SLASH, "");
1833
2261
  }
1834
2262
  function normalizeToolResultEnvelope(value) {
1835
2263
  const record = asRecord(value);
@@ -1883,7 +2311,7 @@ function somePatternMatches(filePath, patterns) {
1883
2311
  return patterns.some((pattern) => patternMatchesPath(filePath, pattern));
1884
2312
  }
1885
2313
 
1886
- // src/evaluators/lintCheckerEvaluator.ts
2314
+ // src/evaluators/lint-checker-evaluator.ts
1887
2315
  function parseConfig(condition) {
1888
2316
  const record = asRecord(condition.evaluatorConfig);
1889
2317
  if (!record) {
@@ -1955,7 +2383,10 @@ var lintCheckerEvaluator = {
1955
2383
  }
1956
2384
  const envelope = normalizeToolResultEnvelope(args.resultData);
1957
2385
  const exitCode = asNumber(envelope.exitCode);
1958
- const matchedDiagnostics = getMatchedDiagnostics(args.contract, args.resultData);
2386
+ const matchedDiagnostics = getMatchedDiagnostics(
2387
+ args.contract,
2388
+ args.resultData
2389
+ );
1959
2390
  if (matchedDiagnostics.length === 0 && exitCode !== 0 && exitCode !== null) {
1960
2391
  return {
1961
2392
  result: "inconclusive",
@@ -1981,7 +2412,7 @@ var lintCheckerEvaluator = {
1981
2412
  }
1982
2413
  };
1983
2414
 
1984
- // src/evaluators/sentryCheckerEvaluator.ts
2415
+ // src/evaluators/sentry-checker-evaluator.ts
1985
2416
  function parseConfig2(condition) {
1986
2417
  const record = asRecord(condition.evaluatorConfig);
1987
2418
  if (!record) {
@@ -2066,7 +2497,7 @@ var sentryCheckerEvaluator = {
2066
2497
  }
2067
2498
  };
2068
2499
 
2069
- // src/evaluators/testRunnerEvaluator.ts
2500
+ // src/evaluators/test-runner-evaluator.ts
2070
2501
  function parseConfig3(condition) {
2071
2502
  const record = asRecord(condition.evaluatorConfig);
2072
2503
  if (!record) {
@@ -2212,7 +2643,7 @@ var testRunnerEvaluator = {
2212
2643
  }
2213
2644
  };
2214
2645
 
2215
- // src/evaluators/tscCheckerEvaluator.ts
2646
+ // src/evaluators/tsc-checker-evaluator.ts
2216
2647
  function parseConfig4(condition) {
2217
2648
  const record = asRecord(condition.evaluatorConfig);
2218
2649
  if (!record) {
@@ -2297,7 +2728,10 @@ var tscCheckerEvaluator = {
2297
2728
  }
2298
2729
  const envelope = normalizeToolResultEnvelope(args.resultData);
2299
2730
  const exitCode = asNumber(envelope.exitCode);
2300
- const matchedDiagnostics = getMatchedDiagnostics2(args.contract, args.resultData);
2731
+ const matchedDiagnostics = getMatchedDiagnostics2(
2732
+ args.contract,
2733
+ args.resultData
2734
+ );
2301
2735
  if (matchedDiagnostics.length === 0 && exitCode !== 0 && exitCode !== null) {
2302
2736
  return {
2303
2737
  result: "inconclusive",
@@ -2346,6 +2780,18 @@ var BUILT_IN_REFERENCE_CHECK_COUNTER2 = METRIC_COMPARATOR_EVALUATOR_NAMES.refere
2346
2780
  var BUILT_IN_TEMPORAL_DEADLINE2 = METRIC_COMPARATOR_EVALUATOR_NAMES.temporalDeadline;
2347
2781
  var BUILT_IN_MARKET_INDEX_COMPARATOR2 = METRIC_COMPARATOR_EVALUATOR_NAMES.marketIndexComparator;
2348
2782
  var MAX_CONTRACT_EVALUATION_BATCH_SIZE = 50;
2783
+ function confidenceSeed(args) {
2784
+ if (typeof args.currentConfidence === "number") {
2785
+ return args.currentConfidence;
2786
+ }
2787
+ if (typeof args.beliefConfidence === "number") {
2788
+ return args.beliefConfidence;
2789
+ }
2790
+ return 0.5;
2791
+ }
2792
+ function contractDocId(contract) {
2793
+ return contract._id;
2794
+ }
2349
2795
  function clearEpistemicEvaluators() {
2350
2796
  evaluatorRegistry.clear();
2351
2797
  ensureBuiltInEvaluators();
@@ -2438,7 +2884,10 @@ async function executeContractEvaluation(args) {
2438
2884
  rationale: `No epistemic evaluator registered for "${args.contract.condition.evaluator}".`
2439
2885
  };
2440
2886
  }
2441
- const confidenceBefore = typeof args.currentConfidence === "number" ? args.currentConfidence : typeof args.belief.confidence === "number" ? args.belief.confidence : 0.5;
2887
+ const confidenceBefore = confidenceSeed({
2888
+ beliefConfidence: args.belief.confidence,
2889
+ currentConfidence: args.currentConfidence
2890
+ });
2442
2891
  const modulationPlan = deriveContractModulationPlan({
2443
2892
  currentConfidence: confidenceBefore,
2444
2893
  modulation: args.contract.modulation,
@@ -2478,16 +2927,16 @@ async function executeContractEvaluation(args) {
2478
2927
  modulationRationale: evaluation.rationale,
2479
2928
  topicId: args.contract.topicId
2480
2929
  });
2481
- const nextStatus = deriveContractStatus(evaluation.result, args.contract.status);
2482
- await args.ctx.db.patch(
2483
- args.contract._id,
2484
- {
2485
- status: nextStatus,
2486
- lastEvaluatedAt: args.now,
2487
- evaluationCount: (args.contract.evaluationCount ?? 0) + 1,
2488
- updatedAt: args.now
2489
- }
2930
+ const nextStatus = deriveContractStatus(
2931
+ evaluation.result,
2932
+ args.contract.status
2490
2933
  );
2934
+ await args.ctx.db.patch(contractDocId(args.contract), {
2935
+ status: nextStatus,
2936
+ lastEvaluatedAt: args.now,
2937
+ evaluationCount: (args.contract.evaluationCount ?? 0) + 1,
2938
+ updatedAt: args.now
2939
+ });
2491
2940
  return {
2492
2941
  evaluationId,
2493
2942
  result: evaluation.result,
@@ -2572,7 +3021,8 @@ async function evaluateContractsForTriggerBatch(args) {
2572
3021
  };
2573
3022
  }
2574
3023
  async function loadContractsForBelief(args) {
2575
- return await args.ctx.db.query("epistemicContracts").withIndex("by_belief", (q) => q.eq("beliefNodeId", args.beliefNodeId)).collect();
3024
+ const rows = await args.ctx.db.query("epistemicContracts").withIndex("by_belief", (q) => q.eq("beliefNodeId", args.beliefNodeId)).collect();
3025
+ return rows;
2576
3026
  }
2577
3027
  async function loadContractsForTrigger(args) {
2578
3028
  const contracts = await loadContractsForBelief(args);
@@ -2607,6 +3057,24 @@ function resolveSchedulesForTrigger2(trigger) {
2607
3057
  }
2608
3058
  return /* @__PURE__ */ new Set(["event_driven"]);
2609
3059
  }
3060
+ function contractTables(ctx) {
3061
+ return ctx.db;
3062
+ }
3063
+ function assertBeliefNode(value, message = "Belief not found.") {
3064
+ if (!value || typeof value !== "object" || value.nodeType !== "belief") {
3065
+ throw new Error(message);
3066
+ }
3067
+ return value;
3068
+ }
3069
+ function normalizeEngineeringTrigger(trigger) {
3070
+ if (trigger === "manual") {
3071
+ return "manual";
3072
+ }
3073
+ if (trigger === "evidence_added") {
3074
+ return "evidence_added";
3075
+ }
3076
+ return trigger;
3077
+ }
2610
3078
  async function requireAuth(ctx) {
2611
3079
  const userId = await getCurrentUserId(ctx);
2612
3080
  if (!userId) {
@@ -2642,17 +3110,21 @@ async function requireTopicReadAccess(ctx, beliefs, userId) {
2642
3110
  projectIds.add(belief.projectId);
2643
3111
  }
2644
3112
  for (const projectId of projectIds) {
2645
- const hasAccess = await checkProjectAccess(ctx, projectId, userId);
3113
+ const hasAccess = await checkProjectAccess(
3114
+ ctx,
3115
+ projectId,
3116
+ userId
3117
+ );
2646
3118
  if (!hasAccess) {
2647
3119
  throw new Error("Project access required.");
2648
3120
  }
2649
3121
  }
2650
3122
  }
2651
3123
  async function getContractByContractId(ctx, contractId) {
2652
- return await ctx.db.query("epistemicContracts").withIndex("by_contractId", (q) => q.eq("contractId", contractId)).first();
3124
+ return await contractTables(ctx).query("epistemicContracts").withIndex("by_contractId", (q) => q.eq("contractId", contractId)).first();
2653
3125
  }
2654
3126
  async function getLatestEvaluation(ctx, contractId) {
2655
- const evaluations = await ctx.db.query("contractEvaluations").withIndex("by_contract_time", (q) => q.eq("contractId", contractId)).order("desc").take(1);
3127
+ const evaluations = await contractTables(ctx).query("contractEvaluations").withIndex("by_contract_time", (q) => q.eq("contractId", contractId)).order("desc").take(1);
2656
3128
  return evaluations[0] ?? null;
2657
3129
  }
2658
3130
  var evaluateEvidenceCount = query({
@@ -2662,10 +3134,7 @@ var evaluateEvidenceCount = query({
2662
3134
  returns: permissiveReturn,
2663
3135
  handler: async (ctx, args) => {
2664
3136
  const userId = await requireAuth(ctx);
2665
- const belief = await ctx.db.get(args.beliefNodeId);
2666
- if (!belief || belief.nodeType !== "belief") {
2667
- throw new Error("Belief not found.");
2668
- }
3137
+ const belief = assertBeliefNode(await ctx.db.get(args.beliefNodeId));
2669
3138
  await requireBeliefProjectAccess(ctx, belief, userId);
2670
3139
  return await computeEvidenceCountMetric(ctx, args.beliefNodeId);
2671
3140
  }
@@ -2677,10 +3146,7 @@ var evaluateContradictionStatus = query({
2677
3146
  returns: permissiveReturn,
2678
3147
  handler: async (ctx, args) => {
2679
3148
  const userId = await requireAuth(ctx);
2680
- const belief = await ctx.db.get(args.beliefNodeId);
2681
- if (!belief || belief.nodeType !== "belief") {
2682
- throw new Error("Belief not found.");
2683
- }
3149
+ const belief = assertBeliefNode(await ctx.db.get(args.beliefNodeId));
2684
3150
  await requireBeliefProjectAccess(ctx, belief, userId);
2685
3151
  return await computeContradictionCounts(ctx, args.beliefNodeId);
2686
3152
  }
@@ -2692,10 +3158,7 @@ var evaluateEdgeFreshness = query({
2692
3158
  returns: permissiveReturn,
2693
3159
  handler: async (ctx, args) => {
2694
3160
  const userId = await requireAuth(ctx);
2695
- const belief = await ctx.db.get(args.beliefNodeId);
2696
- if (!belief || belief.nodeType !== "belief") {
2697
- throw new Error("Belief not found.");
2698
- }
3161
+ const belief = assertBeliefNode(await ctx.db.get(args.beliefNodeId));
2699
3162
  await requireBeliefProjectAccess(ctx, belief, userId);
2700
3163
  return await computeEvidenceFreshness(ctx, args.beliefNodeId);
2701
3164
  }
@@ -2707,10 +3170,7 @@ var evaluateDependentBeliefCount = query({
2707
3170
  returns: permissiveReturn,
2708
3171
  handler: async (ctx, args) => {
2709
3172
  const userId = await requireAuth(ctx);
2710
- const belief = await ctx.db.get(args.beliefNodeId);
2711
- if (!belief || belief.nodeType !== "belief") {
2712
- throw new Error("Belief not found.");
2713
- }
3173
+ const belief = assertBeliefNode(await ctx.db.get(args.beliefNodeId));
2714
3174
  await requireBeliefProjectAccess(ctx, belief, userId);
2715
3175
  return await computeDependentBeliefCount(ctx, args.beliefNodeId);
2716
3176
  }
@@ -2774,10 +3234,7 @@ var createEpistemicContract = mutation({
2774
3234
  ctx,
2775
3235
  args.authenticatedUserId
2776
3236
  );
2777
- const belief = await ctx.db.get(args.beliefNodeId);
2778
- if (!belief || belief.nodeType !== "belief") {
2779
- throw new Error("Belief not found.");
2780
- }
3237
+ const belief = assertBeliefNode(await ctx.db.get(args.beliefNodeId));
2781
3238
  await requireBeliefProjectAccess(ctx, belief, userId);
2782
3239
  const now = Date.now();
2783
3240
  const contractId = generateGlobalId();
@@ -2832,10 +3289,10 @@ var evaluateContract = mutation({
2832
3289
  if (contract.status === "archived") {
2833
3290
  throw new Error("Archived contracts cannot be evaluated.");
2834
3291
  }
2835
- const belief = await ctx.db.get(contract.beliefNodeId);
2836
- if (!belief || belief.nodeType !== "belief") {
2837
- throw new Error("Belief not found for contract.");
2838
- }
3292
+ const belief = assertBeliefNode(
3293
+ await ctx.db.get(contract.beliefNodeId),
3294
+ "Belief not found for contract."
3295
+ );
2839
3296
  await requireBeliefProjectAccess(ctx, belief, userId);
2840
3297
  const evaluation = await executeContractEvaluation({
2841
3298
  ctx,
@@ -2873,14 +3330,11 @@ var evaluateEngineeringContracts = mutation({
2873
3330
  ctx,
2874
3331
  args.authenticatedUserId
2875
3332
  );
2876
- const belief = await ctx.db.get(args.beliefNodeId);
2877
- if (!belief || belief.nodeType !== "belief") {
2878
- throw new Error("Belief not found.");
2879
- }
3333
+ const belief = assertBeliefNode(await ctx.db.get(args.beliefNodeId));
2880
3334
  await requireBeliefProjectAccess(ctx, belief, userId);
2881
3335
  const trigger = args.trigger ?? "event_driven";
2882
3336
  const allowedSchedules = resolveSchedulesForTrigger2(
2883
- trigger === "manual" ? "manual" : trigger === "evidence_added" ? "evidence_added" : trigger
3337
+ normalizeEngineeringTrigger(trigger)
2884
3338
  );
2885
3339
  const payloadByEvaluator = /* @__PURE__ */ new Map([
2886
3340
  ["test_runner", args.testOutput],
@@ -2959,10 +3413,7 @@ var evaluateContractsForTrigger = mutation({
2959
3413
  ctx,
2960
3414
  args.authenticatedUserId
2961
3415
  );
2962
- const belief = await ctx.db.get(args.beliefNodeId);
2963
- if (!belief || belief.nodeType !== "belief") {
2964
- throw new Error("Belief not found.");
2965
- }
3416
+ const belief = assertBeliefNode(await ctx.db.get(args.beliefNodeId));
2966
3417
  await requireBeliefProjectAccess(ctx, belief, userId);
2967
3418
  return await evaluateContractsForTriggerBatch({
2968
3419
  ctx,
@@ -2985,10 +3436,7 @@ var processContractEvaluationOverflow = internalMutation({
2985
3436
  },
2986
3437
  returns: permissiveReturn,
2987
3438
  handler: async (ctx, args) => {
2988
- const belief = await ctx.db.get(args.beliefNodeId);
2989
- if (!belief || belief.nodeType !== "belief") {
2990
- throw new Error("Belief not found.");
2991
- }
3439
+ const belief = assertBeliefNode(await ctx.db.get(args.beliefNodeId));
2992
3440
  return await evaluateContractsForTriggerBatch({
2993
3441
  ctx,
2994
3442
  belief,
@@ -3027,15 +3475,9 @@ var getContractStatus = query({
3027
3475
  const contract = await getContractByContractId(ctx, args.contractId);
3028
3476
  contracts = contract ? [contract] : [];
3029
3477
  } else if (args.beliefNodeId) {
3030
- const belief = await ctx.db.get(args.beliefNodeId);
3031
- if (!belief || belief.nodeType !== "belief") {
3032
- throw new Error("Belief not found.");
3033
- }
3478
+ const belief = assertBeliefNode(await ctx.db.get(args.beliefNodeId));
3034
3479
  await requireBeliefProjectAccess(ctx, belief, userId);
3035
- contracts = await ctx.db.query("epistemicContracts").withIndex(
3036
- "by_belief",
3037
- (q) => q.eq("beliefNodeId", args.beliefNodeId)
3038
- ).collect();
3480
+ contracts = await contractTables(ctx).query("epistemicContracts").withIndex("by_belief", (q) => q.eq("beliefNodeId", args.beliefNodeId)).collect();
3039
3481
  }
3040
3482
  if (contracts.length > 0) {
3041
3483
  const contractBeliefDocs = await Promise.all(
@@ -3043,15 +3485,14 @@ var getContractStatus = query({
3043
3485
  );
3044
3486
  const contractBeliefs = [];
3045
3487
  for (const belief of contractBeliefDocs) {
3046
- if (!belief || belief.nodeType !== "belief") {
3047
- throw new Error("Belief not found.");
3048
- }
3049
- contractBeliefs.push(belief);
3488
+ contractBeliefs.push(assertBeliefNode(belief));
3050
3489
  }
3051
3490
  await requireTopicReadAccess(ctx, contractBeliefs, userId);
3052
3491
  }
3053
3492
  if (args.status) {
3054
- contracts = contracts.filter((contract) => contract.status === args.status);
3493
+ contracts = contracts.filter(
3494
+ (contract) => contract.status === args.status
3495
+ );
3055
3496
  }
3056
3497
  const rows = await Promise.all(
3057
3498
  contracts.map(async (contract) => ({
@@ -3070,21 +3511,22 @@ var getContractCoverage = query({
3070
3511
  },
3071
3512
  returns: permissiveReturn,
3072
3513
  handler: async (ctx, args) => {
3073
- const contracts = await ctx.db.query("epistemicContracts").withIndex("by_topic", (q) => q.eq("topicId", args.topicId)).collect();
3514
+ const contracts = await contractTables(ctx).query("epistemicContracts").withIndex("by_topic", (q) => q.eq("topicId", args.topicId)).collect();
3074
3515
  const userId = await resolveAuthenticatedUserId(
3075
3516
  ctx,
3076
3517
  args.authenticatedUserId
3077
3518
  );
3078
- const beliefs = await ctx.db.query("epistemicNodes").withIndex(
3519
+ const beliefRows = await ctx.db.query("epistemicNodes").withIndex(
3079
3520
  "by_topic_type",
3080
3521
  (q) => q.eq("topicId", args.topicId).eq("nodeType", "belief")
3081
3522
  ).collect();
3523
+ const beliefs = beliefRows.map((belief) => assertBeliefNode(belief));
3082
3524
  await requireTopicReadAccess(ctx, beliefs, userId);
3083
3525
  const recentEvaluationLimit = Math.max(
3084
3526
  0,
3085
3527
  Math.min(args.recentEvaluationLimit ?? 5, 25)
3086
3528
  );
3087
- const recentEvaluations = recentEvaluationLimit === 0 ? [] : await ctx.db.query("contractEvaluations").withIndex("by_topic_time", (q) => q.eq("topicId", args.topicId)).order("desc").take(recentEvaluationLimit) ?? [];
3529
+ const recentEvaluations = recentEvaluationLimit === 0 ? [] : await contractTables(ctx).query("contractEvaluations").withIndex("by_topic_time", (q) => q.eq("topicId", args.topicId)).order("desc").take(recentEvaluationLimit);
3088
3530
  const contractBeliefIds = new Set(
3089
3531
  contracts.filter((contract) => contract.status !== "archived").map((contract) => String(contract.beliefNodeId))
3090
3532
  );
@@ -3107,6 +3549,23 @@ function inheritContractsForFork(contracts, args) {
3107
3549
  return contracts.filter((contract) => contract.status !== "archived").map((contract) => createInheritedContractRecord(contract, args));
3108
3550
  }
3109
3551
 
3110
- export { clearEpistemicEvaluators, createEpistemicContract, evaluateContract, evaluateContractsForTrigger, evaluateContradictionStatus, evaluateDependentBeliefCount, evaluateEdgeFreshness, evaluateEngineeringContracts, evaluateEvidenceCount, getContractCoverage, getContractStatus, getRegisteredEpistemicEvaluators, inheritContractsForFork, processContractEvaluationOverflow, registerEpistemicEvaluator };
3552
+ // src/epistemicContracts.ts
3553
+ var clearEpistemicEvaluators2 = clearEpistemicEvaluators;
3554
+ var getRegisteredEpistemicEvaluators2 = getRegisteredEpistemicEvaluators;
3555
+ var registerEpistemicEvaluator2 = registerEpistemicEvaluator;
3556
+ var createEpistemicContract2 = createEpistemicContract;
3557
+ var evaluateContract2 = evaluateContract;
3558
+ var evaluateContractsForTrigger2 = evaluateContractsForTrigger;
3559
+ var evaluateContradictionStatus2 = evaluateContradictionStatus;
3560
+ var evaluateDependentBeliefCount2 = evaluateDependentBeliefCount;
3561
+ var evaluateEdgeFreshness2 = evaluateEdgeFreshness;
3562
+ var evaluateEngineeringContracts2 = evaluateEngineeringContracts;
3563
+ var evaluateEvidenceCount2 = evaluateEvidenceCount;
3564
+ var getContractCoverage2 = getContractCoverage;
3565
+ var getContractStatus2 = getContractStatus;
3566
+ var inheritContractsForFork2 = inheritContractsForFork;
3567
+ var processContractEvaluationOverflow2 = processContractEvaluationOverflow;
3568
+
3569
+ export { clearEpistemicEvaluators2 as clearEpistemicEvaluators, createEpistemicContract2 as createEpistemicContract, evaluateContract2 as evaluateContract, evaluateContractsForTrigger2 as evaluateContractsForTrigger, evaluateContradictionStatus2 as evaluateContradictionStatus, evaluateDependentBeliefCount2 as evaluateDependentBeliefCount, evaluateEdgeFreshness2 as evaluateEdgeFreshness, evaluateEngineeringContracts2 as evaluateEngineeringContracts, evaluateEvidenceCount2 as evaluateEvidenceCount, getContractCoverage2 as getContractCoverage, getContractStatus2 as getContractStatus, getRegisteredEpistemicEvaluators2 as getRegisteredEpistemicEvaluators, inheritContractsForFork2 as inheritContractsForFork, processContractEvaluationOverflow2 as processContractEvaluationOverflow, registerEpistemicEvaluator2 as registerEpistemicEvaluator };
3111
3570
  //# sourceMappingURL=epistemicContracts.js.map
3112
3571
  //# sourceMappingURL=epistemicContracts.js.map