@lucern/graph-primitives 1.0.31 → 1.0.33

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 (93) hide show
  1. package/dist/beliefEvidenceLinks.js.map +1 -1
  2. package/dist/beliefEvidenceLinks.operational.js.map +1 -1
  3. package/dist/contradictions.js +5 -5
  4. package/dist/contradictions.js.map +1 -1
  5. package/dist/entityBridge.js +2 -1
  6. package/dist/entityBridge.js.map +1 -1
  7. package/dist/entityLifecycle.js.map +1 -1
  8. package/dist/epistemicAnswers.js +1 -1
  9. package/dist/epistemicAnswers.js.map +1 -1
  10. package/dist/epistemicBeliefs.admin.js +2 -2
  11. package/dist/epistemicBeliefs.admin.js.map +1 -1
  12. package/dist/epistemicBeliefs.backfills.js +9 -5
  13. package/dist/epistemicBeliefs.backfills.js.map +1 -1
  14. package/dist/epistemicBeliefs.confidence.js +3 -5
  15. package/dist/epistemicBeliefs.confidence.js.map +1 -1
  16. package/dist/epistemicBeliefs.core.js +20 -30
  17. package/dist/epistemicBeliefs.core.js.map +1 -1
  18. package/dist/epistemicBeliefs.forkEvidence.js.map +1 -1
  19. package/dist/epistemicBeliefs.helpers.js +1 -1
  20. package/dist/epistemicBeliefs.helpers.js.map +1 -1
  21. package/dist/epistemicBeliefs.internal.js +15 -25
  22. package/dist/epistemicBeliefs.internal.js.map +1 -1
  23. package/dist/epistemicBeliefs.js +33 -43
  24. package/dist/epistemicBeliefs.js.map +1 -1
  25. package/dist/epistemicBeliefs.lifecycle.js +3 -5
  26. package/dist/epistemicBeliefs.lifecycle.js.map +1 -1
  27. package/dist/epistemicBeliefs.links.js +1 -1
  28. package/dist/epistemicBeliefs.links.js.map +1 -1
  29. package/dist/epistemicBeliefs.queries.js.map +1 -1
  30. package/dist/epistemicBeliefs.topicAnchor.js +12 -22
  31. package/dist/epistemicBeliefs.topicAnchor.js.map +1 -1
  32. package/dist/epistemicContracts.evaluators.js +3 -5
  33. package/dist/epistemicContracts.evaluators.js.map +1 -1
  34. package/dist/epistemicContracts.handlers.js +3 -6
  35. package/dist/epistemicContracts.handlers.js.map +1 -1
  36. package/dist/epistemicContracts.js +3 -6
  37. package/dist/epistemicContracts.js.map +1 -1
  38. package/dist/epistemicEdgeCreation.js.map +1 -1
  39. package/dist/epistemicEdges.handlers.js.map +1 -1
  40. package/dist/epistemicEdges.js +6 -7
  41. package/dist/epistemicEdges.js.map +1 -1
  42. package/dist/epistemicEdges.mutations.js +3 -4
  43. package/dist/epistemicEdges.mutations.js.map +1 -1
  44. package/dist/epistemicEdges.queries.js +3 -3
  45. package/dist/epistemicEdges.queries.js.map +1 -1
  46. package/dist/epistemicEvidence.js +10 -10
  47. package/dist/epistemicEvidence.js.map +1 -1
  48. package/dist/epistemicEvidenceHelpers.js +1 -1
  49. package/dist/epistemicEvidenceHelpers.js.map +1 -1
  50. package/dist/epistemicEvidenceMutations.js +5 -5
  51. package/dist/epistemicEvidenceMutations.js.map +1 -1
  52. package/dist/epistemicEvidenceQueries.js +6 -6
  53. package/dist/epistemicEvidenceQueries.js.map +1 -1
  54. package/dist/epistemicHelpers.js +4 -4
  55. package/dist/epistemicHelpers.js.map +1 -1
  56. package/dist/epistemicInsert.js.map +1 -1
  57. package/dist/epistemicLayerRules.js +2 -2
  58. package/dist/epistemicLayerRules.js.map +1 -1
  59. package/dist/epistemicLinking.js.map +1 -1
  60. package/dist/epistemicNodeCreation.js +2 -2
  61. package/dist/epistemicNodeCreation.js.map +1 -1
  62. package/dist/epistemicNodes.internal.js +2 -3
  63. package/dist/epistemicNodes.internal.js.map +1 -1
  64. package/dist/epistemicNodes.js +10 -12
  65. package/dist/epistemicNodes.js.map +1 -1
  66. package/dist/epistemicNodes.mutations.js +3 -4
  67. package/dist/epistemicNodes.mutations.js.map +1 -1
  68. package/dist/epistemicNodes.queries.js +5 -5
  69. package/dist/epistemicNodes.queries.js.map +1 -1
  70. package/dist/epistemicQuestions.conviction.js +5 -5
  71. package/dist/epistemicQuestions.conviction.js.map +1 -1
  72. package/dist/epistemicQuestions.create.js +7 -7
  73. package/dist/epistemicQuestions.create.js.map +1 -1
  74. package/dist/epistemicQuestions.evidence.js +2 -2
  75. package/dist/epistemicQuestions.evidence.js.map +1 -1
  76. package/dist/epistemicQuestions.helpers.js +7 -4
  77. package/dist/epistemicQuestions.helpers.js.map +1 -1
  78. package/dist/epistemicQuestions.js +16 -13
  79. package/dist/epistemicQuestions.js.map +1 -1
  80. package/dist/epistemicQuestions.lifecycle.js.map +1 -1
  81. package/dist/epistemicQuestions.queries.js +2 -2
  82. package/dist/epistemicQuestions.queries.js.map +1 -1
  83. package/dist/epistemicQuestions.sprint.js +6 -3
  84. package/dist/epistemicQuestions.sprint.js.map +1 -1
  85. package/dist/epistemicQuestions.tail.js +2 -2
  86. package/dist/epistemicQuestions.tail.js.map +1 -1
  87. package/dist/epistemicSources.js.map +1 -1
  88. package/dist/index.js +88 -98
  89. package/dist/index.js.map +1 -1
  90. package/dist/proof-attestation.json +1 -1
  91. package/dist/questionEvidenceLinks.js +3 -2
  92. package/dist/questionEvidenceLinks.js.map +1 -1
  93. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -8,9 +8,9 @@ import { canAudienceClassAccess, normalizeAudienceKey, classFromAudienceKey } fr
8
8
  import { getCurrentUserId } from '@lucern/access-control/auth';
9
9
  import { throwStructuredMutationError } from '@lucern/access-control/structuredMutationError';
10
10
  import { isNodeType, getLayerForNodeType } from '@lucern/contracts/schema-helpers/spine/tables/epistemicNodes';
11
+ import { generateUuidV7, generateGlobalId, assertUuidV7Identity, assertStorageEdgeVocabulary, isUuidV7, assertUuidShapedEdgeEndpoint } from '@lucern/contracts/ids';
11
12
  import { assertSchemaEnumValue } from '@lucern/contracts/schema-helpers/enumValidation';
12
13
  import { REASONING_METHODS, assertEdgePolicyAllowed, edgePolicyManifest, EVIDENCE_SOURCE_QUALITY_VALUES, EVIDENCE_METHODOLOGY_VALUES, EVIDENCE_INFORMATION_ASYMMETRY_VALUES } from '@lucern/contracts';
13
- import { generateGlobalId, assertUuidV7Identity, generateUuidV7, assertStorageEdgeVocabulary, assertUuidShapedEdgeEndpoint, isUuidV7 } from '@lucern/contracts/ids';
14
14
  import { listAudienceRegistryRows } from '@lucern/access-control/audienceRegistry';
15
15
  import { scoreEntityTypeMatch, scoreEntityConnection, rankEntityTypeMatches, rankEntityConnections } from '@lucern/contracts/v1/ontologies/v1';
16
16
  import { wordTokenize, wordOverlapScore, tokenizeSearchText, tokenOverlapScore, stemToken, scoreLexicalSignals, scoreLexicalSignal, rerankLexicalWindow, rankWindowScore, prepareLexicalQuery, jaccardSimilarity, bigramTokenize } from '@lucern/contracts/text-matching.contract';
@@ -2288,7 +2288,7 @@ async function markBeliefGraphDirty(ctx, scope) {
2288
2288
  );
2289
2289
  }
2290
2290
  async function resolveBeliefScopeOrNull(ctx, args) {
2291
- if (!(args.projectId || args.topicId)) {
2291
+ if (!args.topicId) {
2292
2292
  return null;
2293
2293
  }
2294
2294
  try {
@@ -2818,7 +2818,7 @@ var getByPillar = query({
2818
2818
  },
2819
2819
  returns: permissiveReturn,
2820
2820
  handler: async (ctx, args) => {
2821
- if (!(args.projectId || args.topicId)) {
2821
+ if (!args.topicId) {
2822
2822
  return [];
2823
2823
  }
2824
2824
  let scope;
@@ -3249,7 +3249,7 @@ var getRecentConfidenceChanges = query({
3249
3249
  if (!scope) {
3250
3250
  return [];
3251
3251
  }
3252
- const scopeId = scope.topicId ? String(scope.topicId) : scope.projectId;
3252
+ const scopeId = scope.topicId ? String(scope.topicId) : void 0;
3253
3253
  if (!(scopeId && await checkScopeAccess(ctx, scopeId, args.userId))) {
3254
3254
  return [];
3255
3255
  }
@@ -3506,7 +3506,7 @@ var backfillScoredBeliefEdges = internalMutation({
3506
3506
  returns: permissiveReturn,
3507
3507
  handler: async (ctx, args) => {
3508
3508
  const dryRun = args.dryRun ?? false;
3509
- const scopeTopicId = args.topicId ?? args.projectId;
3509
+ const scopeTopicId = args.topicId;
3510
3510
  if (!scopeTopicId) {
3511
3511
  return {
3512
3512
  dryRun,
@@ -3540,13 +3540,16 @@ var backfillScoredBeliefEdges = internalMutation({
3540
3540
  if (!theme.globalId) {
3541
3541
  continue;
3542
3542
  }
3543
- const edgeGlobalId = `edge-${belief.globalId}-relates_to_thesis-${theme.globalId}`;
3544
- const existing = await ctx.db.query("epistemicEdges").filter((q) => q.eq(q.field("globalId"), edgeGlobalId)).first();
3543
+ const existing = await ctx.db.query("epistemicEdges").withIndex(
3544
+ "by_from_to",
3545
+ (q) => q.eq("fromNodeId", belief.globalId).eq("toNodeId", theme.globalId)
3546
+ ).filter((q) => q.eq(q.field("edgeType"), "relates_to_thesis")).first();
3545
3547
  if (existing) {
3546
3548
  skipped++;
3547
3549
  continue;
3548
3550
  }
3549
3551
  if (!dryRun) {
3552
+ const edgeGlobalId = generateUuidV7();
3550
3553
  await ctx.scheduler.runAfter(0, internal.neo4jEdgeAPI.createEdge, {
3551
3554
  globalId: edgeGlobalId,
3552
3555
  fromGlobalId: belief.globalId,
@@ -4179,16 +4182,13 @@ async function scheduleFirstScoringThemeEdges(ctx, args, node, state) {
4179
4182
  if (!state.isFirstScoring) {
4180
4183
  return;
4181
4184
  }
4182
- const themeNodes = await ctx.db.query("epistemicNodes").withIndex(
4183
- "by_topic",
4184
- (q) => q.eq("topicId", node.topicId || node.projectId)
4185
- ).filter((q) => q.eq(q.field("nodeType"), "theme")).collect();
4185
+ const themeNodes = await ctx.db.query("epistemicNodes").withIndex("by_topic", (q) => q.eq("topicId", node.topicId)).filter((q) => q.eq(q.field("nodeType"), "theme")).collect();
4186
4186
  for (const theme of themeNodes) {
4187
4187
  if (!(theme.globalId && node.globalId)) {
4188
4188
  continue;
4189
4189
  }
4190
4190
  await ctx.scheduler.runAfter(0, internal.neo4jEdgeAPI.createEdge, {
4191
- globalId: `edge-${node.globalId}-relates_to_thesis-${theme.globalId}`,
4191
+ globalId: generateUuidV7(),
4192
4192
  fromGlobalId: node.globalId,
4193
4193
  toGlobalId: theme.globalId,
4194
4194
  edgeType: "relates_to_thesis",
@@ -4551,36 +4551,26 @@ __export(globalId_exports, {
4551
4551
  function cleanString(value) {
4552
4552
  return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
4553
4553
  }
4554
- function topicNodeCandidates(topicRef) {
4554
+ function requireTopicGlobalId(topicRef) {
4555
4555
  const normalized = topicRef.trim();
4556
- if (!normalized) {
4557
- return [];
4558
- }
4559
- const candidates = [normalized];
4560
- if (normalized.startsWith("top_")) {
4561
- candidates.push(normalized.slice(4));
4556
+ if (!(normalized && isUuidV7(normalized))) {
4557
+ throw new Error(
4558
+ "Belief creation topic anchors must be UUIDv7 epistemicNodes.globalId values."
4559
+ );
4562
4560
  }
4563
- return [...new Set(candidates)];
4561
+ return normalized;
4564
4562
  }
4565
4563
  function readTopicNodeRef(args) {
4566
4564
  return cleanString(args.topicGlobalId) ?? cleanString(args.topicNodeId) ?? cleanString(args.topicId);
4567
4565
  }
4568
4566
  async function resolveRequiredTopicAnchor(ctx, topicRef) {
4569
- for (const candidate of topicNodeCandidates(topicRef)) {
4570
- try {
4571
- const direct = await ctx.db.get(candidate);
4572
- if (direct?.nodeType === "topic" && cleanString(direct.globalId)) {
4573
- return direct;
4574
- }
4575
- } catch {
4576
- }
4577
- const byGlobalId = await ctx.db.query("epistemicNodes").withIndex("by_globalId", (q) => q.eq("globalId", candidate)).first();
4578
- if (byGlobalId?.nodeType === "topic" && cleanString(byGlobalId.globalId)) {
4579
- return byGlobalId;
4580
- }
4567
+ const topicGlobalId = requireTopicGlobalId(topicRef);
4568
+ const byGlobalId = await ctx.db.query("epistemicNodes").withIndex("by_globalId", (q) => q.eq("globalId", topicGlobalId)).first();
4569
+ if (byGlobalId?.nodeType === "topic" && cleanString(byGlobalId.globalId)) {
4570
+ return byGlobalId;
4581
4571
  }
4582
4572
  throw new Error(
4583
- "Belief creation requires topicGlobalId or topicNodeId for a topic node in epistemicNodes. Legacy topics-table IDs are not valid belief anchors."
4573
+ "Belief creation requires a UUIDv7 topicGlobalId for a topic node in epistemicNodes. Legacy topics-table IDs are not valid belief anchors."
4584
4574
  );
4585
4575
  }
4586
4576
  function scopeFromTopicAnchor(topicNode) {
@@ -5091,7 +5081,7 @@ var create = mutation({
5091
5081
  projectId: scope.projectId,
5092
5082
  topicId: String(scope.topicId)
5093
5083
  });
5094
- if (scope.projectId || scope.topicId) {
5084
+ if (scope.topicId) {
5095
5085
  await ctx.scheduler.runAfter(
5096
5086
  0,
5097
5087
  "embeddingActions:generateEpistemicNodeEmbedding",
@@ -5110,7 +5100,7 @@ Rationale: ${args.rationale}` : args.formulation
5110
5100
  }
5111
5101
  );
5112
5102
  }
5113
- if (scope.projectId || scope.topicId) {
5103
+ if (scope.topicId) {
5114
5104
  await ctx.scheduler.runAfter(
5115
5105
  2e3,
5116
5106
  // 2 second delay
@@ -5123,7 +5113,7 @@ Rationale: ${args.rationale}` : args.formulation
5123
5113
  }
5124
5114
  );
5125
5115
  }
5126
- if (pillar === "other" && (scope.projectId || scope.topicId)) {
5116
+ if (pillar === "other" && scope.topicId) {
5127
5117
  await ctx.scheduler.runAfter(
5128
5118
  2500,
5129
5119
  "beliefCategorization:autoCategorizeBelief",
@@ -5134,7 +5124,7 @@ Rationale: ${args.rationale}` : args.formulation
5134
5124
  }
5135
5125
  );
5136
5126
  }
5137
- if (scope.projectId || scope.topicId) {
5127
+ if (scope.topicId) {
5138
5128
  await ctx.scheduler.runAfter(
5139
5129
  3e3,
5140
5130
  // 3 second delay — after entity extraction
@@ -5402,7 +5392,7 @@ var getByProject = query({
5402
5392
  },
5403
5393
  returns: permissiveReturn,
5404
5394
  handler: async (ctx, args) => {
5405
- if (!(args.projectId || args.topicId)) {
5395
+ if (!args.topicId) {
5406
5396
  return [];
5407
5397
  }
5408
5398
  const pageSize = clampBeliefLimit(args.limit);
@@ -5425,7 +5415,7 @@ var getByProject = query({
5425
5415
  return [];
5426
5416
  }
5427
5417
  if (args.userId) {
5428
- const scopeId = scope.topicId ? String(scope.topicId) : scope.projectId;
5418
+ const scopeId = scope.topicId ? String(scope.topicId) : void 0;
5429
5419
  if (!scopeId) {
5430
5420
  return [];
5431
5421
  }
@@ -5582,7 +5572,7 @@ var forkBelief = mutation({
5582
5572
  supersededBy: newNodeId,
5583
5573
  updatedAt: now,
5584
5574
  metadata: {
5585
- ...metadata ?? {},
5575
+ ...metadata,
5586
5576
  status: "superseded",
5587
5577
  beliefStatus: "superseded",
5588
5578
  epistemicStatus: "superseded",
@@ -5662,7 +5652,7 @@ var forkBelief = mutation({
5662
5652
  projectId: parent.projectId,
5663
5653
  topicId: parent.topicId
5664
5654
  });
5665
- if (parent.projectId || parent.topicId) {
5655
+ if (parent.topicId) {
5666
5656
  const inheritedPillar = normalizePillar(
5667
5657
  String(metadata?.pillar || metadata?.topic || "")
5668
5658
  );
@@ -6068,7 +6058,7 @@ async function insertInternalBeliefAudit(ctx, args) {
6068
6058
  });
6069
6059
  }
6070
6060
  async function scheduleInternalBeliefEmbedding(ctx, args) {
6071
- if (!(args.scope.projectId || args.scope.topicId)) {
6061
+ if (!args.scope.topicId) {
6072
6062
  return;
6073
6063
  }
6074
6064
  await ctx.scheduler.runAfter(0, EMBEDDING_GENERATION_ACTION, {
@@ -6096,7 +6086,7 @@ function numericRequestedConfidence(confidence) {
6096
6086
  return 0.5;
6097
6087
  }
6098
6088
  async function scheduleInternalBeliefCategorization(ctx, args) {
6099
- if (normalizePillar(args.args.pillar || args.args.topic) !== "other" || !(args.scope.projectId || args.scope.topicId)) {
6089
+ if (normalizePillar(args.args.pillar || args.args.topic) !== "other" || !args.scope.topicId) {
6100
6090
  return;
6101
6091
  }
6102
6092
  await ctx.scheduler.runAfter(2500, BELIEF_CATEGORIZATION_ACTION, {
@@ -7277,9 +7267,9 @@ function shouldContinueTraversal2(currentLayer, targetLayer, options) {
7277
7267
  }
7278
7268
  switch (options.mode) {
7279
7269
  case "anchor_down":
7280
- return targetDepth < currentDepth || targetDepth === currentDepth;
7270
+ return targetDepth <= currentDepth;
7281
7271
  case "anchor_up":
7282
- return targetDepth > currentDepth || targetDepth === currentDepth;
7272
+ return targetDepth >= currentDepth;
7283
7273
  case "same_layer":
7284
7274
  return targetDepth === currentDepth;
7285
7275
  case "decision_trace":
@@ -8003,7 +7993,7 @@ async function createEpistemicNodeForBelief(ctx, beliefId, belief) {
8003
7993
  if (existingBeliefNode?.status === "active") {
8004
7994
  await ctx.db.patch(existingBeliefNode._id, {
8005
7995
  metadata: {
8006
- ...existingBeliefNode.metadata ?? {},
7996
+ ...existingBeliefNode.metadata,
8007
7997
  sourceBeliefId: beliefId
8008
7998
  },
8009
7999
  updatedAt: now
@@ -8114,7 +8104,7 @@ async function createEpistemicNodeForArtifact(ctx, artifactId, artifact) {
8114
8104
  if (existingArtifactNode?.status === "active") {
8115
8105
  await ctx.db.patch(existingArtifactNode._id, {
8116
8106
  metadata: {
8117
- ...existingArtifactNode.metadata ?? {},
8107
+ ...existingArtifactNode.metadata,
8118
8108
  legacyArtifactId: artifactId
8119
8109
  },
8120
8110
  updatedAt: now
@@ -9898,7 +9888,7 @@ var getByProject3 = query({
9898
9888
  contradictions = readRowList7(
9899
9889
  await ctx.db.query("contradictions").withIndex(
9900
9890
  "by_topic_status",
9901
- (q) => q.eq("topicId", String(scope.topicId ?? projectId)).eq("status", status)
9891
+ (q) => q.eq("topicId", String(scope.topicId)).eq("status", status)
9902
9892
  ).order("desc").take(scanLimit),
9903
9893
  readContradictionRow
9904
9894
  );
@@ -9906,7 +9896,7 @@ var getByProject3 = query({
9906
9896
  contradictions = readRowList7(
9907
9897
  await ctx.db.query("contradictions").withIndex(
9908
9898
  "by_topicId",
9909
- (q) => q.eq("topicId", String(scope.topicId ?? projectId))
9899
+ (q) => q.eq("topicId", String(scope.topicId))
9910
9900
  ).order("desc").take(scanLimit),
9911
9901
  readContradictionRow
9912
9902
  );
@@ -9950,7 +9940,7 @@ var getUnresolvedCount = query({
9950
9940
  const contradictions = readRowList7(
9951
9941
  await ctx.db.query("contradictions").withIndex(
9952
9942
  "by_topic_status",
9953
- (q) => q.eq("topicId", String(scope.topicId ?? projectId)).eq("status", "unresolved")
9943
+ (q) => q.eq("topicId", String(scope.topicId)).eq("status", "unresolved")
9954
9944
  ).collect(),
9955
9945
  readContradictionRow
9956
9946
  );
@@ -10075,7 +10065,7 @@ var create3 = mutation({
10075
10065
  }
10076
10066
  return await ctx.db.insert("contradictions", {
10077
10067
  projectId,
10078
- topicId: String(scope.topicId ?? projectId),
10068
+ topicId: String(scope.topicId),
10079
10069
  beliefId: args.beliefId,
10080
10070
  ...args.beliefBId ? { beliefBId: args.beliefBId } : {},
10081
10071
  supportingInsightIds: args.supportingInsightIds,
@@ -10321,7 +10311,7 @@ var scanAndCreateContradictions = mutation({
10321
10311
  if (!existing) {
10322
10312
  await ctx.db.insert("contradictions", {
10323
10313
  projectId,
10324
- topicId: String(scope.topicId ?? projectId),
10314
+ topicId: String(scope.topicId),
10325
10315
  beliefId: belief._id,
10326
10316
  supportingInsightIds,
10327
10317
  contradictingInsightIds,
@@ -10900,7 +10890,7 @@ var linkEntityToBelief = mutation({
10900
10890
  if (existing && existing.edgeType === effectiveEdgeType) {
10901
10891
  return { edgeId: existing._id, existed: true };
10902
10892
  }
10903
- const globalId = `edge-${effectiveEdgeType}-${fromNodeId}-${toNodeId}-${Date.now()}`;
10893
+ const globalId = generateUuidV7();
10904
10894
  await ctx.scheduler.runAfter(0, internal.neo4jEdgeAPI.createEdge, {
10905
10895
  globalId,
10906
10896
  fromGlobalId,
@@ -12196,7 +12186,7 @@ function getNextAnswerVersion(activeAnswers) {
12196
12186
  async function supersedeActiveAnswers(ctx, activeAnswers, now, clearSupersededByBeforeInsert) {
12197
12187
  for (const activeAnswer of activeAnswers) {
12198
12188
  const metadata = {
12199
- ...activeAnswer.metadata ?? {},
12189
+ ...activeAnswer.metadata,
12200
12190
  isLatest: false
12201
12191
  };
12202
12192
  await ctx.db.patch(activeAnswer._id, {
@@ -13390,9 +13380,8 @@ var create5 = mutation({
13390
13380
  await ctx.db.get(args.toNodeId),
13391
13381
  "Create edge target"
13392
13382
  );
13393
- const resolvedScope = args.topicId || args.projectId ? await resolveTopicProjectScope(ctx, {
13394
- topicId: args.topicId,
13395
- projectId: args.projectId
13383
+ const resolvedScope = args.topicId ? await resolveTopicProjectScope(ctx, {
13384
+ topicId: args.topicId
13396
13385
  }) : void 0;
13397
13386
  const resolvedProjectId = resolvedScope?.projectId ?? args.projectId;
13398
13387
  if (resolvedProjectId) {
@@ -13695,7 +13684,7 @@ var cleanupDeprecatedEdges = mutation({
13695
13684
  returns: permissiveReturn,
13696
13685
  handler: async (ctx, args) => {
13697
13686
  const DEPRECATED_TYPES = ["contradicts"];
13698
- const scopeId = args.topicId || args.projectId;
13687
+ const scopeId = args.topicId;
13699
13688
  const allEdges = scopeId ? await ctx.db.query("epistemicEdges").withIndex(
13700
13689
  "by_topic",
13701
13690
  (q) => q.eq("topicId", scopeId)
@@ -14163,7 +14152,7 @@ var getByProjectAndType = query({
14163
14152
  },
14164
14153
  returns: permissiveReturn,
14165
14154
  handler: async (ctx, args) => {
14166
- if (!(args.projectId || args.topicId)) {
14155
+ if (!args.topicId) {
14167
14156
  return [];
14168
14157
  }
14169
14158
  let scope;
@@ -14197,7 +14186,7 @@ var getByProject4 = query({
14197
14186
  },
14198
14187
  returns: permissiveReturn,
14199
14188
  handler: async (ctx, args) => {
14200
- if (!(args.projectId || args.topicId)) {
14189
+ if (!args.topicId) {
14201
14190
  return [];
14202
14191
  }
14203
14192
  let scope;
@@ -14220,7 +14209,7 @@ var getByProject4 = query({
14220
14209
  if (args.userId) {
14221
14210
  const hasAccess = await checkScopeAccess(
14222
14211
  ctx,
14223
- String(scope.topicId ?? scope.projectId),
14212
+ String(scope.topicId),
14224
14213
  args.userId
14225
14214
  );
14226
14215
  if (!hasAccess) {
@@ -14533,7 +14522,7 @@ function resolveEvidenceLinkedWorktreeId(metadata) {
14533
14522
  return typeof sprintId === "string" && sprintId.trim().length > 0 ? sprintId : void 0;
14534
14523
  }
14535
14524
  async function resolveEvidenceScopeOrNull(ctx, args) {
14536
- if (!(args.projectId || args.topicId)) {
14525
+ if (!args.topicId) {
14537
14526
  return null;
14538
14527
  }
14539
14528
  try {
@@ -14917,7 +14906,7 @@ async function createEvidenceBeliefEdge(ctx, args) {
14917
14906
  weight: args.weight,
14918
14907
  confidence,
14919
14908
  createdBy: args.userId,
14920
- topicId: args.projectId ?? args.topicId,
14909
+ topicId: args.topicId,
14921
14910
  fromNodeType: "evidence",
14922
14911
  toNodeType: "belief",
14923
14912
  fromLayer: "L2",
@@ -15051,7 +15040,7 @@ var create6 = mutation({
15051
15040
  weight: impact.weight
15052
15041
  }
15053
15042
  });
15054
- if (scope.projectId || scope.topicId) {
15043
+ if (scope.topicId) {
15055
15044
  await ctx.scheduler.runAfter(0, EMBEDDING_GENERATION_ACTION2, {
15056
15045
  nodeId,
15057
15046
  projectId: scope.projectId,
@@ -15061,7 +15050,7 @@ var create6 = mutation({
15061
15050
  text: args.text
15062
15051
  });
15063
15052
  }
15064
- if (scope.projectId || scope.topicId) {
15053
+ if (scope.topicId) {
15065
15054
  await ctx.scheduler.runAfter(
15066
15055
  2e3,
15067
15056
  internal.nodeClassification.scheduleClassification,
@@ -15332,7 +15321,7 @@ var internalCreate2 = internalMutation({
15332
15321
  projectId: scope.projectId ? String(scope.projectId) : void 0,
15333
15322
  rationale: args.rationale
15334
15323
  });
15335
- if (scope.projectId || scope.topicId) {
15324
+ if (scope.topicId) {
15336
15325
  await ctx.scheduler.runAfter(0, EMBEDDING_GENERATION_ACTION2, {
15337
15326
  nodeId,
15338
15327
  projectId: scope.projectId,
@@ -15791,7 +15780,7 @@ var getByProject5 = query({
15791
15780
  },
15792
15781
  returns: permissiveReturn,
15793
15782
  handler: async (ctx, args) => {
15794
- if (!(args.projectId || args.topicId)) {
15783
+ if (!args.topicId) {
15795
15784
  return [];
15796
15785
  }
15797
15786
  const pageSize = clampEvidenceLimit(args.limit);
@@ -15814,7 +15803,7 @@ var getByProject5 = query({
15814
15803
  return [];
15815
15804
  }
15816
15805
  if (args.userId) {
15817
- const scopeId = scope.topicId ? String(scope.topicId) : scope.projectId;
15806
+ const scopeId = scope.topicId ? String(scope.topicId) : void 0;
15818
15807
  if (!scopeId) {
15819
15808
  return [];
15820
15809
  }
@@ -15906,7 +15895,7 @@ var internalGetByProject2 = internalQuery({
15906
15895
  return [];
15907
15896
  }
15908
15897
  const audienceMode = args.audienceMode ?? "internal";
15909
- const projectScopeId = scope.topicId ? String(scope.topicId) : scope.projectId;
15898
+ const projectScopeId = scope.topicId ? String(scope.topicId) : void 0;
15910
15899
  if (!projectScopeId) {
15911
15900
  return [];
15912
15901
  }
@@ -16065,7 +16054,7 @@ var getEvidenceBalance = query({
16065
16054
  topicId: args.topicId,
16066
16055
  projectId: args.projectId
16067
16056
  });
16068
- const scopeId = scope.topicId ? String(scope.topicId) : scope.projectId;
16057
+ const scopeId = scope.topicId ? String(scope.topicId) : void 0;
16069
16058
  if (!scopeId) {
16070
16059
  return { supporting: 0, challenging: 0, total: 0 };
16071
16060
  }
@@ -16073,7 +16062,7 @@ var getEvidenceBalance = query({
16073
16062
  if (!hasAccess) {
16074
16063
  return { supporting: 0, challenging: 0, total: 0 };
16075
16064
  }
16076
- const resolvedTopicId = scope.topicId || scope.projectId;
16065
+ const resolvedTopicId = scope.topicId;
16077
16066
  const edges2 = resolvedTopicId ? readEvidenceEdgeRows(
16078
16067
  await ctx.db.query("epistemicEdges").withIndex(
16079
16068
  "by_topic",
@@ -16645,7 +16634,7 @@ var getByProjectAndType2 = query({
16645
16634
  },
16646
16635
  returns: permissiveReturn,
16647
16636
  handler: async (ctx, args) => {
16648
- if (!(args.projectId || args.topicId)) {
16637
+ if (!args.topicId) {
16649
16638
  return [];
16650
16639
  }
16651
16640
  const queryCtx = asEpistemicNodesQueryCtx(ctx);
@@ -16687,7 +16676,7 @@ var getByProjectAndTypeLite = query({
16687
16676
  },
16688
16677
  returns: permissiveReturn,
16689
16678
  handler: async (ctx, args) => {
16690
- if (!(args.projectId || args.topicId)) {
16679
+ if (!args.topicId) {
16691
16680
  return [];
16692
16681
  }
16693
16682
  const queryCtx = asEpistemicNodesQueryCtx(ctx);
@@ -16729,7 +16718,7 @@ var getByProject6 = query({
16729
16718
  },
16730
16719
  returns: permissiveReturn,
16731
16720
  handler: async (ctx, args) => {
16732
- if (!(args.projectId || args.topicId)) {
16721
+ if (!args.topicId) {
16733
16722
  return [];
16734
16723
  }
16735
16724
  const queryCtx = asEpistemicNodesQueryCtx(ctx);
@@ -16755,7 +16744,7 @@ var getByProject6 = query({
16755
16744
  if (args.userId) {
16756
16745
  const hasAccess = await checkScopeAccess(
16757
16746
  ctx,
16758
- String(scope.topicId ?? scope.projectId),
16747
+ String(scope.topicId),
16759
16748
  args.userId
16760
16749
  );
16761
16750
  if (!hasAccess) {
@@ -16794,7 +16783,7 @@ var search = query({
16794
16783
  const queryCtx = asEpistemicNodesQueryCtx(ctx);
16795
16784
  const pageSize = clampNodeLimit(args.limit, 100);
16796
16785
  let scope;
16797
- if (args.projectId || args.topicId) {
16786
+ if (args.topicId) {
16798
16787
  try {
16799
16788
  scope = await resolveTopicProjectScope(queryCtx, {
16800
16789
  projectId: args.projectId,
@@ -17218,11 +17207,10 @@ var createInternal2 = internalMutation({
17218
17207
  returns: permissiveReturn,
17219
17208
  handler: async (ctx, args) => {
17220
17209
  const now = Date.now();
17221
- const resolvedScope = args.topicId || args.projectId ? await (async () => {
17210
+ const resolvedScope = args.topicId ? await (async () => {
17222
17211
  try {
17223
17212
  return await resolveTopicProjectScope(ctx, {
17224
- topicId: args.topicId,
17225
- projectId: args.projectId
17213
+ topicId: args.topicId
17226
17214
  });
17227
17215
  } catch (error) {
17228
17216
  debugGraphPrimitiveFallback(
@@ -17560,9 +17548,8 @@ var create7 = mutation({
17560
17548
  return { nodeId: existingNode._id, isDuplicate: true };
17561
17549
  }
17562
17550
  const epistemicLayer = getNodeLayer(args.nodeType);
17563
- const resolvedScope = args.topicId || args.projectId ? await resolveTopicProjectScope(ctx, {
17564
- topicId: args.topicId,
17565
- projectId: args.projectId
17551
+ const resolvedScope = args.topicId ? await resolveTopicProjectScope(ctx, {
17552
+ topicId: args.topicId
17566
17553
  }) : void 0;
17567
17554
  if (resolvedScope) {
17568
17555
  assertWorkspaceScopedEpistemicNodeScope({
@@ -17930,7 +17917,7 @@ var batchCreate2 = mutation({
17930
17917
  returns: permissiveReturn,
17931
17918
  handler: async (ctx, args) => {
17932
17919
  const resolveNodeScope = async (node) => {
17933
- if (!(node.topicId || node.projectId)) {
17920
+ if (!node.topicId) {
17934
17921
  return;
17935
17922
  }
17936
17923
  try {
@@ -18155,16 +18142,16 @@ function normalizeQuestionTopicId(topicId2) {
18155
18142
  return typeof topicId2 === "string" && topicId2.trim().length > 0 ? topicId2 : void 0;
18156
18143
  }
18157
18144
  function resolveQuestionScopeId(scope) {
18158
- return normalizeQuestionTopicId(scope.topicId) ?? scope.projectId ?? void 0;
18145
+ return normalizeQuestionTopicId(scope.topicId);
18159
18146
  }
18160
18147
  function logQuestionFallback(message, error, context) {
18161
18148
  debugGraphPrimitiveFallback(message, {
18162
18149
  error: formatGraphPrimitiveError(error),
18163
- ...context ?? {}
18150
+ ...context
18164
18151
  });
18165
18152
  }
18166
18153
  async function resolveQuestionScopeOrNull(ctx, args) {
18167
- if (!(args.projectId || args.topicId)) {
18154
+ if (!args.topicId) {
18168
18155
  return null;
18169
18156
  }
18170
18157
  try {
@@ -18197,9 +18184,12 @@ async function getQuestionNodesForScope(ctx, scope, args) {
18197
18184
  );
18198
18185
  }
18199
18186
  async function getQuestionEdgesForScope(ctx, scope) {
18187
+ if (!scope.topicId) {
18188
+ return [];
18189
+ }
18200
18190
  const query2 = ctx.db.query("epistemicEdges").withIndex(
18201
18191
  "by_topic",
18202
- (q) => q.eq("topicId", scope.topicId || scope.projectId)
18192
+ (q) => q.eq("topicId", scope.topicId)
18203
18193
  );
18204
18194
  return await query2.collect();
18205
18195
  }
@@ -18422,7 +18412,7 @@ function resolveLinkedBeliefNodeIdFromMetadata(meta) {
18422
18412
  return readOptionalString27(meta.linkedBeliefNodeId) || readOptionalString27(meta.linkedBeliefId) || readOptionalString27(meta.beliefId);
18423
18413
  }
18424
18414
  async function scheduleEvidenceCreationFromScoredQuestion(ctx, options) {
18425
- if (!(options.projectId || options.topicId)) {
18415
+ if (!options.topicId) {
18426
18416
  return;
18427
18417
  }
18428
18418
  const linkedBeliefId = resolveLinkedBeliefNodeIdFromMetadata(
@@ -18534,7 +18524,7 @@ async function syncBeliefTestEdge(ctx, questionNode, beliefNode, args) {
18534
18524
  toGlobalId: beliefGlobalId,
18535
18525
  edgeType: "tests",
18536
18526
  context: args.testType || "tests",
18537
- topicId: normalizeQuestionTopicId(questionNode.topicId) ?? questionNode.projectId,
18527
+ topicId: normalizeQuestionTopicId(questionNode.topicId),
18538
18528
  createdBy: args.userId,
18539
18529
  fromNodeType: "question",
18540
18530
  toNodeType: "belief",
@@ -19290,7 +19280,7 @@ var create8 = mutation({
19290
19280
  createdBy: args.userId,
19291
19281
  questionGlobalId: globalId,
19292
19282
  testType: args.testType,
19293
- topicId: normalizeQuestionTopicId(scope.topicId) ?? scope.projectId
19283
+ topicId: normalizeQuestionTopicId(scope.topicId)
19294
19284
  });
19295
19285
  }
19296
19286
  await ctx.db.insert("epistemicAudit", {
@@ -19307,7 +19297,7 @@ var create8 = mutation({
19307
19297
  priority: args.priority || "medium"
19308
19298
  }
19309
19299
  });
19310
- if (scope.projectId || scope.topicId) {
19300
+ if (scope.topicId) {
19311
19301
  await ctx.scheduler.runAfter(0, EMBEDDING_GENERATION_ACTION3, {
19312
19302
  nodeId,
19313
19303
  projectId: scope.projectId,
@@ -19318,7 +19308,7 @@ var create8 = mutation({
19318
19308
  hasAnswer: false
19319
19309
  });
19320
19310
  }
19321
- if (scope.projectId || scope.topicId) {
19311
+ if (scope.topicId) {
19322
19312
  await ctx.scheduler.runAfter(
19323
19313
  2e3,
19324
19314
  // 2 second delay
@@ -19436,7 +19426,7 @@ var createBatch = mutation({
19436
19426
  createdBy: args.userId,
19437
19427
  questionGlobalId: globalId,
19438
19428
  testType: q.testType,
19439
- topicId: normalizeQuestionTopicId(scope.topicId) ?? scope.projectId
19429
+ topicId: normalizeQuestionTopicId(scope.topicId)
19440
19430
  });
19441
19431
  }
19442
19432
  }
@@ -19523,10 +19513,10 @@ var internalCreate3 = internalMutation({
19523
19513
  createdBy: args.userId,
19524
19514
  questionGlobalId: globalId,
19525
19515
  testType: args.testType,
19526
- topicId: normalizeQuestionTopicId(scope.topicId) ?? scope.projectId
19516
+ topicId: normalizeQuestionTopicId(scope.topicId)
19527
19517
  });
19528
19518
  }
19529
- if (scope.projectId || scope.topicId) {
19519
+ if (scope.topicId) {
19530
19520
  await ctx.scheduler.runAfter(0, EMBEDDING_GENERATION_ACTION3, {
19531
19521
  nodeId,
19532
19522
  projectId: scope.projectId,
@@ -19702,7 +19692,7 @@ function readBeliefNodeRow2(value) {
19702
19692
  return id && globalId && nodeType ? { _id: id, globalId, nodeType } : null;
19703
19693
  }
19704
19694
  function resolveCanonicalEdgeTopicId(args) {
19705
- return normalizeQuestionTopicId(args.topicId) ?? args.projectId;
19695
+ return normalizeQuestionTopicId(args.topicId);
19706
19696
  }
19707
19697
  var createEvidenceFromScoredQuestion = internalMutation({
19708
19698
  args: {
@@ -24311,10 +24301,10 @@ async function applyOperationalLinkEffects2(ctx, args) {
24311
24301
  if (questionNode && questionNode.nodeType === "question" && evidenceNode && evidenceNode.nodeType === "evidence" && questionNode.globalId && evidenceNode.globalId) {
24312
24302
  const existingEdge = await ctx.db.query("epistemicEdges").withIndex(
24313
24303
  "by_from_to",
24314
- (q) => q.eq("fromNodeId", evidenceNode._id).eq("toNodeId", questionNode._id)
24304
+ (q) => q.eq("fromNodeId", evidenceNode.globalId).eq("toNodeId", questionNode.globalId)
24315
24305
  ).first();
24316
24306
  if (!existingEdge) {
24317
- const globalId = `edge-derived_from-${evidenceNode._id}-${questionNode._id}-${Date.now()}`;
24307
+ const globalId = generateUuidV7();
24318
24308
  await ctx.scheduler.runAfter(0, internal.neo4jEdgeAPI.createEdge, {
24319
24309
  globalId,
24320
24310
  fromGlobalId: evidenceNode.globalId,