@lucern/graph-primitives 1.0.29 → 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 +395 -225
  19. package/dist/contradictions.js.map +1 -1
  20. package/dist/convex.d.ts +65 -30
  21. package/dist/convex.js +7 -3
  22. package/dist/convex.js.map +1 -1
  23. package/dist/debug.js.map +1 -1
  24. package/dist/edgeValidation.js +293 -85
  25. package/dist/edgeValidation.js.map +1 -1
  26. package/dist/edges/contains.d.ts +1 -1
  27. package/dist/edges/contains.js.map +1 -1
  28. package/dist/edges/contradicts.d.ts +1 -1
  29. package/dist/edges/contradicts.js.map +1 -1
  30. package/dist/edges/{dependsOn.d.ts → depends-on.d.ts} +1 -1
  31. package/dist/edges/{dependsOn.js → depends-on.js} +4 -4
  32. package/dist/edges/depends-on.js.map +1 -0
  33. package/dist/edges/{derivedFrom.d.ts → derived-from.d.ts} +1 -1
  34. package/dist/edges/{derivedFrom.js → derived-from.js} +3 -3
  35. package/dist/edges/derived-from.js.map +1 -0
  36. package/dist/edges/elaborates.d.ts +1 -1
  37. package/dist/edges/elaborates.js.map +1 -1
  38. package/dist/edges/index.d.ts +7 -3
  39. package/dist/edges/index.js +7 -4
  40. package/dist/edges/index.js.map +1 -1
  41. package/dist/edges/informs.d.ts +1 -1
  42. package/dist/edges/informs.js.map +1 -1
  43. package/dist/edges/{propagationTypes.d.ts → propagation-types.d.ts} +14 -14
  44. package/dist/edges/{propagationTypes.js → propagation-types.js} +3 -3
  45. package/dist/edges/propagation-types.js.map +1 -0
  46. package/dist/edges/refutes.d.ts +1 -1
  47. package/dist/edges/refutes.js.map +1 -1
  48. package/dist/edges/supports.d.ts +1 -1
  49. package/dist/edges/supports.js.map +1 -1
  50. package/dist/edges/tests.d.ts +1 -1
  51. package/dist/edges/tests.js.map +1 -1
  52. package/dist/edges/utils.d.ts +1 -1
  53. package/dist/edges/utils.js.map +1 -1
  54. package/dist/embeddingTrigger.d.ts +14 -6
  55. package/dist/embeddingTrigger.js +11 -14
  56. package/dist/embeddingTrigger.js.map +1 -1
  57. package/dist/{entityBridge-DMaKooYn.d.ts → entityBridge-BhVDM3pc.d.ts} +5 -5
  58. package/dist/entityBridge.d.ts +1 -1
  59. package/dist/entityBridge.js +602 -225
  60. package/dist/entityBridge.js.map +1 -1
  61. package/dist/entityCanonicalMatch.d.ts +14 -12
  62. package/dist/entityCanonicalMatch.js.map +1 -1
  63. package/dist/{entityLifecycle-CvgSK5FV.d.ts → entityLifecycle-BsfCz9pS.d.ts} +5 -9
  64. package/dist/entityLifecycle.d.ts +1 -1
  65. package/dist/entityLifecycle.js +854 -480
  66. package/dist/entityLifecycle.js.map +1 -1
  67. package/dist/{entityValidation-KLZ_Xl2D.d.ts → entityValidation-B1yNEHJx.d.ts} +7 -6
  68. package/dist/entityValidation.d.ts +3 -1
  69. package/dist/entityValidation.js +60 -8
  70. package/dist/entityValidation.js.map +1 -1
  71. package/dist/{epistemicAnswers-C5ib4z6_.d.ts → epistemicAnswers-f47YMu9U.d.ts} +6 -6
  72. package/dist/epistemicAnswers.d.ts +1 -1
  73. package/dist/epistemicAnswers.js +587 -545
  74. package/dist/epistemicAnswers.js.map +1 -1
  75. package/dist/epistemicBeliefs.admin.d.ts +8 -8
  76. package/dist/epistemicBeliefs.admin.js +365 -166
  77. package/dist/epistemicBeliefs.admin.js.map +1 -1
  78. package/dist/epistemicBeliefs.backfills.d.ts +8 -8
  79. package/dist/epistemicBeliefs.backfills.js +655 -289
  80. package/dist/epistemicBeliefs.backfills.js.map +1 -1
  81. package/dist/epistemicBeliefs.confidence.d.ts +19 -15
  82. package/dist/epistemicBeliefs.confidence.js +633 -386
  83. package/dist/epistemicBeliefs.confidence.js.map +1 -1
  84. package/dist/epistemicBeliefs.core.d.ts +6 -6
  85. package/dist/epistemicBeliefs.core.js +717 -371
  86. package/dist/epistemicBeliefs.core.js.map +1 -1
  87. package/dist/epistemicBeliefs.d.ts +11 -9
  88. package/dist/epistemicBeliefs.forkEvidence.d.ts +2 -0
  89. package/dist/epistemicBeliefs.forkEvidence.js +8 -8
  90. package/dist/epistemicBeliefs.forkEvidence.js.map +1 -1
  91. package/dist/epistemicBeliefs.helpers.d.ts +68 -49
  92. package/dist/epistemicBeliefs.helpers.js +358 -211
  93. package/dist/epistemicBeliefs.helpers.js.map +1 -1
  94. package/dist/epistemicBeliefs.internal.d.ts +5 -5
  95. package/dist/epistemicBeliefs.internal.js +1248 -1026
  96. package/dist/epistemicBeliefs.internal.js.map +1 -1
  97. package/dist/epistemicBeliefs.js +4942 -3590
  98. package/dist/epistemicBeliefs.js.map +1 -1
  99. package/dist/epistemicBeliefs.lifecycle.d.ts +5 -5
  100. package/dist/epistemicBeliefs.lifecycle.js +1138 -781
  101. package/dist/epistemicBeliefs.lifecycle.js.map +1 -1
  102. package/dist/epistemicBeliefs.links.d.ts +7 -7
  103. package/dist/epistemicBeliefs.links.js +404 -267
  104. package/dist/epistemicBeliefs.links.js.map +1 -1
  105. package/dist/epistemicBeliefs.queries.d.ts +4 -4
  106. package/dist/epistemicBeliefs.queries.js +175 -20
  107. package/dist/epistemicBeliefs.queries.js.map +1 -1
  108. package/dist/epistemicBeliefs.topicAnchor.d.ts +6 -4
  109. package/dist/epistemicBeliefs.topicAnchor.js +12 -5
  110. package/dist/epistemicBeliefs.topicAnchor.js.map +1 -1
  111. package/dist/epistemicContracts.d.ts +28 -3
  112. package/dist/epistemicContracts.evaluators.d.ts +2 -0
  113. package/dist/epistemicContracts.evaluators.js +1062 -576
  114. package/dist/epistemicContracts.evaluators.js.map +1 -1
  115. package/dist/epistemicContracts.handlers.d.ts +15 -32
  116. package/dist/epistemicContracts.handlers.js +1829 -1351
  117. package/dist/epistemicContracts.handlers.js.map +1 -1
  118. package/dist/epistemicContracts.js +1131 -636
  119. package/dist/epistemicContracts.js.map +1 -1
  120. package/dist/epistemicContracts.metrics.d.ts +2 -0
  121. package/dist/epistemicContracts.metrics.js +375 -158
  122. package/dist/epistemicContracts.metrics.js.map +1 -1
  123. package/dist/epistemicContracts.types.d.ts +87 -81
  124. package/dist/epistemicEdgeCreation.d.ts +2 -0
  125. package/dist/epistemicEdgeCreation.js +87 -16
  126. package/dist/epistemicEdgeCreation.js.map +1 -1
  127. package/dist/{epistemicEdges-BF-cn4i3.d.ts → epistemicEdges-BGBh0QSP.d.ts} +4 -7
  128. package/dist/epistemicEdges.d.ts +6 -5
  129. package/dist/epistemicEdges.handlers.d.ts +3 -3
  130. package/dist/epistemicEdges.handlers.js +129 -24
  131. package/dist/epistemicEdges.handlers.js.map +1 -1
  132. package/dist/epistemicEdges.helpers.d.ts +6 -4
  133. package/dist/epistemicEdges.helpers.js +37 -2
  134. package/dist/epistemicEdges.helpers.js.map +1 -1
  135. package/dist/epistemicEdges.js +1966 -1202
  136. package/dist/epistemicEdges.js.map +1 -1
  137. package/dist/epistemicEdges.mutations.d.ts +7 -7
  138. package/dist/epistemicEdges.mutations.js +956 -579
  139. package/dist/epistemicEdges.mutations.js.map +1 -1
  140. package/dist/epistemicEdges.queries.d.ts +16 -16
  141. package/dist/epistemicEdges.queries.js +639 -367
  142. package/dist/epistemicEdges.queries.js.map +1 -1
  143. package/dist/epistemicEdges.types.d.ts +10 -8
  144. package/dist/epistemicEvidence.d.ts +4 -1
  145. package/dist/epistemicEvidence.js +933 -532
  146. package/dist/epistemicEvidence.js.map +1 -1
  147. package/dist/epistemicEvidenceHelpers.d.ts +26 -10
  148. package/dist/epistemicEvidenceHelpers.js +239 -200
  149. package/dist/epistemicEvidenceHelpers.js.map +1 -1
  150. package/dist/epistemicEvidenceMutations.d.ts +8 -8
  151. package/dist/epistemicEvidenceMutations.js +840 -692
  152. package/dist/epistemicEvidenceMutations.js.map +1 -1
  153. package/dist/epistemicEvidenceQueries.d.ts +8 -8
  154. package/dist/epistemicEvidenceQueries.js +514 -238
  155. package/dist/epistemicEvidenceQueries.js.map +1 -1
  156. package/dist/epistemicHelpers.d.ts +4 -2
  157. package/dist/epistemicHelpers.js +308 -134
  158. package/dist/epistemicHelpers.js.map +1 -1
  159. package/dist/epistemicInsert.d.ts +16 -4
  160. package/dist/epistemicInsert.js +6 -3
  161. package/dist/epistemicInsert.js.map +1 -1
  162. package/dist/epistemicLayerRules.d.ts +10 -8
  163. package/dist/epistemicLayerRules.js +1 -5
  164. package/dist/epistemicLayerRules.js.map +1 -1
  165. package/dist/{epistemicLinking-CfE00tHJ.d.ts → epistemicLinking-CsCDv2cN.d.ts} +3 -3
  166. package/dist/epistemicLinking.d.ts +1 -1
  167. package/dist/epistemicLinking.js +177 -100
  168. package/dist/epistemicLinking.js.map +1 -1
  169. package/dist/epistemicNodeCreation.d.ts +2 -0
  170. package/dist/epistemicNodeCreation.js +203 -40
  171. package/dist/epistemicNodeCreation.js.map +1 -1
  172. package/dist/{epistemicNodes-BCQxpYx_.d.ts → epistemicNodes-CokAgBHg.d.ts} +3 -3
  173. package/dist/epistemicNodes.d.ts +3 -3
  174. package/dist/epistemicNodes.helpers.d.ts +24 -15
  175. package/dist/epistemicNodes.helpers.js.map +1 -1
  176. package/dist/epistemicNodes.internal.d.ts +6 -6
  177. package/dist/epistemicNodes.internal.js +389 -319
  178. package/dist/epistemicNodes.internal.js.map +1 -1
  179. package/dist/epistemicNodes.js +700 -504
  180. package/dist/epistemicNodes.js.map +1 -1
  181. package/dist/epistemicNodes.mutations.d.ts +6 -6
  182. package/dist/epistemicNodes.mutations.js +560 -463
  183. package/dist/epistemicNodes.mutations.js.map +1 -1
  184. package/dist/epistemicNodes.queries.d.ts +8 -8
  185. package/dist/epistemicNodes.queries.js +311 -314
  186. package/dist/epistemicNodes.queries.js.map +1 -1
  187. package/dist/epistemicNodes.validators.d.ts +2 -2
  188. package/dist/epistemicNodes.validators.js.map +1 -1
  189. package/dist/epistemicQuestions.conviction.d.ts +8 -8
  190. package/dist/epistemicQuestions.conviction.js +665 -484
  191. package/dist/epistemicQuestions.conviction.js.map +1 -1
  192. package/dist/epistemicQuestions.create.d.ts +4 -4
  193. package/dist/epistemicQuestions.create.js +640 -612
  194. package/dist/epistemicQuestions.create.js.map +1 -1
  195. package/dist/epistemicQuestions.d.ts +8 -5
  196. package/dist/epistemicQuestions.evidence.d.ts +2 -2
  197. package/dist/epistemicQuestions.evidence.js +475 -383
  198. package/dist/epistemicQuestions.evidence.js.map +1 -1
  199. package/dist/epistemicQuestions.helpers.d.ts +125 -24
  200. package/dist/epistemicQuestions.helpers.js +240 -209
  201. package/dist/epistemicQuestions.helpers.js.map +1 -1
  202. package/dist/epistemicQuestions.js +3474 -2823
  203. package/dist/epistemicQuestions.js.map +1 -1
  204. package/dist/epistemicQuestions.lifecycle.d.ts +2 -2
  205. package/dist/epistemicQuestions.lifecycle.js +607 -546
  206. package/dist/epistemicQuestions.lifecycle.js.map +1 -1
  207. package/dist/epistemicQuestions.queries.d.ts +12 -7
  208. package/dist/epistemicQuestions.queries.js +305 -244
  209. package/dist/epistemicQuestions.queries.js.map +1 -1
  210. package/dist/epistemicQuestions.sprint.d.ts +2 -2
  211. package/dist/epistemicQuestions.sprint.js +600 -394
  212. package/dist/epistemicQuestions.sprint.js.map +1 -1
  213. package/dist/epistemicQuestions.tail.d.ts +6 -6
  214. package/dist/epistemicQuestions.tail.js +572 -433
  215. package/dist/epistemicQuestions.tail.js.map +1 -1
  216. package/dist/{epistemicSources-dlKj58Jp.d.ts → epistemicSources-DQtaEkWs.d.ts} +4 -4
  217. package/dist/epistemicSources.d.ts +1 -1
  218. package/dist/epistemicSources.js +351 -311
  219. package/dist/epistemicSources.js.map +1 -1
  220. package/dist/evaluators/index.d.ts +8 -6
  221. package/dist/evaluators/index.js +399 -167
  222. package/dist/evaluators/index.js.map +1 -1
  223. package/dist/evaluators/lint-checker-evaluator.d.ts +16 -0
  224. package/dist/evaluators/{lintCheckerEvaluator.js → lint-checker-evaluator.js} +10 -5
  225. package/dist/evaluators/lint-checker-evaluator.js.map +1 -0
  226. package/dist/evaluators/{sentryCheckerEvaluator.d.ts → sentry-checker-evaluator.d.ts} +7 -2
  227. package/dist/evaluators/{sentryCheckerEvaluator.js → sentry-checker-evaluator.js} +3 -3
  228. package/dist/evaluators/sentry-checker-evaluator.js.map +1 -0
  229. package/dist/evaluators/shared.d.ts +2 -2
  230. package/dist/evaluators/shared.js +3 -1
  231. package/dist/evaluators/shared.js.map +1 -1
  232. package/dist/evaluators/{testRunnerEvaluator.d.ts → test-runner-evaluator.d.ts} +6 -1
  233. package/dist/evaluators/{testRunnerEvaluator.js → test-runner-evaluator.js} +6 -4
  234. package/dist/evaluators/test-runner-evaluator.js.map +1 -0
  235. package/dist/evaluators/tsc-checker-evaluator.d.ts +16 -0
  236. package/dist/evaluators/{tscCheckerEvaluator.js → tsc-checker-evaluator.js} +10 -5
  237. package/dist/evaluators/tsc-checker-evaluator.js.map +1 -0
  238. package/dist/graphTypes.js +6 -2
  239. package/dist/graphTypes.js.map +1 -1
  240. package/dist/helpers.d.ts +2 -0
  241. package/dist/helpers.js +313 -93
  242. package/dist/helpers.js.map +1 -1
  243. package/dist/{index-C-Kyd7hD.d.ts → index-DZxyC9Pb.d.ts} +7 -6
  244. package/dist/index.d.ts +86 -83
  245. package/dist/index.js +16914 -11760
  246. package/dist/index.js.map +1 -1
  247. package/dist/invariantEnforcement.d.ts +3 -3
  248. package/dist/invariantEnforcement.js.map +1 -1
  249. package/dist/logicalRoleInference.d.ts +2 -0
  250. package/dist/logicalRoleInference.js +1 -1
  251. package/dist/logicalRoleInference.js.map +1 -1
  252. package/dist/matcherFeedbackUtils.d.ts +2 -2
  253. package/dist/matcherFeedbackUtils.js.map +1 -1
  254. package/dist/{ontology-matching-C6rrz2VP.d.ts → ontology-matching-C-mYFrir.d.ts} +16 -16
  255. package/dist/ontology-matching.d.ts +1 -1
  256. package/dist/{ontologyApproval-CFYmqKmk.d.ts → ontologyApproval-BVt0feJi.d.ts} +10 -10
  257. package/dist/ontologyApproval.d.ts +1 -1
  258. package/dist/ontologyApproval.js +7 -1
  259. package/dist/ontologyApproval.js.map +1 -1
  260. package/dist/ontologyDefinitions.d.ts +14 -24
  261. package/dist/ontologyDefinitions.js +269 -34
  262. package/dist/ontologyDefinitions.js.map +1 -1
  263. package/dist/ontologyHelpers.d.ts +13 -13
  264. package/dist/ontologyHelpers.js.map +1 -1
  265. package/dist/{ontologyRegistry-B67rPJ16.d.ts → ontologyRegistry-CljS-ENv.d.ts} +2 -2
  266. package/dist/ontologyRegistry.d.ts +1 -1
  267. package/dist/ontologyRegistry.js +34 -6
  268. package/dist/ontologyRegistry.js.map +1 -1
  269. package/dist/{projectionReconciliation-jww2fBI0.d.ts → projectionReconciliation-DnrSgHSQ.d.ts} +4 -4
  270. package/dist/projectionReconciliation.d.ts +1 -1
  271. package/dist/projectionReconciliation.js +57 -10
  272. package/dist/projectionReconciliation.js.map +1 -1
  273. package/dist/{projectionStaleness-CmdbpjVK.d.ts → projectionStaleness-C8ImQ2zP.d.ts} +17 -17
  274. package/dist/projectionStaleness.d.ts +1 -1
  275. package/dist/projectionStaleness.js +8 -2
  276. package/dist/projectionStaleness.js.map +1 -1
  277. package/dist/proof-attestation.json +1 -1
  278. package/dist/{questionEvidenceLinks-DFlyPpAj.d.ts → questionEvidenceLinks-_nPRa-LY.d.ts} +10 -10
  279. package/dist/questionEvidenceLinks.d.ts +1 -1
  280. package/dist/questionEvidenceLinks.js +564 -347
  281. package/dist/questionEvidenceLinks.js.map +1 -1
  282. package/dist/{resolverTypes-CC8Ea2E2.d.ts → resolverTypes-BOXPxLET.d.ts} +8 -7
  283. package/dist/resolverTypes.d.ts +4 -2
  284. package/dist/{resolvers-Br1a6eLV.d.ts → resolvers-B1TIBmRO.d.ts} +3 -1
  285. package/dist/resolvers.d.ts +5 -3
  286. package/dist/resolvers.js +121 -77
  287. package/dist/resolvers.js.map +1 -1
  288. package/dist/scopeResolverCompat.d.ts +10 -7
  289. package/dist/scopeResolverCompat.js +106 -123
  290. package/dist/scopeResolverCompat.js.map +1 -1
  291. package/dist/{text-matching-DNg4M5Wd.d.ts → text-matching-DzFooju6.d.ts} +7 -7
  292. package/dist/text-matching.d.ts +1 -1
  293. package/dist/topicOntologyResolver.d.ts +22 -21
  294. package/dist/topicOntologyResolver.js +54 -32
  295. package/dist/topicOntologyResolver.js.map +1 -1
  296. package/dist/topicProjectOverlay.d.ts +30 -20
  297. package/dist/topicProjectOverlay.js +120 -76
  298. package/dist/topicProjectOverlay.js.map +1 -1
  299. package/dist/{topicScope-7zhyeGl7.d.ts → topicScope-DJVa0mLa.d.ts} +22 -7
  300. package/dist/topicScope.d.ts +3 -1
  301. package/dist/topicScope.js +104 -119
  302. package/dist/topicScope.js.map +1 -1
  303. package/dist/workflowBridge.d.ts +26 -15
  304. package/dist/workflowBridge.js +140 -144
  305. package/dist/workflowBridge.js.map +1 -1
  306. package/dist/workspaceIsolation.d.ts +14 -12
  307. package/dist/workspaceIsolation.js +108 -122
  308. package/dist/workspaceIsolation.js.map +1 -1
  309. package/package.json +4 -4
  310. package/dist/edges/dependsOn.js.map +0 -1
  311. package/dist/edges/derivedFrom.js.map +0 -1
  312. package/dist/edges/propagationTypes.js.map +0 -1
  313. package/dist/evaluators/lintCheckerEvaluator.d.ts +0 -11
  314. package/dist/evaluators/lintCheckerEvaluator.js.map +0 -1
  315. package/dist/evaluators/sentryCheckerEvaluator.js.map +0 -1
  316. package/dist/evaluators/testRunnerEvaluator.js.map +0 -1
  317. package/dist/evaluators/tscCheckerEvaluator.d.ts +0 -11
  318. package/dist/evaluators/tscCheckerEvaluator.js.map +0 -1
  319. package/dist/{epistemicQuestions-bwHd2FWE.d.ts → epistemicQuestions-Do1fhYm5.d.ts} +4 -4
@@ -1,14 +1,34 @@
1
- import { v } from 'convex/values';
2
- import { throwStructuredMutationError } from '@lucern/access-control/structuredMutationError';
3
- import { normalizeTupleContradictionPolicy, mkOpinion, conditionalDeduction, project, dampedDependencyCascade, hasProjectedOpinionChanged, confidenceFromSL, detectTupleContradiction, evaluateTupleContradictionTransition, trustDiscount, applyNegativeSupport, cumulativeFusion, applyNegativeEvidence, readOpinionFromRecord, deriveContractModulationPlan, deriveContractStatus, parseEvidentialEvaluatorConfig, compareMetricValue, buildEvidentialRationale, parseMetricCheckerConfig, getEvaluatorInputRecord, pickFiniteNumber, resolveComparisonResult, buildComparisonRationale, parseReferenceCheckCounterConfig, parseTemporalDeadlineConfig, parseMarketIndexComparatorConfig } from '@lucern/confidence';
1
+ import { unsafeConvexAnyApi } from '@lucern/contracts/convex/unsafeAnyApi';
2
+ import { componentsGeneric, internalMutationGeneric } from 'convex/server';
4
3
  import '@lucern/access-control/audience';
5
4
  import '@lucern/access-control/auth';
6
- import { componentsGeneric, internalMutationGeneric, anyApi } from 'convex/server';
5
+ import { throwStructuredMutationError } from '@lucern/access-control/structuredMutationError';
6
+ import { normalizeTupleContradictionPolicy, mkOpinion, conditionalDeduction, project, dampedDependencyCascade, trustDiscount, applyNegativeSupport, cumulativeFusion, applyNegativeEvidence, confidenceFromSL, detectTupleContradiction, evaluateTupleContradictionTransition, readOpinionFromRecord, hasProjectedOpinionChanged, deriveContractModulationPlan, deriveContractStatus, parseEvidentialEvaluatorConfig, compareMetricValue, resolveComparisonResult, buildEvidentialRationale, parseMetricCheckerConfig, getEvaluatorInputRecord, pickFiniteNumber, buildComparisonRationale, parseReferenceCheckCounterConfig, parseTemporalDeadlineConfig, parseMarketIndexComparatorConfig } from '@lucern/confidence';
7
+ import { v } from 'convex/values';
7
8
  import '@lucern/contracts/schema-helpers/spine/tables/epistemicNodes';
8
9
  import { requireScopeWriteAccess } from '@lucern/access-control/access';
9
10
  import { permissiveReturn } from '@lucern/contracts/schema-helpers/validators';
10
11
 
11
- // src/epistemicBeliefs.helpers.ts
12
+ // src/convex.ts
13
+ var unsafeApi = unsafeConvexAnyApi(
14
+ "graph-primitives top-level module bundle lacks a committed Convex _generated/api surface"
15
+ );
16
+ var api = unsafeApi;
17
+ componentsGeneric();
18
+ var internal = unsafeApi;
19
+ var internalMutation = internalMutationGeneric;
20
+
21
+ // src/debug.ts
22
+ function isGraphPrimitiveDebugEnabled() {
23
+ const env = globalThis.process?.env;
24
+ return env?.LUCERN_COMPAT_FALLBACK_DEBUG === "1" || env?.LUCERN_GRAPH_DEBUG === "1";
25
+ }
26
+ function debugGraphPrimitiveFallback(message, context) {
27
+ if (!isGraphPrimitiveDebugEnabled()) {
28
+ return;
29
+ }
30
+ console.debug(message, context ?? {});
31
+ }
12
32
 
13
33
  // src/beliefLifecycle.ts
14
34
  var BELIEF_STATUS_VALUES = [
@@ -130,22 +150,6 @@ function promoteBeliefStatusAfterScoring(status, opts) {
130
150
  }
131
151
  return status;
132
152
  }
133
- var api = anyApi;
134
- componentsGeneric();
135
- var internal = anyApi;
136
- var internalMutation = internalMutationGeneric;
137
-
138
- // src/debug.ts
139
- function isGraphPrimitiveDebugEnabled() {
140
- const env = globalThis.process?.env;
141
- return env?.LUCERN_COMPAT_FALLBACK_DEBUG === "1" || env?.LUCERN_GRAPH_DEBUG === "1";
142
- }
143
- function debugGraphPrimitiveFallback(message, context) {
144
- if (!isGraphPrimitiveDebugEnabled()) {
145
- return;
146
- }
147
- console.debug(message, context ?? {});
148
- }
149
153
  var LEGACY_SCOPE_FIELD = "graphScopeProjectId";
150
154
  async function resolveTopicNodeScopeOrNull(ctx, ref) {
151
155
  if (!ctx?.db || typeof ctx.db.query !== "function") {
@@ -180,13 +184,15 @@ function asMappedProjectId(topic) {
180
184
  if (!topic) {
181
185
  return;
182
186
  }
183
- const directLegacyProjectId = normalizeScopeValue(topic[LEGACY_SCOPE_FIELD]);
187
+ const directLegacyProjectId = normalizeScopeValue(
188
+ topic[LEGACY_SCOPE_FIELD]
189
+ );
184
190
  if (directLegacyProjectId) {
185
191
  return directLegacyProjectId;
186
192
  }
187
193
  const metadata = topic.metadata || {};
188
194
  const candidate = metadata[LEGACY_SCOPE_FIELD] || metadata.legacyProjectId || metadata.projectId || metadata.scopeProjectId;
189
- return candidate ? candidate : void 0;
195
+ return typeof candidate === "string" ? normalizeScopeValue(candidate) : void 0;
190
196
  }
191
197
  function normalizeScopeValue(value) {
192
198
  if (typeof value !== "string") {
@@ -211,8 +217,9 @@ function pickPrimaryTopic(candidates) {
211
217
  })[0];
212
218
  }
213
219
  async function findTopicsByScopeAlias(ctx, scopeId) {
220
+ const query = ctx.db.query("topics");
214
221
  try {
215
- return await ctx.db.query("topics").withIndex(
222
+ return await query.withIndex(
216
223
  "by_graph_scope_project",
217
224
  (q) => q.eq(LEGACY_SCOPE_FIELD, scopeId)
218
225
  ).collect();
@@ -224,7 +231,7 @@ async function findTopicsByScopeAlias(ctx, scopeId) {
224
231
  scopeId
225
232
  }
226
233
  );
227
- const topics = await ctx.db.query("topics").collect();
234
+ const topics = await query.collect();
228
235
  return topics.filter((topic) => {
229
236
  const normalizedGlobalId = normalizeScopeValue(topic.globalId);
230
237
  const mappedProjectId = asMappedProjectId(topic);
@@ -280,137 +287,115 @@ async function resolveInheritedWorkspaceScope(ctx, topic) {
280
287
  let current = topic;
281
288
  for (let i = 0; i < MAX_DEPTH && current?.parentTopicId; i++) {
282
289
  current = await ctx.db.get(current.parentTopicId);
283
- if (!current) break;
290
+ if (!current) {
291
+ break;
292
+ }
284
293
  if (!tenantId) {
285
294
  tenantId = normalizeScopeValue(current.tenantId);
286
295
  }
287
296
  if (!workspaceId) {
288
297
  workspaceId = normalizeScopeValue(current.workspaceId);
289
298
  }
290
- if (tenantId && workspaceId) break;
299
+ if (tenantId && workspaceId) {
300
+ break;
301
+ }
291
302
  }
292
303
  return { tenantId, workspaceId };
293
304
  }
294
305
  async function resolveTopicProjectScope(ctx, args) {
295
306
  if (args.topicId) {
296
- let topic = null;
297
- try {
298
- topic = await ctx.db.get(
299
- args.topicId
300
- );
301
- } catch (error) {
302
- debugGraphPrimitiveFallback(
303
- "[topicScope] Failed to load topic by direct id",
304
- {
305
- error,
306
- topicId: args.topicId
307
- }
308
- );
309
- }
310
- if (!topic) {
311
- topic = await tryResolveHostTopicById(ctx, String(args.topicId));
312
- }
313
- if (!topic) {
314
- topic = pickPrimaryTopic(
315
- await findTopicsByScopeAlias(ctx, String(args.topicId))
316
- ) ?? null;
317
- }
318
- if (!topic) {
319
- const nodeScope = await resolveTopicNodeScopeOrNull(
320
- ctx,
321
- String(args.topicId)
322
- );
323
- if (nodeScope) {
324
- return nodeScope;
325
- }
326
- throw new Error(`Topic not found: ${String(args.topicId)}`);
327
- }
328
- const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
329
- const mapped = asMappedProjectId(topic);
330
- if (mapped) {
331
- return {
332
- topicId: topic._id,
333
- projectId: mapped,
334
- tenantId: inherited.tenantId,
335
- workspaceId: inherited.workspaceId,
336
- source: "topic"
337
- };
338
- }
339
- return {
340
- topicId: topic._id,
341
- tenantId: inherited.tenantId,
342
- workspaceId: inherited.workspaceId,
343
- source: "topic"
344
- };
307
+ return await resolveScopeFromTopicId(ctx, args.topicId);
345
308
  }
346
309
  if (args.projectId) {
347
- let directTopic = null;
348
- try {
349
- directTopic = await ctx.db.get(
350
- args.projectId
351
- );
352
- } catch (error) {
353
- debugGraphPrimitiveFallback(
354
- "[topicScope] Failed to load direct project topic",
355
- {
356
- error,
357
- projectId: args.projectId
358
- }
359
- );
360
- }
361
- if (directTopic) {
362
- const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
363
- const mapped = asMappedProjectId(directTopic);
364
- return {
365
- topicId: directTopic._id,
366
- projectId: mapped ?? args.projectId,
367
- tenantId: inherited.tenantId,
368
- workspaceId: inherited.workspaceId,
369
- source: "topic_inferred"
370
- };
371
- }
372
- directTopic = await tryResolveHostTopicByLegacyScope(ctx, args.projectId);
373
- if (directTopic) {
374
- const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
375
- const mapped = asMappedProjectId(directTopic);
376
- return {
377
- topicId: directTopic._id,
378
- projectId: mapped ?? args.projectId,
379
- tenantId: inherited.tenantId,
380
- workspaceId: inherited.workspaceId,
381
- source: "topic_inferred"
382
- };
383
- }
384
- const topics = await findTopicsByScopeAlias(ctx, args.projectId);
385
- const primary = pickPrimaryTopic(topics);
386
- if (primary) {
387
- const inherited = await resolveInheritedWorkspaceScope(ctx, primary);
388
- return {
389
- topicId: primary._id,
390
- projectId: args.projectId,
391
- tenantId: inherited.tenantId,
392
- workspaceId: inherited.workspaceId,
393
- source: "project_mapped_topic"
394
- };
395
- }
396
- const nodeScope = await resolveTopicNodeScopeOrNull(
397
- ctx,
398
- String(args.projectId)
399
- );
400
- if (nodeScope) {
401
- return {
402
- ...nodeScope,
403
- projectId: nodeScope.projectId ?? String(args.projectId)
404
- };
405
- }
406
- throw new Error(
407
- `Legacy project scope ${String(args.projectId)} has no mapped topic.`
408
- );
310
+ return await resolveScopeFromLegacyProjectId(ctx, args.projectId);
409
311
  }
410
312
  throw new Error(
411
313
  "Missing scope: provide topicId (preferred) or legacy projectId alias."
412
314
  );
413
315
  }
316
+ async function resolveScopeFromTopicId(ctx, topicId) {
317
+ const topic = await resolveTopicDocFromTopicId(ctx, topicId);
318
+ if (topic) {
319
+ return await buildTopicScope(ctx, topic, "topic");
320
+ }
321
+ const nodeScope = await resolveTopicNodeScopeOrNull(ctx, String(topicId));
322
+ if (nodeScope) {
323
+ return nodeScope;
324
+ }
325
+ throw new Error(`Topic not found: ${String(topicId)}`);
326
+ }
327
+ async function resolveTopicDocFromTopicId(ctx, topicId) {
328
+ const direct = await tryReadTopicDoc(ctx, topicId, {
329
+ failureLog: "[topicScope] Failed to load topic by direct id",
330
+ idLogKey: "topicId"
331
+ });
332
+ if (direct) {
333
+ return direct;
334
+ }
335
+ const hostTopic = await tryResolveHostTopicById(ctx, String(topicId));
336
+ if (hostTopic) {
337
+ return hostTopic;
338
+ }
339
+ return pickPrimaryTopic(await findTopicsByScopeAlias(ctx, String(topicId))) ?? null;
340
+ }
341
+ async function resolveScopeFromLegacyProjectId(ctx, legacyProjectId) {
342
+ const directTopic = await resolveDirectLegacyProjectTopic(
343
+ ctx,
344
+ legacyProjectId
345
+ );
346
+ if (directTopic) {
347
+ return await buildTopicScope(ctx, directTopic, "topic_inferred", {
348
+ fallbackProjectId: legacyProjectId
349
+ });
350
+ }
351
+ const primary = pickPrimaryTopic(
352
+ await findTopicsByScopeAlias(ctx, legacyProjectId)
353
+ );
354
+ if (primary) {
355
+ return await buildTopicScope(ctx, primary, "project_mapped_topic", {
356
+ fallbackProjectId: legacyProjectId
357
+ });
358
+ }
359
+ const nodeScope = await resolveTopicNodeScopeOrNull(ctx, legacyProjectId);
360
+ if (nodeScope) {
361
+ return {
362
+ ...nodeScope,
363
+ projectId: nodeScope.projectId ?? legacyProjectId
364
+ };
365
+ }
366
+ throw new Error(
367
+ `Legacy project scope ${legacyProjectId} has no mapped topic.`
368
+ );
369
+ }
370
+ async function resolveDirectLegacyProjectTopic(ctx, legacyProjectId) {
371
+ const directTopic = await tryReadTopicDoc(ctx, legacyProjectId, {
372
+ failureLog: "[topicScope] Failed to load direct project topic",
373
+ idLogKey: "projectId"
374
+ });
375
+ return directTopic ?? tryResolveHostTopicByLegacyScope(ctx, legacyProjectId);
376
+ }
377
+ async function tryReadTopicDoc(ctx, id, log) {
378
+ try {
379
+ return await ctx.db.get(id);
380
+ } catch (error) {
381
+ debugGraphPrimitiveFallback(log.failureLog, {
382
+ error,
383
+ [log.idLogKey]: id
384
+ });
385
+ return null;
386
+ }
387
+ }
388
+ async function buildTopicScope(ctx, topic, source, options = {}) {
389
+ const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
390
+ const mapped = asMappedProjectId(topic);
391
+ return {
392
+ topicId: topic._id,
393
+ ...mapped || options.fallbackProjectId ? { projectId: mapped ?? options.fallbackProjectId } : {},
394
+ tenantId: inherited.tenantId,
395
+ workspaceId: inherited.workspaceId,
396
+ source
397
+ };
398
+ }
414
399
  ({
415
400
  projectId: v.optional(v.string()),
416
401
  topicId: v.optional(v.string())
@@ -478,9 +463,10 @@ async function resolveNodeScopeForWorkspaceIsolation(ctx, node) {
478
463
  if (resolved.tenantId || resolved.workspaceId) {
479
464
  return resolved;
480
465
  }
481
- if (node.topicId) {
466
+ const topicId = normalizeScopeValue2(node.topicId);
467
+ if (topicId) {
482
468
  const topicScope = await resolveTopicProjectScope(ctx, {
483
- topicId: node.topicId
469
+ topicId
484
470
  });
485
471
  return {
486
472
  ...resolved,
@@ -500,8 +486,6 @@ async function resolveNodeScopeForWorkspaceIsolation(ctx, node) {
500
486
  }
501
487
  return resolved;
502
488
  }
503
-
504
- // src/epistemicBeliefs.helpers.ts
505
489
  v.id("epistemicNodes");
506
490
  var DEFAULT_CONFIDENCE_POLICY = {
507
491
  scoringMode: "after_worktree",
@@ -581,7 +565,10 @@ function resolveBeliefStatus(node, metadata) {
581
565
  });
582
566
  }
583
567
  async function hasCompletedWorktreeForBelief(ctx, beliefNodeId) {
584
- const clusterMembership = await ctx.db.query("worktreeBeliefCluster").withIndex("by_belief", (q) => q.eq("beliefId", beliefNodeId)).collect();
568
+ const clusterMembership = await ctx.db.query("worktreeBeliefCluster").withIndex(
569
+ "by_belief",
570
+ (q) => q.eq("beliefId", beliefNodeId)
571
+ ).collect();
585
572
  for (const membership of clusterMembership) {
586
573
  const worktree = await ctx.db.get(membership.worktreeId);
587
574
  if (worktree?.status === "completed" || worktree?.status === "merged") {
@@ -592,7 +579,10 @@ async function hasCompletedWorktreeForBelief(ctx, beliefNodeId) {
592
579
  }
593
580
  async function getActiveConfidencePolicy(ctx) {
594
581
  try {
595
- const activeConfig = await ctx.db.query("logicSprintScoring").withIndex("by_active", (q) => q.eq("isActive", true)).first();
582
+ const activeConfig = await ctx.db.query("logicSprintScoring").withIndex(
583
+ "by_active",
584
+ (q) => q.eq("isActive", true)
585
+ ).first();
596
586
  return {
597
587
  scoringMode: activeConfig?.confidencePolicy === "always" ? "always" : DEFAULT_CONFIDENCE_POLICY.scoringMode,
598
588
  tupleContradiction: normalizeTupleContradictionPolicy(
@@ -745,7 +735,7 @@ var dependsOnPropagationSpec = {
745
735
  description: "Structural gating. Textbook conditional deduction when edge conditionals exist, otherwise damped dependency cascade through downstream chains."
746
736
  };
747
737
 
748
- // src/edges/derivedFrom.ts
738
+ // src/edges/derived-from.ts
749
739
  var derivedFromPropagationSpec = {
750
740
  edgeType: "derived_from",
751
741
  direction: "incoming",
@@ -798,7 +788,7 @@ var informsPropagationSpec = {
798
788
  description: "Evidence-bearing influence. Informs can chain through the graph with light per-hop damping."
799
789
  };
800
790
 
801
- // src/edges/propagationTypes.ts
791
+ // src/edges/propagation-types.ts
802
792
  function isPropagationTraversalDirection(direction) {
803
793
  return direction === "outgoing" || direction === "incoming";
804
794
  }
@@ -871,6 +861,9 @@ var testsPropagationSpec = {
871
861
  };
872
862
 
873
863
  // src/edges/index.ts
864
+ var canContinueTransitively2 = canContinueTransitively;
865
+ var canTraverseHop2 = canTraverseHop;
866
+ var isPropagationTraversalDirection2 = isPropagationTraversalDirection;
874
867
  var EDGE_PROPAGATION_SPECS = [
875
868
  supportsPropagationSpec,
876
869
  informsPropagationSpec,
@@ -887,16 +880,15 @@ function getEdgePropagationSpecs() {
887
880
  return EDGE_PROPAGATION_SPECS;
888
881
  }
889
882
  function getTraversalDirections(direction) {
890
- if (isPropagationTraversalDirection(direction)) {
883
+ if (isPropagationTraversalDirection2(direction)) {
891
884
  return [direction];
892
885
  }
893
886
  return ["outgoing", "incoming"];
894
887
  }
895
888
 
896
889
  // src/confidencePropagationDispatch.ts
897
- function resolveTraversalTargetNodeId(edge, direction) {
898
- const targetNodeId = direction === "outgoing" ? edge.toNodeId : edge.fromNodeId;
899
- return targetNodeId ?? void 0;
890
+ function nodeIdToCacheKey(nodeId) {
891
+ return String(nodeId);
900
892
  }
901
893
  function readNodeOpinion(node) {
902
894
  const metadata = node.metadata ?? {};
@@ -912,118 +904,354 @@ function readNodeOpinion(node) {
912
904
  return mkOpinion(0, 0, 1, 0.5);
913
905
  }
914
906
  }
907
+ function resolveTraversalTargetNodeId(edge, direction) {
908
+ const targetNodeId = direction === "outgoing" ? edge.toNodeId : edge.fromNodeId;
909
+ return targetNodeId ?? void 0;
910
+ }
911
+ function buildInitialState(sourceNodeId, sourceOpinion) {
912
+ return {
913
+ nodeId: sourceNodeId,
914
+ opinion: sourceOpinion,
915
+ hop: 0,
916
+ visitedNodeIds: /* @__PURE__ */ new Set([nodeIdToCacheKey(sourceNodeId)])
917
+ };
918
+ }
919
+ function extendVisited(currentVisited, targetNodeId) {
920
+ return /* @__PURE__ */ new Set([...currentVisited, nodeIdToCacheKey(targetNodeId)]);
921
+ }
922
+ function makeTransitiveState(current, targetNodeId, projectedOpinion, nextHop) {
923
+ return {
924
+ nodeId: targetNodeId,
925
+ opinion: projectedOpinion,
926
+ hop: nextHop,
927
+ visitedNodeIds: extendVisited(current.visitedNodeIds, targetNodeId)
928
+ };
929
+ }
930
+ function makeDispatchRecord(targetNodeId, spec, direction, edge, projectedOpinion, nextHop, result, existingDispatch) {
931
+ return {
932
+ targetNodeId,
933
+ edgeType: spec.edgeType,
934
+ traversedDirection: direction,
935
+ weight: edge.weight ?? 1,
936
+ opinion: projectedOpinion,
937
+ operator: result.operator,
938
+ rationale: existingDispatch ? `${existingDispatch.rationale}; ${result.rationale}` : result.rationale,
939
+ hop: nextHop
940
+ };
941
+ }
942
+ async function loadCachedNode(scope, nodeId) {
943
+ const cacheKey = nodeIdToCacheKey(nodeId);
944
+ if (!scope.nodeCache.has(cacheKey)) {
945
+ scope.nodeCache.set(cacheKey, await scope.args.getNode(nodeId));
946
+ }
947
+ return scope.nodeCache.get(cacheKey) ?? null;
948
+ }
949
+ async function collectTargetDispatch(state, nextHop, spec, direction, edge, queue, scope) {
950
+ const sourceScope = scope.args.sourceScope;
951
+ if (sourceScope && !edgeMatchesWorkspaceReasoningScope(edge, sourceScope)) {
952
+ return;
953
+ }
954
+ const targetNodeId = resolveTraversalTargetNodeId(edge, direction);
955
+ if (!targetNodeId) {
956
+ return;
957
+ }
958
+ const targetNodeIdKey = nodeIdToCacheKey(targetNodeId);
959
+ if (state.visitedNodeIds.has(targetNodeIdKey)) {
960
+ return;
961
+ }
962
+ const targetNode = await loadCachedNode(scope, targetNodeId);
963
+ if (targetNode?.nodeType !== "belief") {
964
+ return;
965
+ }
966
+ if (sourceScope && !nodeMatchesWorkspaceReasoningScope(targetNode, sourceScope)) {
967
+ return;
968
+ }
969
+ const targetOpinion = scope.opinionCache.get(targetNodeIdKey) ?? readNodeOpinion(targetNode);
970
+ const result = spec.operator(state.opinion, targetOpinion, edge, {
971
+ hop: nextHop,
972
+ sourceNodeId: state.nodeId,
973
+ targetNodeId,
974
+ traversedDirection: direction,
975
+ spec
976
+ });
977
+ if (!(result && hasProjectedOpinionChanged(targetOpinion, result.opinion))) {
978
+ return;
979
+ }
980
+ const projectedOpinion = mkOpinion(
981
+ result.opinion.b,
982
+ result.opinion.d,
983
+ result.opinion.u,
984
+ result.opinion.a
985
+ );
986
+ scope.opinionCache.set(targetNodeIdKey, projectedOpinion);
987
+ const existingDispatch = scope.dispatchesByTargetId.get(targetNodeIdKey);
988
+ scope.dispatchesByTargetId.set(
989
+ targetNodeIdKey,
990
+ makeDispatchRecord(
991
+ targetNodeId,
992
+ spec,
993
+ direction,
994
+ edge,
995
+ projectedOpinion,
996
+ nextHop,
997
+ result,
998
+ existingDispatch
999
+ )
1000
+ );
1001
+ if (canContinueTransitively2(spec, nextHop)) {
1002
+ queue.push(
1003
+ makeTransitiveState(state, targetNodeId, projectedOpinion, nextHop)
1004
+ );
1005
+ }
1006
+ }
1007
+ async function processTraversalSpec(state, nextHop, spec, queue, scope) {
1008
+ const sourceNodeId = state.nodeId;
1009
+ for (const direction of getTraversalDirections(spec.direction)) {
1010
+ const edges = await scope.args.queryEdges({
1011
+ nodeId: sourceNodeId,
1012
+ spec,
1013
+ direction,
1014
+ hop: nextHop
1015
+ });
1016
+ for (const edge of edges) {
1017
+ await collectTargetDispatch(
1018
+ state,
1019
+ nextHop,
1020
+ spec,
1021
+ direction,
1022
+ edge,
1023
+ queue,
1024
+ scope
1025
+ );
1026
+ }
1027
+ }
1028
+ }
1029
+ async function processQueuedState(state, queue, scope) {
1030
+ const nextHop = state.hop + 1;
1031
+ for (const spec of scope.traversalSpecs) {
1032
+ if (!canTraverseHop2(spec, nextHop)) {
1033
+ continue;
1034
+ }
1035
+ await processTraversalSpec(state, nextHop, spec, queue, scope);
1036
+ }
1037
+ }
1038
+ function sortDispatches(dispatches) {
1039
+ return Array.from(dispatches).sort((left, right) => {
1040
+ if (left.hop !== right.hop) {
1041
+ return left.hop - right.hop;
1042
+ }
1043
+ return String(left.targetNodeId).localeCompare(String(right.targetNodeId));
1044
+ });
1045
+ }
915
1046
  async function collectConfidencePropagationDispatches(args) {
916
1047
  const dispatchesByTargetId = /* @__PURE__ */ new Map();
917
1048
  const opinionCache = /* @__PURE__ */ new Map();
918
1049
  const nodeCache = /* @__PURE__ */ new Map();
919
1050
  const traversalSpecs = args.traversalSpecs ?? getEdgePropagationSpecs();
1051
+ const scope = {
1052
+ args,
1053
+ dispatchesByTargetId,
1054
+ opinionCache,
1055
+ nodeCache,
1056
+ traversalSpecs
1057
+ };
920
1058
  const queue = [
921
- {
922
- nodeId: args.sourceNodeId,
923
- opinion: args.sourceOpinion,
924
- hop: 0,
925
- visitedNodeIds: /* @__PURE__ */ new Set([String(args.sourceNodeId)])
926
- }
1059
+ buildInitialState(args.sourceNodeId, args.sourceOpinion)
927
1060
  ];
928
- const loadNode = async (nodeId) => {
929
- const cacheKey = String(nodeId);
930
- if (!nodeCache.has(cacheKey)) {
931
- nodeCache.set(cacheKey, await args.getNode(nodeId));
932
- }
933
- return nodeCache.get(cacheKey) ?? null;
934
- };
935
1061
  while (queue.length > 0) {
936
1062
  const state = queue.shift();
937
1063
  if (!state) {
938
1064
  continue;
939
1065
  }
940
- for (const spec of traversalSpecs) {
941
- const nextHop = state.hop + 1;
942
- if (!canTraverseHop(spec, nextHop)) {
943
- continue;
944
- }
945
- for (const direction of getTraversalDirections(spec.direction)) {
946
- const edges = await args.queryEdges({
947
- nodeId: state.nodeId,
948
- spec,
949
- direction,
950
- hop: nextHop
951
- });
952
- for (const edge of edges) {
953
- if (args.sourceScope && !edgeMatchesWorkspaceReasoningScope(edge, args.sourceScope)) {
954
- continue;
955
- }
956
- const targetNodeId = resolveTraversalTargetNodeId(edge, direction);
957
- if (!targetNodeId) {
958
- continue;
959
- }
960
- if (state.visitedNodeIds.has(String(targetNodeId))) {
961
- continue;
962
- }
963
- const targetNode = await loadNode(targetNodeId);
964
- if (!targetNode || targetNode.nodeType !== "belief") {
965
- continue;
966
- }
967
- if (args.sourceScope && !nodeMatchesWorkspaceReasoningScope(targetNode, args.sourceScope)) {
968
- continue;
969
- }
970
- const cacheKey = String(targetNodeId);
971
- const targetOpinion = opinionCache.get(cacheKey) ?? readNodeOpinion(targetNode);
972
- const result = spec.operator(state.opinion, targetOpinion, edge, {
973
- hop: nextHop,
974
- sourceNodeId: state.nodeId,
975
- targetNodeId,
976
- traversedDirection: direction,
977
- spec
978
- });
979
- if (!result || !hasProjectedOpinionChanged(targetOpinion, result.opinion)) {
980
- continue;
981
- }
982
- const projectedOpinion = mkOpinion(
983
- result.opinion.b,
984
- result.opinion.d,
985
- result.opinion.u,
986
- result.opinion.a
987
- );
988
- opinionCache.set(cacheKey, projectedOpinion);
989
- const existingDispatch = dispatchesByTargetId.get(cacheKey);
990
- dispatchesByTargetId.set(cacheKey, {
991
- targetNodeId,
992
- edgeType: spec.edgeType,
993
- traversedDirection: direction,
994
- weight: edge.weight ?? 1,
995
- opinion: projectedOpinion,
996
- operator: result.operator,
997
- rationale: existingDispatch ? `${existingDispatch.rationale}; ${result.rationale}` : result.rationale,
998
- hop: nextHop
999
- });
1000
- if (canContinueTransitively(spec, nextHop)) {
1001
- queue.push({
1002
- nodeId: targetNodeId,
1003
- opinion: projectedOpinion,
1004
- hop: nextHop,
1005
- visitedNodeIds: /* @__PURE__ */ new Set([
1006
- ...state.visitedNodeIds,
1007
- String(targetNodeId)
1008
- ])
1009
- });
1010
- }
1011
- }
1012
- }
1013
- }
1066
+ await processQueuedState(state, queue, scope);
1014
1067
  }
1015
- return Array.from(dispatchesByTargetId.values()).sort((left, right) => {
1016
- if (left.hop !== right.hop) {
1017
- return left.hop - right.hop;
1018
- }
1019
- return String(left.targetNodeId).localeCompare(String(right.targetNodeId));
1020
- });
1068
+ return sortDispatches(dispatchesByTargetId.values());
1021
1069
  }
1022
1070
 
1023
1071
  // src/epistemicBeliefs.confidence.ts
1072
+ function isRecord(value) {
1073
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
1074
+ }
1075
+ function readConvexId(value) {
1076
+ return typeof value === "string" && value.trim().length > 0 ? value : void 0;
1077
+ }
1078
+ function readOptionalBoolean(value) {
1079
+ return typeof value === "boolean" ? value : void 0;
1080
+ }
1081
+ function readOptionalNumber(value) {
1082
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
1083
+ }
1084
+ function readOptionalString(value) {
1085
+ return typeof value === "string" && value.trim().length > 0 ? value : void 0;
1086
+ }
1087
+ function readRecord(value) {
1088
+ return isRecord(value) ? value : void 0;
1089
+ }
1090
+ function readConfidenceBeliefNode(value) {
1091
+ if (!isRecord(value)) {
1092
+ return null;
1093
+ }
1094
+ const id = readConvexId(value._id);
1095
+ const nodeType = readOptionalString(value.nodeType);
1096
+ const projectId = readOptionalString(value.projectId);
1097
+ if (!(id && nodeType === "belief" && projectId)) {
1098
+ return null;
1099
+ }
1100
+ const node = {
1101
+ _id: id,
1102
+ nodeType,
1103
+ projectId
1104
+ };
1105
+ const confidence = readOptionalNumber(value.confidence);
1106
+ const epistemicLayer = readOptionalString(value.epistemicLayer);
1107
+ const globalId = readOptionalString(value.globalId);
1108
+ const metadata = readRecord(value.metadata);
1109
+ const opinionA = readOptionalNumber(value.opinion_a);
1110
+ const opinionB = readOptionalNumber(value.opinion_b);
1111
+ const opinionD = readOptionalNumber(value.opinion_d);
1112
+ const opinionU = readOptionalNumber(value.opinion_u);
1113
+ const predictionMeta = readRecord(value.predictionMeta);
1114
+ const publicationStatus = readOptionalString(value.publicationStatus);
1115
+ const status = readOptionalString(value.status);
1116
+ const tenantId = readOptionalString(value.tenantId);
1117
+ const topicId = readOptionalString(value.topicId);
1118
+ const tupleContradicted = readOptionalBoolean(value.tupleContradicted);
1119
+ const workspaceId = readOptionalString(value.workspaceId);
1120
+ if (confidence !== void 0) {
1121
+ node.confidence = confidence;
1122
+ }
1123
+ if (epistemicLayer !== void 0) {
1124
+ node.epistemicLayer = epistemicLayer;
1125
+ }
1126
+ if (globalId !== void 0) {
1127
+ node.globalId = globalId;
1128
+ }
1129
+ if (metadata !== void 0) {
1130
+ node.metadata = metadata;
1131
+ }
1132
+ if (opinionA !== void 0) {
1133
+ node.opinion_a = opinionA;
1134
+ }
1135
+ if (opinionB !== void 0) {
1136
+ node.opinion_b = opinionB;
1137
+ }
1138
+ if (opinionD !== void 0) {
1139
+ node.opinion_d = opinionD;
1140
+ }
1141
+ if (opinionU !== void 0) {
1142
+ node.opinion_u = opinionU;
1143
+ }
1144
+ if (predictionMeta !== void 0) {
1145
+ node.predictionMeta = predictionMeta;
1146
+ }
1147
+ if (publicationStatus !== void 0) {
1148
+ node.publicationStatus = publicationStatus;
1149
+ }
1150
+ if (status !== void 0) {
1151
+ node.status = status;
1152
+ }
1153
+ if (tenantId !== void 0) {
1154
+ node.tenantId = tenantId;
1155
+ }
1156
+ if (topicId !== void 0) {
1157
+ node.topicId = topicId;
1158
+ }
1159
+ if (tupleContradicted !== void 0) {
1160
+ node.tupleContradicted = tupleContradicted;
1161
+ }
1162
+ if (workspaceId !== void 0) {
1163
+ node.workspaceId = workspaceId;
1164
+ }
1165
+ return node;
1166
+ }
1167
+ function readPropagationEdge(value) {
1168
+ if (!isRecord(value)) {
1169
+ return null;
1170
+ }
1171
+ const edgeType = readOptionalString(value.edgeType);
1172
+ if (!edgeType) {
1173
+ return null;
1174
+ }
1175
+ const edge = { edgeType };
1176
+ const fromNodeId = readConvexId(value.fromNodeId);
1177
+ const tenantId = readOptionalString(value.tenantId);
1178
+ const toNodeId = readConvexId(value.toNodeId);
1179
+ const weight = readOptionalNumber(value.weight);
1180
+ const workspaceId = readOptionalString(value.workspaceId);
1181
+ if (fromNodeId !== void 0) {
1182
+ edge.fromNodeId = fromNodeId;
1183
+ }
1184
+ if (tenantId !== void 0) {
1185
+ edge.tenantId = tenantId;
1186
+ }
1187
+ if (toNodeId !== void 0) {
1188
+ edge.toNodeId = toNodeId;
1189
+ }
1190
+ if (weight !== void 0) {
1191
+ edge.weight = weight;
1192
+ }
1193
+ if (workspaceId !== void 0) {
1194
+ edge.workspaceId = workspaceId;
1195
+ }
1196
+ return edge;
1197
+ }
1198
+ function readRowList(values, reader) {
1199
+ return values.flatMap((value) => {
1200
+ const row = reader(value);
1201
+ return row ? [row] : [];
1202
+ });
1203
+ }
1024
1204
  async function applyBeliefConfidenceChange(ctx, args) {
1025
1205
  const now = Date.now();
1026
- const node = await ctx.db.get(args.nodeId);
1206
+ const node = await requireConfidenceBeliefNode(ctx, args);
1207
+ const state = await buildConfidenceChangeState(ctx, node, args);
1208
+ await assertConfidenceScoringPolicySatisfied(ctx, args, state);
1209
+ const tupleContradictionId = await createTupleContradictionIfNeeded(
1210
+ ctx,
1211
+ args,
1212
+ node,
1213
+ state
1214
+ );
1215
+ await patchBeliefConfidenceState(ctx, args, state);
1216
+ await scheduleFirstScoringThemeEdges(ctx, args, node, state);
1217
+ const beliefConfidenceId = await insertBeliefConfidenceRecord(
1218
+ ctx,
1219
+ args,
1220
+ state,
1221
+ tupleContradictionId,
1222
+ now
1223
+ );
1224
+ await ctx.scheduler.runAfter(0, internal.neo4jSync.syncNodeToNeo4j, {
1225
+ nodeId: args.nodeId,
1226
+ operation: "upsert"
1227
+ });
1228
+ await insertConfidenceAudit(
1229
+ ctx,
1230
+ args,
1231
+ node,
1232
+ state,
1233
+ tupleContradictionId,
1234
+ now
1235
+ );
1236
+ await insertTupleTransitionAuditIfNeeded(
1237
+ ctx,
1238
+ args,
1239
+ node,
1240
+ state,
1241
+ tupleContradictionId,
1242
+ now
1243
+ );
1244
+ await scheduleConfidenceFollowups(ctx, args, node, state);
1245
+ return {
1246
+ nodeId: args.nodeId,
1247
+ previousConfidence: state.previousConfidence,
1248
+ newConfidence: state.derivedConfidence,
1249
+ opinion: state.nextOpinion,
1250
+ beliefConfidenceId
1251
+ };
1252
+ }
1253
+ async function requireConfidenceBeliefNode(ctx, args) {
1254
+ const node = readConfidenceBeliefNode(await ctx.db.get(args.nodeId));
1027
1255
  if (!node) {
1028
1256
  throwStructuredMutationError({
1029
1257
  message: "Node not found.",
@@ -1034,59 +1262,28 @@ async function applyBeliefConfidenceChange(ctx, args) {
1034
1262
  details: { nodeId: args.nodeId }
1035
1263
  });
1036
1264
  }
1037
- if (node.nodeType !== "belief") {
1038
- throwStructuredMutationError({
1039
- 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.`,
1040
- status: 400,
1041
- code: "INVALID_ARGUMENT",
1042
- invariantCode: "entity.no_confidence",
1043
- suggestion: "Use entityLifecycle.updateEntityAttributes for entity mutations. appendSlScoring is for belief nodes only.",
1044
- details: { nodeId: args.nodeId, nodeType: node.nodeType }
1045
- });
1046
- }
1047
- if (!node.projectId) {
1048
- throwStructuredMutationError({
1049
- message: "Belief has no project scope.",
1050
- status: 400,
1051
- code: "MISSING_SCOPE",
1052
- invariantCode: "belief.project_required",
1053
- suggestion: "Belief must have a projectId before SL scoring can be appended.",
1054
- details: { nodeId: args.nodeId }
1055
- });
1056
- }
1057
- await requireScopeWriteAccess(
1058
- ctx,
1059
- node.projectId,
1060
- args.authenticatedUserId
1061
- );
1062
- const existingMetadata = node.metadata || {};
1265
+ await requireScopeWriteAccess(ctx, node.projectId, args.authenticatedUserId);
1266
+ return node;
1267
+ }
1268
+ async function buildConfidenceChangeState(ctx, node, args) {
1269
+ const existingMetadata = readNodeMetadata(node);
1063
1270
  const currentBeliefStatus = resolveBeliefStatus(node, existingMetadata);
1064
1271
  const confidencePolicy = await getActiveConfidencePolicy(ctx);
1065
- if (confidencePolicy.scoringMode === "after_worktree" && isPreValidationBeliefStatus(currentBeliefStatus)) {
1066
- const hasCompletedWorktree = await hasCompletedWorktreeForBelief(
1067
- ctx,
1068
- args.nodeId
1069
- );
1070
- if (!hasCompletedWorktree) {
1071
- throwStructuredMutationError({
1072
- message: "Cannot score belief before worktree completion. Complete a worktree that tests this belief first.",
1073
- status: 409,
1074
- code: "CONFLICT",
1075
- invariantCode: "belief.confidence_append_only",
1076
- suggestion: "Complete a worktree linked to this belief before recording SL scoring.",
1077
- details: { nodeId: args.nodeId }
1078
- });
1079
- }
1080
- }
1081
1272
  const previousConfidence = node.confidence || 0.5;
1082
1273
  const predictionMeta = node.predictionMeta || existingMetadata.predictionMeta;
1083
1274
  const previousOpinion = readBeliefOpinionSnapshot(node, existingMetadata);
1084
- const slB = args.belief;
1085
- const slD = args.disbelief;
1086
- const slU = args.uncertainty;
1087
- const slA = args.baseRate ?? 0.5;
1088
- const nextOpinion = { b: slB, d: slD, u: slU, a: slA };
1089
- const derivedConfidence = confidenceFromSL(slB, slD, slU, slA);
1275
+ const nextOpinion = {
1276
+ b: args.belief,
1277
+ d: args.disbelief,
1278
+ u: args.uncertainty,
1279
+ a: args.baseRate ?? 0.5
1280
+ };
1281
+ const derivedConfidence = confidenceFromSL(
1282
+ nextOpinion.b,
1283
+ nextOpinion.d,
1284
+ nextOpinion.u,
1285
+ nextOpinion.a
1286
+ );
1090
1287
  const isFirstScoring = typeof node.confidence !== "number" || !Number.isFinite(node.confidence);
1091
1288
  const previousTupleContradicted = readTupleContradictedFlag(node.tupleContradicted) ?? readTupleContradictedFlag(existingMetadata.tupleContradicted) ?? detectTupleContradiction(
1092
1289
  previousOpinion,
@@ -1107,79 +1304,121 @@ async function applyBeliefConfidenceChange(ctx, args) {
1107
1304
  predictionMeta,
1108
1305
  metadata: existingMetadata
1109
1306
  });
1110
- let tupleContradictionId;
1111
- if (tupleTransition.crossedIntoTupleContradiction) {
1112
- tupleContradictionId = await ctx.runMutation(
1113
- "contradictions:create",
1114
- {
1115
- projectId: node.projectId,
1116
- topicId: node.topicId,
1117
- beliefId: args.nodeId,
1118
- beliefBId: args.nodeId,
1119
- supportingInsightIds: [],
1120
- contradictingInsightIds: [],
1121
- severity: deriveTupleContradictionSeverity(node),
1122
- source: "tuple_space",
1123
- detectionMethod: "agent",
1124
- description: tupleContradictionDescription,
1125
- createdBy: args.authenticatedUserId
1126
- }
1127
- );
1307
+ const storedRationale = args.rationale ?? `Confidence changed from ${previousConfidence.toFixed(2)} (nodeId: ${args.nodeId})`;
1308
+ return {
1309
+ confidencePolicy,
1310
+ currentBeliefStatus,
1311
+ derivedConfidence,
1312
+ existingMetadata,
1313
+ isFirstScoring,
1314
+ newBeliefStatus,
1315
+ nextOpinion,
1316
+ previousConfidence,
1317
+ previousTupleContradicted,
1318
+ storedRationale,
1319
+ tupleContradictionDescription,
1320
+ tupleTransition
1321
+ };
1322
+ }
1323
+ function readNodeMetadata(node) {
1324
+ return node.metadata ?? {};
1325
+ }
1326
+ async function assertConfidenceScoringPolicySatisfied(ctx, args, state) {
1327
+ if (state.confidencePolicy.scoringMode !== "after_worktree" || !isPreValidationBeliefStatus(state.currentBeliefStatus)) {
1328
+ return;
1329
+ }
1330
+ const hasCompletedWorktree = await hasCompletedWorktreeForBelief(
1331
+ ctx,
1332
+ args.nodeId
1333
+ );
1334
+ if (hasCompletedWorktree) {
1335
+ return;
1128
1336
  }
1337
+ throwStructuredMutationError({
1338
+ message: "Cannot score belief before worktree completion. Complete a worktree that tests this belief first.",
1339
+ status: 409,
1340
+ code: "CONFLICT",
1341
+ invariantCode: "belief.confidence_append_only",
1342
+ suggestion: "Complete a worktree linked to this belief before recording SL scoring.",
1343
+ details: { nodeId: args.nodeId }
1344
+ });
1345
+ }
1346
+ async function createTupleContradictionIfNeeded(ctx, args, node, state) {
1347
+ if (!state.tupleTransition.crossedIntoTupleContradiction) {
1348
+ return;
1349
+ }
1350
+ return await ctx.runMutation("contradictions:create", {
1351
+ projectId: node.projectId,
1352
+ topicId: node.topicId,
1353
+ beliefId: args.nodeId,
1354
+ beliefBId: args.nodeId,
1355
+ supportingInsightIds: [],
1356
+ contradictingInsightIds: [],
1357
+ severity: deriveTupleContradictionSeverity(node),
1358
+ source: "tuple_space",
1359
+ detectionMethod: "agent",
1360
+ description: state.tupleContradictionDescription,
1361
+ createdBy: args.authenticatedUserId
1362
+ });
1363
+ }
1364
+ async function patchBeliefConfidenceState(ctx, args, state) {
1129
1365
  await ctx.db.patch(args.nodeId, {
1130
- confidence: derivedConfidence,
1131
- beliefStatus: newBeliefStatus,
1132
- tupleContradicted: tupleTransition.tupleContradicted,
1133
- updatedAt: now,
1134
- // Store SL opinion fields at node level for fast access
1135
- opinion_b: slB,
1136
- opinion_d: slD,
1137
- opinion_u: slU,
1138
- opinion_a: slA,
1366
+ confidence: state.derivedConfidence,
1367
+ beliefStatus: state.newBeliefStatus,
1368
+ tupleContradicted: state.tupleTransition.tupleContradicted,
1369
+ updatedAt: Date.now(),
1370
+ opinion_b: state.nextOpinion.b,
1371
+ opinion_d: state.nextOpinion.d,
1372
+ opinion_u: state.nextOpinion.u,
1373
+ opinion_a: state.nextOpinion.a,
1139
1374
  metadata: {
1140
- ...existingMetadata,
1141
- beliefStatus: newBeliefStatus,
1142
- slBelief: slB,
1143
- slDisbelief: slD,
1144
- slUncertainty: slU,
1145
- slBaseRate: slA,
1146
- tupleContradicted: tupleTransition.tupleContradicted
1375
+ ...state.existingMetadata,
1376
+ beliefStatus: state.newBeliefStatus,
1377
+ slBelief: state.nextOpinion.b,
1378
+ slDisbelief: state.nextOpinion.d,
1379
+ slUncertainty: state.nextOpinion.u,
1380
+ slBaseRate: state.nextOpinion.a,
1381
+ tupleContradicted: state.tupleTransition.tupleContradicted
1147
1382
  }
1148
1383
  });
1149
- if (isFirstScoring) {
1150
- const nodeTopicId = node.topicId;
1151
- const themeNodes = await ctx.db.query("epistemicNodes").withIndex(
1152
- "by_topic",
1153
- (q) => q.eq("topicId", nodeTopicId || node.projectId)
1154
- ).filter((q) => q.eq(q.field("nodeType"), "theme")).collect();
1155
- for (const theme of themeNodes) {
1156
- if (theme.globalId && node.globalId) {
1157
- await ctx.scheduler.runAfter(0, internal.neo4jEdgeAPI.createEdge, {
1158
- globalId: `edge-${node.globalId}-relates_to_thesis-${theme.globalId}`,
1159
- fromGlobalId: node.globalId,
1160
- toGlobalId: theme.globalId,
1161
- edgeType: "relates_to_thesis",
1162
- weight: derivedConfidence,
1163
- createdBy: args.authenticatedUserId,
1164
- topicId: String(node.projectId),
1165
- fromNodeType: "belief",
1166
- toNodeType: "theme",
1167
- fromLayer: "L3",
1168
- toLayer: "L3"
1169
- });
1170
- }
1384
+ }
1385
+ async function scheduleFirstScoringThemeEdges(ctx, args, node, state) {
1386
+ if (!state.isFirstScoring) {
1387
+ return;
1388
+ }
1389
+ const themeNodes = await ctx.db.query("epistemicNodes").withIndex(
1390
+ "by_topic",
1391
+ (q) => q.eq("topicId", node.topicId || node.projectId)
1392
+ ).filter((q) => q.eq(q.field("nodeType"), "theme")).collect();
1393
+ for (const theme of themeNodes) {
1394
+ if (!(theme.globalId && node.globalId)) {
1395
+ continue;
1171
1396
  }
1397
+ await ctx.scheduler.runAfter(0, internal.neo4jEdgeAPI.createEdge, {
1398
+ globalId: `edge-${node.globalId}-relates_to_thesis-${theme.globalId}`,
1399
+ fromGlobalId: node.globalId,
1400
+ toGlobalId: theme.globalId,
1401
+ edgeType: "relates_to_thesis",
1402
+ weight: state.derivedConfidence,
1403
+ createdBy: args.authenticatedUserId,
1404
+ topicId: String(node.projectId),
1405
+ fromNodeType: "belief",
1406
+ toNodeType: "theme",
1407
+ fromLayer: "L3",
1408
+ toLayer: "L3"
1409
+ });
1172
1410
  }
1173
- const storedRationale = args.rationale ?? `Confidence changed from ${previousConfidence.toFixed(2)} (nodeId: ${args.nodeId})`;
1174
- const beliefConfidenceId = await ctx.db.insert("beliefConfidence", {
1411
+ }
1412
+ async function insertBeliefConfidenceRecord(ctx, args, state, tupleContradictionId, now) {
1413
+ return await ctx.db.insert("beliefConfidence", {
1175
1414
  ...buildBeliefConfidenceRow({
1176
1415
  beliefId: args.nodeId,
1177
- belief: slB,
1178
- disbelief: slD,
1179
- uncertainty: slU,
1180
- baseRate: slA,
1416
+ belief: state.nextOpinion.b,
1417
+ disbelief: state.nextOpinion.d,
1418
+ uncertainty: state.nextOpinion.u,
1419
+ baseRate: state.nextOpinion.a,
1181
1420
  trigger: args.trigger,
1182
- rationale: storedRationale,
1421
+ rationale: state.storedRationale,
1183
1422
  assessedBy: args.authenticatedUserId,
1184
1423
  assessedAt: now,
1185
1424
  slOperator: args.slOperator,
@@ -1188,25 +1427,23 @@ async function applyBeliefConfidenceChange(ctx, args) {
1188
1427
  triggeringWorktreeId: args.triggeringWorktreeId
1189
1428
  })
1190
1429
  });
1191
- await ctx.scheduler.runAfter(0, internal.neo4jSync.syncNodeToNeo4j, {
1192
- nodeId: args.nodeId,
1193
- operation: "upsert"
1194
- });
1430
+ }
1431
+ async function insertConfidenceAudit(ctx, args, node, state, tupleContradictionId, now) {
1195
1432
  await ctx.db.insert("epistemicAudit", {
1196
1433
  entityType: "belief",
1197
1434
  entityId: args.nodeId,
1198
1435
  changeType: "confidence_changed",
1199
1436
  previousState: {
1200
- confidence: previousConfidence,
1201
- tupleContradicted: previousTupleContradicted
1437
+ confidence: state.previousConfidence,
1438
+ tupleContradicted: state.previousTupleContradicted
1202
1439
  },
1203
1440
  newState: {
1204
- opinion: nextOpinion,
1205
- confidence: derivedConfidence,
1441
+ opinion: state.nextOpinion,
1442
+ confidence: state.derivedConfidence,
1206
1443
  trigger: args.trigger,
1207
- rationale: storedRationale,
1208
- tupleContradicted: tupleTransition.tupleContradicted,
1209
- tupleContradictionPolicy: tupleTransition.policy,
1444
+ rationale: state.storedRationale,
1445
+ tupleContradicted: state.tupleTransition.tupleContradicted,
1446
+ tupleContradictionPolicy: state.tupleTransition.policy,
1210
1447
  ...tupleContradictionId ? { tupleContradictionId: String(tupleContradictionId) } : {}
1211
1448
  },
1212
1449
  changedBy: args.authenticatedUserId,
@@ -1215,28 +1452,39 @@ async function applyBeliefConfidenceChange(ctx, args) {
1215
1452
  projectId: node.projectId,
1216
1453
  topicId: node.topicId
1217
1454
  });
1218
- if (tupleTransition.crossedIntoTupleContradiction || tupleTransition.crossedOutOfTupleContradiction) {
1219
- await ctx.db.insert("epistemicAudit", {
1220
- entityType: "belief",
1221
- entityId: args.nodeId,
1222
- changeType: "updated",
1223
- previousState: { tupleContradicted: previousTupleContradicted },
1224
- newState: {
1225
- tupleContradicted: tupleTransition.tupleContradicted,
1226
- action: tupleTransition.crossedIntoTupleContradiction ? "tuple_contradiction_detected" : "tuple_contradiction_cleared",
1227
- opinion: nextOpinion,
1228
- tupleContradictionPolicy: tupleTransition.policy,
1229
- ...tupleContradictionId ? { tupleContradictionId: String(tupleContradictionId) } : {}
1230
- },
1231
- 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.`,
1232
- changedBy: args.authenticatedUserId,
1233
- isAgent: false,
1234
- changedAt: now,
1235
- projectId: node.projectId,
1236
- topicId: node.topicId
1237
- });
1455
+ }
1456
+ async function insertTupleTransitionAuditIfNeeded(ctx, args, node, state, tupleContradictionId, now) {
1457
+ if (!(state.tupleTransition.crossedIntoTupleContradiction || state.tupleTransition.crossedOutOfTupleContradiction)) {
1458
+ return;
1459
+ }
1460
+ await ctx.db.insert("epistemicAudit", {
1461
+ entityType: "belief",
1462
+ entityId: args.nodeId,
1463
+ changeType: "updated",
1464
+ previousState: { tupleContradicted: state.previousTupleContradicted },
1465
+ newState: {
1466
+ tupleContradicted: state.tupleTransition.tupleContradicted,
1467
+ action: state.tupleTransition.crossedIntoTupleContradiction ? "tuple_contradiction_detected" : "tuple_contradiction_cleared",
1468
+ opinion: state.nextOpinion,
1469
+ tupleContradictionPolicy: state.tupleTransition.policy,
1470
+ ...tupleContradictionId ? { tupleContradictionId: String(tupleContradictionId) } : {}
1471
+ },
1472
+ rationale: tupleAuditRationale(state),
1473
+ changedBy: args.authenticatedUserId,
1474
+ isAgent: false,
1475
+ changedAt: now,
1476
+ projectId: node.projectId,
1477
+ topicId: node.topicId
1478
+ });
1479
+ }
1480
+ function tupleAuditRationale(state) {
1481
+ if (state.tupleTransition.crossedIntoTupleContradiction) {
1482
+ return state.tupleContradictionDescription;
1238
1483
  }
1239
- if (Math.abs(derivedConfidence - previousConfidence) >= 0.15) {
1484
+ return `Tuple-space contradiction cleared: b=${state.nextOpinion.b.toFixed(2)}, d=${state.nextOpinion.d.toFixed(2)} no longer exceed the configured policy thresholds.`;
1485
+ }
1486
+ async function scheduleConfidenceFollowups(ctx, args, node, state) {
1487
+ if (Math.abs(state.derivedConfidence - state.previousConfidence) >= 0.15) {
1240
1488
  await ctx.scheduler.runAfter(
1241
1489
  5e3,
1242
1490
  internal.bi.contradictionSemanticDetector.scanAffectedBeliefs,
@@ -1253,13 +1501,6 @@ async function applyBeliefConfidenceChange(ctx, args) {
1253
1501
  { nodeId: args.nodeId }
1254
1502
  );
1255
1503
  }
1256
- return {
1257
- nodeId: args.nodeId,
1258
- previousConfidence,
1259
- newConfidence: derivedConfidence,
1260
- opinion: { b: slB, d: slD, u: slU, a: slA },
1261
- beliefConfidenceId
1262
- };
1263
1504
  }
1264
1505
  function propagationPressureLabel(edgeType, weight) {
1265
1506
  if (edgeType === "contradicts" || edgeType === "refutes") {
@@ -1287,7 +1528,7 @@ internalMutation({
1287
1528
  args.opinion_u,
1288
1529
  args.opinion_a
1289
1530
  );
1290
- const sourceNode = await ctx.db.get(args.nodeId);
1531
+ const sourceNode = readConfidenceBeliefNode(await ctx.db.get(args.nodeId));
1291
1532
  const sourceScope = await resolveNodeScopeForWorkspaceIsolation(
1292
1533
  ctx,
1293
1534
  sourceNode
@@ -1296,16 +1537,20 @@ internalMutation({
1296
1537
  sourceNodeId: args.nodeId,
1297
1538
  sourceOpinion,
1298
1539
  sourceScope,
1299
- queryEdges: async ({ nodeId, spec, direction }) => {
1300
- return await ctx.db.query("epistemicEdges").withIndex(
1540
+ queryEdges: async ({ nodeId, spec, direction }) => readRowList(
1541
+ await ctx.db.query("epistemicEdges").withIndex(
1301
1542
  direction === "outgoing" ? "by_from_type" : "by_to_type",
1302
1543
  (q) => direction === "outgoing" ? q.eq("fromNodeId", nodeId).eq("edgeType", spec.edgeType) : q.eq("toNodeId", nodeId).eq("edgeType", spec.edgeType)
1303
- ).collect();
1304
- },
1305
- getNode: async (nodeId) => await ctx.db.get(nodeId)
1544
+ ).collect(),
1545
+ readPropagationEdge
1546
+ ),
1547
+ getNode: async (nodeId) => readConfidenceBeliefNode(await ctx.db.get(nodeId))
1306
1548
  });
1307
1549
  for (const dispatch of dispatches) {
1308
- const pressureLabel = propagationPressureLabel(dispatch.edgeType, dispatch.weight);
1550
+ const pressureLabel = propagationPressureLabel(
1551
+ dispatch.edgeType,
1552
+ dispatch.weight
1553
+ );
1309
1554
  await applyBeliefConfidenceChange(ctx, {
1310
1555
  nodeId: dispatch.targetNodeId,
1311
1556
  belief: dispatch.opinion.b,
@@ -1335,9 +1580,7 @@ var ACTIVE_CONTRADICTION_STATUSES = /* @__PURE__ */ new Set([
1335
1580
  "investigating",
1336
1581
  "accepted_as_permanent"
1337
1582
  ]);
1338
- var DEPENDENT_EDGE_TYPES = /* @__PURE__ */ new Set([
1339
- "depends_on"
1340
- ]);
1583
+ var DEPENDENT_EDGE_TYPES = /* @__PURE__ */ new Set(["depends_on"]);
1341
1584
  function classifyContradictionStatus(status) {
1342
1585
  if (typeof status !== "string") {
1343
1586
  return "active";
@@ -1350,6 +1593,99 @@ function classifyContradictionStatus(status) {
1350
1593
  }
1351
1594
  return "resolved";
1352
1595
  }
1596
+ function isRecord2(value) {
1597
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
1598
+ }
1599
+ function readOptionalNumber2(value) {
1600
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
1601
+ }
1602
+ function readOptionalString2(value) {
1603
+ return typeof value === "string" && value.trim().length > 0 ? value : void 0;
1604
+ }
1605
+ function readConvexId2(value) {
1606
+ const normalized = readOptionalString2(value);
1607
+ return normalized;
1608
+ }
1609
+ function readMetricNodeDoc(value) {
1610
+ if (!isRecord2(value)) {
1611
+ return null;
1612
+ }
1613
+ const id = readConvexId2(value._id);
1614
+ const nodeType = readOptionalString2(value.nodeType);
1615
+ if (!(id && nodeType)) {
1616
+ return null;
1617
+ }
1618
+ const node = { _id: id, nodeType };
1619
+ const globalId = readOptionalString2(value.globalId);
1620
+ if (globalId !== void 0) {
1621
+ node.globalId = globalId;
1622
+ }
1623
+ if ("metadata" in value) {
1624
+ node.metadata = value.metadata;
1625
+ }
1626
+ const status = readOptionalString2(value.status);
1627
+ if (status !== void 0) {
1628
+ node.status = status;
1629
+ }
1630
+ return node;
1631
+ }
1632
+ function readIncomingEdgeRow(value) {
1633
+ if (!isRecord2(value)) {
1634
+ return null;
1635
+ }
1636
+ const fromNodeId = readOptionalString2(value.fromNodeId);
1637
+ if (!fromNodeId) {
1638
+ return null;
1639
+ }
1640
+ const edge = { fromNodeId };
1641
+ const id = readConvexId2(value._id);
1642
+ if (id !== void 0) {
1643
+ edge._id = id;
1644
+ }
1645
+ const edgeType = readOptionalString2(value.edgeType);
1646
+ if (edgeType !== void 0) {
1647
+ edge.edgeType = edgeType;
1648
+ }
1649
+ const fromGlobalId = readOptionalString2(value.fromGlobalId);
1650
+ if (fromGlobalId !== void 0) {
1651
+ edge.fromGlobalId = fromGlobalId;
1652
+ }
1653
+ const fromUuid = readOptionalString2(value.fromUuid);
1654
+ if (fromUuid !== void 0) {
1655
+ edge.fromUuid = fromUuid;
1656
+ }
1657
+ const sourceGlobalId = readOptionalString2(value.sourceGlobalId);
1658
+ if (sourceGlobalId !== void 0) {
1659
+ edge.sourceGlobalId = sourceGlobalId;
1660
+ }
1661
+ const targetGlobalId = readOptionalString2(value.targetGlobalId);
1662
+ if (targetGlobalId !== void 0) {
1663
+ edge.targetGlobalId = targetGlobalId;
1664
+ }
1665
+ const toGlobalId = readOptionalString2(value.toGlobalId);
1666
+ if (toGlobalId !== void 0) {
1667
+ edge.toGlobalId = toGlobalId;
1668
+ }
1669
+ const toNodeId = readOptionalString2(value.toNodeId);
1670
+ if (toNodeId !== void 0) {
1671
+ edge.toNodeId = toNodeId;
1672
+ }
1673
+ const toUuid = readOptionalString2(value.toUuid);
1674
+ if (toUuid !== void 0) {
1675
+ edge.toUuid = toUuid;
1676
+ }
1677
+ const weight = readOptionalNumber2(value.weight);
1678
+ if (weight !== void 0) {
1679
+ edge.weight = weight;
1680
+ }
1681
+ for (const timestampField of ["_creationTime", "createdAt", "updatedAt"]) {
1682
+ const timestamp = readOptionalNumber2(value[timestampField]);
1683
+ if (timestamp !== void 0) {
1684
+ edge[timestampField] = timestamp;
1685
+ }
1686
+ }
1687
+ return edge;
1688
+ }
1353
1689
  function getEdgeTimestamp(edge) {
1354
1690
  if (typeof edge.updatedAt === "number") {
1355
1691
  return edge.updatedAt;
@@ -1362,22 +1698,86 @@ function getEdgeTimestamp(edge) {
1362
1698
  }
1363
1699
  return null;
1364
1700
  }
1701
+ async function collectNodeEndpointRefs(ctx, nodeId) {
1702
+ const refs = /* @__PURE__ */ new Set([String(nodeId)]);
1703
+ const node = readMetricNodeDoc(await ctx.db.get(nodeId));
1704
+ if (node?.globalId) {
1705
+ refs.add(node.globalId);
1706
+ }
1707
+ return [...refs];
1708
+ }
1709
+ async function collectIncomingEdgeRows(ctx, nodeId, edgeType) {
1710
+ const refs = await collectNodeEndpointRefs(ctx, nodeId);
1711
+ const seen = /* @__PURE__ */ new Set();
1712
+ const edges = [];
1713
+ for (const ref of refs) {
1714
+ 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(
1715
+ "by_to_type",
1716
+ (q) => q.eq("toNodeId", ref).eq("edgeType", edgeType)
1717
+ ).collect();
1718
+ for (const row of rows) {
1719
+ const edge = readIncomingEdgeRow(row);
1720
+ if (!edge) {
1721
+ continue;
1722
+ }
1723
+ if (edgeType !== void 0 && edge.edgeType !== edgeType) {
1724
+ continue;
1725
+ }
1726
+ const key = edge._id === void 0 ? `${edge.fromNodeId}->${edge.toNodeId ?? ref}:${edge.edgeType ?? ""}` : String(edge._id);
1727
+ if (seen.has(key)) {
1728
+ continue;
1729
+ }
1730
+ seen.add(key);
1731
+ edges.push(edge);
1732
+ }
1733
+ }
1734
+ return edges;
1735
+ }
1736
+ function sourceEndpointRefs(edge) {
1737
+ return [
1738
+ edge.fromNodeId,
1739
+ edge.sourceGlobalId,
1740
+ edge.fromGlobalId,
1741
+ edge.fromUuid
1742
+ ].filter((value) => value !== void 0);
1743
+ }
1744
+ async function resolveEndpointNode(ctx, refs) {
1745
+ const candidates = refs.map((value) => value.trim()).filter(
1746
+ (value, index, values) => value.length > 0 && values.indexOf(value) === index
1747
+ );
1748
+ for (const candidate of candidates) {
1749
+ try {
1750
+ const direct = readMetricNodeDoc(
1751
+ await ctx.db.get(candidate)
1752
+ );
1753
+ if (direct) {
1754
+ return direct;
1755
+ }
1756
+ } catch {
1757
+ }
1758
+ const byGlobalId = readMetricNodeDoc(
1759
+ await ctx.db.query("epistemicNodes").withIndex("by_globalId", (q) => q.eq("globalId", candidate)).first()
1760
+ );
1761
+ if (byGlobalId) {
1762
+ return byGlobalId;
1763
+ }
1764
+ }
1765
+ return null;
1766
+ }
1365
1767
  async function getEvidenceLinks(ctx, beliefNodeId) {
1366
- const edges = await ctx.db.query("epistemicEdges").withIndex(
1367
- "by_to_type",
1368
- (q) => q.eq("toNodeId", beliefNodeId).eq("edgeType", "informs")
1369
- ).collect();
1768
+ const edges = await collectIncomingEdgeRows(ctx, beliefNodeId, "informs");
1370
1769
  if (edges.length === 0) {
1371
1770
  return [];
1372
1771
  }
1373
- const nodes = await Promise.all(edges.map((edge) => ctx.db.get(edge.fromNodeId)));
1374
- return edges.flatMap((edge, index) => {
1375
- const node = nodes[index];
1376
- if (!node || node.nodeType !== "evidence" || node.status === "archived") {
1377
- return [];
1772
+ const links = [];
1773
+ for (const edge of edges) {
1774
+ const node = await resolveEndpointNode(ctx, sourceEndpointRefs(edge));
1775
+ if (node?.nodeType !== "evidence" || node.status === "archived") {
1776
+ continue;
1378
1777
  }
1379
- return [{ edge, node }];
1380
- });
1778
+ links.push({ edge, node });
1779
+ }
1780
+ return links;
1381
1781
  }
1382
1782
  function getEvidenceTags(node) {
1383
1783
  const metadata = node.metadata && typeof node.metadata === "object" ? node.metadata : null;
@@ -1403,7 +1803,8 @@ async function computeTaggedEvidenceCount(args) {
1403
1803
  };
1404
1804
  }
1405
1805
  async function computeContradictionCounts(ctx, beliefNodeId) {
1406
- const contradictions = await ctx.db.query("contradictions").withIndex("by_beliefId", (q) => q.eq("beliefId", beliefNodeId)).collect();
1806
+ const contradictionDb = ctx.db;
1807
+ const contradictions = await contradictionDb.query("contradictions").withIndex("by_beliefId", (q) => q.eq("beliefId", beliefNodeId)).collect();
1407
1808
  return contradictions.reduce(
1408
1809
  (counts, contradiction) => {
1409
1810
  const status = contradiction.resolutionStatus ?? contradiction.status ?? "unresolved";
@@ -1439,18 +1840,16 @@ async function computeEvidenceFreshness(ctx, beliefNodeId, now = Date.now()) {
1439
1840
  };
1440
1841
  }
1441
1842
  async function computeDependentBeliefCount(ctx, beliefNodeId) {
1442
- const incomingEdges = await ctx.db.query("epistemicEdges").withIndex("by_to", (q) => q.eq("toNodeId", beliefNodeId)).collect();
1843
+ const incomingEdges = await collectIncomingEdgeRows(ctx, beliefNodeId);
1443
1844
  const dependencyEdges = incomingEdges.filter(
1444
- (edge) => DEPENDENT_EDGE_TYPES.has(edge.edgeType)
1845
+ (edge) => edge.edgeType ? DEPENDENT_EDGE_TYPES.has(edge.edgeType) : false
1445
1846
  );
1446
1847
  if (dependencyEdges.length === 0) {
1447
1848
  return 0;
1448
1849
  }
1449
- const dependentBeliefs = await Promise.all(
1450
- dependencyEdges.map((edge) => ctx.db.get(edge.fromNodeId))
1451
- );
1452
1850
  const uniqueBeliefIds = /* @__PURE__ */ new Set();
1453
- for (const node of dependentBeliefs) {
1851
+ for (const edge of dependencyEdges) {
1852
+ const node = await resolveEndpointNode(ctx, sourceEndpointRefs(edge));
1454
1853
  if (node && node.nodeType === "belief" && node.status !== "archived" && node.status !== "deleted") {
1455
1854
  uniqueBeliefIds.add(String(node._id));
1456
1855
  }
@@ -1460,7 +1859,10 @@ async function computeDependentBeliefCount(ctx, beliefNodeId) {
1460
1859
  async function snapshotEvidentialMetric(args) {
1461
1860
  switch (args.metric) {
1462
1861
  case "evidence_count": {
1463
- const count = await computeEvidenceCountMetric(args.ctx, args.beliefNodeId);
1862
+ const count = await computeEvidenceCountMetric(
1863
+ args.ctx,
1864
+ args.beliefNodeId
1865
+ );
1464
1866
  return {
1465
1867
  metric: args.metric,
1466
1868
  value: count,
@@ -1468,7 +1870,10 @@ async function snapshotEvidentialMetric(args) {
1468
1870
  };
1469
1871
  }
1470
1872
  case "contradiction_status": {
1471
- const counts = await computeContradictionCounts(args.ctx, args.beliefNodeId);
1873
+ const counts = await computeContradictionCounts(
1874
+ args.ctx,
1875
+ args.beliefNodeId
1876
+ );
1472
1877
  return {
1473
1878
  metric: args.metric,
1474
1879
  value: counts.activeCount,
@@ -1488,7 +1893,10 @@ async function snapshotEvidentialMetric(args) {
1488
1893
  };
1489
1894
  }
1490
1895
  case "dependent_count": {
1491
- const count = await computeDependentBeliefCount(args.ctx, args.beliefNodeId);
1896
+ const count = await computeDependentBeliefCount(
1897
+ args.ctx,
1898
+ args.beliefNodeId
1899
+ );
1492
1900
  return {
1493
1901
  metric: args.metric,
1494
1902
  value: count,
@@ -1504,7 +1912,9 @@ async function snapshotEvidentialMetric(args) {
1504
1912
  }
1505
1913
  }
1506
1914
  async function evaluateBuiltInEvidentialContract(args) {
1507
- const config = parseEvidentialEvaluatorConfig(args.contract.condition.evaluatorConfig);
1915
+ const config = parseEvidentialEvaluatorConfig(
1916
+ args.contract.condition.evaluatorConfig
1917
+ );
1508
1918
  const snapshot = await snapshotEvidentialMetric({
1509
1919
  ctx: args.ctx,
1510
1920
  beliefNodeId: args.belief._id,
@@ -1512,7 +1922,10 @@ async function evaluateBuiltInEvidentialContract(args) {
1512
1922
  now: args.now
1513
1923
  });
1514
1924
  const comparisonSatisfied = snapshot.value !== null && compareMetricValue(config.operator, snapshot.value, config.threshold);
1515
- const result = args.contract.direction === "falsifies" ? comparisonSatisfied ? "disconfirmed" : "confirmed" : comparisonSatisfied ? "confirmed" : "disconfirmed";
1925
+ const result = resolveComparisonResult(
1926
+ args.contract.direction,
1927
+ comparisonSatisfied
1928
+ );
1516
1929
  return {
1517
1930
  result,
1518
1931
  rationale: buildEvidentialRationale({
@@ -1532,57 +1945,66 @@ async function evaluateBuiltInEvidentialContract(args) {
1532
1945
  }
1533
1946
  };
1534
1947
  }
1535
- async function evaluateMetricCheckerContract(args) {
1536
- const config = parseMetricCheckerConfig(args.contract.condition.evaluatorConfig);
1537
- const input = getEvaluatorInputRecord(args.inputData, "metricData");
1538
- const metric = typeof input.metric === "string" && input.metric.length > 0 ? input.metric : config.metric;
1539
- const observedValue = pickFiniteNumber(input, [
1540
- "observedValue",
1541
- "currentValue",
1542
- "metricValue",
1543
- "value"
1544
- ]) ?? config.observedValue ?? config.currentValue ?? config.metricValue ?? null;
1545
- if (observedValue === null) {
1948
+ function evaluateMetricCheckerContract(args) {
1949
+ return Promise.resolve().then(() => {
1950
+ const config = parseMetricCheckerConfig(
1951
+ args.contract.condition.evaluatorConfig
1952
+ );
1953
+ const input = getEvaluatorInputRecord(args.inputData, "metricData");
1954
+ const metric = typeof input.metric === "string" && input.metric.length > 0 ? input.metric : config.metric;
1955
+ const observedValue = pickFiniteNumber(input, [
1956
+ "observedValue",
1957
+ "currentValue",
1958
+ "metricValue",
1959
+ "value"
1960
+ ]) ?? config.observedValue ?? config.currentValue ?? config.metricValue ?? null;
1961
+ if (observedValue === null) {
1962
+ return {
1963
+ result: "inconclusive",
1964
+ rationale: `metric_checker is awaiting data for ${metric ?? args.contract.condition.expression}.`,
1965
+ data: {
1966
+ metric,
1967
+ observedValue: null,
1968
+ operator: config.operator,
1969
+ threshold: config.threshold,
1970
+ unit: config.unit
1971
+ }
1972
+ };
1973
+ }
1974
+ const comparisonSatisfied = compareMetricValue(
1975
+ config.operator,
1976
+ observedValue,
1977
+ config.threshold
1978
+ );
1979
+ const result = resolveComparisonResult(
1980
+ args.contract.direction,
1981
+ comparisonSatisfied
1982
+ );
1546
1983
  return {
1547
- result: "inconclusive",
1548
- rationale: `metric_checker is awaiting data for ${metric ?? args.contract.condition.expression}.`,
1984
+ result,
1985
+ rationale: buildComparisonRationale({
1986
+ label: metric ?? "metric",
1987
+ observedValue,
1988
+ operator: config.operator,
1989
+ threshold: config.threshold,
1990
+ comparisonSatisfied,
1991
+ result,
1992
+ unit: config.unit
1993
+ }),
1549
1994
  data: {
1550
1995
  metric,
1551
- observedValue: null,
1996
+ observedValue,
1552
1997
  operator: config.operator,
1553
1998
  threshold: config.threshold,
1554
1999
  unit: config.unit
1555
2000
  }
1556
2001
  };
1557
- }
1558
- const comparisonSatisfied = compareMetricValue(
1559
- config.operator,
1560
- observedValue,
1561
- config.threshold
1562
- );
1563
- const result = resolveComparisonResult(args.contract.direction, comparisonSatisfied);
1564
- return {
1565
- result,
1566
- rationale: buildComparisonRationale({
1567
- label: metric ?? "metric",
1568
- observedValue,
1569
- operator: config.operator,
1570
- threshold: config.threshold,
1571
- comparisonSatisfied,
1572
- result,
1573
- unit: config.unit
1574
- }),
1575
- data: {
1576
- metric,
1577
- observedValue,
1578
- operator: config.operator,
1579
- threshold: config.threshold,
1580
- unit: config.unit
1581
- }
1582
- };
2002
+ });
1583
2003
  }
1584
2004
  async function evaluateReferenceCheckCounterContract(args) {
1585
- const config = parseReferenceCheckCounterConfig(args.contract.condition.evaluatorConfig);
2005
+ const config = parseReferenceCheckCounterConfig(
2006
+ args.contract.condition.evaluatorConfig
2007
+ );
1586
2008
  const input = getEvaluatorInputRecord(args.inputData, "referenceCheckData");
1587
2009
  const tag = typeof input.tag === "string" && input.tag.trim().length > 0 ? input.tag.trim() : config.tag;
1588
2010
  const snapshot = await computeTaggedEvidenceCount({
@@ -1596,7 +2018,10 @@ async function evaluateReferenceCheckCounterContract(args) {
1596
2018
  snapshot.count,
1597
2019
  config.threshold
1598
2020
  );
1599
- const result = resolveComparisonResult(args.contract.direction, comparisonSatisfied);
2021
+ const result = resolveComparisonResult(
2022
+ args.contract.direction,
2023
+ comparisonSatisfied
2024
+ );
1600
2025
  return {
1601
2026
  result,
1602
2027
  rationale: buildComparisonRationale({
@@ -1618,130 +2043,167 @@ async function evaluateReferenceCheckCounterContract(args) {
1618
2043
  }
1619
2044
  };
1620
2045
  }
1621
- async function evaluateTemporalDeadlineContract(args) {
1622
- if (typeof args.contract.deadline !== "number" || !Number.isFinite(args.contract.deadline)) {
1623
- throw new Error(
1624
- "temporal_deadline requires contract.deadline to be set to a finite timestamp."
1625
- );
1626
- }
1627
- const config = parseTemporalDeadlineConfig(args.contract.condition.evaluatorConfig);
1628
- const input = getEvaluatorInputRecord(args.inputData, "temporalData");
1629
- const label = (typeof input.label === "string" && input.label.length > 0 ? input.label : config.label) ?? args.contract.title ?? args.contract.condition.expression;
1630
- const completedAt = pickFiniteNumber(input, [
1631
- "completedAt",
1632
- "observedAt",
1633
- "satisfiedAt",
1634
- "achievedAt"
1635
- ]) ?? config.completedAt ?? config.observedAt ?? config.satisfiedAt ?? config.achievedAt;
1636
- const completed = input.completed === true || config.completed === true || completedAt !== void 0;
1637
- if (completed) {
1638
- if (completedAt !== void 0 && completedAt > args.contract.deadline) {
1639
- return {
1640
- result: "expired",
1641
- rationale: `${label} completed at ${completedAt}, after deadline ${args.contract.deadline}.`,
1642
- data: {
1643
- label,
1644
- deadline: args.contract.deadline,
1645
- completed: true,
1646
- completedAt,
1647
- missedDeadline: true,
1648
- overdueByMs: completedAt - args.contract.deadline
1649
- }
1650
- };
1651
- }
1652
- const result = args.contract.direction === "falsifies" ? "disconfirmed" : "confirmed";
2046
+ function resolveCompletedTemporalDeadlineResult(args) {
2047
+ const { completedAt, context, deadline, label } = args;
2048
+ if (completedAt !== void 0 && completedAt > deadline) {
1653
2049
  return {
1654
- result,
1655
- rationale: `${label} completed before deadline ${args.contract.deadline}.`,
2050
+ result: "expired",
2051
+ rationale: `${label} completed at ${completedAt}, after deadline ${deadline}.`,
1656
2052
  data: {
1657
2053
  label,
1658
- deadline: args.contract.deadline,
2054
+ deadline,
1659
2055
  completed: true,
1660
- completedAt: completedAt ?? null,
1661
- missedDeadline: false
2056
+ completedAt,
2057
+ missedDeadline: true,
2058
+ overdueByMs: completedAt - deadline
1662
2059
  }
1663
2060
  };
1664
2061
  }
1665
- if (args.now > args.contract.deadline) {
2062
+ const result = context.contract.direction === "falsifies" ? "disconfirmed" : "confirmed";
2063
+ return {
2064
+ result,
2065
+ rationale: `${label} completed before deadline ${deadline}.`,
2066
+ data: {
2067
+ label,
2068
+ deadline,
2069
+ completed: true,
2070
+ completedAt: completedAt ?? null,
2071
+ missedDeadline: false
2072
+ }
2073
+ };
2074
+ }
2075
+ function resolveOpenTemporalDeadlineResult(args) {
2076
+ const { context, deadline, label } = args;
2077
+ if (context.now > deadline) {
1666
2078
  return {
1667
2079
  result: "expired",
1668
- rationale: `${label} missed deadline ${args.contract.deadline}; temporal contract expired.`,
2080
+ rationale: `${label} missed deadline ${deadline}; temporal contract expired.`,
1669
2081
  data: {
1670
2082
  label,
1671
- deadline: args.contract.deadline,
2083
+ deadline,
1672
2084
  completed: false,
1673
- overdueByMs: args.now - args.contract.deadline
2085
+ overdueByMs: context.now - deadline
1674
2086
  }
1675
2087
  };
1676
2088
  }
1677
2089
  return {
1678
2090
  result: "inconclusive",
1679
- rationale: `${label} is still before deadline ${args.contract.deadline}; awaiting outcome.`,
2091
+ rationale: `${label} is still before deadline ${deadline}; awaiting outcome.`,
1680
2092
  data: {
1681
2093
  label,
1682
- deadline: args.contract.deadline,
2094
+ deadline,
1683
2095
  completed: false,
1684
- timeRemainingMs: args.contract.deadline - args.now
2096
+ timeRemainingMs: deadline - context.now
1685
2097
  }
1686
2098
  };
1687
2099
  }
1688
- async function evaluateMarketIndexComparatorContract(args) {
1689
- const config = parseMarketIndexComparatorConfig(args.contract.condition.evaluatorConfig);
1690
- const input = getEvaluatorInputRecord(args.inputData, "marketIndexData");
1691
- const subject = typeof input.subject === "string" && input.subject.length > 0 ? input.subject : config.subject;
1692
- const benchmark = typeof input.benchmark === "string" && input.benchmark.length > 0 ? input.benchmark : config.benchmark;
1693
- const subjectValue = pickFiniteNumber(input, ["subjectValue", "primaryValue", "leftValue"]) ?? config.subjectValue ?? config.primaryValue ?? null;
1694
- const benchmarkValue = pickFiniteNumber(input, ["benchmarkValue", "comparisonValue", "rightValue"]) ?? config.benchmarkValue ?? config.comparisonValue ?? null;
1695
- if (subjectValue === null || benchmarkValue === null) {
2100
+ function evaluateTemporalDeadlineContract(args) {
2101
+ return Promise.resolve().then(() => {
2102
+ if (typeof args.contract.deadline !== "number" || !Number.isFinite(args.contract.deadline)) {
2103
+ throw new Error(
2104
+ "temporal_deadline requires contract.deadline to be set to a finite timestamp."
2105
+ );
2106
+ }
2107
+ const deadline = args.contract.deadline;
2108
+ const config = parseTemporalDeadlineConfig(
2109
+ args.contract.condition.evaluatorConfig
2110
+ );
2111
+ const input = getEvaluatorInputRecord(args.inputData, "temporalData");
2112
+ const label = (typeof input.label === "string" && input.label.length > 0 ? input.label : config.label) ?? args.contract.title ?? args.contract.condition.expression;
2113
+ const completedAt = pickFiniteNumber(input, [
2114
+ "completedAt",
2115
+ "observedAt",
2116
+ "satisfiedAt",
2117
+ "achievedAt"
2118
+ ]) ?? config.completedAt ?? config.observedAt ?? config.satisfiedAt ?? config.achievedAt;
2119
+ const completed = input.completed === true || config.completed === true || completedAt !== void 0;
2120
+ if (completed) {
2121
+ return resolveCompletedTemporalDeadlineResult({
2122
+ completedAt,
2123
+ context: args,
2124
+ deadline,
2125
+ label
2126
+ });
2127
+ }
2128
+ return resolveOpenTemporalDeadlineResult({
2129
+ context: args,
2130
+ deadline,
2131
+ label
2132
+ });
2133
+ });
2134
+ }
2135
+ function evaluateMarketIndexComparatorContract(args) {
2136
+ return Promise.resolve().then(() => {
2137
+ const config = parseMarketIndexComparatorConfig(
2138
+ args.contract.condition.evaluatorConfig
2139
+ );
2140
+ const input = getEvaluatorInputRecord(args.inputData, "marketIndexData");
2141
+ const subject = typeof input.subject === "string" && input.subject.length > 0 ? input.subject : config.subject;
2142
+ const benchmark = typeof input.benchmark === "string" && input.benchmark.length > 0 ? input.benchmark : config.benchmark;
2143
+ const subjectValue = pickFiniteNumber(input, ["subjectValue", "primaryValue", "leftValue"]) ?? config.subjectValue ?? config.primaryValue ?? null;
2144
+ const benchmarkValue = pickFiniteNumber(input, [
2145
+ "benchmarkValue",
2146
+ "comparisonValue",
2147
+ "rightValue"
2148
+ ]) ?? config.benchmarkValue ?? config.comparisonValue ?? null;
2149
+ if (subjectValue === null || benchmarkValue === null) {
2150
+ return {
2151
+ result: "inconclusive",
2152
+ rationale: "market_index_comparator is awaiting both subject and benchmark values.",
2153
+ data: {
2154
+ subject,
2155
+ subjectValue,
2156
+ benchmark,
2157
+ benchmarkValue,
2158
+ operator: config.operator,
2159
+ threshold: config.threshold
2160
+ }
2161
+ };
2162
+ }
2163
+ if (benchmarkValue === 0) {
2164
+ throw new Error(
2165
+ "market_index_comparator cannot compare against a zero benchmark value."
2166
+ );
2167
+ }
2168
+ const differentialPercent = (subjectValue - benchmarkValue) / Math.abs(benchmarkValue) * 100;
2169
+ const comparisonSatisfied = compareMetricValue(
2170
+ config.operator,
2171
+ differentialPercent,
2172
+ config.threshold
2173
+ );
2174
+ const result = resolveComparisonResult(
2175
+ args.contract.direction,
2176
+ comparisonSatisfied
2177
+ );
1696
2178
  return {
1697
- result: "inconclusive",
1698
- rationale: "market_index_comparator is awaiting both subject and benchmark values.",
2179
+ result,
2180
+ rationale: buildComparisonRationale({
2181
+ label: `${subject ?? "subject"} vs ${benchmark ?? "benchmark"} differential`,
2182
+ observedValue: differentialPercent,
2183
+ operator: config.operator,
2184
+ threshold: config.threshold,
2185
+ comparisonSatisfied,
2186
+ result,
2187
+ unit: "%"
2188
+ }),
1699
2189
  data: {
1700
2190
  subject,
1701
2191
  subjectValue,
1702
2192
  benchmark,
1703
2193
  benchmarkValue,
2194
+ differentialPercent,
1704
2195
  operator: config.operator,
1705
2196
  threshold: config.threshold
1706
2197
  }
1707
2198
  };
1708
- }
1709
- if (benchmarkValue === 0) {
1710
- throw new Error(
1711
- "market_index_comparator cannot compare against a zero benchmark value."
1712
- );
1713
- }
1714
- const differentialPercent = (subjectValue - benchmarkValue) / Math.abs(benchmarkValue) * 100;
1715
- const comparisonSatisfied = compareMetricValue(
1716
- config.operator,
1717
- differentialPercent,
1718
- config.threshold
1719
- );
1720
- const result = resolveComparisonResult(args.contract.direction, comparisonSatisfied);
1721
- return {
1722
- result,
1723
- rationale: buildComparisonRationale({
1724
- label: `${subject ?? "subject"} vs ${benchmark ?? "benchmark"} differential`,
1725
- observedValue: differentialPercent,
1726
- operator: config.operator,
1727
- threshold: config.threshold,
1728
- comparisonSatisfied,
1729
- result,
1730
- unit: "%"
1731
- }),
1732
- data: {
1733
- subject,
1734
- subjectValue,
1735
- benchmark,
1736
- benchmarkValue,
1737
- differentialPercent,
1738
- operator: config.operator,
1739
- threshold: config.threshold
1740
- }
1741
- };
2199
+ });
1742
2200
  }
1743
2201
  var METRIC_COMPARATOR_EVALUATOR_NAMES = {
1744
- evidentialAliases: /* @__PURE__ */ new Set(["evidential", "built_in_evidential", "builtin_evidential"]),
2202
+ evidentialAliases: /* @__PURE__ */ new Set([
2203
+ "evidential",
2204
+ "built_in_evidential",
2205
+ "builtin_evidential"
2206
+ ]),
1745
2207
  metricChecker: "metric_checker",
1746
2208
  referenceCheckCounter: "reference_check_counter",
1747
2209
  temporalDeadline: "temporal_deadline",
@@ -1749,6 +2211,8 @@ var METRIC_COMPARATOR_EVALUATOR_NAMES = {
1749
2211
  };
1750
2212
 
1751
2213
  // src/evaluators/shared.ts
2214
+ var WINDOWS_PATH_SEPARATORS = /\\/g;
2215
+ var LEADING_DOT_SLASH = /^\.\//;
1752
2216
  function asArray(value) {
1753
2217
  return Array.isArray(value) ? value : [];
1754
2218
  }
@@ -1790,7 +2254,7 @@ function extractTextCandidates(value) {
1790
2254
  return Array.from(new Set(candidates));
1791
2255
  }
1792
2256
  function normalizeFilePath(value) {
1793
- return value.replace(/\\/g, "/").replace(/^\.\//, "");
2257
+ return value.replace(WINDOWS_PATH_SEPARATORS, "/").replace(LEADING_DOT_SLASH, "");
1794
2258
  }
1795
2259
  function normalizeToolResultEnvelope(value) {
1796
2260
  const record = asRecord(value);
@@ -1844,7 +2308,7 @@ function somePatternMatches(filePath, patterns) {
1844
2308
  return patterns.some((pattern) => patternMatchesPath(filePath, pattern));
1845
2309
  }
1846
2310
 
1847
- // src/evaluators/lintCheckerEvaluator.ts
2311
+ // src/evaluators/lint-checker-evaluator.ts
1848
2312
  function parseConfig(condition) {
1849
2313
  const record = asRecord(condition.evaluatorConfig);
1850
2314
  if (!record) {
@@ -1916,7 +2380,10 @@ var lintCheckerEvaluator = {
1916
2380
  }
1917
2381
  const envelope = normalizeToolResultEnvelope(args.resultData);
1918
2382
  const exitCode = asNumber(envelope.exitCode);
1919
- const matchedDiagnostics = getMatchedDiagnostics(args.contract, args.resultData);
2383
+ const matchedDiagnostics = getMatchedDiagnostics(
2384
+ args.contract,
2385
+ args.resultData
2386
+ );
1920
2387
  if (matchedDiagnostics.length === 0 && exitCode !== 0 && exitCode !== null) {
1921
2388
  return {
1922
2389
  result: "inconclusive",
@@ -1942,7 +2409,7 @@ var lintCheckerEvaluator = {
1942
2409
  }
1943
2410
  };
1944
2411
 
1945
- // src/evaluators/sentryCheckerEvaluator.ts
2412
+ // src/evaluators/sentry-checker-evaluator.ts
1946
2413
  function parseConfig2(condition) {
1947
2414
  const record = asRecord(condition.evaluatorConfig);
1948
2415
  if (!record) {
@@ -2027,7 +2494,7 @@ var sentryCheckerEvaluator = {
2027
2494
  }
2028
2495
  };
2029
2496
 
2030
- // src/evaluators/testRunnerEvaluator.ts
2497
+ // src/evaluators/test-runner-evaluator.ts
2031
2498
  function parseConfig3(condition) {
2032
2499
  const record = asRecord(condition.evaluatorConfig);
2033
2500
  if (!record) {
@@ -2173,7 +2640,7 @@ var testRunnerEvaluator = {
2173
2640
  }
2174
2641
  };
2175
2642
 
2176
- // src/evaluators/tscCheckerEvaluator.ts
2643
+ // src/evaluators/tsc-checker-evaluator.ts
2177
2644
  function parseConfig4(condition) {
2178
2645
  const record = asRecord(condition.evaluatorConfig);
2179
2646
  if (!record) {
@@ -2258,7 +2725,10 @@ var tscCheckerEvaluator = {
2258
2725
  }
2259
2726
  const envelope = normalizeToolResultEnvelope(args.resultData);
2260
2727
  const exitCode = asNumber(envelope.exitCode);
2261
- const matchedDiagnostics = getMatchedDiagnostics2(args.contract, args.resultData);
2728
+ const matchedDiagnostics = getMatchedDiagnostics2(
2729
+ args.contract,
2730
+ args.resultData
2731
+ );
2262
2732
  if (matchedDiagnostics.length === 0 && exitCode !== 0 && exitCode !== null) {
2263
2733
  return {
2264
2734
  result: "inconclusive",
@@ -2302,6 +2772,18 @@ var BUILT_IN_REFERENCE_CHECK_COUNTER2 = METRIC_COMPARATOR_EVALUATOR_NAMES.refere
2302
2772
  var BUILT_IN_TEMPORAL_DEADLINE2 = METRIC_COMPARATOR_EVALUATOR_NAMES.temporalDeadline;
2303
2773
  var BUILT_IN_MARKET_INDEX_COMPARATOR2 = METRIC_COMPARATOR_EVALUATOR_NAMES.marketIndexComparator;
2304
2774
  var MAX_CONTRACT_EVALUATION_BATCH_SIZE = 50;
2775
+ function confidenceSeed(args) {
2776
+ if (typeof args.currentConfidence === "number") {
2777
+ return args.currentConfidence;
2778
+ }
2779
+ if (typeof args.beliefConfidence === "number") {
2780
+ return args.beliefConfidence;
2781
+ }
2782
+ return 0.5;
2783
+ }
2784
+ function contractDocId(contract) {
2785
+ return contract._id;
2786
+ }
2305
2787
  function clearEpistemicEvaluators() {
2306
2788
  evaluatorRegistry.clear();
2307
2789
  ensureBuiltInEvaluators();
@@ -2394,7 +2876,10 @@ async function executeContractEvaluation(args) {
2394
2876
  rationale: `No epistemic evaluator registered for "${args.contract.condition.evaluator}".`
2395
2877
  };
2396
2878
  }
2397
- const confidenceBefore = typeof args.currentConfidence === "number" ? args.currentConfidence : typeof args.belief.confidence === "number" ? args.belief.confidence : 0.5;
2879
+ const confidenceBefore = confidenceSeed({
2880
+ beliefConfidence: args.belief.confidence,
2881
+ currentConfidence: args.currentConfidence
2882
+ });
2398
2883
  const modulationPlan = deriveContractModulationPlan({
2399
2884
  currentConfidence: confidenceBefore,
2400
2885
  modulation: args.contract.modulation,
@@ -2434,16 +2919,16 @@ async function executeContractEvaluation(args) {
2434
2919
  modulationRationale: evaluation.rationale,
2435
2920
  topicId: args.contract.topicId
2436
2921
  });
2437
- const nextStatus = deriveContractStatus(evaluation.result, args.contract.status);
2438
- await args.ctx.db.patch(
2439
- args.contract._id,
2440
- {
2441
- status: nextStatus,
2442
- lastEvaluatedAt: args.now,
2443
- evaluationCount: (args.contract.evaluationCount ?? 0) + 1,
2444
- updatedAt: args.now
2445
- }
2922
+ const nextStatus = deriveContractStatus(
2923
+ evaluation.result,
2924
+ args.contract.status
2446
2925
  );
2926
+ await args.ctx.db.patch(contractDocId(args.contract), {
2927
+ status: nextStatus,
2928
+ lastEvaluatedAt: args.now,
2929
+ evaluationCount: (args.contract.evaluationCount ?? 0) + 1,
2930
+ updatedAt: args.now
2931
+ });
2447
2932
  return {
2448
2933
  evaluationId,
2449
2934
  result: evaluation.result,
@@ -2528,7 +3013,8 @@ async function evaluateContractsForTriggerBatch(args) {
2528
3013
  };
2529
3014
  }
2530
3015
  async function loadContractsForBelief(args) {
2531
- return await args.ctx.db.query("epistemicContracts").withIndex("by_belief", (q) => q.eq("beliefNodeId", args.beliefNodeId)).collect();
3016
+ const rows = await args.ctx.db.query("epistemicContracts").withIndex("by_belief", (q) => q.eq("beliefNodeId", args.beliefNodeId)).collect();
3017
+ return rows;
2532
3018
  }
2533
3019
  async function loadContractsForTrigger(args) {
2534
3020
  const contracts = await loadContractsForBelief(args);