@lucern/graph-primitives 1.0.0 → 1.0.1

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 (202) hide show
  1. package/README.md +13 -12
  2. package/dist/beliefDecay.js +24 -17
  3. package/dist/beliefDecay.js.map +1 -1
  4. package/dist/beliefEvidenceLinks.js +32 -8
  5. package/dist/beliefEvidenceLinks.js.map +1 -1
  6. package/dist/confidencePropagationDispatch.js.map +1 -1
  7. package/dist/contradictions.js +32 -9
  8. package/dist/contradictions.js.map +1 -1
  9. package/dist/convex.d.ts +55 -12
  10. package/dist/convex.js.map +1 -1
  11. package/dist/edgeValidation.d.ts +25 -2
  12. package/dist/edges/index.d.ts +9 -2
  13. package/dist/edges/index.js.map +1 -1
  14. package/dist/edges/propagationTypes.d.ts +2 -3
  15. package/dist/edges/propagationTypes.js.map +1 -1
  16. package/dist/entityBridge.js +10 -3
  17. package/dist/entityBridge.js.map +1 -1
  18. package/dist/entityLifecycle.js +15 -3
  19. package/dist/entityLifecycle.js.map +1 -1
  20. package/dist/epistemicAnswers.js.map +1 -1
  21. package/dist/epistemicBeliefs.admin.d.ts +36 -0
  22. package/dist/epistemicBeliefs.admin.js +745 -0
  23. package/dist/epistemicBeliefs.admin.js.map +1 -0
  24. package/dist/epistemicBeliefs.backfills.d.ts +62 -0
  25. package/dist/epistemicBeliefs.backfills.js +1004 -0
  26. package/dist/epistemicBeliefs.backfills.js.map +1 -0
  27. package/dist/epistemicBeliefs.confidence.d.ts +45 -0
  28. package/dist/epistemicBeliefs.confidence.js +1285 -0
  29. package/dist/epistemicBeliefs.confidence.js.map +1 -0
  30. package/dist/epistemicBeliefs.core.d.ts +35 -0
  31. package/dist/epistemicBeliefs.core.js +1508 -0
  32. package/dist/epistemicBeliefs.core.js.map +1 -0
  33. package/dist/epistemicBeliefs.d.ts +12 -3
  34. package/dist/epistemicBeliefs.helpers.d.ts +168 -0
  35. package/dist/epistemicBeliefs.helpers.js +1060 -0
  36. package/dist/epistemicBeliefs.helpers.js.map +1 -0
  37. package/dist/epistemicBeliefs.internal.d.ts +30 -0
  38. package/dist/epistemicBeliefs.internal.js +1329 -0
  39. package/dist/epistemicBeliefs.internal.js.map +1 -0
  40. package/dist/epistemicBeliefs.js +1196 -1184
  41. package/dist/epistemicBeliefs.js.map +1 -1
  42. package/dist/epistemicBeliefs.lifecycle.d.ts +19 -0
  43. package/dist/epistemicBeliefs.lifecycle.js +1608 -0
  44. package/dist/epistemicBeliefs.lifecycle.js.map +1 -0
  45. package/dist/epistemicBeliefs.links.d.ts +30 -0
  46. package/dist/epistemicBeliefs.links.js +761 -0
  47. package/dist/epistemicBeliefs.links.js.map +1 -0
  48. package/dist/epistemicBeliefs.queries.d.ts +16 -0
  49. package/dist/epistemicBeliefs.queries.js +90 -0
  50. package/dist/epistemicBeliefs.queries.js.map +1 -0
  51. package/dist/epistemicContractHelpers.d.ts +1 -1
  52. package/dist/epistemicContractHelpers.js +1 -1
  53. package/dist/epistemicContracts.d.ts +5 -76
  54. package/dist/epistemicContracts.evaluators.d.ts +36 -0
  55. package/dist/epistemicContracts.evaluators.js +2506 -0
  56. package/dist/epistemicContracts.evaluators.js.map +1 -0
  57. package/dist/epistemicContracts.handlers.d.ts +40 -0
  58. package/dist/epistemicContracts.handlers.js +3029 -0
  59. package/dist/epistemicContracts.handlers.js.map +1 -0
  60. package/dist/epistemicContracts.js +2006 -5281
  61. package/dist/epistemicContracts.js.map +1 -1
  62. package/dist/epistemicContracts.metrics.d.ts +26 -0
  63. package/dist/epistemicContracts.metrics.js +427 -0
  64. package/dist/epistemicContracts.metrics.js.map +1 -0
  65. package/dist/epistemicContracts.types.d.ts +159 -0
  66. package/dist/epistemicContracts.types.js +3 -0
  67. package/dist/epistemicContracts.types.js.map +1 -0
  68. package/dist/epistemicEdgeCreation.d.ts +73 -0
  69. package/dist/epistemicEdgeCreation.js +450 -0
  70. package/dist/epistemicEdgeCreation.js.map +1 -0
  71. package/dist/epistemicEdges-BF-cn4i3.d.ts +43 -0
  72. package/dist/epistemicEdges.d.ts +8 -1
  73. package/dist/epistemicEdges.handlers.d.ts +20 -0
  74. package/dist/epistemicEdges.handlers.js +289 -0
  75. package/dist/epistemicEdges.handlers.js.map +1 -0
  76. package/dist/epistemicEdges.helpers.d.ts +27 -0
  77. package/dist/epistemicEdges.helpers.js +162 -0
  78. package/dist/epistemicEdges.helpers.js.map +1 -0
  79. package/dist/epistemicEdges.js +797 -875
  80. package/dist/epistemicEdges.js.map +1 -1
  81. package/dist/epistemicEdges.mutations.d.ts +39 -0
  82. package/dist/epistemicEdges.mutations.js +1365 -0
  83. package/dist/epistemicEdges.mutations.js.map +1 -0
  84. package/dist/epistemicEdges.queries.d.ts +95 -0
  85. package/dist/epistemicEdges.queries.js +851 -0
  86. package/dist/epistemicEdges.queries.js.map +1 -0
  87. package/dist/epistemicEdges.types.d.ts +32 -0
  88. package/dist/epistemicEdges.types.js +3 -0
  89. package/dist/epistemicEdges.types.js.map +1 -0
  90. package/dist/epistemicEvidence-DvfchNt7.d.ts +46 -0
  91. package/dist/epistemicEvidence.d.ts +5 -2
  92. package/dist/epistemicEvidence.js +801 -807
  93. package/dist/epistemicEvidence.js.map +1 -1
  94. package/dist/epistemicEvidenceHelpers.d.ts +71 -0
  95. package/dist/epistemicEvidenceHelpers.js +769 -0
  96. package/dist/epistemicEvidenceHelpers.js.map +1 -0
  97. package/dist/epistemicEvidenceMutations.d.ts +10 -0
  98. package/dist/epistemicEvidenceMutations.js +1421 -0
  99. package/dist/epistemicEvidenceMutations.js.map +1 -0
  100. package/dist/epistemicEvidenceQueries.d.ts +10 -0
  101. package/dist/epistemicEvidenceQueries.js +1049 -0
  102. package/dist/epistemicEvidenceQueries.js.map +1 -0
  103. package/dist/epistemicHelpers.d.ts +4 -2
  104. package/dist/epistemicHelpers.js +132 -127
  105. package/dist/epistemicHelpers.js.map +1 -1
  106. package/dist/epistemicLayerRules.d.ts +138 -0
  107. package/dist/epistemicLayerRules.js +481 -0
  108. package/dist/epistemicLayerRules.js.map +1 -0
  109. package/dist/epistemicLinking.js +1 -1
  110. package/dist/epistemicLinking.js.map +1 -1
  111. package/dist/epistemicNodeCreation.d.ts +101 -0
  112. package/dist/epistemicNodeCreation.js +709 -0
  113. package/dist/epistemicNodeCreation.js.map +1 -0
  114. package/dist/epistemicNodes-BCQxpYx_.d.ts +54 -0
  115. package/dist/epistemicNodes.d.ts +5 -1
  116. package/dist/epistemicNodes.helpers.d.ts +51 -0
  117. package/dist/epistemicNodes.helpers.js +73 -0
  118. package/dist/epistemicNodes.helpers.js.map +1 -0
  119. package/dist/epistemicNodes.internal.d.ts +34 -0
  120. package/dist/epistemicNodes.internal.js +658 -0
  121. package/dist/epistemicNodes.internal.js.map +1 -0
  122. package/dist/epistemicNodes.js +698 -693
  123. package/dist/epistemicNodes.js.map +1 -1
  124. package/dist/epistemicNodes.mutations.d.ts +34 -0
  125. package/dist/epistemicNodes.mutations.js +1153 -0
  126. package/dist/epistemicNodes.mutations.js.map +1 -0
  127. package/dist/epistemicNodes.queries.d.ts +36 -0
  128. package/dist/epistemicNodes.queries.js +619 -0
  129. package/dist/epistemicNodes.queries.js.map +1 -0
  130. package/dist/epistemicNodes.validators.d.ts +23 -0
  131. package/dist/epistemicNodes.validators.js +105 -0
  132. package/dist/epistemicNodes.validators.js.map +1 -0
  133. package/dist/epistemicQuestions-bwHd2FWE.d.ts +68 -0
  134. package/dist/epistemicQuestions.conviction.d.ts +52 -0
  135. package/dist/epistemicQuestions.conviction.js +1389 -0
  136. package/dist/epistemicQuestions.conviction.js.map +1 -0
  137. package/dist/epistemicQuestions.create.d.ts +29 -0
  138. package/dist/epistemicQuestions.create.js +1300 -0
  139. package/dist/epistemicQuestions.create.js.map +1 -0
  140. package/dist/epistemicQuestions.d.ts +10 -2
  141. package/dist/epistemicQuestions.evidence.d.ts +22 -0
  142. package/dist/epistemicQuestions.evidence.js +929 -0
  143. package/dist/epistemicQuestions.evidence.js.map +1 -0
  144. package/dist/epistemicQuestions.helpers.d.ts +69 -0
  145. package/dist/epistemicQuestions.helpers.js +824 -0
  146. package/dist/epistemicQuestions.helpers.js.map +1 -0
  147. package/dist/epistemicQuestions.js +2435 -2430
  148. package/dist/epistemicQuestions.js.map +1 -1
  149. package/dist/epistemicQuestions.lifecycle.d.ts +24 -0
  150. package/dist/epistemicQuestions.lifecycle.js +838 -0
  151. package/dist/epistemicQuestions.lifecycle.js.map +1 -0
  152. package/dist/epistemicQuestions.queries.d.ts +41 -0
  153. package/dist/epistemicQuestions.queries.js +1013 -0
  154. package/dist/epistemicQuestions.queries.js.map +1 -0
  155. package/dist/epistemicQuestions.sprint.d.ts +22 -0
  156. package/dist/epistemicQuestions.sprint.js +757 -0
  157. package/dist/epistemicQuestions.sprint.js.map +1 -0
  158. package/dist/epistemicQuestions.tail.d.ts +42 -0
  159. package/dist/epistemicQuestions.tail.js +1345 -0
  160. package/dist/epistemicQuestions.tail.js.map +1 -0
  161. package/dist/epistemicSources.js +6 -2
  162. package/dist/epistemicSources.js.map +1 -1
  163. package/dist/evaluators/index.d.ts +2 -2
  164. package/dist/evaluators/index.js +45 -5320
  165. package/dist/evaluators/index.js.map +1 -1
  166. package/dist/evaluators/lintCheckerEvaluator.d.ts +1 -1
  167. package/dist/evaluators/sentryCheckerEvaluator.d.ts +1 -1
  168. package/dist/evaluators/testRunnerEvaluator.d.ts +1 -1
  169. package/dist/evaluators/tscCheckerEvaluator.d.ts +1 -1
  170. package/dist/{graphTypes-CpgIuCdo.d.ts → graphTypes-B8VaIjnl.d.ts} +1 -1
  171. package/dist/graphTypes.d.ts +1 -1
  172. package/dist/{helpers-BYHIk5vU.d.ts → helpers-DNYfg6mo.d.ts} +2 -3
  173. package/dist/helpers.d.ts +2 -2
  174. package/dist/helpers.js.map +1 -1
  175. package/dist/{index-Dq-7R-gi.d.ts → index-C-Kyd7hD.d.ts} +1 -1
  176. package/dist/index.d.ts +160 -14
  177. package/dist/index.js +12291 -13001
  178. package/dist/index.js.map +1 -1
  179. package/dist/logicalRoleInference.js.map +1 -1
  180. package/dist/ontologyApproval.js +1 -1
  181. package/dist/ontologyApproval.js.map +1 -1
  182. package/dist/ontologyDefinitions.js +25 -7
  183. package/dist/ontologyDefinitions.js.map +1 -1
  184. package/dist/ontologyRegistry.js.map +1 -1
  185. package/dist/projectionReconciliation.js.map +1 -1
  186. package/dist/questionEvidenceLinks.js +28 -7
  187. package/dist/questionEvidenceLinks.js.map +1 -1
  188. package/dist/resolvers.js.map +1 -1
  189. package/dist/scopeResolverCompat.js.map +1 -1
  190. package/dist/topicProjectOverlay.js.map +1 -1
  191. package/dist/topicScope.js.map +1 -1
  192. package/dist/workflowBridge.js.map +1 -1
  193. package/dist/workspaceIsolation.js.map +1 -1
  194. package/package.json +4 -5
  195. package/dist/edgeValidation-CeI0wc0r.d.ts +0 -35
  196. package/dist/epistemicBeliefs-DzKjZAeC.d.ts +0 -377
  197. package/dist/epistemicEdges-CvlKnEyy.d.ts +0 -191
  198. package/dist/epistemicEvidence-xw6UUrwh.d.ts +0 -128
  199. package/dist/epistemicHelpers-DevrYgPN.d.ts +0 -329
  200. package/dist/epistemicNodes-DjSUfvyD.d.ts +0 -167
  201. package/dist/epistemicQuestions-B_nUclrH.d.ts +0 -214
  202. package/dist/index-Dct1T70K.d.ts +0 -25
@@ -0,0 +1,851 @@
1
+ import { v } from 'convex/values';
2
+ import { checkScopeAccess } from '@lucern/access-control/access';
3
+ import { permissiveReturn } from '@lucern/contracts/schema-helpers/validators';
4
+ import { componentsGeneric, queryGeneric, anyApi } from 'convex/server';
5
+
6
+ // src/epistemicEdges.queries.ts
7
+
8
+ // src/debug.ts
9
+ function isGraphPrimitiveDebugEnabled() {
10
+ const env = globalThis.process?.env;
11
+ return env?.LUCERN_COMPAT_FALLBACK_DEBUG === "1" || env?.LUCERN_GRAPH_DEBUG === "1";
12
+ }
13
+ function debugGraphPrimitiveFallback(message, context) {
14
+ if (!isGraphPrimitiveDebugEnabled()) {
15
+ return;
16
+ }
17
+ console.debug(message, context ?? {});
18
+ }
19
+ var api = anyApi;
20
+ componentsGeneric();
21
+ var query = queryGeneric;
22
+ v.union(
23
+ v.literal("L4"),
24
+ v.literal("L3"),
25
+ v.literal("L2"),
26
+ v.literal("L1"),
27
+ v.literal("ontological"),
28
+ v.literal("organizational")
29
+ );
30
+ v.object({
31
+ b: v.number(),
32
+ d: v.number(),
33
+ u: v.number(),
34
+ a: v.number()
35
+ });
36
+ var edgeTypeValidator = v.union(
37
+ // --- L4 Decision Edges (Phase 2A) ---
38
+ v.literal("based_on_belief"),
39
+ v.literal("based_on_question"),
40
+ v.literal("blocked_by_contradiction"),
41
+ v.literal("informed_by_theme"),
42
+ // --- Evidence Flow (L2 → L3, L2 → L1) ---
43
+ v.literal("derived_from"),
44
+ v.literal("responds_to"),
45
+ v.literal("informs"),
46
+ v.literal("tests"),
47
+ v.literal("explores"),
48
+ v.literal("qualifies"),
49
+ // --- Synthesis (L2 → L2, L2 → L1) ---
50
+ // "based_on" removed — use "derived_from" instead
51
+ // --- Theme Relationships (L3 → L3) ---
52
+ v.literal("relates_to_thesis"),
53
+ v.literal("belongs_to"),
54
+ v.literal("plays_theme"),
55
+ v.literal("scoped_by"),
56
+ // --- Deal/Company ---
57
+ v.literal("evaluates"),
58
+ // --- People (ontological → ontological, ontological → L3) ---
59
+ v.literal("perspective_on"),
60
+ v.literal("works_at"),
61
+ v.literal("mentioned_in"),
62
+ v.literal("founded_by"),
63
+ // --- Value Chain (ontological → ontological) ---
64
+ v.literal("participates_in"),
65
+ v.literal("performs"),
66
+ v.literal("function_in"),
67
+ v.literal("impacts"),
68
+ // --- Investment (ontological → ontological) ---
69
+ v.literal("invested_in"),
70
+ v.literal("raised_from"),
71
+ // --- Lifecycle (same layer only) ---
72
+ v.literal("supersedes"),
73
+ v.literal("same_as"),
74
+ // --- Same-Type Relationships: Belief ↔ Belief (L3 → L3) ---
75
+ v.literal("depends_on"),
76
+ v.literal("supports"),
77
+ v.literal("contains"),
78
+ // --- Belief Cluster Mapping (L3 → L3) ---
79
+ v.literal("counterfactual_of"),
80
+ v.literal("cascade_to"),
81
+ v.literal("cascade_from"),
82
+ v.literal("mutually_exclusive"),
83
+ v.literal("correlates_with"),
84
+ v.literal("amplifies"),
85
+ v.literal("precondition_for"),
86
+ v.literal("in_tension_with"),
87
+ // --- Belief ↔ Belief: Epistemic Impact (Confidence Propagation) ---
88
+ v.literal("falsified_by"),
89
+ v.literal("exclusive_with"),
90
+ v.literal("contradicts"),
91
+ v.literal("collapses_if"),
92
+ v.literal("strengthened_by"),
93
+ v.literal("weakened_by"),
94
+ v.literal("alternative_to"),
95
+ v.literal("subsumes"),
96
+ v.literal("validated_by"),
97
+ v.literal("required_for"),
98
+ v.literal("blocks"),
99
+ // --- Same-Type Relationships: Question ↔ Question (L3 → L3) ---
100
+ v.literal("prerequisite_for"),
101
+ v.literal("parallel_to"),
102
+ // --- Same-Type Relationships: Evidence ↔ Evidence (L2 → L2) ---
103
+ v.literal("corroborates"),
104
+ v.literal("extends"),
105
+ v.literal("same_source_as"),
106
+ v.literal("same_theme_as"),
107
+ // --- NEW: Deep Epistemic Analysis Edges (Phase: Schema Upgrade) ---
108
+ v.literal("assumes"),
109
+ v.literal("would_predict"),
110
+ v.literal("analogous_to"),
111
+ v.literal("independent_of"),
112
+ // --- Entity↔Belief Bridge (OE-B) ---
113
+ v.literal("competes_with")
114
+ );
115
+ function edgeMatchesWorkspaceReasoningScope(edge, scope) {
116
+ return scope.topicId !== void 0 && edge.topicId === scope.topicId || scope.projectId !== void 0 && edge.projectId === scope.projectId;
117
+ }
118
+ async function collectScopedEdges(ctx, scope, scanLimit) {
119
+ const queries = [];
120
+ if (scope.topicId) {
121
+ queries.push(
122
+ ctx.db.query("epistemicEdges").withIndex(
123
+ "by_topic",
124
+ (q) => q.eq("topicId", scope.topicId)
125
+ ).order("desc").take(scanLimit)
126
+ );
127
+ }
128
+ if (scope.projectId) {
129
+ queries.push(
130
+ ctx.db.query("epistemicEdges").withIndex(
131
+ "by_topic",
132
+ (q) => q.eq("topicId", scope.projectId)
133
+ ).order("desc").take(scanLimit)
134
+ );
135
+ }
136
+ const seen = /* @__PURE__ */ new Set();
137
+ const deduped = [];
138
+ const flattened = (await Promise.all(queries)).flat();
139
+ for (const edge of flattened) {
140
+ const key = String(edge._id);
141
+ if (seen.has(key)) {
142
+ continue;
143
+ }
144
+ seen.add(key);
145
+ deduped.push(edge);
146
+ }
147
+ return deduped;
148
+ }
149
+
150
+ // src/graphTypes.ts
151
+ function getNodeLayer(nodeType) {
152
+ const L4_TYPES = ["decision"];
153
+ const L3_TYPES = ["belief", "question", "theme", "deal"];
154
+ const L2_TYPES = ["claim", "evidence", "synthesis", "answer"];
155
+ const L1_TYPES = ["atomic_fact", "excerpt", "source"];
156
+ const ONTOLOGICAL_TYPES = [
157
+ "company",
158
+ "person",
159
+ "investor",
160
+ "function",
161
+ "value_chain"
162
+ ];
163
+ const ORGANIZATIONAL_TYPES = ["topic"];
164
+ if (L4_TYPES.includes(nodeType)) {
165
+ return "L4";
166
+ }
167
+ if (L3_TYPES.includes(nodeType)) {
168
+ return "L3";
169
+ }
170
+ if (L2_TYPES.includes(nodeType)) {
171
+ return "L2";
172
+ }
173
+ if (L1_TYPES.includes(nodeType)) {
174
+ return "L1";
175
+ }
176
+ if (ONTOLOGICAL_TYPES.includes(nodeType)) {
177
+ return "ontological";
178
+ }
179
+ if (ORGANIZATIONAL_TYPES.includes(nodeType)) {
180
+ return "organizational";
181
+ }
182
+ console.warn(`[GraphTypes] Unknown nodeType "${nodeType}", defaulting to L2`);
183
+ return "L2";
184
+ }
185
+
186
+ // src/edgeValidation.ts
187
+ function getLayerDepth(layer) {
188
+ switch (layer) {
189
+ case "L4":
190
+ return 4;
191
+ case "L3":
192
+ return 3;
193
+ case "L2":
194
+ return 2;
195
+ case "L1":
196
+ return 1;
197
+ case "ontological":
198
+ return 0;
199
+ default:
200
+ return -1;
201
+ }
202
+ }
203
+ function shouldContinueTraversal(currentLayer, targetLayer, options) {
204
+ const currentDepth = getLayerDepth(currentLayer);
205
+ const targetDepth = getLayerDepth(targetLayer);
206
+ if (options.minLayer !== void 0 && targetDepth < options.minLayer) {
207
+ return false;
208
+ }
209
+ if (options.maxLayer !== void 0 && targetDepth > options.maxLayer) {
210
+ return false;
211
+ }
212
+ switch (options.mode) {
213
+ case "anchor_down":
214
+ return targetDepth <= currentDepth;
215
+ case "anchor_up":
216
+ return targetDepth >= currentDepth;
217
+ case "same_layer":
218
+ return targetDepth === currentDepth;
219
+ case "decision_trace":
220
+ return currentDepth === 4 ? targetDepth === 3 : targetDepth === currentDepth;
221
+ default:
222
+ return true;
223
+ }
224
+ }
225
+ function getDefaultMinLayer(mode) {
226
+ switch (mode) {
227
+ case "anchor_down":
228
+ return 1;
229
+ case "anchor_up":
230
+ return 2;
231
+ case "same_layer":
232
+ return 1;
233
+ case "decision_trace":
234
+ return 3;
235
+ default:
236
+ return 1;
237
+ }
238
+ }
239
+ var LEGACY_SCOPE_FIELD = "graphScopeProjectId";
240
+ function asMappedProjectId(topic) {
241
+ if (!topic) {
242
+ return;
243
+ }
244
+ const directLegacyProjectId = normalizeScopeValue(topic[LEGACY_SCOPE_FIELD]);
245
+ if (directLegacyProjectId) {
246
+ return directLegacyProjectId;
247
+ }
248
+ const metadata = topic.metadata || {};
249
+ const candidate = metadata[LEGACY_SCOPE_FIELD] || metadata.legacyProjectId || metadata.projectId || metadata.scopeProjectId;
250
+ return candidate ? candidate : void 0;
251
+ }
252
+ function normalizeScopeValue(value) {
253
+ if (typeof value !== "string") {
254
+ return;
255
+ }
256
+ const normalized = value.trim();
257
+ return normalized.length > 0 ? normalized : void 0;
258
+ }
259
+ function pickPrimaryTopic(candidates) {
260
+ return [...candidates].sort((a, b) => {
261
+ const depthA = a.depth ?? 9999;
262
+ const depthB = b.depth ?? 9999;
263
+ if (depthA !== depthB) {
264
+ return depthA - depthB;
265
+ }
266
+ const createdA = a.createdAt ?? Number.MAX_SAFE_INTEGER;
267
+ const createdB = b.createdAt ?? Number.MAX_SAFE_INTEGER;
268
+ if (createdA !== createdB) {
269
+ return createdA - createdB;
270
+ }
271
+ return String(a.name || "").localeCompare(String(b.name || ""));
272
+ })[0];
273
+ }
274
+ async function findTopicsByScopeAlias(ctx, scopeId) {
275
+ try {
276
+ return await ctx.db.query("topics").withIndex(
277
+ "by_graph_scope_project",
278
+ (q) => q.eq(LEGACY_SCOPE_FIELD, scopeId)
279
+ ).collect();
280
+ } catch (error) {
281
+ debugGraphPrimitiveFallback(
282
+ "[topicScope] Failed to resolve scope alias via index",
283
+ {
284
+ error,
285
+ scopeId
286
+ }
287
+ );
288
+ const topics = await ctx.db.query("topics").collect();
289
+ return topics.filter((topic) => {
290
+ const normalizedGlobalId = normalizeScopeValue(topic.globalId);
291
+ const mappedProjectId = asMappedProjectId(topic);
292
+ return String(topic._id) === scopeId || normalizedGlobalId === scopeId || mappedProjectId === scopeId;
293
+ });
294
+ }
295
+ }
296
+ async function tryResolveHostTopicById(ctx, topicId) {
297
+ if (typeof ctx.runQuery !== "function") {
298
+ return null;
299
+ }
300
+ try {
301
+ return await ctx.runQuery(api.topics.get, {
302
+ id: topicId
303
+ }) ?? null;
304
+ } catch (error) {
305
+ debugGraphPrimitiveFallback(
306
+ "[topicScope] Failed to resolve topic by host query",
307
+ {
308
+ error,
309
+ topicId
310
+ }
311
+ );
312
+ return null;
313
+ }
314
+ }
315
+ async function tryResolveHostTopicByLegacyScope(ctx, legacyScopeId) {
316
+ if (typeof ctx.runQuery !== "function") {
317
+ return null;
318
+ }
319
+ try {
320
+ return await ctx.runQuery(api.topics.getByLegacyScopeId, {
321
+ projectId: legacyScopeId
322
+ }) ?? null;
323
+ } catch (error) {
324
+ debugGraphPrimitiveFallback(
325
+ "[topicScope] Failed to resolve topic by legacy scope",
326
+ {
327
+ error,
328
+ legacyScopeId
329
+ }
330
+ );
331
+ return null;
332
+ }
333
+ }
334
+ async function resolveInheritedWorkspaceScope(ctx, topic) {
335
+ const MAX_DEPTH = 10;
336
+ let tenantId = normalizeScopeValue(topic.tenantId);
337
+ let workspaceId = normalizeScopeValue(topic.workspaceId);
338
+ if (tenantId && workspaceId) {
339
+ return { tenantId, workspaceId };
340
+ }
341
+ let current = topic;
342
+ for (let i = 0; i < MAX_DEPTH && current?.parentTopicId; i++) {
343
+ current = await ctx.db.get(current.parentTopicId);
344
+ if (!current) break;
345
+ if (!tenantId) {
346
+ tenantId = normalizeScopeValue(current.tenantId);
347
+ }
348
+ if (!workspaceId) {
349
+ workspaceId = normalizeScopeValue(current.workspaceId);
350
+ }
351
+ if (tenantId && workspaceId) break;
352
+ }
353
+ return { tenantId, workspaceId };
354
+ }
355
+ async function resolveTopicProjectScope(ctx, args) {
356
+ if (args.topicId) {
357
+ let topic = null;
358
+ try {
359
+ topic = await ctx.db.get(
360
+ args.topicId
361
+ );
362
+ } catch (error) {
363
+ debugGraphPrimitiveFallback(
364
+ "[topicScope] Failed to load topic by direct id",
365
+ {
366
+ error,
367
+ topicId: args.topicId
368
+ }
369
+ );
370
+ }
371
+ if (!topic) {
372
+ topic = await tryResolveHostTopicById(ctx, String(args.topicId));
373
+ }
374
+ if (!topic) {
375
+ topic = pickPrimaryTopic(
376
+ await findTopicsByScopeAlias(ctx, String(args.topicId))
377
+ ) ?? null;
378
+ }
379
+ if (!topic) {
380
+ throw new Error(`Topic not found: ${String(args.topicId)}`);
381
+ }
382
+ const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
383
+ const mapped = asMappedProjectId(topic);
384
+ if (mapped) {
385
+ return {
386
+ topicId: topic._id,
387
+ projectId: mapped,
388
+ tenantId: inherited.tenantId,
389
+ workspaceId: inherited.workspaceId,
390
+ source: "topic"
391
+ };
392
+ }
393
+ return {
394
+ topicId: topic._id,
395
+ tenantId: inherited.tenantId,
396
+ workspaceId: inherited.workspaceId,
397
+ source: "topic"
398
+ };
399
+ }
400
+ if (args.projectId) {
401
+ let directTopic = null;
402
+ try {
403
+ directTopic = await ctx.db.get(
404
+ args.projectId
405
+ );
406
+ } catch (error) {
407
+ debugGraphPrimitiveFallback(
408
+ "[topicScope] Failed to load direct project topic",
409
+ {
410
+ error,
411
+ projectId: args.projectId
412
+ }
413
+ );
414
+ }
415
+ if (directTopic) {
416
+ const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
417
+ const mapped = asMappedProjectId(directTopic);
418
+ return {
419
+ topicId: directTopic._id,
420
+ projectId: mapped ?? args.projectId,
421
+ tenantId: inherited.tenantId,
422
+ workspaceId: inherited.workspaceId,
423
+ source: "topic_inferred"
424
+ };
425
+ }
426
+ directTopic = await tryResolveHostTopicByLegacyScope(ctx, args.projectId);
427
+ if (directTopic) {
428
+ const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
429
+ const mapped = asMappedProjectId(directTopic);
430
+ return {
431
+ topicId: directTopic._id,
432
+ projectId: mapped ?? args.projectId,
433
+ tenantId: inherited.tenantId,
434
+ workspaceId: inherited.workspaceId,
435
+ source: "topic_inferred"
436
+ };
437
+ }
438
+ const topics = await findTopicsByScopeAlias(ctx, args.projectId);
439
+ const primary = pickPrimaryTopic(topics);
440
+ if (primary) {
441
+ const inherited = await resolveInheritedWorkspaceScope(ctx, primary);
442
+ return {
443
+ topicId: primary._id,
444
+ projectId: args.projectId,
445
+ tenantId: inherited.tenantId,
446
+ workspaceId: inherited.workspaceId,
447
+ source: "project_mapped_topic"
448
+ };
449
+ }
450
+ throw new Error(
451
+ `Legacy project scope ${String(args.projectId)} has no mapped topic.`
452
+ );
453
+ }
454
+ throw new Error(
455
+ "Missing scope: provide topicId (preferred) or legacy projectId alias."
456
+ );
457
+ }
458
+ var optionalScopeArgs = {
459
+ projectId: v.optional(v.string()),
460
+ topicId: v.optional(v.string())
461
+ };
462
+
463
+ // src/epistemicEdges.queries.ts
464
+ var get = query({
465
+ args: { edgeId: v.id("epistemicEdges") },
466
+ returns: permissiveReturn,
467
+ handler: async (ctx, args) => {
468
+ return await ctx.db.get(args.edgeId);
469
+ }
470
+ });
471
+ var getByGlobalId = query({
472
+ args: { globalId: v.string() },
473
+ returns: permissiveReturn,
474
+ handler: async (ctx, args) => {
475
+ return await ctx.db.query("epistemicEdges").withIndex("by_globalId", (q) => q.eq("globalId", args.globalId)).first();
476
+ }
477
+ });
478
+ var getFromNode = query({
479
+ args: {
480
+ fromNodeId: v.id("epistemicNodes"),
481
+ edgeType: v.optional(edgeTypeValidator)
482
+ },
483
+ returns: permissiveReturn,
484
+ handler: async (ctx, args) => {
485
+ const { edgeType } = args;
486
+ if (edgeType) {
487
+ return await ctx.db.query("epistemicEdges").withIndex(
488
+ "by_from_type",
489
+ (q) => q.eq("fromNodeId", args.fromNodeId).eq("edgeType", edgeType)
490
+ ).collect();
491
+ }
492
+ return await ctx.db.query("epistemicEdges").withIndex("by_from", (q) => q.eq("fromNodeId", args.fromNodeId)).collect();
493
+ }
494
+ });
495
+ var getToNode = query({
496
+ args: {
497
+ toNodeId: v.id("epistemicNodes"),
498
+ edgeType: v.optional(edgeTypeValidator)
499
+ },
500
+ returns: permissiveReturn,
501
+ handler: async (ctx, args) => {
502
+ const { edgeType } = args;
503
+ if (edgeType) {
504
+ return await ctx.db.query("epistemicEdges").withIndex(
505
+ "by_to_type",
506
+ (q) => q.eq("toNodeId", args.toNodeId).eq("edgeType", edgeType)
507
+ ).collect();
508
+ }
509
+ return await ctx.db.query("epistemicEdges").withIndex("by_to", (q) => q.eq("toNodeId", args.toNodeId)).collect();
510
+ }
511
+ });
512
+ var getBySourceNode = query({
513
+ args: {
514
+ sourceNodeId: v.string(),
515
+ edgeType: v.optional(v.string())
516
+ },
517
+ returns: permissiveReturn,
518
+ handler: async (ctx, args) => {
519
+ const isConvexId = args.sourceNodeId.length === 32 || args.sourceNodeId.includes("epistemicNodes");
520
+ if (isConvexId) {
521
+ const query2 = args.edgeType ? ctx.db.query("epistemicEdges").withIndex(
522
+ "by_from_type",
523
+ (q) => q.eq("fromNodeId", args.sourceNodeId).eq("edgeType", args.edgeType)
524
+ ) : ctx.db.query("epistemicEdges").withIndex(
525
+ "by_from",
526
+ (q) => q.eq("fromNodeId", args.sourceNodeId)
527
+ );
528
+ return await query2.collect();
529
+ }
530
+ const byGlobalId = await ctx.db.query("epistemicEdges").withIndex(
531
+ "by_source_global_id",
532
+ (q) => q.eq("sourceGlobalId", args.sourceNodeId)
533
+ ).collect();
534
+ if (args.edgeType) {
535
+ return byGlobalId.filter((edge) => edge.edgeType === args.edgeType);
536
+ }
537
+ return byGlobalId;
538
+ }
539
+ });
540
+ var getByTargetNode = query({
541
+ args: {
542
+ targetNodeId: v.string(),
543
+ edgeType: v.optional(v.string())
544
+ },
545
+ returns: permissiveReturn,
546
+ handler: async (ctx, args) => {
547
+ const isConvexId = args.targetNodeId.length === 32 || args.targetNodeId.includes("epistemicNodes");
548
+ if (isConvexId) {
549
+ const query2 = args.edgeType ? ctx.db.query("epistemicEdges").withIndex(
550
+ "by_to_type",
551
+ (q) => q.eq("toNodeId", args.targetNodeId).eq("edgeType", args.edgeType)
552
+ ) : ctx.db.query("epistemicEdges").withIndex(
553
+ "by_to",
554
+ (q) => q.eq("toNodeId", args.targetNodeId)
555
+ );
556
+ return await query2.collect();
557
+ }
558
+ const byGlobalId = await ctx.db.query("epistemicEdges").withIndex(
559
+ "by_target_global_id",
560
+ (q) => q.eq("targetGlobalId", args.targetNodeId)
561
+ ).collect();
562
+ if (args.edgeType) {
563
+ return byGlobalId.filter((edge) => edge.edgeType === args.edgeType);
564
+ }
565
+ return byGlobalId;
566
+ }
567
+ });
568
+ var getBetween = query({
569
+ args: {
570
+ fromNodeId: v.id("epistemicNodes"),
571
+ toNodeId: v.id("epistemicNodes"),
572
+ edgeType: v.optional(edgeTypeValidator)
573
+ },
574
+ returns: permissiveReturn,
575
+ handler: async (ctx, args) => {
576
+ const edges = await ctx.db.query("epistemicEdges").withIndex(
577
+ "by_from_to",
578
+ (q) => q.eq("fromNodeId", args.fromNodeId).eq("toNodeId", args.toNodeId)
579
+ ).collect();
580
+ if (args.edgeType) {
581
+ return edges.filter((e) => e.edgeType === args.edgeType);
582
+ }
583
+ return edges;
584
+ }
585
+ });
586
+ var getByNodes = query({
587
+ args: {
588
+ fromNodeId: v.id("epistemicNodes"),
589
+ toNodeId: v.id("epistemicNodes")
590
+ },
591
+ returns: permissiveReturn,
592
+ handler: async (ctx, args) => {
593
+ return await ctx.db.query("epistemicEdges").withIndex(
594
+ "by_from_to",
595
+ (q) => q.eq("fromNodeId", args.fromNodeId).eq("toNodeId", args.toNodeId)
596
+ ).first();
597
+ }
598
+ });
599
+ var getByProjectAndType = query({
600
+ args: {
601
+ ...optionalScopeArgs,
602
+ edgeType: edgeTypeValidator
603
+ },
604
+ returns: permissiveReturn,
605
+ handler: async (ctx, args) => {
606
+ if (!args.projectId && !args.topicId) {
607
+ return [];
608
+ }
609
+ let scope;
610
+ try {
611
+ scope = await resolveTopicProjectScope(ctx, {
612
+ projectId: args.projectId,
613
+ topicId: args.topicId
614
+ });
615
+ } catch (error) {
616
+ debugGraphPrimitiveFallback(
617
+ "[epistemicEdges] Failed to resolve getAll scope",
618
+ {
619
+ error,
620
+ projectId: args.projectId,
621
+ topicId: args.topicId
622
+ }
623
+ );
624
+ return [];
625
+ }
626
+ const projectEdges = await collectScopedEdges(ctx, scope, 5e3);
627
+ return projectEdges.filter(
628
+ (e) => e.edgeType === args.edgeType && edgeMatchesWorkspaceReasoningScope(e, scope)
629
+ ).slice(0, 5e3);
630
+ }
631
+ });
632
+ var getByProject = query({
633
+ args: {
634
+ ...optionalScopeArgs,
635
+ userId: v.optional(v.string()),
636
+ limit: v.optional(v.number())
637
+ },
638
+ returns: permissiveReturn,
639
+ handler: async (ctx, args) => {
640
+ if (!args.projectId && !args.topicId) {
641
+ return [];
642
+ }
643
+ let scope;
644
+ try {
645
+ scope = await resolveTopicProjectScope(ctx, {
646
+ projectId: args.projectId,
647
+ topicId: args.topicId
648
+ });
649
+ } catch (error) {
650
+ debugGraphPrimitiveFallback(
651
+ "[epistemicEdges] Failed to resolve getByProject scope",
652
+ {
653
+ error,
654
+ projectId: args.projectId,
655
+ topicId: args.topicId
656
+ }
657
+ );
658
+ return [];
659
+ }
660
+ if (args.userId) {
661
+ const hasAccess = await checkScopeAccess(
662
+ ctx,
663
+ String(scope.topicId ?? scope.projectId),
664
+ args.userId
665
+ );
666
+ if (!hasAccess) {
667
+ return [];
668
+ }
669
+ }
670
+ const pageSize = Math.max(1, Math.min(Math.floor(args.limit ?? 500), 2e3));
671
+ const edges = await collectScopedEdges(
672
+ ctx,
673
+ scope,
674
+ Math.min(pageSize * 3, 6e3)
675
+ );
676
+ return edges.filter((edge) => edgeMatchesWorkspaceReasoningScope(edge, scope)).slice(0, pageSize);
677
+ }
678
+ });
679
+ var listAll = query({
680
+ args: {
681
+ limit: v.optional(v.number())
682
+ },
683
+ returns: permissiveReturn,
684
+ handler: async (ctx, args) => {
685
+ const pageSize = Math.max(
686
+ 1,
687
+ Math.min(Math.floor(args.limit ?? 5e3), 1e4)
688
+ );
689
+ return await ctx.db.query("epistemicEdges").order("desc").take(pageSize);
690
+ }
691
+ });
692
+ var findContradictions = query({
693
+ args: {
694
+ nodeId: v.id("epistemicNodes")
695
+ },
696
+ returns: permissiveReturn,
697
+ handler: async (ctx, args) => {
698
+ const edges = await ctx.db.query("epistemicEdges").withIndex(
699
+ "by_to_type",
700
+ (q) => q.eq("toNodeId", args.nodeId).eq("edgeType", "informs")
701
+ ).collect();
702
+ return edges.filter((e) => (e.weight ?? 0) < 0);
703
+ }
704
+ });
705
+ var findSupport = query({
706
+ args: {
707
+ nodeId: v.id("epistemicNodes")
708
+ },
709
+ returns: permissiveReturn,
710
+ handler: async (ctx, args) => {
711
+ const edges = await ctx.db.query("epistemicEdges").withIndex(
712
+ "by_to_type",
713
+ (q) => q.eq("toNodeId", args.nodeId).eq("edgeType", "informs")
714
+ ).collect();
715
+ return edges.filter((e) => (e.weight ?? 0) >= 0);
716
+ }
717
+ });
718
+ var getLineage = query({
719
+ args: {
720
+ nodeId: v.id("epistemicNodes"),
721
+ maxDepth: v.optional(v.number()),
722
+ // Phase 2D: Layer-aware traversal options
723
+ minLayer: v.optional(v.number()),
724
+ // 1=L1, 2=L2, 3=L3, 4=L4
725
+ maxLayer: v.optional(v.number()),
726
+ mode: v.optional(
727
+ v.union(
728
+ v.literal("anchor_down"),
729
+ v.literal("anchor_up"),
730
+ v.literal("same_layer"),
731
+ v.literal("decision_trace")
732
+ )
733
+ )
734
+ },
735
+ returns: permissiveReturn,
736
+ handler: async (ctx, args) => {
737
+ const maxDepth = args.maxDepth ?? 10;
738
+ const mode = args.mode ?? "anchor_down";
739
+ const minLayer = args.minLayer ?? getDefaultMinLayer(mode);
740
+ const maxLayer = args.maxLayer ?? 4;
741
+ const lineage = [];
742
+ const visited = /* @__PURE__ */ new Set();
743
+ const startNode = await ctx.db.get(args.nodeId);
744
+ if (!startNode) {
745
+ return lineage;
746
+ }
747
+ const startLayer = startNode.epistemicLayer || getNodeLayer(startNode.nodeType);
748
+ const queue = [{ nodeId: args.nodeId, depth: 0, currentLayer: startLayer }];
749
+ while (queue.length > 0) {
750
+ const current = queue.shift();
751
+ if (!current || current.depth >= maxDepth) {
752
+ continue;
753
+ }
754
+ const nodeIdStr = current.nodeId.toString();
755
+ if (visited.has(nodeIdStr)) {
756
+ continue;
757
+ }
758
+ visited.add(nodeIdStr);
759
+ const edges = await ctx.db.query("epistemicEdges").withIndex("by_from", (q) => q.eq("fromNodeId", current.nodeId)).collect();
760
+ const lineageEdges = edges.filter((e) => e.edgeType === "derived_from");
761
+ for (const edge of lineageEdges) {
762
+ if (!edge.toNodeId) {
763
+ continue;
764
+ }
765
+ const targetNode = await ctx.db.get(edge.toNodeId);
766
+ if (!targetNode || visited.has(edge.toNodeId.toString())) {
767
+ continue;
768
+ }
769
+ const targetLayer = edge.toLayer || targetNode.epistemicLayer || getNodeLayer(targetNode.nodeType);
770
+ const shouldContinue = shouldContinueTraversal(
771
+ current.currentLayer,
772
+ targetLayer,
773
+ { mode, minLayer, maxLayer }
774
+ );
775
+ if (!shouldContinue) {
776
+ continue;
777
+ }
778
+ lineage.push({
779
+ node: targetNode,
780
+ depth: current.depth + 1,
781
+ edgeType: edge.edgeType,
782
+ layer: targetLayer
783
+ });
784
+ queue.push({
785
+ nodeId: edge.toNodeId,
786
+ depth: current.depth + 1,
787
+ currentLayer: targetLayer
788
+ });
789
+ }
790
+ }
791
+ return lineage;
792
+ }
793
+ });
794
+ var getEvidenceForBelief = query({
795
+ args: {
796
+ beliefNodeId: v.id("epistemicNodes")
797
+ },
798
+ returns: permissiveReturn,
799
+ handler: async (ctx, args) => {
800
+ const informsEdges = await ctx.db.query("epistemicEdges").withIndex(
801
+ "by_to_type",
802
+ (q) => q.eq("toNodeId", args.beliefNodeId).eq("edgeType", "informs")
803
+ ).collect();
804
+ const supportEdges = informsEdges.filter((e) => (e.weight ?? 0) >= 0);
805
+ const contradictEdges = informsEdges.filter((e) => (e.weight ?? 0) < 0);
806
+ const supportingEvidence = await Promise.all(
807
+ supportEdges.map(async (edge) => ({
808
+ edge,
809
+ node: await ctx.db.get(edge.fromNodeId)
810
+ }))
811
+ );
812
+ const contradictingEvidence = await Promise.all(
813
+ contradictEdges.map(async (edge) => ({
814
+ edge,
815
+ node: await ctx.db.get(edge.fromNodeId)
816
+ }))
817
+ );
818
+ const filteredSupporting = supportingEvidence.filter((e) => e.node !== null);
819
+ const filteredContradicting = contradictingEvidence.filter(
820
+ (e) => e.node !== null
821
+ );
822
+ return {
823
+ supporting: filteredSupporting,
824
+ contradicting: filteredContradicting,
825
+ supportCount: filteredSupporting.length,
826
+ contradictCount: filteredContradicting.length
827
+ };
828
+ }
829
+ });
830
+ var getClusterEdges = query({
831
+ args: {
832
+ beliefIds: v.array(v.string())
833
+ },
834
+ returns: permissiveReturn,
835
+ handler: async (ctx, args) => {
836
+ if (args.beliefIds.length === 0) {
837
+ return [];
838
+ }
839
+ const beliefIdSet = new Set(args.beliefIds);
840
+ const allEdges = await ctx.db.query("epistemicEdges").collect();
841
+ return allEdges.filter((edge) => {
842
+ const fromInCluster = beliefIdSet.has(String(edge.fromNodeId)) || edge.sourceGlobalId && beliefIdSet.has(edge.sourceGlobalId);
843
+ const toInCluster = beliefIdSet.has(String(edge.toNodeId)) || edge.targetGlobalId && beliefIdSet.has(edge.targetGlobalId);
844
+ return fromInCluster && toInCluster;
845
+ });
846
+ }
847
+ });
848
+
849
+ export { findContradictions, findSupport, get, getBetween, getByGlobalId, getByNodes, getByProject, getByProjectAndType, getBySourceNode, getByTargetNode, getClusterEdges, getEvidenceForBelief, getFromNode, getLineage, getToNode, listAll };
850
+ //# sourceMappingURL=epistemicEdges.queries.js.map
851
+ //# sourceMappingURL=epistemicEdges.queries.js.map