@lucern/graph-primitives 1.0.28 → 1.0.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (319) hide show
  1. package/dist/{beliefDecay-DZ6tkLYq.d.ts → beliefDecay-BmkEk5OJ.d.ts} +3 -3
  2. package/dist/beliefDecay.d.ts +1 -1
  3. package/dist/beliefDecay.js +448 -314
  4. package/dist/beliefDecay.js.map +1 -1
  5. package/dist/{beliefEvidenceLinks-CWOXxxJg.d.ts → beliefEvidenceLinks-BzfjON_6.d.ts} +13 -13
  6. package/dist/beliefEvidenceLinks.d.ts +1 -1
  7. package/dist/beliefEvidenceLinks.js +843 -624
  8. package/dist/beliefEvidenceLinks.js.map +1 -1
  9. package/dist/beliefEvidenceLinks.operational.d.ts +7 -5
  10. package/dist/beliefEvidenceLinks.operational.js +91 -18
  11. package/dist/beliefEvidenceLinks.operational.js.map +1 -1
  12. package/dist/beliefLifecycle.js.map +1 -1
  13. package/dist/confidencePropagationDispatch.d.ts +28 -27
  14. package/dist/confidencePropagationDispatch.js +157 -99
  15. package/dist/confidencePropagationDispatch.js.map +1 -1
  16. package/dist/{contradictions-51VLsESq.d.ts → contradictions-BATPuZTL.d.ts} +10 -10
  17. package/dist/contradictions.d.ts +1 -1
  18. package/dist/contradictions.js +398 -228
  19. package/dist/contradictions.js.map +1 -1
  20. package/dist/convex.d.ts +65 -30
  21. package/dist/convex.js +7 -3
  22. package/dist/convex.js.map +1 -1
  23. package/dist/debug.js.map +1 -1
  24. package/dist/edgeValidation.js +293 -85
  25. package/dist/edgeValidation.js.map +1 -1
  26. package/dist/edges/contains.d.ts +1 -1
  27. package/dist/edges/contains.js.map +1 -1
  28. package/dist/edges/contradicts.d.ts +1 -1
  29. package/dist/edges/contradicts.js.map +1 -1
  30. package/dist/edges/{dependsOn.d.ts → depends-on.d.ts} +1 -1
  31. package/dist/edges/{dependsOn.js → depends-on.js} +4 -4
  32. package/dist/edges/depends-on.js.map +1 -0
  33. package/dist/edges/{derivedFrom.d.ts → derived-from.d.ts} +1 -1
  34. package/dist/edges/{derivedFrom.js → derived-from.js} +3 -3
  35. package/dist/edges/derived-from.js.map +1 -0
  36. package/dist/edges/elaborates.d.ts +1 -1
  37. package/dist/edges/elaborates.js.map +1 -1
  38. package/dist/edges/index.d.ts +7 -3
  39. package/dist/edges/index.js +7 -4
  40. package/dist/edges/index.js.map +1 -1
  41. package/dist/edges/informs.d.ts +1 -1
  42. package/dist/edges/informs.js.map +1 -1
  43. package/dist/edges/{propagationTypes.d.ts → propagation-types.d.ts} +14 -14
  44. package/dist/edges/{propagationTypes.js → propagation-types.js} +3 -3
  45. package/dist/edges/propagation-types.js.map +1 -0
  46. package/dist/edges/refutes.d.ts +1 -1
  47. package/dist/edges/refutes.js.map +1 -1
  48. package/dist/edges/supports.d.ts +1 -1
  49. package/dist/edges/supports.js.map +1 -1
  50. package/dist/edges/tests.d.ts +1 -1
  51. package/dist/edges/tests.js.map +1 -1
  52. package/dist/edges/utils.d.ts +1 -1
  53. package/dist/edges/utils.js.map +1 -1
  54. package/dist/embeddingTrigger.d.ts +14 -6
  55. package/dist/embeddingTrigger.js +11 -14
  56. package/dist/embeddingTrigger.js.map +1 -1
  57. package/dist/{entityBridge-DMaKooYn.d.ts → entityBridge-BhVDM3pc.d.ts} +5 -5
  58. package/dist/entityBridge.d.ts +1 -1
  59. package/dist/entityBridge.js +602 -225
  60. package/dist/entityBridge.js.map +1 -1
  61. package/dist/entityCanonicalMatch.d.ts +14 -12
  62. package/dist/entityCanonicalMatch.js.map +1 -1
  63. package/dist/{entityLifecycle-CvgSK5FV.d.ts → entityLifecycle-BsfCz9pS.d.ts} +5 -9
  64. package/dist/entityLifecycle.d.ts +1 -1
  65. package/dist/entityLifecycle.js +857 -515
  66. package/dist/entityLifecycle.js.map +1 -1
  67. package/dist/{entityValidation-KLZ_Xl2D.d.ts → entityValidation-B1yNEHJx.d.ts} +7 -6
  68. package/dist/entityValidation.d.ts +3 -1
  69. package/dist/entityValidation.js +60 -8
  70. package/dist/entityValidation.js.map +1 -1
  71. package/dist/{epistemicAnswers-C5ib4z6_.d.ts → epistemicAnswers-f47YMu9U.d.ts} +6 -6
  72. package/dist/epistemicAnswers.d.ts +1 -1
  73. package/dist/epistemicAnswers.js +587 -545
  74. package/dist/epistemicAnswers.js.map +1 -1
  75. package/dist/epistemicBeliefs.admin.d.ts +8 -8
  76. package/dist/epistemicBeliefs.admin.js +366 -203
  77. package/dist/epistemicBeliefs.admin.js.map +1 -1
  78. package/dist/epistemicBeliefs.backfills.d.ts +8 -8
  79. package/dist/epistemicBeliefs.backfills.js +655 -308
  80. package/dist/epistemicBeliefs.backfills.js.map +1 -1
  81. package/dist/epistemicBeliefs.confidence.d.ts +19 -14
  82. package/dist/epistemicBeliefs.confidence.js +634 -423
  83. package/dist/epistemicBeliefs.confidence.js.map +1 -1
  84. package/dist/epistemicBeliefs.core.d.ts +6 -6
  85. package/dist/epistemicBeliefs.core.js +719 -411
  86. package/dist/epistemicBeliefs.core.js.map +1 -1
  87. package/dist/epistemicBeliefs.d.ts +11 -8
  88. package/dist/epistemicBeliefs.forkEvidence.d.ts +2 -0
  89. package/dist/epistemicBeliefs.forkEvidence.js +8 -28
  90. package/dist/epistemicBeliefs.forkEvidence.js.map +1 -1
  91. package/dist/epistemicBeliefs.helpers.d.ts +69 -74
  92. package/dist/epistemicBeliefs.helpers.js +359 -248
  93. package/dist/epistemicBeliefs.helpers.js.map +1 -1
  94. package/dist/epistemicBeliefs.internal.d.ts +5 -5
  95. package/dist/epistemicBeliefs.internal.js +1246 -1044
  96. package/dist/epistemicBeliefs.internal.js.map +1 -1
  97. package/dist/epistemicBeliefs.js +4922 -3608
  98. package/dist/epistemicBeliefs.js.map +1 -1
  99. package/dist/epistemicBeliefs.lifecycle.d.ts +5 -5
  100. package/dist/epistemicBeliefs.lifecycle.js +1137 -818
  101. package/dist/epistemicBeliefs.lifecycle.js.map +1 -1
  102. package/dist/epistemicBeliefs.links.d.ts +7 -7
  103. package/dist/epistemicBeliefs.links.js +408 -307
  104. package/dist/epistemicBeliefs.links.js.map +1 -1
  105. package/dist/epistemicBeliefs.queries.d.ts +4 -4
  106. package/dist/epistemicBeliefs.queries.js +175 -20
  107. package/dist/epistemicBeliefs.queries.js.map +1 -1
  108. package/dist/epistemicBeliefs.topicAnchor.d.ts +6 -4
  109. package/dist/epistemicBeliefs.topicAnchor.js +12 -5
  110. package/dist/epistemicBeliefs.topicAnchor.js.map +1 -1
  111. package/dist/epistemicContracts.d.ts +28 -3
  112. package/dist/epistemicContracts.evaluators.d.ts +2 -0
  113. package/dist/epistemicContracts.evaluators.js +1063 -613
  114. package/dist/epistemicContracts.evaluators.js.map +1 -1
  115. package/dist/epistemicContracts.handlers.d.ts +15 -32
  116. package/dist/epistemicContracts.handlers.js +2086 -1644
  117. package/dist/epistemicContracts.handlers.js.map +1 -1
  118. package/dist/epistemicContracts.js +1131 -672
  119. package/dist/epistemicContracts.js.map +1 -1
  120. package/dist/epistemicContracts.metrics.d.ts +2 -0
  121. package/dist/epistemicContracts.metrics.js +375 -158
  122. package/dist/epistemicContracts.metrics.js.map +1 -1
  123. package/dist/epistemicContracts.types.d.ts +87 -81
  124. package/dist/epistemicEdgeCreation.d.ts +2 -0
  125. package/dist/epistemicEdgeCreation.js +87 -16
  126. package/dist/epistemicEdgeCreation.js.map +1 -1
  127. package/dist/{epistemicEdges-BF-cn4i3.d.ts → epistemicEdges-BGBh0QSP.d.ts} +4 -7
  128. package/dist/epistemicEdges.d.ts +6 -5
  129. package/dist/epistemicEdges.handlers.d.ts +3 -3
  130. package/dist/epistemicEdges.handlers.js +129 -24
  131. package/dist/epistemicEdges.handlers.js.map +1 -1
  132. package/dist/epistemicEdges.helpers.d.ts +6 -4
  133. package/dist/epistemicEdges.helpers.js +37 -2
  134. package/dist/epistemicEdges.helpers.js.map +1 -1
  135. package/dist/epistemicEdges.js +1969 -1205
  136. package/dist/epistemicEdges.js.map +1 -1
  137. package/dist/epistemicEdges.mutations.d.ts +7 -7
  138. package/dist/epistemicEdges.mutations.js +960 -583
  139. package/dist/epistemicEdges.mutations.js.map +1 -1
  140. package/dist/epistemicEdges.queries.d.ts +16 -16
  141. package/dist/epistemicEdges.queries.js +639 -367
  142. package/dist/epistemicEdges.queries.js.map +1 -1
  143. package/dist/epistemicEdges.types.d.ts +10 -8
  144. package/dist/epistemicEvidence.d.ts +4 -1
  145. package/dist/epistemicEvidence.js +937 -536
  146. package/dist/epistemicEvidence.js.map +1 -1
  147. package/dist/epistemicEvidenceHelpers.d.ts +26 -10
  148. package/dist/epistemicEvidenceHelpers.js +239 -200
  149. package/dist/epistemicEvidenceHelpers.js.map +1 -1
  150. package/dist/epistemicEvidenceMutations.d.ts +8 -8
  151. package/dist/epistemicEvidenceMutations.js +844 -696
  152. package/dist/epistemicEvidenceMutations.js.map +1 -1
  153. package/dist/epistemicEvidenceQueries.d.ts +8 -8
  154. package/dist/epistemicEvidenceQueries.js +514 -238
  155. package/dist/epistemicEvidenceQueries.js.map +1 -1
  156. package/dist/epistemicHelpers.d.ts +4 -2
  157. package/dist/epistemicHelpers.js +308 -134
  158. package/dist/epistemicHelpers.js.map +1 -1
  159. package/dist/epistemicInsert.d.ts +16 -4
  160. package/dist/epistemicInsert.js +6 -3
  161. package/dist/epistemicInsert.js.map +1 -1
  162. package/dist/epistemicLayerRules.d.ts +10 -8
  163. package/dist/epistemicLayerRules.js +1 -5
  164. package/dist/epistemicLayerRules.js.map +1 -1
  165. package/dist/{epistemicLinking-CfE00tHJ.d.ts → epistemicLinking-CsCDv2cN.d.ts} +3 -3
  166. package/dist/epistemicLinking.d.ts +1 -1
  167. package/dist/epistemicLinking.js +177 -100
  168. package/dist/epistemicLinking.js.map +1 -1
  169. package/dist/epistemicNodeCreation.d.ts +2 -0
  170. package/dist/epistemicNodeCreation.js +203 -40
  171. package/dist/epistemicNodeCreation.js.map +1 -1
  172. package/dist/{epistemicNodes-BCQxpYx_.d.ts → epistemicNodes-CokAgBHg.d.ts} +3 -3
  173. package/dist/epistemicNodes.d.ts +3 -3
  174. package/dist/epistemicNodes.helpers.d.ts +24 -15
  175. package/dist/epistemicNodes.helpers.js.map +1 -1
  176. package/dist/epistemicNodes.internal.d.ts +6 -6
  177. package/dist/epistemicNodes.internal.js +389 -319
  178. package/dist/epistemicNodes.internal.js.map +1 -1
  179. package/dist/epistemicNodes.js +704 -508
  180. package/dist/epistemicNodes.js.map +1 -1
  181. package/dist/epistemicNodes.mutations.d.ts +6 -6
  182. package/dist/epistemicNodes.mutations.js +564 -467
  183. package/dist/epistemicNodes.mutations.js.map +1 -1
  184. package/dist/epistemicNodes.queries.d.ts +8 -8
  185. package/dist/epistemicNodes.queries.js +311 -314
  186. package/dist/epistemicNodes.queries.js.map +1 -1
  187. package/dist/epistemicNodes.validators.d.ts +2 -2
  188. package/dist/epistemicNodes.validators.js.map +1 -1
  189. package/dist/epistemicQuestions.conviction.d.ts +8 -8
  190. package/dist/epistemicQuestions.conviction.js +665 -484
  191. package/dist/epistemicQuestions.conviction.js.map +1 -1
  192. package/dist/epistemicQuestions.create.d.ts +4 -4
  193. package/dist/epistemicQuestions.create.js +640 -612
  194. package/dist/epistemicQuestions.create.js.map +1 -1
  195. package/dist/epistemicQuestions.d.ts +8 -5
  196. package/dist/epistemicQuestions.evidence.d.ts +2 -2
  197. package/dist/epistemicQuestions.evidence.js +475 -383
  198. package/dist/epistemicQuestions.evidence.js.map +1 -1
  199. package/dist/epistemicQuestions.helpers.d.ts +125 -24
  200. package/dist/epistemicQuestions.helpers.js +240 -209
  201. package/dist/epistemicQuestions.helpers.js.map +1 -1
  202. package/dist/epistemicQuestions.js +3474 -2823
  203. package/dist/epistemicQuestions.js.map +1 -1
  204. package/dist/epistemicQuestions.lifecycle.d.ts +2 -2
  205. package/dist/epistemicQuestions.lifecycle.js +607 -546
  206. package/dist/epistemicQuestions.lifecycle.js.map +1 -1
  207. package/dist/epistemicQuestions.queries.d.ts +12 -7
  208. package/dist/epistemicQuestions.queries.js +305 -244
  209. package/dist/epistemicQuestions.queries.js.map +1 -1
  210. package/dist/epistemicQuestions.sprint.d.ts +2 -2
  211. package/dist/epistemicQuestions.sprint.js +600 -394
  212. package/dist/epistemicQuestions.sprint.js.map +1 -1
  213. package/dist/epistemicQuestions.tail.d.ts +6 -6
  214. package/dist/epistemicQuestions.tail.js +572 -433
  215. package/dist/epistemicQuestions.tail.js.map +1 -1
  216. package/dist/{epistemicSources-dlKj58Jp.d.ts → epistemicSources-DQtaEkWs.d.ts} +4 -4
  217. package/dist/epistemicSources.d.ts +1 -1
  218. package/dist/epistemicSources.js +352 -312
  219. package/dist/epistemicSources.js.map +1 -1
  220. package/dist/evaluators/index.d.ts +8 -6
  221. package/dist/evaluators/index.js +399 -167
  222. package/dist/evaluators/index.js.map +1 -1
  223. package/dist/evaluators/lint-checker-evaluator.d.ts +16 -0
  224. package/dist/evaluators/{lintCheckerEvaluator.js → lint-checker-evaluator.js} +10 -5
  225. package/dist/evaluators/lint-checker-evaluator.js.map +1 -0
  226. package/dist/evaluators/{sentryCheckerEvaluator.d.ts → sentry-checker-evaluator.d.ts} +7 -2
  227. package/dist/evaluators/{sentryCheckerEvaluator.js → sentry-checker-evaluator.js} +3 -3
  228. package/dist/evaluators/sentry-checker-evaluator.js.map +1 -0
  229. package/dist/evaluators/shared.d.ts +2 -2
  230. package/dist/evaluators/shared.js +3 -1
  231. package/dist/evaluators/shared.js.map +1 -1
  232. package/dist/evaluators/{testRunnerEvaluator.d.ts → test-runner-evaluator.d.ts} +6 -1
  233. package/dist/evaluators/{testRunnerEvaluator.js → test-runner-evaluator.js} +6 -4
  234. package/dist/evaluators/test-runner-evaluator.js.map +1 -0
  235. package/dist/evaluators/tsc-checker-evaluator.d.ts +16 -0
  236. package/dist/evaluators/{tscCheckerEvaluator.js → tsc-checker-evaluator.js} +10 -5
  237. package/dist/evaluators/tsc-checker-evaluator.js.map +1 -0
  238. package/dist/graphTypes.js +6 -2
  239. package/dist/graphTypes.js.map +1 -1
  240. package/dist/helpers.d.ts +2 -0
  241. package/dist/helpers.js +313 -93
  242. package/dist/helpers.js.map +1 -1
  243. package/dist/{index-C-Kyd7hD.d.ts → index-DZxyC9Pb.d.ts} +7 -6
  244. package/dist/index.d.ts +87 -83
  245. package/dist/index.js +15677 -10594
  246. package/dist/index.js.map +1 -1
  247. package/dist/invariantEnforcement.d.ts +3 -3
  248. package/dist/invariantEnforcement.js.map +1 -1
  249. package/dist/logicalRoleInference.d.ts +2 -0
  250. package/dist/logicalRoleInference.js +1 -1
  251. package/dist/logicalRoleInference.js.map +1 -1
  252. package/dist/matcherFeedbackUtils.d.ts +2 -2
  253. package/dist/matcherFeedbackUtils.js.map +1 -1
  254. package/dist/{ontology-matching-C6rrz2VP.d.ts → ontology-matching-C-mYFrir.d.ts} +16 -16
  255. package/dist/ontology-matching.d.ts +1 -1
  256. package/dist/{ontologyApproval-CFYmqKmk.d.ts → ontologyApproval-BVt0feJi.d.ts} +10 -10
  257. package/dist/ontologyApproval.d.ts +1 -1
  258. package/dist/ontologyApproval.js +7 -1
  259. package/dist/ontologyApproval.js.map +1 -1
  260. package/dist/ontologyDefinitions.d.ts +14 -24
  261. package/dist/ontologyDefinitions.js +269 -34
  262. package/dist/ontologyDefinitions.js.map +1 -1
  263. package/dist/ontologyHelpers.d.ts +13 -13
  264. package/dist/ontologyHelpers.js.map +1 -1
  265. package/dist/{ontologyRegistry-B67rPJ16.d.ts → ontologyRegistry-CljS-ENv.d.ts} +2 -2
  266. package/dist/ontologyRegistry.d.ts +1 -1
  267. package/dist/ontologyRegistry.js +34 -6
  268. package/dist/ontologyRegistry.js.map +1 -1
  269. package/dist/{projectionReconciliation-jww2fBI0.d.ts → projectionReconciliation-DnrSgHSQ.d.ts} +4 -4
  270. package/dist/projectionReconciliation.d.ts +1 -1
  271. package/dist/projectionReconciliation.js +57 -10
  272. package/dist/projectionReconciliation.js.map +1 -1
  273. package/dist/{projectionStaleness-CmdbpjVK.d.ts → projectionStaleness-C8ImQ2zP.d.ts} +17 -17
  274. package/dist/projectionStaleness.d.ts +1 -1
  275. package/dist/projectionStaleness.js +8 -2
  276. package/dist/projectionStaleness.js.map +1 -1
  277. package/dist/proof-attestation.json +1 -1
  278. package/dist/{questionEvidenceLinks-DFlyPpAj.d.ts → questionEvidenceLinks-_nPRa-LY.d.ts} +10 -10
  279. package/dist/questionEvidenceLinks.d.ts +1 -1
  280. package/dist/questionEvidenceLinks.js +564 -347
  281. package/dist/questionEvidenceLinks.js.map +1 -1
  282. package/dist/{resolverTypes-CC8Ea2E2.d.ts → resolverTypes-BOXPxLET.d.ts} +8 -7
  283. package/dist/resolverTypes.d.ts +4 -2
  284. package/dist/{resolvers-Br1a6eLV.d.ts → resolvers-B1TIBmRO.d.ts} +3 -1
  285. package/dist/resolvers.d.ts +5 -3
  286. package/dist/resolvers.js +121 -77
  287. package/dist/resolvers.js.map +1 -1
  288. package/dist/scopeResolverCompat.d.ts +10 -7
  289. package/dist/scopeResolverCompat.js +106 -123
  290. package/dist/scopeResolverCompat.js.map +1 -1
  291. package/dist/{text-matching-DNg4M5Wd.d.ts → text-matching-DzFooju6.d.ts} +7 -7
  292. package/dist/text-matching.d.ts +1 -1
  293. package/dist/topicOntologyResolver.d.ts +22 -21
  294. package/dist/topicOntologyResolver.js +54 -32
  295. package/dist/topicOntologyResolver.js.map +1 -1
  296. package/dist/topicProjectOverlay.d.ts +30 -20
  297. package/dist/topicProjectOverlay.js +120 -76
  298. package/dist/topicProjectOverlay.js.map +1 -1
  299. package/dist/{topicScope-7zhyeGl7.d.ts → topicScope-DJVa0mLa.d.ts} +22 -7
  300. package/dist/topicScope.d.ts +3 -1
  301. package/dist/topicScope.js +104 -119
  302. package/dist/topicScope.js.map +1 -1
  303. package/dist/workflowBridge.d.ts +26 -15
  304. package/dist/workflowBridge.js +140 -144
  305. package/dist/workflowBridge.js.map +1 -1
  306. package/dist/workspaceIsolation.d.ts +14 -12
  307. package/dist/workspaceIsolation.js +108 -122
  308. package/dist/workspaceIsolation.js.map +1 -1
  309. package/package.json +4 -4
  310. package/dist/edges/dependsOn.js.map +0 -1
  311. package/dist/edges/derivedFrom.js.map +0 -1
  312. package/dist/edges/propagationTypes.js.map +0 -1
  313. package/dist/evaluators/lintCheckerEvaluator.d.ts +0 -11
  314. package/dist/evaluators/lintCheckerEvaluator.js.map +0 -1
  315. package/dist/evaluators/sentryCheckerEvaluator.js.map +0 -1
  316. package/dist/evaluators/testRunnerEvaluator.js.map +0 -1
  317. package/dist/evaluators/tscCheckerEvaluator.d.ts +0 -11
  318. package/dist/evaluators/tscCheckerEvaluator.js.map +0 -1
  319. package/dist/{epistemicQuestions-bwHd2FWE.d.ts → epistemicQuestions-Do1fhYm5.d.ts} +4 -4
@@ -1,15 +1,19 @@
1
- import { v } from 'convex/values';
2
- import { requireProjectAccess } from '@lucern/access-control/access';
1
+ import { requireScopeWriteAccess } from '@lucern/access-control/access';
3
2
  import { permissiveReturn } from '@lucern/contracts/schema-helpers/validators';
4
- import { componentsGeneric, anyApi, mutationGeneric } from 'convex/server';
5
- import { isNodeType, getLayerForNodeType } from '@lucern/contracts/schema-helpers/spine/tables/epistemicNodes';
6
- import { assertUuidV7Identity } from '@lucern/contracts/ids';
3
+ import { v } from 'convex/values';
4
+ import { unsafeConvexAnyApi } from '@lucern/contracts/convex/unsafeAnyApi';
5
+ import { componentsGeneric, mutationGeneric } from 'convex/server';
7
6
  import '@lucern/contracts';
7
+ import { assertUuidV7Identity } from '@lucern/contracts/ids';
8
+ import { isNodeType, getLayerForNodeType } from '@lucern/contracts/schema-helpers/spine/tables/epistemicNodes';
8
9
 
9
10
  // src/epistemicNodes.mutations.ts
10
- var api = anyApi;
11
+ var unsafeApi = unsafeConvexAnyApi(
12
+ "graph-primitives top-level module bundle lacks a committed Convex _generated/api surface"
13
+ );
14
+ var api = unsafeApi;
11
15
  componentsGeneric();
12
- var internal = anyApi;
16
+ var internal = unsafeApi;
13
17
  var mutation = mutationGeneric;
14
18
 
15
19
  // src/debug.ts
@@ -23,6 +27,119 @@ function debugGraphPrimitiveFallback(message, context) {
23
27
  }
24
28
  console.debug(message, context ?? {});
25
29
  }
30
+ function insertEpistemicNode(ctx, doc) {
31
+ assertUuidV7Identity("epistemicNodes", doc.globalId);
32
+ return ctx.db.insert("epistemicNodes", doc);
33
+ }
34
+
35
+ // src/epistemicNodes.helpers.ts
36
+ function buildNodeStatusSuccessResult() {
37
+ return { success: true };
38
+ }
39
+ function buildNodeArchivedResult() {
40
+ return {
41
+ success: true,
42
+ effectiveStatus: "archived"
43
+ };
44
+ }
45
+ v.union(
46
+ v.literal("L4"),
47
+ v.literal("L3"),
48
+ v.literal("L2"),
49
+ v.literal("L1"),
50
+ v.literal("ontological"),
51
+ v.literal("organizational")
52
+ );
53
+ v.union(v.literal("decision"));
54
+ v.union(
55
+ v.literal("belief"),
56
+ v.literal("question"),
57
+ v.literal("theme"),
58
+ v.literal("deal")
59
+ );
60
+ v.union(
61
+ v.literal("claim"),
62
+ v.literal("evidence"),
63
+ v.literal("synthesis")
64
+ );
65
+ v.union(
66
+ v.literal("atomic_fact"),
67
+ v.literal("excerpt"),
68
+ v.literal("source")
69
+ );
70
+ v.union(
71
+ // L4: Audit targets
72
+ v.literal("decision"),
73
+ // L3: Traversal anchors
74
+ v.literal("belief"),
75
+ v.literal("question"),
76
+ v.literal("theme"),
77
+ v.literal("deal"),
78
+ // L2: Compression boundary
79
+ v.literal("claim"),
80
+ v.literal("evidence"),
81
+ v.literal("synthesis"),
82
+ v.literal("answer"),
83
+ // L1: Terminal leaves
84
+ v.literal("atomic_fact"),
85
+ v.literal("excerpt"),
86
+ v.literal("source")
87
+ );
88
+ v.union(
89
+ v.literal("company"),
90
+ v.literal("person"),
91
+ v.literal("investor"),
92
+ v.literal("function"),
93
+ v.literal("value_chain")
94
+ );
95
+ v.union(v.literal("topic"));
96
+ var nodeTypeValidator = v.union(
97
+ // L4: Audit targets
98
+ v.literal("decision"),
99
+ // L3: Traversal anchors
100
+ v.literal("belief"),
101
+ v.literal("question"),
102
+ v.literal("theme"),
103
+ v.literal("deal"),
104
+ // L2: Compression boundary
105
+ v.literal("claim"),
106
+ v.literal("evidence"),
107
+ v.literal("synthesis"),
108
+ v.literal("answer"),
109
+ // L1: Terminal leaves
110
+ v.literal("atomic_fact"),
111
+ v.literal("excerpt"),
112
+ v.literal("source"),
113
+ // Ontological
114
+ v.literal("company"),
115
+ v.literal("person"),
116
+ v.literal("investor"),
117
+ v.literal("function"),
118
+ v.literal("value_chain"),
119
+ // Organizational
120
+ v.literal("topic")
121
+ );
122
+ var sourceTypeValidator = v.union(
123
+ v.literal("human"),
124
+ v.literal("ai_extracted"),
125
+ v.literal("ai_generated"),
126
+ v.literal("imported"),
127
+ v.literal("system")
128
+ // System-generated (migrations, classifiers)
129
+ );
130
+ var statusValidator = v.union(
131
+ v.literal("active"),
132
+ v.literal("superseded"),
133
+ v.literal("archived"),
134
+ v.literal("deleted")
135
+ );
136
+ var verificationStatusValidator = v.union(
137
+ v.literal("unverified"),
138
+ v.literal("human_verified"),
139
+ v.literal("ai_verified"),
140
+ v.literal("contradicted"),
141
+ v.literal("outdated")
142
+ );
26
143
 
27
144
  // src/graphTypes.ts
28
145
  function getNodeLayer(nodeType) {
@@ -59,6 +176,209 @@ function getNodeLayer(nodeType) {
59
176
  console.warn(`[GraphTypes] Unknown nodeType "${nodeType}", defaulting to L2`);
60
177
  return "L2";
61
178
  }
179
+
180
+ // src/beliefLifecycle.ts
181
+ var RESOLVED_PREDICTION_OUTCOMES = [
182
+ "confirmed",
183
+ "disconfirmed",
184
+ "partial",
185
+ "expired"
186
+ ];
187
+ function hasResolvedPredictionOutcome(predictionMeta) {
188
+ if (!predictionMeta || typeof predictionMeta !== "object") {
189
+ return false;
190
+ }
191
+ const outcome = predictionMeta.outcome;
192
+ return typeof outcome === "string" && RESOLVED_PREDICTION_OUTCOMES.includes(outcome);
193
+ }
194
+
195
+ // src/invariantEnforcement.ts
196
+ var FORBIDDEN_GENERIC_BELIEF_METADATA_KEYS = /* @__PURE__ */ new Set([
197
+ "beliefStatus",
198
+ "epistemicStatus",
199
+ "forkedBy",
200
+ "forkedFrom",
201
+ "forkReason",
202
+ "forkTimestamp",
203
+ "status",
204
+ "supersededBy",
205
+ "supersedes"
206
+ ]);
207
+ var ONTOLOGICAL_NODE_TYPES = /* @__PURE__ */ new Set([
208
+ "company",
209
+ "person",
210
+ "investor",
211
+ "function",
212
+ "value_chain"
213
+ ]);
214
+ function throwInvariantError(args) {
215
+ const error = new Error(args.message);
216
+ error.status = args.status ?? 409;
217
+ error.code = args.code ?? "INVARIANT_VIOLATION";
218
+ error.invariantCode = args.invariantCode;
219
+ error.suggestion = args.suggestion;
220
+ error.details = args.details;
221
+ throw error;
222
+ }
223
+ function isBeliefNode(node) {
224
+ return node?.nodeType === "belief";
225
+ }
226
+ function isOntologicalNode(node) {
227
+ return typeof node?.nodeType === "string" && ONTOLOGICAL_NODE_TYPES.has(node.nodeType);
228
+ }
229
+ function isScoredBeliefNode(node) {
230
+ if (!isBeliefNode(node)) {
231
+ return false;
232
+ }
233
+ const metadata = node.metadata && typeof node.metadata === "object" ? node.metadata : void 0;
234
+ const numericConfidence = typeof node.confidence === "number" && Number.isFinite(node.confidence);
235
+ if (numericConfidence) {
236
+ return true;
237
+ }
238
+ return hasResolvedPredictionOutcome(node.predictionMeta) || hasResolvedPredictionOutcome(metadata?.predictionMeta);
239
+ }
240
+ function getForbiddenMetadataKeys(metadata) {
241
+ if (!metadata || typeof metadata !== "object" || Array.isArray(metadata)) {
242
+ return [];
243
+ }
244
+ return Object.keys(metadata).filter(
245
+ (key) => FORBIDDEN_GENERIC_BELIEF_METADATA_KEYS.has(key)
246
+ );
247
+ }
248
+ function assertBeliefNodeGenericUpdateAllowed(args) {
249
+ if (!isBeliefNode(args.node)) {
250
+ return;
251
+ }
252
+ if (Object.hasOwn(args.updates, "confidence")) {
253
+ throwInvariantError({
254
+ message: "Belief confidence is append-only. Generic node updates cannot set confidence directly.",
255
+ invariantCode: "belief.confidence_append_only",
256
+ suggestion: "Use epistemicBeliefs.appendSlScoring() so the beliefConfidence ledger and audit trail are updated together.",
257
+ details: { mutationName: args.mutationName, nodeId: args.node._id }
258
+ });
259
+ }
260
+ if (Object.hasOwn(args.updates, "status")) {
261
+ throwInvariantError({
262
+ message: "Belief status transitions must use the dedicated belief lifecycle APIs.",
263
+ invariantCode: "belief.status_transition_requires_belief_api",
264
+ suggestion: "Use epistemicBeliefs.updateStatus() or epistemicBeliefs.archive() so status transitions emit the correct audit event.",
265
+ details: { mutationName: args.mutationName, nodeId: args.node._id }
266
+ });
267
+ }
268
+ const forbiddenMetadataKeys = getForbiddenMetadataKeys(args.updates.metadata);
269
+ if (forbiddenMetadataKeys.length > 0) {
270
+ throwInvariantError({
271
+ message: "Belief lineage and lifecycle metadata cannot be rewritten through generic node updates.",
272
+ invariantCode: "belief.lineage_requires_fork_belief",
273
+ suggestion: "Use epistemicBeliefs.forkBelief() for lineage changes and dedicated belief lifecycle mutations for status changes.",
274
+ details: {
275
+ mutationName: args.mutationName,
276
+ nodeId: args.node._id,
277
+ forbiddenMetadataKeys
278
+ }
279
+ });
280
+ }
281
+ if (isScoredBeliefNode(args.node) && (Object.hasOwn(args.updates, "canonicalText") || Object.hasOwn(args.updates, "contentHash"))) {
282
+ throwInvariantError({
283
+ message: "Cannot refine a scored belief in place. Scored formulations are immutable.",
284
+ invariantCode: "belief.formulation_immutable_after_scoring",
285
+ suggestion: "Use epistemicBeliefs.forkBelief() to evolve the formulation while preserving lineage.",
286
+ details: { mutationName: args.mutationName, nodeId: args.node._id }
287
+ });
288
+ }
289
+ }
290
+ function assertBeliefNodeArchiveAllowed(args) {
291
+ if (!isBeliefNode(args.node)) {
292
+ return;
293
+ }
294
+ throwInvariantError({
295
+ message: "Belief archiving must go through the dedicated belief lifecycle API.",
296
+ invariantCode: "belief.status_transition_requires_belief_api",
297
+ suggestion: "Use epistemicBeliefs.archive() so the belief lifecycle audit trail stays consistent.",
298
+ details: { mutationName: args.mutationName, nodeId: args.node._id }
299
+ });
300
+ }
301
+ function assertBeliefNodeVerifyAllowed(args) {
302
+ if (!isBeliefNode(args.node) || args.confidence === void 0) {
303
+ return;
304
+ }
305
+ throwInvariantError({
306
+ message: "Belief verification cannot set confidence directly. Confidence changes must stay append-only.",
307
+ invariantCode: "belief.confidence_append_only",
308
+ suggestion: "Call epistemicBeliefs.appendSlScoring() after verification so the confidence history is preserved.",
309
+ details: { mutationName: args.mutationName, nodeId: args.node._id }
310
+ });
311
+ }
312
+ function assertBeliefNodeSupersedeAllowed(args) {
313
+ if (!isBeliefNode(args.node)) {
314
+ return;
315
+ }
316
+ throwInvariantError({
317
+ message: "Belief lineage changes must use forkBelief(), not the generic supersede path.",
318
+ invariantCode: "belief.lineage_requires_fork_belief",
319
+ suggestion: "Use epistemicBeliefs.forkBelief() so the child belief, supersedes edge, and audit trail are created together.",
320
+ details: { mutationName: args.mutationName, nodeId: args.node._id }
321
+ });
322
+ }
323
+ function assertOntologicalNodeGenericCreateAllowed(args) {
324
+ if (!ONTOLOGICAL_NODE_TYPES.has(args.nodeType)) {
325
+ return;
326
+ }
327
+ throwInvariantError({
328
+ message: "Ontological entities must be created through the dedicated entity lifecycle API.",
329
+ invariantCode: "entity.create_requires_entity_lifecycle",
330
+ suggestion: "Use entityLifecycle.createEntity() so tenant-global canonical scope and deduplication are enforced.",
331
+ details: {
332
+ mutationName: args.mutationName,
333
+ nodeType: args.nodeType
334
+ }
335
+ });
336
+ }
337
+ function assertOntologicalNodeGenericUpdateAllowed(args) {
338
+ if (!isOntologicalNode(args.node)) {
339
+ return;
340
+ }
341
+ throwInvariantError({
342
+ message: "Ontological entities must be updated through the dedicated entity lifecycle API.",
343
+ invariantCode: "entity.update_requires_entity_lifecycle",
344
+ suggestion: "Use entityLifecycle.updateEntityAttributes() so canonical entity mutations stay type-safe and audited.",
345
+ details: {
346
+ mutationName: args.mutationName,
347
+ nodeId: args.node._id,
348
+ nodeType: args.node.nodeType
349
+ }
350
+ });
351
+ }
352
+ function assertOntologicalNodeArchiveAllowed(args) {
353
+ if (!isOntologicalNode(args.node)) {
354
+ return;
355
+ }
356
+ throwInvariantError({
357
+ message: "Ontological entities must be archived through the dedicated entity lifecycle API.",
358
+ invariantCode: "entity.archive_requires_entity_lifecycle",
359
+ suggestion: "Use entityLifecycle.archiveEntity() so entity archival emits the correct audit trail and review hooks.",
360
+ details: {
361
+ mutationName: args.mutationName,
362
+ nodeId: args.node._id,
363
+ nodeType: args.node.nodeType
364
+ }
365
+ });
366
+ }
367
+ function assertOntologicalNodeSupersedeAllowed(args) {
368
+ if (!isOntologicalNode(args.node)) {
369
+ return;
370
+ }
371
+ throwInvariantError({
372
+ message: "Ontological entities do not use the generic supersede path.",
373
+ invariantCode: "entity.supersede_requires_entity_lifecycle",
374
+ suggestion: "Use entityLifecycle.updateEntityAttributes() to edit an entity in place or entityLifecycle.mergeEntities() to collapse duplicates.",
375
+ details: {
376
+ mutationName: args.mutationName,
377
+ nodeId: args.node._id,
378
+ nodeType: args.node.nodeType
379
+ }
380
+ });
381
+ }
62
382
  var LEGACY_SCOPE_FIELD = "graphScopeProjectId";
63
383
  async function resolveTopicNodeScopeOrNull(ctx, ref) {
64
384
  if (!ctx?.db || typeof ctx.db.query !== "function") {
@@ -93,13 +413,15 @@ function asMappedProjectId(topic) {
93
413
  if (!topic) {
94
414
  return;
95
415
  }
96
- const directLegacyProjectId = normalizeScopeValue(topic[LEGACY_SCOPE_FIELD]);
416
+ const directLegacyProjectId = normalizeScopeValue(
417
+ topic[LEGACY_SCOPE_FIELD]
418
+ );
97
419
  if (directLegacyProjectId) {
98
420
  return directLegacyProjectId;
99
421
  }
100
422
  const metadata = topic.metadata || {};
101
423
  const candidate = metadata[LEGACY_SCOPE_FIELD] || metadata.legacyProjectId || metadata.projectId || metadata.scopeProjectId;
102
- return candidate ? candidate : void 0;
424
+ return typeof candidate === "string" ? normalizeScopeValue(candidate) : void 0;
103
425
  }
104
426
  function normalizeScopeValue(value) {
105
427
  if (typeof value !== "string") {
@@ -124,8 +446,9 @@ function pickPrimaryTopic(candidates) {
124
446
  })[0];
125
447
  }
126
448
  async function findTopicsByScopeAlias(ctx, scopeId) {
449
+ const query = ctx.db.query("topics");
127
450
  try {
128
- return await ctx.db.query("topics").withIndex(
451
+ return await query.withIndex(
129
452
  "by_graph_scope_project",
130
453
  (q) => q.eq(LEGACY_SCOPE_FIELD, scopeId)
131
454
  ).collect();
@@ -137,7 +460,7 @@ async function findTopicsByScopeAlias(ctx, scopeId) {
137
460
  scopeId
138
461
  }
139
462
  );
140
- const topics = await ctx.db.query("topics").collect();
463
+ const topics = await query.collect();
141
464
  return topics.filter((topic) => {
142
465
  const normalizedGlobalId = normalizeScopeValue(topic.globalId);
143
466
  const mappedProjectId = asMappedProjectId(topic);
@@ -193,344 +516,119 @@ async function resolveInheritedWorkspaceScope(ctx, topic) {
193
516
  let current = topic;
194
517
  for (let i = 0; i < MAX_DEPTH && current?.parentTopicId; i++) {
195
518
  current = await ctx.db.get(current.parentTopicId);
196
- if (!current) break;
519
+ if (!current) {
520
+ break;
521
+ }
197
522
  if (!tenantId) {
198
523
  tenantId = normalizeScopeValue(current.tenantId);
199
524
  }
200
525
  if (!workspaceId) {
201
526
  workspaceId = normalizeScopeValue(current.workspaceId);
202
527
  }
203
- if (tenantId && workspaceId) break;
204
- }
205
- return { tenantId, workspaceId };
206
- }
207
- async function resolveTopicProjectScope(ctx, args) {
208
- if (args.topicId) {
209
- let topic = null;
210
- try {
211
- topic = await ctx.db.get(
212
- args.topicId
213
- );
214
- } catch (error) {
215
- debugGraphPrimitiveFallback(
216
- "[topicScope] Failed to load topic by direct id",
217
- {
218
- error,
219
- topicId: args.topicId
220
- }
221
- );
222
- }
223
- if (!topic) {
224
- topic = await tryResolveHostTopicById(ctx, String(args.topicId));
225
- }
226
- if (!topic) {
227
- topic = pickPrimaryTopic(
228
- await findTopicsByScopeAlias(ctx, String(args.topicId))
229
- ) ?? null;
230
- }
231
- if (!topic) {
232
- const nodeScope = await resolveTopicNodeScopeOrNull(
233
- ctx,
234
- String(args.topicId)
235
- );
236
- if (nodeScope) {
237
- return nodeScope;
238
- }
239
- throw new Error(`Topic not found: ${String(args.topicId)}`);
240
- }
241
- const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
242
- const mapped = asMappedProjectId(topic);
243
- if (mapped) {
244
- return {
245
- topicId: topic._id,
246
- projectId: mapped,
247
- tenantId: inherited.tenantId,
248
- workspaceId: inherited.workspaceId,
249
- source: "topic"
250
- };
251
- }
252
- return {
253
- topicId: topic._id,
254
- tenantId: inherited.tenantId,
255
- workspaceId: inherited.workspaceId,
256
- source: "topic"
257
- };
258
- }
259
- if (args.projectId) {
260
- let directTopic = null;
261
- try {
262
- directTopic = await ctx.db.get(
263
- args.projectId
264
- );
265
- } catch (error) {
266
- debugGraphPrimitiveFallback(
267
- "[topicScope] Failed to load direct project topic",
268
- {
269
- error,
270
- projectId: args.projectId
271
- }
272
- );
273
- }
274
- if (directTopic) {
275
- const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
276
- const mapped = asMappedProjectId(directTopic);
277
- return {
278
- topicId: directTopic._id,
279
- projectId: mapped ?? args.projectId,
280
- tenantId: inherited.tenantId,
281
- workspaceId: inherited.workspaceId,
282
- source: "topic_inferred"
283
- };
284
- }
285
- directTopic = await tryResolveHostTopicByLegacyScope(ctx, args.projectId);
286
- if (directTopic) {
287
- const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
288
- const mapped = asMappedProjectId(directTopic);
289
- return {
290
- topicId: directTopic._id,
291
- projectId: mapped ?? args.projectId,
292
- tenantId: inherited.tenantId,
293
- workspaceId: inherited.workspaceId,
294
- source: "topic_inferred"
295
- };
296
- }
297
- const topics = await findTopicsByScopeAlias(ctx, args.projectId);
298
- const primary = pickPrimaryTopic(topics);
299
- if (primary) {
300
- const inherited = await resolveInheritedWorkspaceScope(ctx, primary);
301
- return {
302
- topicId: primary._id,
303
- projectId: args.projectId,
304
- tenantId: inherited.tenantId,
305
- workspaceId: inherited.workspaceId,
306
- source: "project_mapped_topic"
307
- };
308
- }
309
- const nodeScope = await resolveTopicNodeScopeOrNull(
310
- ctx,
311
- String(args.projectId)
312
- );
313
- if (nodeScope) {
314
- return {
315
- ...nodeScope,
316
- projectId: nodeScope.projectId ?? String(args.projectId)
317
- };
318
- }
319
- throw new Error(
320
- `Legacy project scope ${String(args.projectId)} has no mapped topic.`
321
- );
322
- }
323
- throw new Error(
324
- "Missing scope: provide topicId (preferred) or legacy projectId alias."
325
- );
326
- }
327
- var optionalScopeArgs = {
328
- projectId: v.optional(v.string()),
329
- topicId: v.optional(v.string())
330
- };
331
-
332
- // src/beliefLifecycle.ts
333
- var RESOLVED_PREDICTION_OUTCOMES = [
334
- "confirmed",
335
- "disconfirmed",
336
- "partial",
337
- "expired"
338
- ];
339
- function hasResolvedPredictionOutcome(predictionMeta) {
340
- if (!predictionMeta || typeof predictionMeta !== "object") {
341
- return false;
342
- }
343
- const outcome = predictionMeta.outcome;
344
- return typeof outcome === "string" && RESOLVED_PREDICTION_OUTCOMES.includes(outcome);
345
- }
346
-
347
- // src/invariantEnforcement.ts
348
- var FORBIDDEN_GENERIC_BELIEF_METADATA_KEYS = /* @__PURE__ */ new Set([
349
- "beliefStatus",
350
- "epistemicStatus",
351
- "forkedBy",
352
- "forkedFrom",
353
- "forkReason",
354
- "forkTimestamp",
355
- "status",
356
- "supersededBy",
357
- "supersedes"
358
- ]);
359
- var ONTOLOGICAL_NODE_TYPES = /* @__PURE__ */ new Set([
360
- "company",
361
- "person",
362
- "investor",
363
- "function",
364
- "value_chain"
365
- ]);
366
- function throwInvariantError(args) {
367
- const error = new Error(args.message);
368
- error.status = args.status ?? 409;
369
- error.code = args.code ?? "INVARIANT_VIOLATION";
370
- error.invariantCode = args.invariantCode;
371
- error.suggestion = args.suggestion;
372
- error.details = args.details;
373
- throw error;
374
- }
375
- function isBeliefNode(node) {
376
- return node?.nodeType === "belief";
377
- }
378
- function isOntologicalNode(node) {
379
- return typeof node?.nodeType === "string" && ONTOLOGICAL_NODE_TYPES.has(node.nodeType);
380
- }
381
- function isScoredBeliefNode(node) {
382
- if (!isBeliefNode(node)) {
383
- return false;
384
- }
385
- const metadata = node.metadata && typeof node.metadata === "object" ? node.metadata : void 0;
386
- const numericConfidence = typeof node.confidence === "number" && Number.isFinite(node.confidence);
387
- if (numericConfidence) {
388
- return true;
389
- }
390
- return hasResolvedPredictionOutcome(node.predictionMeta) || hasResolvedPredictionOutcome(metadata?.predictionMeta);
391
- }
392
- function getForbiddenMetadataKeys(metadata) {
393
- if (!metadata || typeof metadata !== "object" || Array.isArray(metadata)) {
394
- return [];
395
- }
396
- return Object.keys(metadata).filter(
397
- (key) => FORBIDDEN_GENERIC_BELIEF_METADATA_KEYS.has(key)
398
- );
399
- }
400
- function assertBeliefNodeGenericUpdateAllowed(args) {
401
- if (!isBeliefNode(args.node)) {
402
- return;
403
- }
404
- if (Object.hasOwn(args.updates, "confidence")) {
405
- throwInvariantError({
406
- message: "Belief confidence is append-only. Generic node updates cannot set confidence directly.",
407
- invariantCode: "belief.confidence_append_only",
408
- suggestion: "Use epistemicBeliefs.appendSlScoring() so the beliefConfidence ledger and audit trail are updated together.",
409
- details: { mutationName: args.mutationName, nodeId: args.node._id }
410
- });
411
- }
412
- if (Object.hasOwn(args.updates, "status")) {
413
- throwInvariantError({
414
- message: "Belief status transitions must use the dedicated belief lifecycle APIs.",
415
- invariantCode: "belief.status_transition_requires_belief_api",
416
- suggestion: "Use epistemicBeliefs.updateStatus() or epistemicBeliefs.archive() so status transitions emit the correct audit event.",
417
- details: { mutationName: args.mutationName, nodeId: args.node._id }
418
- });
419
- }
420
- const forbiddenMetadataKeys = getForbiddenMetadataKeys(args.updates.metadata);
421
- if (forbiddenMetadataKeys.length > 0) {
422
- throwInvariantError({
423
- message: "Belief lineage and lifecycle metadata cannot be rewritten through generic node updates.",
424
- invariantCode: "belief.lineage_requires_fork_belief",
425
- suggestion: "Use epistemicBeliefs.forkBelief() for lineage changes and dedicated belief lifecycle mutations for status changes.",
426
- details: {
427
- mutationName: args.mutationName,
428
- nodeId: args.node._id,
429
- forbiddenMetadataKeys
430
- }
431
- });
432
- }
433
- if (isScoredBeliefNode(args.node) && (Object.hasOwn(args.updates, "canonicalText") || Object.hasOwn(args.updates, "contentHash"))) {
434
- throwInvariantError({
435
- message: "Cannot refine a scored belief in place. Scored formulations are immutable.",
436
- invariantCode: "belief.formulation_immutable_after_scoring",
437
- suggestion: "Use epistemicBeliefs.forkBelief() to evolve the formulation while preserving lineage.",
438
- details: { mutationName: args.mutationName, nodeId: args.node._id }
439
- });
440
- }
441
- }
442
- function assertBeliefNodeArchiveAllowed(args) {
443
- if (!isBeliefNode(args.node)) {
444
- return;
528
+ if (tenantId && workspaceId) {
529
+ break;
530
+ }
445
531
  }
446
- throwInvariantError({
447
- message: "Belief archiving must go through the dedicated belief lifecycle API.",
448
- invariantCode: "belief.status_transition_requires_belief_api",
449
- suggestion: "Use epistemicBeliefs.archive() so the belief lifecycle audit trail stays consistent.",
450
- details: { mutationName: args.mutationName, nodeId: args.node._id }
451
- });
532
+ return { tenantId, workspaceId };
452
533
  }
453
- function assertBeliefNodeVerifyAllowed(args) {
454
- if (!isBeliefNode(args.node) || args.confidence === void 0) {
455
- return;
534
+ async function resolveTopicProjectScope(ctx, args) {
535
+ if (args.topicId) {
536
+ return await resolveScopeFromTopicId(ctx, args.topicId);
456
537
  }
457
- throwInvariantError({
458
- message: "Belief verification cannot set confidence directly. Confidence changes must stay append-only.",
459
- invariantCode: "belief.confidence_append_only",
460
- suggestion: "Call epistemicBeliefs.appendSlScoring() after verification so the confidence history is preserved.",
461
- details: { mutationName: args.mutationName, nodeId: args.node._id }
462
- });
463
- }
464
- function assertBeliefNodeSupersedeAllowed(args) {
465
- if (!isBeliefNode(args.node)) {
466
- return;
538
+ if (args.projectId) {
539
+ return await resolveScopeFromLegacyProjectId(ctx, args.projectId);
467
540
  }
468
- throwInvariantError({
469
- message: "Belief lineage changes must use forkBelief(), not the generic supersede path.",
470
- invariantCode: "belief.lineage_requires_fork_belief",
471
- suggestion: "Use epistemicBeliefs.forkBelief() so the child belief, supersedes edge, and audit trail are created together.",
472
- details: { mutationName: args.mutationName, nodeId: args.node._id }
473
- });
541
+ throw new Error(
542
+ "Missing scope: provide topicId (preferred) or legacy projectId alias."
543
+ );
474
544
  }
475
- function assertOntologicalNodeGenericCreateAllowed(args) {
476
- if (!ONTOLOGICAL_NODE_TYPES.has(args.nodeType)) {
477
- return;
545
+ async function resolveScopeFromTopicId(ctx, topicId) {
546
+ const topic = await resolveTopicDocFromTopicId(ctx, topicId);
547
+ if (topic) {
548
+ return await buildTopicScope(ctx, topic, "topic");
478
549
  }
479
- throwInvariantError({
480
- message: "Ontological entities must be created through the dedicated entity lifecycle API.",
481
- invariantCode: "entity.create_requires_entity_lifecycle",
482
- suggestion: "Use entityLifecycle.createEntity() so tenant-global canonical scope and deduplication are enforced.",
483
- details: {
484
- mutationName: args.mutationName,
485
- nodeType: args.nodeType
486
- }
487
- });
488
- }
489
- function assertOntologicalNodeGenericUpdateAllowed(args) {
490
- if (!isOntologicalNode(args.node)) {
491
- return;
550
+ const nodeScope = await resolveTopicNodeScopeOrNull(ctx, String(topicId));
551
+ if (nodeScope) {
552
+ return nodeScope;
492
553
  }
493
- throwInvariantError({
494
- message: "Ontological entities must be updated through the dedicated entity lifecycle API.",
495
- invariantCode: "entity.update_requires_entity_lifecycle",
496
- suggestion: "Use entityLifecycle.updateEntityAttributes() so canonical entity mutations stay type-safe and audited.",
497
- details: {
498
- mutationName: args.mutationName,
499
- nodeId: args.node._id,
500
- nodeType: args.node.nodeType
501
- }
554
+ throw new Error(`Topic not found: ${String(topicId)}`);
555
+ }
556
+ async function resolveTopicDocFromTopicId(ctx, topicId) {
557
+ const direct = await tryReadTopicDoc(ctx, topicId, {
558
+ failureLog: "[topicScope] Failed to load topic by direct id",
559
+ idLogKey: "topicId"
502
560
  });
561
+ if (direct) {
562
+ return direct;
563
+ }
564
+ const hostTopic = await tryResolveHostTopicById(ctx, String(topicId));
565
+ if (hostTopic) {
566
+ return hostTopic;
567
+ }
568
+ return pickPrimaryTopic(await findTopicsByScopeAlias(ctx, String(topicId))) ?? null;
503
569
  }
504
- function assertOntologicalNodeArchiveAllowed(args) {
505
- if (!isOntologicalNode(args.node)) {
506
- return;
570
+ async function resolveScopeFromLegacyProjectId(ctx, legacyProjectId) {
571
+ const directTopic = await resolveDirectLegacyProjectTopic(
572
+ ctx,
573
+ legacyProjectId
574
+ );
575
+ if (directTopic) {
576
+ return await buildTopicScope(ctx, directTopic, "topic_inferred", {
577
+ fallbackProjectId: legacyProjectId
578
+ });
507
579
  }
508
- throwInvariantError({
509
- message: "Ontological entities must be archived through the dedicated entity lifecycle API.",
510
- invariantCode: "entity.archive_requires_entity_lifecycle",
511
- suggestion: "Use entityLifecycle.archiveEntity() so entity archival emits the correct audit trail and review hooks.",
512
- details: {
513
- mutationName: args.mutationName,
514
- nodeId: args.node._id,
515
- nodeType: args.node.nodeType
516
- }
580
+ const primary = pickPrimaryTopic(
581
+ await findTopicsByScopeAlias(ctx, legacyProjectId)
582
+ );
583
+ if (primary) {
584
+ return await buildTopicScope(ctx, primary, "project_mapped_topic", {
585
+ fallbackProjectId: legacyProjectId
586
+ });
587
+ }
588
+ const nodeScope = await resolveTopicNodeScopeOrNull(ctx, legacyProjectId);
589
+ if (nodeScope) {
590
+ return {
591
+ ...nodeScope,
592
+ projectId: nodeScope.projectId ?? legacyProjectId
593
+ };
594
+ }
595
+ throw new Error(
596
+ `Legacy project scope ${legacyProjectId} has no mapped topic.`
597
+ );
598
+ }
599
+ async function resolveDirectLegacyProjectTopic(ctx, legacyProjectId) {
600
+ const directTopic = await tryReadTopicDoc(ctx, legacyProjectId, {
601
+ failureLog: "[topicScope] Failed to load direct project topic",
602
+ idLogKey: "projectId"
517
603
  });
604
+ return directTopic ?? tryResolveHostTopicByLegacyScope(ctx, legacyProjectId);
518
605
  }
519
- function assertOntologicalNodeSupersedeAllowed(args) {
520
- if (!isOntologicalNode(args.node)) {
521
- return;
606
+ async function tryReadTopicDoc(ctx, id, log) {
607
+ try {
608
+ return await ctx.db.get(id);
609
+ } catch (error) {
610
+ debugGraphPrimitiveFallback(log.failureLog, {
611
+ error,
612
+ [log.idLogKey]: id
613
+ });
614
+ return null;
522
615
  }
523
- throwInvariantError({
524
- message: "Ontological entities do not use the generic supersede path.",
525
- invariantCode: "entity.supersede_requires_entity_lifecycle",
526
- suggestion: "Use entityLifecycle.updateEntityAttributes() to edit an entity in place or entityLifecycle.mergeEntities() to collapse duplicates.",
527
- details: {
528
- mutationName: args.mutationName,
529
- nodeId: args.node._id,
530
- nodeType: args.node.nodeType
531
- }
532
- });
533
616
  }
617
+ async function buildTopicScope(ctx, topic, source, options = {}) {
618
+ const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
619
+ const mapped = asMappedProjectId(topic);
620
+ return {
621
+ topicId: topic._id,
622
+ ...mapped || options.fallbackProjectId ? { projectId: mapped ?? options.fallbackProjectId } : {},
623
+ tenantId: inherited.tenantId,
624
+ workspaceId: inherited.workspaceId,
625
+ source
626
+ };
627
+ }
628
+ var optionalScopeArgs = {
629
+ projectId: v.optional(v.string()),
630
+ topicId: v.optional(v.string())
631
+ };
534
632
  function normalizeScopeValue2(value) {
535
633
  if (typeof value !== "string") {
536
634
  return;
@@ -569,7 +667,7 @@ function assertWorkspaceScopedEpistemicNodeScope(args) {
569
667
  });
570
668
  }
571
669
  function resolveRuntimePackMutationContext(args) {
572
- if (!args.runtimeToolName && !args.runtimePackKey && !args.runtimePackInstallScope) {
670
+ if (!(args.runtimeToolName || args.runtimePackKey || args.runtimePackInstallScope)) {
573
671
  return;
574
672
  }
575
673
  return {
@@ -602,121 +700,116 @@ function assertTenantPackWorkspaceMutationAllowed(args) {
602
700
  });
603
701
  }
604
702
 
605
- // src/epistemicNodes.helpers.ts
606
- function buildNodeStatusSuccessResult() {
607
- return { success: true };
703
+ // src/epistemicNodes.mutations.ts
704
+ var optionalNodeScopeArgs = optionalScopeArgs;
705
+ var EPISTEMIC_LAYERS = /* @__PURE__ */ new Set([
706
+ "L4",
707
+ "L3",
708
+ "L2",
709
+ "L1",
710
+ "ontological",
711
+ "organizational"
712
+ ]);
713
+ function readOptionalString(value) {
714
+ return typeof value === "string" && value.trim().length > 0 ? value : void 0;
608
715
  }
609
- function buildNodeArchivedResult() {
610
- return {
611
- success: true,
612
- effectiveStatus: "archived"
613
- };
716
+ function readOptionalNumber(value) {
717
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
614
718
  }
615
- v.union(
616
- v.literal("L4"),
617
- v.literal("L3"),
618
- v.literal("L2"),
619
- v.literal("L1"),
620
- v.literal("ontological"),
621
- v.literal("organizational")
622
- );
623
- v.union(v.literal("decision"));
624
- v.union(
625
- v.literal("belief"),
626
- v.literal("question"),
627
- v.literal("theme"),
628
- v.literal("deal")
629
- );
630
- v.union(
631
- v.literal("claim"),
632
- v.literal("evidence"),
633
- v.literal("synthesis")
634
- );
635
- v.union(
636
- v.literal("atomic_fact"),
637
- v.literal("excerpt"),
638
- v.literal("source")
639
- );
640
- v.union(
641
- // L4: Audit targets
642
- v.literal("decision"),
643
- // L3: Traversal anchors
644
- v.literal("belief"),
645
- v.literal("question"),
646
- v.literal("theme"),
647
- v.literal("deal"),
648
- // L2: Compression boundary
649
- v.literal("claim"),
650
- v.literal("evidence"),
651
- v.literal("synthesis"),
652
- v.literal("answer"),
653
- // L1: Terminal leaves
654
- v.literal("atomic_fact"),
655
- v.literal("excerpt"),
656
- v.literal("source")
657
- );
658
- v.union(
659
- v.literal("company"),
660
- v.literal("person"),
661
- v.literal("investor"),
662
- v.literal("function"),
663
- v.literal("value_chain")
664
- );
665
- v.union(v.literal("topic"));
666
- var nodeTypeValidator = v.union(
667
- // L4: Audit targets
668
- v.literal("decision"),
669
- // L3: Traversal anchors
670
- v.literal("belief"),
671
- v.literal("question"),
672
- v.literal("theme"),
673
- v.literal("deal"),
674
- // L2: Compression boundary
675
- v.literal("claim"),
676
- v.literal("evidence"),
677
- v.literal("synthesis"),
678
- v.literal("answer"),
679
- // L1: Terminal leaves
680
- v.literal("atomic_fact"),
681
- v.literal("excerpt"),
682
- v.literal("source"),
683
- // Ontological
684
- v.literal("company"),
685
- v.literal("person"),
686
- v.literal("investor"),
687
- v.literal("function"),
688
- v.literal("value_chain"),
689
- // Organizational
690
- v.literal("topic")
691
- );
692
- var sourceTypeValidator = v.union(
693
- v.literal("human"),
694
- v.literal("ai_extracted"),
695
- v.literal("ai_generated"),
696
- v.literal("imported"),
697
- v.literal("system")
698
- // System-generated (migrations, classifiers)
699
- );
700
- var statusValidator = v.union(
701
- v.literal("active"),
702
- v.literal("superseded"),
703
- v.literal("archived"),
704
- v.literal("deleted")
705
- );
706
- var verificationStatusValidator = v.union(
707
- v.literal("unverified"),
708
- v.literal("human_verified"),
709
- v.literal("ai_verified"),
710
- v.literal("contradicted"),
711
- v.literal("outdated")
712
- );
713
- async function insertEpistemicNode(ctx, doc) {
714
- assertUuidV7Identity("epistemicNodes", doc.globalId);
715
- return ctx.db.insert("epistemicNodes", doc);
719
+ function readConvexId(value) {
720
+ const normalized = readOptionalString(value);
721
+ return normalized ? normalized : null;
722
+ }
723
+ function readRecord(value) {
724
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
725
+ }
726
+ function readStringArray(value) {
727
+ return Array.isArray(value) && value.every((item) => typeof item === "string") ? value : void 0;
728
+ }
729
+ function readEpistemicLayer(value) {
730
+ const layer = readOptionalString(value);
731
+ return layer && EPISTEMIC_LAYERS.has(layer) ? layer : void 0;
732
+ }
733
+ function readEpistemicNodeRow(value) {
734
+ const record = readRecord(value);
735
+ if (!record) {
736
+ return null;
737
+ }
738
+ const id = readConvexId(record._id);
739
+ const nodeType = readOptionalString(record.nodeType);
740
+ if (!(id && nodeType)) {
741
+ return null;
742
+ }
743
+ const node = { _id: id, nodeType };
744
+ const canonicalText = readOptionalString(record.canonicalText);
745
+ if (canonicalText !== void 0) {
746
+ node.canonicalText = canonicalText;
747
+ }
748
+ const confidence = readOptionalNumber(record.confidence);
749
+ if (confidence !== void 0) {
750
+ node.confidence = confidence;
751
+ }
752
+ const content = readOptionalString(record.content);
753
+ if (content !== void 0) {
754
+ node.content = content;
755
+ }
756
+ const contentType = readOptionalString(record.contentType);
757
+ if (contentType !== void 0) {
758
+ node.contentType = contentType;
759
+ }
760
+ const createdBy = readOptionalString(record.createdBy);
761
+ if (createdBy !== void 0) {
762
+ node.createdBy = createdBy;
763
+ }
764
+ const epistemicLayer = readEpistemicLayer(record.epistemicLayer);
765
+ if (epistemicLayer !== void 0) {
766
+ node.epistemicLayer = epistemicLayer;
767
+ }
768
+ const metadata = readRecord(record.metadata);
769
+ if (metadata) {
770
+ node.metadata = metadata;
771
+ }
772
+ const projectId = readOptionalString(record.projectId);
773
+ if (projectId !== void 0) {
774
+ node.projectId = projectId;
775
+ }
776
+ const status = readOptionalString(record.status);
777
+ if (status !== void 0) {
778
+ node.status = status;
779
+ }
780
+ const tags = readStringArray(record.tags);
781
+ if (tags !== void 0) {
782
+ node.tags = tags;
783
+ }
784
+ const tenantId = readOptionalString(record.tenantId);
785
+ if (tenantId !== void 0) {
786
+ node.tenantId = tenantId;
787
+ }
788
+ const title = readOptionalString(record.title);
789
+ if (title !== void 0) {
790
+ node.title = title;
791
+ }
792
+ const topicId = readOptionalString(record.topicId);
793
+ if (topicId !== void 0) {
794
+ node.topicId = topicId;
795
+ }
796
+ const verificationStatus = readOptionalString(record.verificationStatus);
797
+ if (verificationStatus !== void 0) {
798
+ node.verificationStatus = verificationStatus;
799
+ }
800
+ const workspaceId = readOptionalString(record.workspaceId);
801
+ if (workspaceId !== void 0) {
802
+ node.workspaceId = workspaceId;
803
+ }
804
+ return node;
805
+ }
806
+ function requireEpistemicNodeRow(value, context) {
807
+ const node = readEpistemicNodeRow(value);
808
+ if (!node) {
809
+ throw new Error(`${context} requires a stored epistemic node.`);
810
+ }
811
+ return node;
716
812
  }
717
-
718
- // src/epistemicNodes.mutations.ts
719
- var optionalNodeScopeArgs = optionalScopeArgs;
720
813
  var create = mutation({
721
814
  args: {
722
815
  globalId: v.string(),
@@ -762,8 +855,9 @@ var create = mutation({
762
855
  mutationName: "epistemicNodes.create"
763
856
  });
764
857
  const existing = await ctx.db.query("epistemicNodes").withIndex("by_contentHash", (q) => q.eq("contentHash", args.contentHash)).first();
765
- if (existing && existing.status === "active") {
766
- return { nodeId: existing._id, isDuplicate: true };
858
+ const existingNode = readEpistemicNodeRow(existing);
859
+ if (existingNode?.status === "active") {
860
+ return { nodeId: existingNode._id, isDuplicate: true };
767
861
  }
768
862
  const epistemicLayer = getNodeLayer(args.nodeType);
769
863
  const resolvedScope = args.topicId || args.projectId ? await resolveTopicProjectScope(ctx, {
@@ -878,12 +972,12 @@ var update = mutation({
878
972
  returns: permissiveReturn,
879
973
  handler: async (ctx, args) => {
880
974
  const { nodeId, userId, ...updates } = args;
881
- const node = await ctx.db.get(nodeId);
882
- if (!node) {
883
- throw new Error("Node not found");
884
- }
975
+ const node = requireEpistemicNodeRow(
976
+ await ctx.db.get(nodeId),
977
+ "Update node"
978
+ );
885
979
  if (node.projectId && userId) {
886
- await requireProjectAccess(ctx, node.projectId, userId);
980
+ await requireScopeWriteAccess(ctx, node.projectId, userId);
887
981
  }
888
982
  const cleanUpdates = {};
889
983
  for (const [key, value] of Object.entries(updates)) {
@@ -910,7 +1004,7 @@ var update = mutation({
910
1004
  entityId: String(nodeId),
911
1005
  changeType: "updated",
912
1006
  changedAt: Date.now(),
913
- changedBy: userId || node.createdBy,
1007
+ changedBy: userId ?? node.createdBy ?? "system:update",
914
1008
  isAgent: false,
915
1009
  previousState: {
916
1010
  status: node.status,
@@ -939,12 +1033,12 @@ var supersede = mutation({
939
1033
  },
940
1034
  returns: permissiveReturn,
941
1035
  handler: async (ctx, args) => {
942
- const oldNode = await ctx.db.get(args.oldNodeId);
943
- if (!oldNode) {
944
- throw new Error("Node not found");
945
- }
1036
+ const oldNode = requireEpistemicNodeRow(
1037
+ await ctx.db.get(args.oldNodeId),
1038
+ "Supersede node"
1039
+ );
946
1040
  if (oldNode.projectId) {
947
- await requireProjectAccess(ctx, oldNode.projectId, args.createdBy);
1041
+ await requireScopeWriteAccess(ctx, oldNode.projectId, args.createdBy);
948
1042
  }
949
1043
  assertBeliefNodeSupersedeAllowed({
950
1044
  node: oldNode,
@@ -974,7 +1068,10 @@ var supersede = mutation({
974
1068
  verificationStatus: "unverified",
975
1069
  // New version needs re-verification
976
1070
  status: "active",
1071
+ topicId: oldNode.topicId,
977
1072
  projectId: oldNode.projectId,
1073
+ tenantId: oldNode.tenantId,
1074
+ workspaceId: oldNode.workspaceId,
978
1075
  createdBy: args.createdBy,
979
1076
  createdAt: now,
980
1077
  updatedAt: now
@@ -1015,12 +1112,12 @@ var archive = mutation({
1015
1112
  },
1016
1113
  returns: permissiveReturn,
1017
1114
  handler: async (ctx, args) => {
1018
- const node = await ctx.db.get(args.nodeId);
1019
- if (!node) {
1020
- throw new Error("Node not found");
1021
- }
1115
+ const node = requireEpistemicNodeRow(
1116
+ await ctx.db.get(args.nodeId),
1117
+ "Archive node"
1118
+ );
1022
1119
  if (node.projectId && args.userId) {
1023
- await requireProjectAccess(ctx, node.projectId, args.userId);
1120
+ await requireScopeWriteAccess(ctx, node.projectId, args.userId);
1024
1121
  }
1025
1122
  assertBeliefNodeArchiveAllowed({
1026
1123
  node,
@@ -1040,7 +1137,7 @@ var archive = mutation({
1040
1137
  entityId: String(args.nodeId),
1041
1138
  changeType: "archived",
1042
1139
  changedAt: Date.now(),
1043
- changedBy: args.userId || node.createdBy,
1140
+ changedBy: args.userId ?? node.createdBy ?? "system:archive",
1044
1141
  isAgent: false,
1045
1142
  previousState: { status: node.status },
1046
1143
  newState: { status: "archived" },
@@ -1059,10 +1156,10 @@ var verify = mutation({
1059
1156
  },
1060
1157
  returns: permissiveReturn,
1061
1158
  handler: async (ctx, args) => {
1062
- const node = await ctx.db.get(args.nodeId);
1063
- if (!node) {
1064
- throw new Error("Node not found");
1065
- }
1159
+ const node = requireEpistemicNodeRow(
1160
+ await ctx.db.get(args.nodeId),
1161
+ "Verify node"
1162
+ );
1066
1163
  assertBeliefNodeVerifyAllowed({
1067
1164
  node,
1068
1165
  confidence: args.confidence,
@@ -1134,7 +1231,7 @@ var batchCreate = mutation({
1134
1231
  handler: async (ctx, args) => {
1135
1232
  const resolveNodeScope = async (node) => {
1136
1233
  if (!(node.topicId || node.projectId)) {
1137
- return void 0;
1234
+ return;
1138
1235
  }
1139
1236
  try {
1140
1237
  return await resolveTopicProjectScope(ctx, {
@@ -1150,7 +1247,7 @@ var batchCreate = mutation({
1150
1247
  projectId: node.projectId
1151
1248
  }
1152
1249
  );
1153
- return void 0;
1250
+ return;
1154
1251
  }
1155
1252
  };
1156
1253
  const now = Date.now();