@lucern/graph-primitives 0.3.0-alpha.6 → 0.3.0-alpha.8

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 (123) hide show
  1. package/dist/{beliefDecay-Q_26RTc-.d.ts → beliefDecay-DZ6tkLYq.d.ts} +1 -1
  2. package/dist/beliefDecay.d.ts +1 -1
  3. package/dist/beliefDecay.js +158 -47
  4. package/dist/beliefDecay.js.map +1 -1
  5. package/dist/{beliefEvidenceLinks-42FlR48t.d.ts → beliefEvidenceLinks-CWOXxxJg.d.ts} +1 -1
  6. package/dist/beliefEvidenceLinks.d.ts +1 -1
  7. package/dist/beliefEvidenceLinks.js +141 -45
  8. package/dist/beliefEvidenceLinks.js.map +1 -1
  9. package/dist/{beliefLifecycle-C-AehZgF.d.ts → beliefLifecycle-y8WLXqQj.d.ts} +1 -1
  10. package/dist/beliefLifecycle.d.ts +1 -1
  11. package/dist/confidencePropagationDispatch.d.ts +1 -1
  12. package/dist/confidencePropagationDispatch.js +1 -3
  13. package/dist/confidencePropagationDispatch.js.map +1 -1
  14. package/dist/{contradictions-Hdwl7zid.d.ts → contradictions-51VLsESq.d.ts} +1 -1
  15. package/dist/contradictions.d.ts +1 -1
  16. package/dist/contradictions.js +67 -8
  17. package/dist/contradictions.js.map +1 -1
  18. package/dist/debug.d.ts +4 -0
  19. package/dist/debug.js +34 -0
  20. package/dist/debug.js.map +1 -0
  21. package/dist/edges/contradicts.js.map +1 -1
  22. package/dist/edges/dependsOn.js.map +1 -1
  23. package/dist/edges/elaborates.js.map +1 -1
  24. package/dist/edges/index.js +1 -3
  25. package/dist/edges/index.js.map +1 -1
  26. package/dist/edges/informs.js +1 -3
  27. package/dist/edges/informs.js.map +1 -1
  28. package/dist/edges/refutes.js +1 -3
  29. package/dist/edges/refutes.js.map +1 -1
  30. package/dist/edges/supports.js.map +1 -1
  31. package/dist/edges/utils.d.ts +3 -3
  32. package/dist/edges/utils.js +2 -4
  33. package/dist/edges/utils.js.map +1 -1
  34. package/dist/embeddingTrigger.js +21 -1
  35. package/dist/embeddingTrigger.js.map +1 -1
  36. package/dist/entityBridge.js +1 -1
  37. package/dist/entityBridge.js.map +1 -1
  38. package/dist/{entityLifecycle-BkhRJ-XI.d.ts → entityLifecycle-CvgSK5FV.d.ts} +1 -1
  39. package/dist/entityLifecycle.d.ts +1 -1
  40. package/dist/entityLifecycle.js +134 -47
  41. package/dist/entityLifecycle.js.map +1 -1
  42. package/dist/{epistemicAnswers-DSP1slZ9.d.ts → epistemicAnswers-C5ib4z6_.d.ts} +1 -1
  43. package/dist/epistemicAnswers.d.ts +1 -1
  44. package/dist/epistemicAnswers.js +67 -8
  45. package/dist/epistemicAnswers.js.map +1 -1
  46. package/dist/{epistemicBeliefs-DtFVTp-k.d.ts → epistemicBeliefs-DzKjZAeC.d.ts} +3 -3
  47. package/dist/epistemicBeliefs.d.ts +2 -2
  48. package/dist/epistemicBeliefs.js +289 -114
  49. package/dist/epistemicBeliefs.js.map +1 -1
  50. package/dist/epistemicContracts.d.ts +1 -1
  51. package/dist/epistemicContracts.js +297 -115
  52. package/dist/epistemicContracts.js.map +1 -1
  53. package/dist/{epistemicEdges-DcA8ErUG.d.ts → epistemicEdges-CvlKnEyy.d.ts} +1 -1
  54. package/dist/epistemicEdges.d.ts +1 -1
  55. package/dist/epistemicEdges.js +192 -60
  56. package/dist/epistemicEdges.js.map +1 -1
  57. package/dist/{epistemicEvidence-Bo638XDP.d.ts → epistemicEvidence-xw6UUrwh.d.ts} +1 -1
  58. package/dist/epistemicEvidence.d.ts +1 -1
  59. package/dist/epistemicEvidence.js +163 -49
  60. package/dist/epistemicEvidence.js.map +1 -1
  61. package/dist/{epistemicHelpers-Bd9xbaib.d.ts → epistemicHelpers-DevrYgPN.d.ts} +1 -1
  62. package/dist/epistemicHelpers.d.ts +1 -1
  63. package/dist/{epistemicLinking-CyeLOIzN.d.ts → epistemicLinking-CfE00tHJ.d.ts} +1 -1
  64. package/dist/epistemicLinking.d.ts +1 -1
  65. package/dist/epistemicLinking.js +1 -1
  66. package/dist/{epistemicNodes-BpD6Koud.d.ts → epistemicNodes-DjSUfvyD.d.ts} +1 -1
  67. package/dist/epistemicNodes.d.ts +1 -1
  68. package/dist/epistemicNodes.js +163 -33
  69. package/dist/epistemicNodes.js.map +1 -1
  70. package/dist/{epistemicQuestions-CmEeY6zQ.d.ts → epistemicQuestions-B_nUclrH.d.ts} +1 -1
  71. package/dist/epistemicQuestions.d.ts +1 -1
  72. package/dist/epistemicQuestions.js +311 -62
  73. package/dist/epistemicQuestions.js.map +1 -1
  74. package/dist/{epistemicSources-ZazxHOK1.d.ts → epistemicSources-dlKj58Jp.d.ts} +1 -1
  75. package/dist/epistemicSources.d.ts +1 -1
  76. package/dist/epistemicSources.js +65 -8
  77. package/dist/epistemicSources.js.map +1 -1
  78. package/dist/evaluators/index.js +297 -115
  79. package/dist/evaluators/index.js.map +1 -1
  80. package/dist/evaluators/lintCheckerEvaluator.js.map +1 -1
  81. package/dist/evaluators/sentryCheckerEvaluator.js.map +1 -1
  82. package/dist/evaluators/shared.js +20 -1
  83. package/dist/evaluators/shared.js.map +1 -1
  84. package/dist/evaluators/testRunnerEvaluator.js +20 -1
  85. package/dist/evaluators/testRunnerEvaluator.js.map +1 -1
  86. package/dist/evaluators/tscCheckerEvaluator.js.map +1 -1
  87. package/dist/index.d.ts +20 -20
  88. package/dist/index.js +729 -206
  89. package/dist/index.js.map +1 -1
  90. package/dist/{ontology-matching-Buhu23ss.d.ts → ontology-matching-C6rrz2VP.d.ts} +1 -1
  91. package/dist/ontology-matching.d.ts +1 -1
  92. package/dist/{ontologyApproval-Ba0Jjk1k.d.ts → ontologyApproval-CFYmqKmk.d.ts} +1 -1
  93. package/dist/ontologyApproval.d.ts +1 -1
  94. package/dist/ontologyDefinitions.js +4 -3
  95. package/dist/ontologyDefinitions.js.map +1 -1
  96. package/dist/ontologyHelpers.d.ts +1 -1
  97. package/dist/ontologyHelpers.js +4 -3
  98. package/dist/ontologyHelpers.js.map +1 -1
  99. package/dist/{projectionReconciliation-CxrXYGaB.d.ts → projectionReconciliation-jww2fBI0.d.ts} +1 -1
  100. package/dist/projectionReconciliation.d.ts +1 -1
  101. package/dist/projectionReconciliation.js +14 -20
  102. package/dist/projectionReconciliation.js.map +1 -1
  103. package/dist/{projectionStaleness-CAdpIsaW.d.ts → projectionStaleness-CmdbpjVK.d.ts} +1 -1
  104. package/dist/projectionStaleness.d.ts +1 -1
  105. package/dist/{questionEvidenceLinks-BdQD0TkM.d.ts → questionEvidenceLinks-DFlyPpAj.d.ts} +1 -1
  106. package/dist/questionEvidenceLinks.d.ts +1 -1
  107. package/dist/questionEvidenceLinks.js +144 -45
  108. package/dist/questionEvidenceLinks.js.map +1 -1
  109. package/dist/resolvers.js +86 -37
  110. package/dist/resolvers.js.map +1 -1
  111. package/dist/scopeResolverCompat.js +64 -7
  112. package/dist/scopeResolverCompat.js.map +1 -1
  113. package/dist/{text-matching-CMn2WnVD.d.ts → text-matching-DNg4M5Wd.d.ts} +1 -1
  114. package/dist/text-matching.d.ts +1 -1
  115. package/dist/topicProjectOverlay.js +56 -13
  116. package/dist/topicProjectOverlay.js.map +1 -1
  117. package/dist/topicScope.js +55 -6
  118. package/dist/topicScope.js.map +1 -1
  119. package/dist/workflowBridge.js +55 -6
  120. package/dist/workflowBridge.js.map +1 -1
  121. package/dist/workspaceIsolation.js +55 -6
  122. package/dist/workspaceIsolation.js.map +1 -1
  123. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import { v } from 'convex/values';
2
2
  import { getRescoringSchedule, normalizeTupleContradictionPolicy, mkOpinion, createInheritedContractRecord, confidenceFromSL, conditionalDeduction, project, dampedDependencyCascade, hasProjectedOpinionChanged, detectTupleContradiction, evaluateTupleContradictionTransition, readOpinionFromRecord, deriveContractModulationPlan, deriveContractStatus, trustDiscount, applyNegativeSupport, cumulativeFusion, applyNegativeEvidence, parseEvidentialEvaluatorConfig, compareMetricValue, buildEvidentialRationale, parseMetricCheckerConfig, getEvaluatorInputRecord, pickFiniteNumber, resolveComparisonResult, buildComparisonRationale, parseReferenceCheckCounterConfig, parseTemporalDeadlineConfig, parseMarketIndexComparatorConfig, computeEffectiveDecay, computeDeadlineUrgency, computeBaseDecay, bayesianUpdate, DECAY_TIERS, DEADLINE_URGENCY } from '@lucern/confidence';
3
3
  import { getAccessibleProjectIds, checkProjectAccess, requireProjectAccess, checkScopeAccess } from '@lucern/access-control/access';
4
4
  import { permissiveReturn } from '@lucern/contracts/schema-helpers/validators';
5
- import { componentsGeneric, queryGeneric, mutationGeneric, anyApi, internalMutationGeneric, internalQueryGeneric, internalActionGeneric } from 'convex/server';
5
+ import { componentsGeneric, anyApi, queryGeneric, mutationGeneric, internalMutationGeneric, internalQueryGeneric, internalActionGeneric } from 'convex/server';
6
6
  import { getCurrentUserId } from '@lucern/access-control/auth';
7
7
  import { canAudienceClassAccess, normalizeAudienceKey, classFromAudienceKey } from '@lucern/access-control/audience';
8
8
  import { listAudienceRegistryRows } from '@lucern/access-control/audienceRegistry';
@@ -40,6 +40,37 @@ var internalQuery = internalQueryGeneric;
40
40
  var mutation = mutationGeneric;
41
41
  var query = queryGeneric;
42
42
 
43
+ // src/debug.ts
44
+ function isGraphPrimitiveDebugEnabled() {
45
+ const env = globalThis.process?.env;
46
+ return env?.LUCERN_COMPAT_FALLBACK_DEBUG === "1" || env?.LUCERN_GRAPH_DEBUG === "1";
47
+ }
48
+ function formatGraphPrimitiveError(error) {
49
+ if (error instanceof Error) {
50
+ return `${error.name}: ${error.message}`;
51
+ }
52
+ if (typeof error === "string") {
53
+ return error;
54
+ }
55
+ if (error === null) {
56
+ return "null";
57
+ }
58
+ if (error === void 0) {
59
+ return "undefined";
60
+ }
61
+ try {
62
+ return JSON.stringify(error);
63
+ } catch {
64
+ return Object.prototype.toString.call(error);
65
+ }
66
+ }
67
+ function debugGraphPrimitiveFallback(message, context) {
68
+ if (!isGraphPrimitiveDebugEnabled()) {
69
+ return;
70
+ }
71
+ console.debug(message, context ?? {});
72
+ }
73
+
43
74
  // src/resolvers.ts
44
75
  var resolvers_exports = {};
45
76
  __export(resolvers_exports, {
@@ -93,19 +124,37 @@ function isProjectLikeTopic(topic) {
93
124
  return topic.type === "theme" || topic.type === "thematic" || topic.type === "deal" || topic.type === "monitoring" || readLegacyProjectId(topic) !== void 0 || readNonEmptyString(metadata.projectType) !== void 0;
94
125
  }
95
126
  function isMissingLucernChildComponentError(error) {
96
- const message = error instanceof Error ? error.message : String(error);
127
+ const message = getErrorMessage(error);
97
128
  return message.includes(
98
129
  'Child component ComponentName(Identifier("lucern")) not found'
99
130
  ) || message.includes("Child component") && message.includes("lucern") && message.includes("not found");
100
131
  }
132
+ function getErrorMessage(error) {
133
+ if (error instanceof Error) {
134
+ return error.message;
135
+ }
136
+ if (typeof error === "object" && error !== null && "message" in error && typeof error.message === "string") {
137
+ return error.message;
138
+ }
139
+ return "unknown error";
140
+ }
101
141
  async function resolveTopicDoc(ctx, scopeId) {
102
142
  if (ctx?.db && typeof ctx.db.get === "function") {
103
143
  try {
104
- const directTopic = await ctx.db.get(scopeId);
144
+ const directTopic = await ctx.db.get(
145
+ scopeId
146
+ );
105
147
  if (directTopic) {
106
148
  return directTopic;
107
149
  }
108
- } catch {
150
+ } catch (error) {
151
+ debugGraphPrimitiveFallback(
152
+ "[topicProjectOverlay] Failed to resolve topic by direct ID",
153
+ {
154
+ error,
155
+ scopeId
156
+ }
157
+ );
109
158
  }
110
159
  }
111
160
  if (typeof ctx.runQuery !== "function") {
@@ -118,7 +167,14 @@ async function resolveTopicDoc(ctx, scopeId) {
118
167
  if (topic?.name !== void 0 && topic?.type !== void 0) {
119
168
  return topic;
120
169
  }
121
- } catch {
170
+ } catch (error) {
171
+ debugGraphPrimitiveFallback(
172
+ "[topicProjectOverlay] Failed to resolve topic by ID query",
173
+ {
174
+ error,
175
+ scopeId
176
+ }
177
+ );
122
178
  }
123
179
  try {
124
180
  const topic = await ctx.runQuery(api.topics.getByLegacyScopeId, {
@@ -127,7 +183,11 @@ async function resolveTopicDoc(ctx, scopeId) {
127
183
  if (topic?.name !== void 0 && topic?.type !== void 0) {
128
184
  return topic;
129
185
  }
130
- } catch {
186
+ } catch (error) {
187
+ debugGraphPrimitiveFallback(
188
+ "[topicProjectOverlay] Failed to resolve topic by legacy scope ID",
189
+ { error, scopeId }
190
+ );
131
191
  }
132
192
  return null;
133
193
  }
@@ -181,7 +241,11 @@ async function listTopicProjectOverlays(ctx, options = {}) {
181
241
  if (ctx?.db?.query && typeof ctx.db.query === "function") {
182
242
  try {
183
243
  allTopics = await ctx.db.query("topics").collect();
184
- } catch {
244
+ } catch (error) {
245
+ debugGraphPrimitiveFallback(
246
+ "[topicProjectOverlay] Failed to read topics table; falling back to API",
247
+ { error }
248
+ );
185
249
  allTopics = [];
186
250
  }
187
251
  }
@@ -276,19 +340,28 @@ async function patchTopicProjectOverlay(ctx, scopeId, value) {
276
340
  "Cannot patch topic without component adapter (ctx.runMutation unavailable)"
277
341
  );
278
342
  }
279
- return materializeTopicProjectOverlay(
280
- {
281
- ...topic,
282
- ...patch,
283
- metadata: nextMetadata
284
- }
285
- );
343
+ return materializeTopicProjectOverlay({
344
+ ...topic,
345
+ ...patch,
346
+ metadata: nextMetadata
347
+ });
286
348
  }
287
349
 
288
350
  // src/resolvers.ts
289
351
  function isMissingLucernChildComponentError2(error) {
290
- const message = error instanceof Error ? error.message : String(error);
291
- return message.includes('Child component ComponentName(Identifier("lucern")) not found') || message.includes("Child component") && message.includes("lucern") && message.includes("not found");
352
+ const message = getErrorMessage2(error);
353
+ return message.includes(
354
+ 'Child component ComponentName(Identifier("lucern")) not found'
355
+ ) || message.includes("Child component") && message.includes("lucern") && message.includes("not found");
356
+ }
357
+ function getErrorMessage2(error) {
358
+ if (error instanceof Error) {
359
+ return error.message;
360
+ }
361
+ if (typeof error === "object" && error !== null && "message" in error && typeof error.message === "string") {
362
+ return error.message;
363
+ }
364
+ return "unknown error";
292
365
  }
293
366
  function isAdvisoryTopicPatch(value) {
294
367
  const advisoryKeys = /* @__PURE__ */ new Set(["lastActivityAt", "updatedAt"]);
@@ -302,32 +375,27 @@ async function patchProjectWithTolerance(ctx, projectId, value) {
302
375
  if (!isAdvisoryTopicPatch(value) || !isMissingLucernChildComponentError2(error)) {
303
376
  throw error;
304
377
  }
305
- console.warn("[lucern graph-primitives] Non-fatal advisory topic patch failure", {
306
- projectId,
307
- keys: Object.keys(value),
308
- error: error instanceof Error ? error.message : error
309
- });
378
+ console.warn(
379
+ "[lucern graph-primitives] Non-fatal advisory topic patch failure",
380
+ {
381
+ projectId,
382
+ keys: Object.keys(value),
383
+ error: getErrorMessage2(error)
384
+ }
385
+ );
310
386
  }
311
387
  }
312
388
  function defaultResolvers() {
313
389
  return {
314
- async getProject(ctx, projectId) {
315
- return await resolveTopicProjectOverlay(ctx, projectId, {
316
- idMode: "legacy",
317
- projectLikeOnly: false
318
- });
319
- },
320
- async patchProject(ctx, projectId, value) {
321
- await patchProjectWithTolerance(ctx, projectId, value);
322
- },
323
- async listTopics(ctx) {
324
- return await listTopicProjectOverlays(ctx, {
325
- idMode: "legacy"
326
- });
327
- },
328
- async getFinalArtifact(ctx, artifactId) {
329
- return await ctx.db.get(artifactId);
330
- }
390
+ getProject: (ctx, projectId) => resolveTopicProjectOverlay(ctx, projectId, {
391
+ idMode: "legacy",
392
+ projectLikeOnly: false
393
+ }),
394
+ patchProject: (ctx, projectId, value) => patchProjectWithTolerance(ctx, projectId, value),
395
+ listTopics: (ctx) => listTopicProjectOverlays(ctx, {
396
+ idMode: "legacy"
397
+ }),
398
+ getFinalArtifact: (ctx, artifactId) => ctx.db.get(artifactId)
331
399
  };
332
400
  }
333
401
  var resolverOverrides = {};
@@ -395,7 +463,14 @@ async function findTopicsByScopeAlias(ctx, scopeId) {
395
463
  "by_graph_scope_project",
396
464
  (q) => q.eq(LEGACY_SCOPE_FIELD2, scopeId)
397
465
  ).collect();
398
- } catch {
466
+ } catch (error) {
467
+ debugGraphPrimitiveFallback(
468
+ "[topicScope] Failed to resolve scope alias via index",
469
+ {
470
+ error,
471
+ scopeId
472
+ }
473
+ );
399
474
  const topics = await ctx.db.query("topics").collect();
400
475
  return topics.filter((topic) => {
401
476
  const normalizedGlobalId = normalizeScopeValue(topic.globalId);
@@ -412,7 +487,14 @@ async function tryResolveHostTopicById(ctx, topicId) {
412
487
  return await ctx.runQuery(api.topics.get, {
413
488
  id: topicId
414
489
  }) ?? null;
415
- } catch {
490
+ } catch (error) {
491
+ debugGraphPrimitiveFallback(
492
+ "[topicScope] Failed to resolve topic by host query",
493
+ {
494
+ error,
495
+ topicId
496
+ }
497
+ );
416
498
  return null;
417
499
  }
418
500
  }
@@ -424,7 +506,14 @@ async function tryResolveHostTopicByLegacyScope(ctx, legacyScopeId) {
424
506
  return await ctx.runQuery(api.topics.getByLegacyScopeId, {
425
507
  projectId: legacyScopeId
426
508
  }) ?? null;
427
- } catch {
509
+ } catch (error) {
510
+ debugGraphPrimitiveFallback(
511
+ "[topicScope] Failed to resolve topic by legacy scope",
512
+ {
513
+ error,
514
+ legacyScopeId
515
+ }
516
+ );
428
517
  return null;
429
518
  }
430
519
  }
@@ -461,8 +550,17 @@ async function resolveTopicProjectScope(ctx, args) {
461
550
  if (args.topicId) {
462
551
  let topic = null;
463
552
  try {
464
- topic = await ctx.db.get(args.topicId);
465
- } catch {
553
+ topic = await ctx.db.get(
554
+ args.topicId
555
+ );
556
+ } catch (error) {
557
+ debugGraphPrimitiveFallback(
558
+ "[topicScope] Failed to load topic by direct id",
559
+ {
560
+ error,
561
+ topicId: args.topicId
562
+ }
563
+ );
466
564
  }
467
565
  if (!topic) {
468
566
  topic = await tryResolveHostTopicById(ctx, String(args.topicId));
@@ -499,7 +597,14 @@ async function resolveTopicProjectScope(ctx, args) {
499
597
  directTopic = await ctx.db.get(
500
598
  args.projectId
501
599
  );
502
- } catch {
600
+ } catch (error) {
601
+ debugGraphPrimitiveFallback(
602
+ "[topicScope] Failed to load direct project topic",
603
+ {
604
+ error,
605
+ projectId: args.projectId
606
+ }
607
+ );
503
608
  }
504
609
  if (directTopic) {
505
610
  const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
@@ -567,7 +672,20 @@ var identifyBeliefsNeedingRescore = query({
567
672
  returns: permissiveReturn,
568
673
  handler: async (ctx, args) => {
569
674
  const { maxResults = 20, minPriority = "medium" } = args;
570
- const scope = await resolveTopicProjectScope(ctx, args).catch(() => null);
675
+ let scope;
676
+ try {
677
+ scope = await resolveTopicProjectScope(ctx, args);
678
+ } catch (error) {
679
+ debugGraphPrimitiveFallback(
680
+ "[beliefDecay] Failed to resolve scope for identify beliefs",
681
+ {
682
+ error,
683
+ projectId: args.projectId,
684
+ topicId: args.topicId
685
+ }
686
+ );
687
+ scope = null;
688
+ }
571
689
  if (!scope) {
572
690
  return [];
573
691
  }
@@ -670,9 +788,21 @@ var getGlobalBeliefHealth = query({
670
788
  );
671
789
  const allResults = [];
672
790
  for (const project3 of accessibleProjects.slice(0, 20)) {
673
- const scope = await resolveTopicProjectScope(ctx, {
674
- projectId: String(project3._id)
675
- }).catch(() => null);
791
+ let scope;
792
+ try {
793
+ scope = await resolveTopicProjectScope(ctx, {
794
+ projectId: String(project3._id)
795
+ });
796
+ } catch (error) {
797
+ debugGraphPrimitiveFallback(
798
+ "[beliefDecay] Failed to resolve project scope in health query",
799
+ {
800
+ error,
801
+ projectId: String(project3._id)
802
+ }
803
+ );
804
+ continue;
805
+ }
676
806
  if (!scope) {
677
807
  continue;
678
808
  }
@@ -870,7 +1000,15 @@ async function resolveScope(ctx, args) {
870
1000
  topicId,
871
1001
  projectId
872
1002
  });
873
- } catch {
1003
+ } catch (error) {
1004
+ debugGraphPrimitiveFallback(
1005
+ "[scopeResolverCompat] Failed to resolve scope",
1006
+ {
1007
+ error,
1008
+ topicId,
1009
+ projectId
1010
+ }
1011
+ );
874
1012
  return null;
875
1013
  }
876
1014
  }
@@ -2234,9 +2372,7 @@ function propagateNegativeSupportWithMetadata(sourceOpinion, targetOpinion, edge
2234
2372
  readEdgeMetadata(edge)
2235
2373
  );
2236
2374
  }
2237
- function propagateNegativeInform(sourceOpinion, targetOpinion, edgeWeight) {
2238
- return applyNegativeEvidence(sourceOpinion, targetOpinion, edgeWeight);
2239
- }
2375
+ var propagateNegativeInform = applyNegativeEvidence;
2240
2376
 
2241
2377
  // src/edges/contradicts.ts
2242
2378
  var contradictsPropagationSpec = {
@@ -3447,9 +3583,10 @@ var ONTOLOGICAL_NODE_TYPES = [
3447
3583
  "function",
3448
3584
  "value_chain"
3449
3585
  ];
3450
- function isOntologicalNodeType(nodeType) {
3451
- return ONTOLOGICAL_NODE_TYPES.includes(nodeType);
3452
- }
3586
+ var ONTOLOGICAL_NODE_TYPE_SET = new Set(ONTOLOGICAL_NODE_TYPES);
3587
+ var isOntologicalNodeType = ONTOLOGICAL_NODE_TYPE_SET.has.bind(
3588
+ ONTOLOGICAL_NODE_TYPE_SET
3589
+ );
3453
3590
  function normalizeCanonicalEntityText(value) {
3454
3591
  return value.trim().toLowerCase().replace(/\s+/g, " ");
3455
3592
  }
@@ -4419,7 +4556,15 @@ async function scheduleEmbeddingGeneration(args) {
4419
4556
  confidence: args.confidence
4420
4557
  }
4421
4558
  );
4422
- } catch {
4559
+ } catch (error) {
4560
+ debugGraphPrimitiveFallback(
4561
+ "[embeddingTrigger] Failed to schedule embedding generation",
4562
+ {
4563
+ error,
4564
+ nodeId: String(args.nodeId),
4565
+ nodeType: args.nodeType
4566
+ }
4567
+ );
4423
4568
  }
4424
4569
  }
4425
4570
 
@@ -4553,6 +4698,15 @@ function buildBeliefConfidenceRow(args) {
4553
4698
  ...args.triggeringWorktreeId ? { triggeringWorktreeId: args.triggeringWorktreeId } : {}
4554
4699
  };
4555
4700
  }
4701
+ function buildBeliefStatusSuccessResult() {
4702
+ return { success: true };
4703
+ }
4704
+ function buildBeliefEvidenceNotFoundResult() {
4705
+ const result = {};
4706
+ result.success = false;
4707
+ result.message = "Evidence node not found";
4708
+ return result;
4709
+ }
4556
4710
  function deriveSyntheticBackfillOpinion(source) {
4557
4711
  const belief = readFiniteNumber(source.opinion_b) ?? readFiniteNumber(source.belief);
4558
4712
  const disbelief = readFiniteNumber(source.opinion_d) ?? readFiniteNumber(source.disbelief);
@@ -4561,7 +4715,13 @@ function deriveSyntheticBackfillOpinion(source) {
4561
4715
  if (belief !== void 0 || disbelief !== void 0 || uncertainty !== void 0 || baseRate !== void 0) {
4562
4716
  try {
4563
4717
  return readOpinionFromRecord(source);
4564
- } catch {
4718
+ } catch (error) {
4719
+ debugGraphPrimitiveFallback(
4720
+ "[epistemicBeliefs] Failed to decode legacy belief opinion",
4721
+ {
4722
+ error
4723
+ }
4724
+ );
4565
4725
  return mkOpinion(0, 0, 1, 0.5);
4566
4726
  }
4567
4727
  }
@@ -4589,7 +4749,14 @@ function readBeliefOpinionSnapshot(node, metadata) {
4589
4749
  opinion_u: node.opinion_u,
4590
4750
  opinion_a: node.opinion_a
4591
4751
  });
4592
- } catch {
4752
+ } catch (error) {
4753
+ debugGraphPrimitiveFallback(
4754
+ "[epistemicBeliefs] Failed to read belief opinion snapshot",
4755
+ {
4756
+ error,
4757
+ beliefId: node._id
4758
+ }
4759
+ );
4593
4760
  return mkOpinion(0, 0, 1, 0.5);
4594
4761
  }
4595
4762
  }
@@ -4682,7 +4849,15 @@ async function resolveBeliefScopeOrNull(ctx, args) {
4682
4849
  projectId: args.projectId ?? void 0,
4683
4850
  topicId: args.topicId ?? void 0
4684
4851
  });
4685
- } catch {
4852
+ } catch (error) {
4853
+ debugGraphPrimitiveFallback(
4854
+ "[epistemicBeliefs] Failed to resolve belief scope",
4855
+ {
4856
+ error,
4857
+ projectId: args.projectId,
4858
+ topicId: args.topicId
4859
+ }
4860
+ );
4686
4861
  return null;
4687
4862
  }
4688
4863
  }
@@ -4782,7 +4957,13 @@ async function getActiveConfidencePolicy(ctx) {
4782
4957
  activeConfig?.tupleContradictionPolicy
4783
4958
  )
4784
4959
  };
4785
- } catch {
4960
+ } catch (error) {
4961
+ debugGraphPrimitiveFallback(
4962
+ "[epistemicBeliefs] Failed to load active confidence policy",
4963
+ {
4964
+ error
4965
+ }
4966
+ );
4786
4967
  return DEFAULT_CONFIDENCE_POLICY;
4787
4968
  }
4788
4969
  }
@@ -4819,7 +5000,11 @@ async function applyBeliefConfidenceChange(ctx, args) {
4819
5000
  details: { nodeId: args.nodeId }
4820
5001
  });
4821
5002
  }
4822
- await requireProjectWriteAccess2(ctx, node.projectId, args.authenticatedUserId);
5003
+ await requireProjectWriteAccess2(
5004
+ ctx,
5005
+ node.projectId,
5006
+ args.authenticatedUserId
5007
+ );
4823
5008
  const existingMetadata = node.metadata || {};
4824
5009
  const currentBeliefStatus = resolveBeliefStatus(node, existingMetadata);
4825
5010
  const confidencePolicy = await getActiveConfidencePolicy(ctx);
@@ -4863,29 +5048,29 @@ async function applyBeliefConfidenceChange(ctx, args) {
4863
5048
  opinion: nextOpinion,
4864
5049
  policy: tupleTransition.policy
4865
5050
  });
4866
- const newBeliefStatus = promoteBeliefStatusAfterScoring(
4867
- currentBeliefStatus,
4868
- {
4869
- confidence: derivedConfidence,
4870
- predictionMeta,
4871
- metadata: existingMetadata
4872
- }
4873
- );
5051
+ const newBeliefStatus = promoteBeliefStatusAfterScoring(currentBeliefStatus, {
5052
+ confidence: derivedConfidence,
5053
+ predictionMeta,
5054
+ metadata: existingMetadata
5055
+ });
4874
5056
  let tupleContradictionId;
4875
5057
  if (tupleTransition.crossedIntoTupleContradiction) {
4876
- tupleContradictionId = await ctx.runMutation("contradictions:create", {
4877
- projectId: node.projectId,
4878
- topicId: node.topicId,
4879
- beliefId: args.nodeId,
4880
- beliefBId: args.nodeId,
4881
- supportingInsightIds: [],
4882
- contradictingInsightIds: [],
4883
- severity: deriveTupleContradictionSeverity(node),
4884
- source: "tuple_space",
4885
- detectionMethod: "agent",
4886
- description: tupleContradictionDescription,
4887
- createdBy: args.authenticatedUserId
4888
- });
5058
+ tupleContradictionId = await ctx.runMutation(
5059
+ "contradictions:create",
5060
+ {
5061
+ projectId: node.projectId,
5062
+ topicId: node.topicId,
5063
+ beliefId: args.nodeId,
5064
+ beliefBId: args.nodeId,
5065
+ supportingInsightIds: [],
5066
+ contradictingInsightIds: [],
5067
+ severity: deriveTupleContradictionSeverity(node),
5068
+ source: "tuple_space",
5069
+ detectionMethod: "agent",
5070
+ description: tupleContradictionDescription,
5071
+ createdBy: args.authenticatedUserId
5072
+ }
5073
+ );
4889
5074
  }
4890
5075
  await ctx.db.patch(args.nodeId, {
4891
5076
  confidence: derivedConfidence,
@@ -4909,7 +5094,10 @@ async function applyBeliefConfidenceChange(ctx, args) {
4909
5094
  });
4910
5095
  if (isFirstScoring) {
4911
5096
  const nodeTopicId = node.topicId;
4912
- const themeNodes = await ctx.db.query("epistemicNodes").withIndex("by_topic", (q) => q.eq("topicId", nodeTopicId || node.projectId)).filter((q) => q.eq(q.field("nodeType"), "theme")).collect();
5097
+ const themeNodes = await ctx.db.query("epistemicNodes").withIndex(
5098
+ "by_topic",
5099
+ (q) => q.eq("topicId", nodeTopicId || node.projectId)
5100
+ ).filter((q) => q.eq(q.field("nodeType"), "theme")).collect();
4913
5101
  for (const theme of themeNodes) {
4914
5102
  if (theme.globalId && node.globalId) {
4915
5103
  await ctx.scheduler.runAfter(0, internal.neo4jEdgeAPI.createEdge, {
@@ -5507,7 +5695,15 @@ var getByProject3 = query({
5507
5695
  projectId: args.projectId,
5508
5696
  topicId: args.topicId
5509
5697
  });
5510
- } catch {
5698
+ } catch (error) {
5699
+ debugGraphPrimitiveFallback(
5700
+ "[epistemicBeliefs] Failed to resolve project scope",
5701
+ {
5702
+ error,
5703
+ projectId: args.projectId,
5704
+ topicId: args.topicId
5705
+ }
5706
+ );
5511
5707
  return [];
5512
5708
  }
5513
5709
  if (args.userId) {
@@ -5551,7 +5747,9 @@ var getByTopic = query({
5551
5747
  handler: async (ctx, args) => {
5552
5748
  const pageSize = clampBeliefLimit(args.limit);
5553
5749
  const scanLimit = Math.min(pageSize * 3, MAX_PROJECT_BELIEF_LIMIT);
5554
- const scope = await resolveTopicProjectScope(ctx, { topicId: args.topicId });
5750
+ const scope = await resolveTopicProjectScope(ctx, {
5751
+ topicId: args.topicId
5752
+ });
5555
5753
  const query2 = ctx.db.query("epistemicNodes").withIndex(
5556
5754
  "by_topic_type",
5557
5755
  (q) => q.eq("topicId", args.topicId).eq("nodeType", "belief")
@@ -5777,16 +5975,18 @@ var modulateConfidence = mutation({
5777
5975
  rationale: v.optional(v.string()),
5778
5976
  userId: v.string(),
5779
5977
  // SL operator provenance (optional — defaults to manual_assessment)
5780
- slOperator: v.optional(v.union(
5781
- v.literal("cumulative_fusion"),
5782
- v.literal("averaging_fusion"),
5783
- v.literal("trust_discount"),
5784
- v.literal("conditional_deduction"),
5785
- v.literal("dependency_cascade"),
5786
- v.literal("negation"),
5787
- v.literal("constraint_fusion"),
5788
- v.literal("manual_assessment")
5789
- )),
5978
+ slOperator: v.optional(
5979
+ v.union(
5980
+ v.literal("cumulative_fusion"),
5981
+ v.literal("averaging_fusion"),
5982
+ v.literal("trust_discount"),
5983
+ v.literal("conditional_deduction"),
5984
+ v.literal("dependency_cascade"),
5985
+ v.literal("negation"),
5986
+ v.literal("constraint_fusion"),
5987
+ v.literal("manual_assessment")
5988
+ )
5989
+ ),
5790
5990
  triggeringEvidenceId: v.optional(v.id("epistemicNodes")),
5791
5991
  triggeringWorktreeId: v.optional(v.string())
5792
5992
  },
@@ -6017,10 +6217,7 @@ var getConfidenceHistory = query({
6017
6217
  if (!node || node.nodeType !== "belief") {
6018
6218
  return [];
6019
6219
  }
6020
- return await ctx.db.query("beliefConfidence").withIndex(
6021
- "by_beliefId_time",
6022
- (q) => q.eq("beliefId", args.nodeId)
6023
- ).order("asc").collect();
6220
+ return await ctx.db.query("beliefConfidence").withIndex("by_beliefId_time", (q) => q.eq("beliefId", args.nodeId)).order("asc").collect();
6024
6221
  }
6025
6222
  });
6026
6223
  var getLineage = query({
@@ -6324,7 +6521,7 @@ var unlinkEvidence = mutation({
6324
6521
  const now = Date.now();
6325
6522
  const evidenceNode = await ctx.db.get(args.insightId);
6326
6523
  if (!evidenceNode || evidenceNode.nodeType !== "evidence") {
6327
- return { success: false, message: "Evidence node not found" };
6524
+ return buildBeliefEvidenceNotFoundResult();
6328
6525
  }
6329
6526
  if (!evidenceNode.projectId) {
6330
6527
  throw new Error("Evidence has no project scope");
@@ -6365,7 +6562,7 @@ var unlinkEvidence = mutation({
6365
6562
  projectId: evidenceNode.projectId
6366
6563
  });
6367
6564
  }
6368
- return { success: true };
6565
+ return buildBeliefStatusSuccessResult();
6369
6566
  }
6370
6567
  });
6371
6568
  var getWithEvidence = query({
@@ -6477,7 +6674,7 @@ var deleteRelationship = mutation({
6477
6674
  changedAt: now,
6478
6675
  projectId: edge.projectId
6479
6676
  });
6480
- return { success: true };
6677
+ return buildBeliefStatusSuccessResult();
6481
6678
  }
6482
6679
  });
6483
6680
  var updateCriticality = mutation({
@@ -6606,13 +6803,23 @@ var batchUpdateCriticality = mutation({
6606
6803
  changedAt: now,
6607
6804
  projectId: node.projectId
6608
6805
  });
6609
- results.push({
6610
- beliefId: update5.beliefId,
6611
- nodeId: node._id,
6612
- success: true
6613
- });
6614
- } catch {
6615
- results.push({ beliefId: update5.beliefId, success: false });
6806
+ const result = {};
6807
+ result.beliefId = update5.beliefId;
6808
+ result.nodeId = node._id;
6809
+ result.success = true;
6810
+ results.push(result);
6811
+ } catch (error) {
6812
+ debugGraphPrimitiveFallback(
6813
+ "[epistemicBeliefs] Failed to update belief criticality",
6814
+ {
6815
+ error,
6816
+ beliefId: update5.beliefId
6817
+ }
6818
+ );
6819
+ const result = {};
6820
+ result.beliefId = update5.beliefId;
6821
+ result.success = false;
6822
+ results.push(result);
6616
6823
  }
6617
6824
  }
6618
6825
  return { results, updatedCount: results.filter((r) => r.success).length };
@@ -6727,7 +6934,15 @@ var getByPillar = query({
6727
6934
  projectId: args.projectId,
6728
6935
  topicId: args.topicId
6729
6936
  });
6730
- } catch {
6937
+ } catch (error) {
6938
+ debugGraphPrimitiveFallback(
6939
+ "[epistemicBeliefs] Failed to resolve criticality scope",
6940
+ {
6941
+ error,
6942
+ projectId: args.projectId,
6943
+ topicId: args.topicId
6944
+ }
6945
+ );
6731
6946
  return [];
6732
6947
  }
6733
6948
  const nodes = await ctx.db.query("epistemicNodes").withIndex(
@@ -6848,7 +7063,9 @@ var internalGetByTopic = internalQuery({
6848
7063
  const pageSize = clampBeliefLimit(args.limit, 500);
6849
7064
  const scanLimit = Math.min(pageSize * 3, MAX_PROJECT_BELIEF_LIMIT);
6850
7065
  const audienceMode = args.audienceMode ?? "internal";
6851
- const scope = await resolveTopicProjectScope(ctx, { topicId: args.topicId });
7066
+ const scope = await resolveTopicProjectScope(ctx, {
7067
+ topicId: args.topicId
7068
+ });
6852
7069
  const registryRows = await listAudienceRegistryRows(ctx, {
6853
7070
  tenantId: scope.tenantId,
6854
7071
  workspaceId: scope.workspaceId
@@ -7193,7 +7410,9 @@ var backfillSyntheticOpinionHistory = internalMutation({
7193
7410
  skippedHasHistory++;
7194
7411
  continue;
7195
7412
  }
7196
- const opinion = deriveSyntheticBackfillOpinion(node);
7413
+ const opinion = deriveSyntheticBackfillOpinion(
7414
+ node
7415
+ );
7197
7416
  await ctx.db.insert(
7198
7417
  "beliefConfidence",
7199
7418
  buildBeliefConfidenceRow({
@@ -7499,7 +7718,13 @@ var getBeliefClusterPositions = query({
7499
7718
  return {
7500
7719
  positions: {},
7501
7720
  hasClusters: false,
7502
- counts: { raw: 0, hypothesis: 0, conditional: 0, unprocessed: 0, total: 0 }
7721
+ counts: {
7722
+ raw: 0,
7723
+ hypothesis: 0,
7724
+ conditional: 0,
7725
+ unprocessed: 0,
7726
+ total: 0
7727
+ }
7503
7728
  };
7504
7729
  }
7505
7730
  const allBeliefNodes = await getBeliefNodesForScope(ctx, scope);
@@ -7561,14 +7786,8 @@ var reassignBeliefsTopic = mutation({
7561
7786
  let connectedReassigned = 0;
7562
7787
  const alreadyReassigned = /* @__PURE__ */ new Set();
7563
7788
  for (const beliefId of movedBeliefIds) {
7564
- const outbound = await ctx.db.query("epistemicEdges").withIndex(
7565
- "by_from",
7566
- (q) => q.eq("fromNodeId", beliefId)
7567
- ).collect();
7568
- const inbound = await ctx.db.query("epistemicEdges").withIndex(
7569
- "by_to",
7570
- (q) => q.eq("toNodeId", beliefId)
7571
- ).collect();
7789
+ const outbound = await ctx.db.query("epistemicEdges").withIndex("by_from", (q) => q.eq("fromNodeId", beliefId)).collect();
7790
+ const inbound = await ctx.db.query("epistemicEdges").withIndex("by_to", (q) => q.eq("toNodeId", beliefId)).collect();
7572
7791
  const connectedNodeIds = /* @__PURE__ */ new Set();
7573
7792
  for (const edge of outbound) {
7574
7793
  if (edge.toNodeId) connectedNodeIds.add(String(edge.toNodeId));
@@ -7591,7 +7810,14 @@ var reassignBeliefsTopic = mutation({
7591
7810
  alreadyReassigned.add(connectedId);
7592
7811
  connectedReassigned++;
7593
7812
  }
7594
- } catch {
7813
+ } catch (error) {
7814
+ debugGraphPrimitiveFallback(
7815
+ "[epistemicBeliefs] Failed to reassign connected node",
7816
+ {
7817
+ error,
7818
+ connectedId
7819
+ }
7820
+ );
7595
7821
  }
7596
7822
  }
7597
7823
  }
@@ -8889,7 +9115,14 @@ function parseJsonCandidate(value) {
8889
9115
  }
8890
9116
  try {
8891
9117
  return JSON.parse(value);
8892
- } catch {
9118
+ } catch (error) {
9119
+ debugGraphPrimitiveFallback(
9120
+ "[evaluators/shared] Failed to parse JSON candidate",
9121
+ {
9122
+ error,
9123
+ valueType: typeof value
9124
+ }
9125
+ );
8893
9126
  return null;
8894
9127
  }
8895
9128
  }
@@ -10177,6 +10410,34 @@ var edgeTypeValidator = v.union(
10177
10410
  v.literal("competes_with")
10178
10411
  // Company → Company (ontological → ontological)
10179
10412
  );
10413
+ function buildEdgeStatusSuccessResult() {
10414
+ return { success: true };
10415
+ }
10416
+ function buildEdgeNotFoundResult() {
10417
+ const result = {};
10418
+ result.success = false;
10419
+ result.error = "Edge not found";
10420
+ return result;
10421
+ }
10422
+ function buildEdgeMirrorSkippedResult() {
10423
+ return {
10424
+ success: false,
10425
+ reason: "source_not_in_convex"
10426
+ };
10427
+ }
10428
+ function buildEdgeMirrorMissingResult() {
10429
+ return {
10430
+ success: false,
10431
+ reason: "not_found"
10432
+ };
10433
+ }
10434
+ function buildEdgeMirrorWriteResult(edgeId, existed) {
10435
+ return {
10436
+ success: true,
10437
+ edgeId,
10438
+ existed
10439
+ };
10440
+ }
10180
10441
  var get = query({
10181
10442
  args: { edgeId: v.id("epistemicEdges") },
10182
10443
  returns: permissiveReturn,
@@ -10328,7 +10589,15 @@ var getByProjectAndType = query({
10328
10589
  projectId: args.projectId,
10329
10590
  topicId: args.topicId
10330
10591
  });
10331
- } catch {
10592
+ } catch (error) {
10593
+ debugGraphPrimitiveFallback(
10594
+ "[epistemicEdges] Failed to resolve getAll scope",
10595
+ {
10596
+ error,
10597
+ projectId: args.projectId,
10598
+ topicId: args.topicId
10599
+ }
10600
+ );
10332
10601
  return [];
10333
10602
  }
10334
10603
  const projectEdges = await collectScopedEdges(ctx, scope, 5e3);
@@ -10354,7 +10623,15 @@ var getByProject4 = query({
10354
10623
  projectId: args.projectId,
10355
10624
  topicId: args.topicId
10356
10625
  });
10357
- } catch {
10626
+ } catch (error) {
10627
+ debugGraphPrimitiveFallback(
10628
+ "[epistemicEdges] Failed to resolve getByProject scope",
10629
+ {
10630
+ error,
10631
+ projectId: args.projectId,
10632
+ topicId: args.topicId
10633
+ }
10634
+ );
10358
10635
  return [];
10359
10636
  }
10360
10637
  if (args.userId) {
@@ -10368,7 +10645,11 @@ var getByProject4 = query({
10368
10645
  }
10369
10646
  }
10370
10647
  const pageSize = Math.max(1, Math.min(Math.floor(args.limit ?? 500), 2e3));
10371
- const edges = await collectScopedEdges(ctx, scope, Math.min(pageSize * 3, 6e3));
10648
+ const edges = await collectScopedEdges(
10649
+ ctx,
10650
+ scope,
10651
+ Math.min(pageSize * 3, 6e3)
10652
+ );
10372
10653
  return edges.filter((edge) => edgeMatchesWorkspaceReasoningScope2(edge, scope)).slice(0, pageSize);
10373
10654
  }
10374
10655
  });
@@ -10602,7 +10883,7 @@ var update2 = mutation({
10602
10883
  projectId: edge.projectId
10603
10884
  });
10604
10885
  }
10605
- return { success: true };
10886
+ return buildEdgeStatusSuccessResult();
10606
10887
  }
10607
10888
  });
10608
10889
  var remove2 = mutation({
@@ -10614,7 +10895,7 @@ var remove2 = mutation({
10614
10895
  handler: async (ctx, args) => {
10615
10896
  const edge = await ctx.db.get(args.edgeId);
10616
10897
  if (!edge) {
10617
- return { success: false, error: "Edge not found" };
10898
+ return buildEdgeNotFoundResult();
10618
10899
  }
10619
10900
  if (edge.projectId && args.userId) {
10620
10901
  await requireProjectAccess(ctx, edge.projectId, args.userId);
@@ -10649,7 +10930,7 @@ var remove2 = mutation({
10649
10930
  globalId: edge.globalId
10650
10931
  });
10651
10932
  await ctx.db.delete(args.edgeId);
10652
- return { success: true };
10933
+ return buildEdgeStatusSuccessResult();
10653
10934
  }
10654
10935
  });
10655
10936
  var removeBetween = mutation({
@@ -10809,9 +11090,7 @@ var getLineage2 = query({
10809
11090
  }
10810
11091
  visited.add(nodeIdStr);
10811
11092
  const edges = await ctx.db.query("epistemicEdges").withIndex("by_from", (q) => q.eq("fromNodeId", current.nodeId)).collect();
10812
- const lineageEdges = edges.filter(
10813
- (e) => e.edgeType === "derived_from"
10814
- );
11093
+ const lineageEdges = edges.filter((e) => e.edgeType === "derived_from");
10815
11094
  for (const edge of lineageEdges) {
10816
11095
  if (!edge.toNodeId) {
10817
11096
  continue;
@@ -11012,13 +11291,13 @@ var mirrorEdgeToConvex = internalMutation({
11012
11291
  console.log(
11013
11292
  `[Dual-Write] Skipping mirror - source node not in Convex: ${args.fromGlobalId}`
11014
11293
  );
11015
- return { success: false, reason: "source_not_in_convex" };
11294
+ return buildEdgeMirrorSkippedResult();
11016
11295
  }
11017
11296
  const toNode = await ctx.db.query("epistemicNodes").withIndex("by_globalId", (q) => q.eq("globalId", args.toGlobalId)).first();
11018
11297
  const existing = await ctx.db.query("epistemicEdges").withIndex("by_globalId", (q) => q.eq("globalId", args.globalId)).first();
11019
11298
  if (existing) {
11020
11299
  console.log(`[Dual-Write] Edge already exists: ${args.globalId}`);
11021
- return { success: true, edgeId: existing._id, existed: true };
11300
+ return buildEdgeMirrorWriteResult(existing._id, true);
11022
11301
  }
11023
11302
  const now = Date.now();
11024
11303
  const edgeId = await ctx.db.insert("epistemicEdges", {
@@ -11059,7 +11338,7 @@ var mirrorEdgeToConvex = internalMutation({
11059
11338
  console.log(
11060
11339
  `[Dual-Write] Mirrored edge to Convex: ${args.globalId} (${args.edgeType})`
11061
11340
  );
11062
- return { success: true, edgeId, existed: false };
11341
+ return buildEdgeMirrorWriteResult(edgeId, false);
11063
11342
  }
11064
11343
  });
11065
11344
  var deleteEdgeFromConvex = internalMutation({
@@ -11070,11 +11349,11 @@ var deleteEdgeFromConvex = internalMutation({
11070
11349
  handler: async (ctx, args) => {
11071
11350
  const existing = await ctx.db.query("epistemicEdges").withIndex("by_globalId", (q) => q.eq("globalId", args.globalId)).first();
11072
11351
  if (!existing) {
11073
- return { success: false, reason: "not_found" };
11352
+ return buildEdgeMirrorMissingResult();
11074
11353
  }
11075
11354
  await ctx.db.delete(existing._id);
11076
11355
  console.log(`[Dual-Write] Deleted edge from Convex: ${args.globalId}`);
11077
- return { success: true };
11356
+ return buildEdgeStatusSuccessResult();
11078
11357
  }
11079
11358
  });
11080
11359
  var updateEdgeInConvex = internalMutation({
@@ -11095,7 +11374,7 @@ var updateEdgeInConvex = internalMutation({
11095
11374
  handler: async (ctx, args) => {
11096
11375
  const existing = await ctx.db.query("epistemicEdges").withIndex("by_globalId", (q) => q.eq("globalId", args.globalId)).first();
11097
11376
  if (!existing) {
11098
- return { success: false, reason: "not_found" };
11377
+ return buildEdgeMirrorMissingResult();
11099
11378
  }
11100
11379
  const updates = {
11101
11380
  updatedAt: Date.now()
@@ -11132,7 +11411,7 @@ var updateEdgeInConvex = internalMutation({
11132
11411
  }
11133
11412
  await ctx.db.patch(existing._id, updates);
11134
11413
  console.log(`[Dual-Write] Updated edge in Convex: ${args.globalId}`);
11135
- return { success: true };
11414
+ return buildEdgeStatusSuccessResult();
11136
11415
  }
11137
11416
  });
11138
11417
 
@@ -11265,7 +11544,15 @@ async function resolveEvidenceScopeOrNull(ctx, args) {
11265
11544
  projectId: args.projectId ?? void 0,
11266
11545
  topicId: args.topicId ?? void 0
11267
11546
  });
11268
- } catch {
11547
+ } catch (error) {
11548
+ debugGraphPrimitiveFallback(
11549
+ "[epistemicEvidence] Failed to resolve evidence scope",
11550
+ {
11551
+ error,
11552
+ projectId: args.projectId,
11553
+ topicId: args.topicId
11554
+ }
11555
+ );
11269
11556
  return null;
11270
11557
  }
11271
11558
  }
@@ -11641,7 +11928,15 @@ var getByProject5 = query({
11641
11928
  projectId: args.projectId,
11642
11929
  topicId: args.topicId
11643
11930
  });
11644
- } catch {
11931
+ } catch (error) {
11932
+ debugGraphPrimitiveFallback(
11933
+ "[epistemicEvidence] Failed to resolve getByProject scope",
11934
+ {
11935
+ error,
11936
+ projectId: args.projectId,
11937
+ topicId: args.topicId
11938
+ }
11939
+ );
11645
11940
  return [];
11646
11941
  }
11647
11942
  if (args.userId) {
@@ -11676,7 +11971,9 @@ var getByTopic3 = query({
11676
11971
  handler: async (ctx, args) => {
11677
11972
  const pageSize = clampEvidenceLimit(args.limit);
11678
11973
  const scanLimit = Math.min(pageSize * 3, MAX_EVIDENCE_PAGE_SIZE);
11679
- const scope = await resolveTopicProjectScope(ctx, { topicId: args.topicId });
11974
+ const scope = await resolveTopicProjectScope(ctx, {
11975
+ topicId: args.topicId
11976
+ });
11680
11977
  const topicNodes = await ctx.db.query("epistemicNodes").withIndex(
11681
11978
  "by_topic_type",
11682
11979
  (q) => q.eq("topicId", scope.topicId).eq("nodeType", "evidence")
@@ -11786,7 +12083,9 @@ var internalGetByTopic2 = internalQuery({
11786
12083
  const pageSize = clampEvidenceLimit(args.limit, 500);
11787
12084
  const scanLimit = Math.min(pageSize * 3, MAX_EVIDENCE_PAGE_SIZE);
11788
12085
  const audienceMode = args.audienceMode ?? "internal";
11789
- const scope = await resolveTopicProjectScope(ctx, { topicId: args.topicId });
12086
+ const scope = await resolveTopicProjectScope(ctx, {
12087
+ topicId: args.topicId
12088
+ });
11790
12089
  const registryRows = await listAudienceRegistryRows(ctx, {
11791
12090
  tenantId: scope.tenantId,
11792
12091
  workspaceId: scope.workspaceId
@@ -13862,7 +14161,15 @@ var getByProjectAndType2 = query({
13862
14161
  projectId: args.projectId,
13863
14162
  topicId: args.topicId
13864
14163
  });
13865
- } catch {
14164
+ } catch (error) {
14165
+ debugGraphPrimitiveFallback(
14166
+ "[epistemicNodes] Failed to resolve getByProjectAndType scope",
14167
+ {
14168
+ error,
14169
+ projectId: args.projectId,
14170
+ topicId: args.topicId
14171
+ }
14172
+ );
13866
14173
  return [];
13867
14174
  }
13868
14175
  const pageSize = clampNodeLimit(args.limit);
@@ -13899,7 +14206,15 @@ var getByProjectAndTypeLite = query({
13899
14206
  projectId: args.projectId,
13900
14207
  topicId: args.topicId
13901
14208
  });
13902
- } catch {
14209
+ } catch (error) {
14210
+ debugGraphPrimitiveFallback(
14211
+ "[epistemicNodes] Failed to resolve getByNodeType scope",
14212
+ {
14213
+ error,
14214
+ projectId: args.projectId,
14215
+ topicId: args.topicId
14216
+ }
14217
+ );
13903
14218
  return [];
13904
14219
  }
13905
14220
  const pageSize = clampNodeLimit(args.limit);
@@ -13931,6 +14246,27 @@ function clampNodeLimit(limit, fallback = DEFAULT_NODE_PAGE_SIZE) {
13931
14246
  }
13932
14247
  return Math.max(1, Math.min(Math.floor(limit), MAX_NODE_PAGE_SIZE));
13933
14248
  }
14249
+ function buildNodeStatusSuccessResult() {
14250
+ return { success: true };
14251
+ }
14252
+ function buildNodeArchivedResult() {
14253
+ return {
14254
+ success: true,
14255
+ effectiveStatus: "archived"
14256
+ };
14257
+ }
14258
+ function buildNodeNotFoundResult() {
14259
+ const result = {};
14260
+ result.success = false;
14261
+ result.error = "Node not found";
14262
+ return result;
14263
+ }
14264
+ function buildNodeDeletedResult(deletedEdgeCount) {
14265
+ return {
14266
+ success: true,
14267
+ deletedEdgeCount
14268
+ };
14269
+ }
13934
14270
  function dedupeWorkspaceNodes(nodes) {
13935
14271
  const seen = /* @__PURE__ */ new Set();
13936
14272
  const deduped = [];
@@ -13962,14 +14298,13 @@ async function collectScopedNodes(ctx, scope, args) {
13962
14298
  args.nodeType ? ctx.db.query("epistemicNodes").withIndex(
13963
14299
  "by_topic_type",
13964
14300
  (q) => q.eq("topicId", scope.projectId).eq("nodeType", args.nodeType)
13965
- ).order("desc").take(args.scanLimit) : ctx.db.query("epistemicNodes").withIndex(
13966
- "by_topic",
13967
- (q) => q.eq("topicId", scope.projectId)
13968
- ).order("desc").take(args.scanLimit)
14301
+ ).order("desc").take(args.scanLimit) : ctx.db.query("epistemicNodes").withIndex("by_topic", (q) => q.eq("topicId", scope.projectId)).order("desc").take(args.scanLimit)
13969
14302
  );
13970
14303
  }
13971
14304
  const combined = dedupeWorkspaceNodes((await Promise.all(queries)).flat());
13972
- return combined.filter((node) => nodeMatchesWorkspaceReasoningScope2(node, scope));
14305
+ return combined.filter(
14306
+ (node) => nodeMatchesWorkspaceReasoningScope2(node, scope)
14307
+ );
13973
14308
  }
13974
14309
  var getByProject6 = query({
13975
14310
  args: {
@@ -13991,7 +14326,15 @@ var getByProject6 = query({
13991
14326
  projectId: args.projectId,
13992
14327
  topicId: args.topicId
13993
14328
  });
13994
- } catch {
14329
+ } catch (error) {
14330
+ debugGraphPrimitiveFallback(
14331
+ "[epistemicNodes] Failed to resolve list scope",
14332
+ {
14333
+ error,
14334
+ projectId: args.projectId,
14335
+ topicId: args.topicId
14336
+ }
14337
+ );
13995
14338
  return [];
13996
14339
  }
13997
14340
  if (args.userId) {
@@ -14045,7 +14388,15 @@ var search = query({
14045
14388
  projectId: args.projectId,
14046
14389
  topicId: args.topicId
14047
14390
  });
14048
- } catch {
14391
+ } catch (error) {
14392
+ debugGraphPrimitiveFallback(
14393
+ "[epistemicNodes] Failed to resolve search scope",
14394
+ {
14395
+ error,
14396
+ projectId: args.projectId,
14397
+ topicId: args.topicId
14398
+ }
14399
+ );
14049
14400
  return [];
14050
14401
  }
14051
14402
  }
@@ -14272,7 +14623,7 @@ var update4 = mutation({
14272
14623
  nodeId,
14273
14624
  operation: "upsert"
14274
14625
  });
14275
- return { success: true };
14626
+ return buildNodeStatusSuccessResult();
14276
14627
  }
14277
14628
  });
14278
14629
  var supersede = mutation({
@@ -14394,7 +14745,7 @@ var archive2 = mutation({
14394
14745
  projectId: node.projectId
14395
14746
  });
14396
14747
  }
14397
- return { success: true, effectiveStatus: "archived" };
14748
+ return buildNodeArchivedResult();
14398
14749
  }
14399
14750
  });
14400
14751
  var hardDelete = internalMutation({
@@ -14408,7 +14759,7 @@ var hardDelete = internalMutation({
14408
14759
  handler: async (ctx, args) => {
14409
14760
  const node = await ctx.db.get(args.nodeId);
14410
14761
  if (!node) {
14411
- return { success: false, error: "Node not found" };
14762
+ return buildNodeNotFoundResult();
14412
14763
  }
14413
14764
  assertBeliefNodeHardDeleteAllowed({
14414
14765
  node,
@@ -14444,10 +14795,7 @@ var hardDelete = internalMutation({
14444
14795
  await ctx.db.delete(edge._id);
14445
14796
  }
14446
14797
  await ctx.db.delete(args.nodeId);
14447
- return {
14448
- success: true,
14449
- deletedEdgeCount: uniqueEdges.size
14450
- };
14798
+ return buildNodeDeletedResult(uniqueEdges.size);
14451
14799
  }
14452
14800
  });
14453
14801
  var verify = mutation({
@@ -14494,7 +14842,7 @@ var verify = mutation({
14494
14842
  projectId: node.projectId,
14495
14843
  triggeringAction: "epistemicNodes.verify"
14496
14844
  });
14497
- return { success: true };
14845
+ return buildNodeStatusSuccessResult();
14498
14846
  }
14499
14847
  });
14500
14848
  var batchCreate2 = mutation({
@@ -14532,6 +14880,27 @@ var batchCreate2 = mutation({
14532
14880
  },
14533
14881
  returns: permissiveReturn,
14534
14882
  handler: async (ctx, args) => {
14883
+ const resolveNodeScope = async (node) => {
14884
+ if (!(node.topicId || node.projectId)) {
14885
+ return void 0;
14886
+ }
14887
+ try {
14888
+ return await resolveTopicProjectScope(ctx, {
14889
+ topicId: node.topicId,
14890
+ projectId: node.projectId
14891
+ });
14892
+ } catch (error) {
14893
+ debugGraphPrimitiveFallback(
14894
+ "[epistemicNodes] Failed to resolve scope for batch create node",
14895
+ {
14896
+ error,
14897
+ topicId: node.topicId,
14898
+ projectId: node.projectId
14899
+ }
14900
+ );
14901
+ return void 0;
14902
+ }
14903
+ };
14535
14904
  const now = Date.now();
14536
14905
  const results = [];
14537
14906
  for (const node of args.nodes) {
@@ -14540,10 +14909,7 @@ var batchCreate2 = mutation({
14540
14909
  mutationName: "epistemicNodes.batchCreate"
14541
14910
  });
14542
14911
  const epistemicLayer = getNodeLayer(node.nodeType);
14543
- const resolvedScope = node.topicId || node.projectId ? await resolveTopicProjectScope(ctx, {
14544
- topicId: node.topicId,
14545
- projectId: node.projectId
14546
- }).catch(() => void 0) : void 0;
14912
+ const resolvedScope = await resolveNodeScope(node);
14547
14913
  const nodeId = await ctx.db.insert("epistemicNodes", {
14548
14914
  ...node,
14549
14915
  epistemicLayer,
@@ -14625,10 +14991,24 @@ var createInternal2 = internalMutation({
14625
14991
  returns: permissiveReturn,
14626
14992
  handler: async (ctx, args) => {
14627
14993
  const now = Date.now();
14628
- const resolvedScope = args.topicId || args.projectId ? await resolveTopicProjectScope(ctx, {
14629
- topicId: args.topicId,
14630
- projectId: args.projectId
14631
- }).catch(() => void 0) : void 0;
14994
+ const resolvedScope = args.topicId || args.projectId ? await (async () => {
14995
+ try {
14996
+ return await resolveTopicProjectScope(ctx, {
14997
+ topicId: args.topicId,
14998
+ projectId: args.projectId
14999
+ });
15000
+ } catch (error) {
15001
+ debugGraphPrimitiveFallback(
15002
+ "[epistemicNodes] Failed to resolve create scope",
15003
+ {
15004
+ error,
15005
+ topicId: args.topicId,
15006
+ projectId: args.projectId
15007
+ }
15008
+ );
15009
+ return void 0;
15010
+ }
15011
+ })() : void 0;
14632
15012
  const contentHash = args.contentHash || `${args.nodeType}:${args.canonicalText}`.slice(0, 64);
14633
15013
  const epistemicLayer = args.epistemicLayer || getNodeLayer(args.nodeType);
14634
15014
  const nodeId = await ctx.db.insert("epistemicNodes", {
@@ -14695,7 +15075,7 @@ var updateSyncStatus = internalMutation({
14695
15075
  updates.syncError = args.syncError;
14696
15076
  }
14697
15077
  await ctx.db.patch(args.nodeId, updates);
14698
- return { success: true };
15078
+ return buildNodeStatusSuccessResult();
14699
15079
  }
14700
15080
  });
14701
15081
  var backfillTopicId = internalMutation({
@@ -14967,6 +15347,12 @@ function normalizeQuestionTopicId(topicId) {
14967
15347
  function resolveQuestionScopeId(scope) {
14968
15348
  return normalizeQuestionTopicId(scope.topicId) ?? scope.projectId ?? void 0;
14969
15349
  }
15350
+ function logQuestionFallback(message, error, context) {
15351
+ debugGraphPrimitiveFallback(message, {
15352
+ error: formatGraphPrimitiveError(error),
15353
+ ...context ?? {}
15354
+ });
15355
+ }
14970
15356
  async function resolveQuestionScopeOrNull(ctx, args) {
14971
15357
  if (!args.projectId && !args.topicId) {
14972
15358
  return null;
@@ -14976,7 +15362,15 @@ async function resolveQuestionScopeOrNull(ctx, args) {
14976
15362
  projectId: args.projectId ?? void 0,
14977
15363
  topicId: args.topicId ?? void 0
14978
15364
  });
14979
- } catch {
15365
+ } catch (error) {
15366
+ debugGraphPrimitiveFallback(
15367
+ "[epistemicQuestions] Failed to resolve question scope",
15368
+ {
15369
+ error: formatGraphPrimitiveError(error),
15370
+ projectId: args.projectId,
15371
+ topicId: args.topicId
15372
+ }
15373
+ );
14980
15374
  return null;
14981
15375
  }
14982
15376
  }
@@ -15180,9 +15574,7 @@ var create8 = mutation({
15180
15574
  source: args.source || "ai_suggested",
15181
15575
  questionStatus: "open",
15182
15576
  linkedBeliefNodeId: args.linkedBeliefNodeId,
15183
- ...buildLinkedWorktreeMetadata(
15184
- args.linkedWorktreeId
15185
- ),
15577
+ ...buildLinkedWorktreeMetadata(args.linkedWorktreeId),
15186
15578
  testType: args.testType,
15187
15579
  importance: args.importance,
15188
15580
  epistemicUnlock: args.epistemicUnlock,
@@ -15593,7 +15985,9 @@ var getByTopic5 = query({
15593
15985
  handler: async (ctx, args) => {
15594
15986
  const pageSize = clampQuestionLimit(args.limit);
15595
15987
  const scanLimit = Math.min(pageSize * 3, MAX_QUESTION_PAGE_SIZE);
15596
- const scope = await resolveTopicProjectScope(ctx, { topicId: args.topicId });
15988
+ const scope = await resolveTopicProjectScope(ctx, {
15989
+ topicId: args.topicId
15990
+ });
15597
15991
  const scopedNodes = await getQuestionNodesForScope(ctx, scope, {
15598
15992
  scanLimit
15599
15993
  });
@@ -15617,7 +16011,7 @@ var getByCategory = query({
15617
16011
  const nodes = await getQuestionNodesForScope(ctx, scope);
15618
16012
  return nodes.filter((n) => {
15619
16013
  const metadata = n.metadata || {};
15620
- return questionMatchesScope(n, scope) && (isActiveQuestionNode(n) && metadata.category === normalizeCategory(args.category));
16014
+ return questionMatchesScope(n, scope) && isActiveQuestionNode(n) && metadata.category === normalizeCategory(args.category);
15621
16015
  });
15622
16016
  }
15623
16017
  });
@@ -15713,7 +16107,9 @@ var internalGetByTopic3 = internalQuery({
15713
16107
  const pageSize = clampQuestionLimit(args.limit, 500);
15714
16108
  const scanLimit = Math.min(pageSize * 3, MAX_QUESTION_PAGE_SIZE);
15715
16109
  const audienceMode = args.audienceMode ?? "internal";
15716
- const scope = await resolveTopicProjectScope(ctx, { topicId: args.topicId });
16110
+ const scope = await resolveTopicProjectScope(ctx, {
16111
+ topicId: args.topicId
16112
+ });
15717
16113
  const registryRows = await listAudienceRegistryRows(ctx, {
15718
16114
  tenantId: scope.tenantId,
15719
16115
  workspaceId: scope.workspaceId
@@ -16043,7 +16439,14 @@ A: ${args.answerText}`;
16043
16439
  if (node?.nodeType === "belief") {
16044
16440
  return node;
16045
16441
  }
16046
- } catch {
16442
+ } catch (error) {
16443
+ debugGraphPrimitiveFallback(
16444
+ "[epistemicQuestions] Failed to resolve belief node",
16445
+ {
16446
+ error: formatGraphPrimitiveError(error),
16447
+ beliefId: bId
16448
+ }
16449
+ );
16047
16450
  return null;
16048
16451
  }
16049
16452
  return null;
@@ -16449,7 +16852,14 @@ var getInConviction = query({
16449
16852
  exclusiveWithCount: 0
16450
16853
  };
16451
16854
  }
16452
- } catch {
16855
+ } catch (error) {
16856
+ debugGraphPrimitiveFallback(
16857
+ "[epistemicQuestions] Failed to hydrate linked belief",
16858
+ {
16859
+ error: formatGraphPrimitiveError(error),
16860
+ beliefId
16861
+ }
16862
+ );
16453
16863
  }
16454
16864
  return null;
16455
16865
  })
@@ -16547,6 +16957,14 @@ var advanceToConviction = mutation({
16547
16957
  triggeringAction: "question_advanced_to_conviction"
16548
16958
  });
16549
16959
  } catch (e) {
16960
+ logQuestionFallback(
16961
+ "[epistemicQuestions] Failed to log advanceToConviction audit",
16962
+ e,
16963
+ {
16964
+ questionId: args.questionId,
16965
+ projectId: node.projectId
16966
+ }
16967
+ );
16550
16968
  console.error("[EpistemicAudit] Failed to log advanceToConviction:", e);
16551
16969
  }
16552
16970
  await markProjectGraphDirty3(ctx, node.projectId, node.topicId);
@@ -16673,6 +17091,14 @@ var finalizeConviction = mutation({
16673
17091
  triggeringAction: "question_conviction_finalized"
16674
17092
  });
16675
17093
  } catch (e) {
17094
+ logQuestionFallback(
17095
+ "[epistemicQuestions] Failed to log finalizeConviction audit",
17096
+ e,
17097
+ {
17098
+ questionId: args.questionId,
17099
+ projectId: node.projectId
17100
+ }
17101
+ );
16676
17102
  console.error("[EpistemicAudit] Failed to log finalizeConviction:", e);
16677
17103
  }
16678
17104
  if (node.projectId || node.topicId) {
@@ -16696,6 +17122,15 @@ var finalizeConviction = mutation({
16696
17122
  }
16697
17123
  );
16698
17124
  } catch (e) {
17125
+ logQuestionFallback(
17126
+ "[epistemicQuestions] Failed to schedule evidence creation from scored question",
17127
+ e,
17128
+ {
17129
+ questionId: args.questionId,
17130
+ beliefId,
17131
+ projectId: node.projectId
17132
+ }
17133
+ );
16699
17134
  console.error(
16700
17135
  "[finalizeConviction] Failed to schedule evidence creation:",
16701
17136
  e
@@ -16725,10 +17160,24 @@ var getByBeliefWithAccess = query({
16725
17160
  let beliefNode = null;
16726
17161
  try {
16727
17162
  beliefNode = await ctx.db.get(args.beliefId);
16728
- } catch {
17163
+ } catch (error) {
17164
+ debugGraphPrimitiveFallback(
17165
+ "[epistemicQuestions] Failed to resolve belief node directly",
17166
+ {
17167
+ error: formatGraphPrimitiveError(error),
17168
+ beliefId: args.beliefId
17169
+ }
17170
+ );
16729
17171
  try {
16730
17172
  beliefNode = await ctx.db.get(args.beliefId);
16731
- } catch {
17173
+ } catch (legacyError) {
17174
+ debugGraphPrimitiveFallback(
17175
+ "[epistemicQuestions] Failed to resolve legacy belief node",
17176
+ {
17177
+ error: formatGraphPrimitiveError(legacyError),
17178
+ beliefId: args.beliefId
17179
+ }
17180
+ );
16732
17181
  return [];
16733
17182
  }
16734
17183
  }
@@ -16872,10 +17321,24 @@ var linkToBelief = mutation({
16872
17321
  let beliefNode = null;
16873
17322
  try {
16874
17323
  beliefNode = await ctx.db.get(args.beliefId);
16875
- } catch {
17324
+ } catch (error) {
17325
+ debugGraphPrimitiveFallback(
17326
+ "[epistemicQuestions] Failed to resolve belief node directly",
17327
+ {
17328
+ error: formatGraphPrimitiveError(error),
17329
+ beliefId: args.beliefId
17330
+ }
17331
+ );
16876
17332
  try {
16877
17333
  beliefNode = await ctx.db.get(args.beliefId);
16878
- } catch {
17334
+ } catch (legacyError) {
17335
+ debugGraphPrimitiveFallback(
17336
+ "[epistemicQuestions] Failed to resolve legacy belief node",
17337
+ {
17338
+ error: formatGraphPrimitiveError(legacyError),
17339
+ beliefId: args.beliefId
17340
+ }
17341
+ );
16879
17342
  throw new Error("Belief not found");
16880
17343
  }
16881
17344
  }
@@ -16936,6 +17399,14 @@ var linkToBelief = mutation({
16936
17399
  });
16937
17400
  }
16938
17401
  } catch (e) {
17402
+ logQuestionFallback(
17403
+ "[epistemicQuestions] Failed to create tests edge",
17404
+ e,
17405
+ {
17406
+ questionId: args.questionId,
17407
+ beliefId: args.beliefId
17408
+ }
17409
+ );
16939
17410
  console.error("[linkToBelief] Failed to create tests edge:", e);
16940
17411
  }
16941
17412
  await markProjectGraphDirty3(
@@ -17074,6 +17545,14 @@ var unlinkInsight = mutation({
17074
17545
  }
17075
17546
  }
17076
17547
  } catch (e) {
17548
+ logQuestionFallback(
17549
+ "[epistemicQuestions] Failed to remove questionEvidenceLink",
17550
+ e,
17551
+ {
17552
+ questionId: args.questionId,
17553
+ insightId: args.insightId
17554
+ }
17555
+ );
17077
17556
  console.error(
17078
17557
  "[unlinkInsight] Failed to remove questionEvidenceLink:",
17079
17558
  e
@@ -17096,6 +17575,14 @@ var unlinkInsight = mutation({
17096
17575
  }
17097
17576
  }
17098
17577
  } catch (e) {
17578
+ logQuestionFallback(
17579
+ "[epistemicQuestions] Failed to remove derived edge",
17580
+ e,
17581
+ {
17582
+ questionId: args.questionId,
17583
+ insightId: args.insightId
17584
+ }
17585
+ );
17099
17586
  console.error("[unlinkInsight] Failed to remove edge:", e);
17100
17587
  }
17101
17588
  await markProjectGraphDirty3(
@@ -17266,7 +17753,14 @@ var consolidate = mutation({
17266
17753
  args.questionIds.map(async (qid) => {
17267
17754
  try {
17268
17755
  return await ctx.db.get(qid);
17269
- } catch {
17756
+ } catch (error) {
17757
+ debugGraphPrimitiveFallback(
17758
+ "[epistemicQuestions] Failed to load original question",
17759
+ {
17760
+ error: formatGraphPrimitiveError(error),
17761
+ questionId: qid
17762
+ }
17763
+ );
17270
17764
  return null;
17271
17765
  }
17272
17766
  })
@@ -17327,7 +17821,14 @@ var consolidate = mutation({
17327
17821
  const bMeta = belief.metadata || {};
17328
17822
  category = bMeta.category || bMeta.pillar || "other";
17329
17823
  }
17330
- } catch {
17824
+ } catch (error) {
17825
+ debugGraphPrimitiveFallback(
17826
+ "[epistemicQuestions] Failed to read first linked belief metadata",
17827
+ {
17828
+ error: formatGraphPrimitiveError(error),
17829
+ beliefId: firstBeliefId
17830
+ }
17831
+ );
17331
17832
  }
17332
17833
  }
17333
17834
  const now = Date.now();
@@ -17377,7 +17878,14 @@ var consolidate = mutation({
17377
17878
  }
17378
17879
  });
17379
17880
  }
17380
- } catch {
17881
+ } catch (error) {
17882
+ debugGraphPrimitiveFallback(
17883
+ "[epistemicQuestions] Failed to archive linked question",
17884
+ {
17885
+ error: formatGraphPrimitiveError(error),
17886
+ questionId: qid
17887
+ }
17888
+ );
17381
17889
  }
17382
17890
  }
17383
17891
  await ctx.scheduler.runAfter(0, internal.neo4jSync.syncNodeToNeo4j, {
@@ -17509,7 +18017,15 @@ var getQuestionClusterPositions = query({
17509
18017
  projectId: args.projectId,
17510
18018
  topicId: args.topicId
17511
18019
  });
17512
- } catch {
18020
+ } catch (error) {
18021
+ debugGraphPrimitiveFallback(
18022
+ "[epistemicQuestions] Failed to resolve question cluster scope",
18023
+ {
18024
+ error: formatGraphPrimitiveError(error),
18025
+ projectId: args.projectId,
18026
+ topicId: args.topicId
18027
+ }
18028
+ );
17513
18029
  return {
17514
18030
  positions: {},
17515
18031
  counts: {
@@ -18345,9 +18861,6 @@ function shouldFailClosedForProjection(envelope) {
18345
18861
  }
18346
18862
 
18347
18863
  // src/projectionReconciliation.ts
18348
- async function collectQueueByStatus(ctx, status) {
18349
- return await ctx.db.query("neo4jSyncQueue").withIndex("by_status", (q) => q.eq("status", status)).collect();
18350
- }
18351
18864
  function maxTimestamp(rows, field) {
18352
18865
  let maxValue;
18353
18866
  for (const row of rows) {
@@ -18376,10 +18889,10 @@ function minTimestamp(rows, field) {
18376
18889
  }
18377
18890
  async function getQueueSnapshot(ctx) {
18378
18891
  const [pendingRows, inProgressRows, failedRows, succeededRows] = await Promise.all([
18379
- collectQueueByStatus(ctx, "pending"),
18380
- collectQueueByStatus(ctx, "in_progress"),
18381
- collectQueueByStatus(ctx, "failed"),
18382
- collectQueueByStatus(ctx, "succeeded")
18892
+ ctx.db.query("neo4jSyncQueue").withIndex("by_status", (q) => q.eq("status", "pending")).collect(),
18893
+ ctx.db.query("neo4jSyncQueue").withIndex("by_status", (q) => q.eq("status", "in_progress")).collect(),
18894
+ ctx.db.query("neo4jSyncQueue").withIndex("by_status", (q) => q.eq("status", "failed")).collect(),
18895
+ ctx.db.query("neo4jSyncQueue").withIndex("by_status", (q) => q.eq("status", "succeeded")).collect()
18383
18896
  ]);
18384
18897
  const now = Date.now();
18385
18898
  const backlogOldestCreatedAt = minTimestamp(
@@ -18439,6 +18952,13 @@ function buildEndpointAssessments(snapshot) {
18439
18952
  nonGraph
18440
18953
  };
18441
18954
  }
18955
+ function buildProjectionReconciliationStatus(snapshot) {
18956
+ return {
18957
+ ...snapshot,
18958
+ endpointAssessments: buildEndpointAssessments(snapshot),
18959
+ generatedAt: snapshot.now
18960
+ };
18961
+ }
18442
18962
  function assertAuthenticated(clerkId) {
18443
18963
  if (!clerkId) {
18444
18964
  throw new Error("Authentication required");
@@ -18450,12 +18970,7 @@ var getProjectionReconciliationStatusInternal = internalQuery({
18450
18970
  returns: permissiveReturn,
18451
18971
  handler: async (ctx) => {
18452
18972
  const snapshot = await getQueueSnapshot(ctx);
18453
- const assessments = buildEndpointAssessments(snapshot);
18454
- return {
18455
- ...snapshot,
18456
- endpointAssessments: assessments,
18457
- generatedAt: snapshot.now
18458
- };
18973
+ return buildProjectionReconciliationStatus(snapshot);
18459
18974
  }
18460
18975
  });
18461
18976
  var getProjectionReconciliationStatus = query({
@@ -18464,12 +18979,7 @@ var getProjectionReconciliationStatus = query({
18464
18979
  handler: async (ctx) => {
18465
18980
  assertAuthenticated(await getCurrentUserId(ctx));
18466
18981
  const snapshot = await getQueueSnapshot(ctx);
18467
- const assessments = buildEndpointAssessments(snapshot);
18468
- return {
18469
- ...snapshot,
18470
- endpointAssessments: assessments,
18471
- generatedAt: snapshot.now
18472
- };
18982
+ return buildProjectionReconciliationStatus(snapshot);
18473
18983
  }
18474
18984
  });
18475
18985
  var assessProjectionStaleness = query({
@@ -19038,7 +19548,20 @@ var getByProject8 = query({
19038
19548
  if (!hasAccess) {
19039
19549
  return [];
19040
19550
  }
19041
- const scope = await resolveTopicProjectScope(ctx, args).catch(() => null);
19551
+ let scope;
19552
+ try {
19553
+ scope = await resolveTopicProjectScope(ctx, args);
19554
+ } catch (error) {
19555
+ debugGraphPrimitiveFallback(
19556
+ "[questionEvidenceLinks] Failed to resolve topic scope",
19557
+ {
19558
+ error,
19559
+ projectId: args.projectId,
19560
+ topicId: args.topicId
19561
+ }
19562
+ );
19563
+ scope = null;
19564
+ }
19042
19565
  if (!scope) {
19043
19566
  return [];
19044
19567
  }