@lucern/graph-primitives 1.0.16 → 1.0.18

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 (92) hide show
  1. package/dist/beliefEvidenceLinks.js +144 -99
  2. package/dist/beliefEvidenceLinks.js.map +1 -1
  3. package/dist/beliefEvidenceLinks.operational.d.ts +29 -0
  4. package/dist/beliefEvidenceLinks.operational.js +157 -0
  5. package/dist/beliefEvidenceLinks.operational.js.map +1 -0
  6. package/dist/{beliefLifecycle-y8WLXqQj.d.ts → beliefLifecycle-CXwdDw5e.d.ts} +7 -4
  7. package/dist/beliefLifecycle.d.ts +1 -1
  8. package/dist/beliefLifecycle.js +75 -18
  9. package/dist/beliefLifecycle.js.map +1 -1
  10. package/dist/entityLifecycle.js +1 -12
  11. package/dist/entityLifecycle.js.map +1 -1
  12. package/dist/epistemicAnswers.js +1 -12
  13. package/dist/epistemicAnswers.js.map +1 -1
  14. package/dist/epistemicBeliefs.admin.js.map +1 -1
  15. package/dist/epistemicBeliefs.backfills.d.ts +1 -1
  16. package/dist/epistemicBeliefs.backfills.js +63 -35
  17. package/dist/epistemicBeliefs.backfills.js.map +1 -1
  18. package/dist/epistemicBeliefs.confidence.d.ts +1 -1
  19. package/dist/epistemicBeliefs.confidence.js +70 -41
  20. package/dist/epistemicBeliefs.confidence.js.map +1 -1
  21. package/dist/epistemicBeliefs.core.js +946 -566
  22. package/dist/epistemicBeliefs.core.js.map +1 -1
  23. package/dist/epistemicBeliefs.d.ts +2 -2
  24. package/dist/epistemicBeliefs.forkEvidence.d.ts +18 -0
  25. package/dist/epistemicBeliefs.forkEvidence.js +121 -0
  26. package/dist/epistemicBeliefs.forkEvidence.js.map +1 -0
  27. package/dist/epistemicBeliefs.helpers.d.ts +2 -2
  28. package/dist/epistemicBeliefs.helpers.js +60 -32
  29. package/dist/epistemicBeliefs.helpers.js.map +1 -1
  30. package/dist/epistemicBeliefs.internal.js +175 -51
  31. package/dist/epistemicBeliefs.internal.js.map +1 -1
  32. package/dist/epistemicBeliefs.js +437 -84
  33. package/dist/epistemicBeliefs.js.map +1 -1
  34. package/dist/epistemicBeliefs.lifecycle.d.ts +2 -2
  35. package/dist/epistemicBeliefs.lifecycle.js +75 -47
  36. package/dist/epistemicBeliefs.lifecycle.js.map +1 -1
  37. package/dist/epistemicBeliefs.links.js +47 -13
  38. package/dist/epistemicBeliefs.links.js.map +1 -1
  39. package/dist/epistemicBeliefs.topicAnchor.d.ts +29 -0
  40. package/dist/epistemicBeliefs.topicAnchor.js +105 -0
  41. package/dist/epistemicBeliefs.topicAnchor.js.map +1 -0
  42. package/dist/epistemicContracts.evaluators.js +71 -42
  43. package/dist/epistemicContracts.evaluators.js.map +1 -1
  44. package/dist/epistemicContracts.handlers.js +72 -54
  45. package/dist/epistemicContracts.handlers.js.map +1 -1
  46. package/dist/epistemicContracts.js +72 -54
  47. package/dist/epistemicContracts.js.map +1 -1
  48. package/dist/epistemicContracts.metrics.js +1 -1
  49. package/dist/epistemicContracts.metrics.js.map +1 -1
  50. package/dist/epistemicContracts.types.d.ts +1 -1
  51. package/dist/epistemicEdgeCreation.js +1 -12
  52. package/dist/epistemicEdgeCreation.js.map +1 -1
  53. package/dist/epistemicEdges.helpers.d.ts +1 -1
  54. package/dist/epistemicEvidence.js +173 -93
  55. package/dist/epistemicEvidence.js.map +1 -1
  56. package/dist/epistemicEvidenceMutations.js +173 -93
  57. package/dist/epistemicEvidenceMutations.js.map +1 -1
  58. package/dist/epistemicHelpers.js +1 -12
  59. package/dist/epistemicHelpers.js.map +1 -1
  60. package/dist/epistemicNodeCreation.js +1 -10
  61. package/dist/epistemicNodeCreation.js.map +1 -1
  62. package/dist/epistemicNodes.internal.js.map +1 -1
  63. package/dist/epistemicNodes.js +2 -2
  64. package/dist/epistemicNodes.js.map +1 -1
  65. package/dist/epistemicNodes.mutations.js +2 -2
  66. package/dist/epistemicNodes.mutations.js.map +1 -1
  67. package/dist/epistemicQuestions.create.js +1 -12
  68. package/dist/epistemicQuestions.create.js.map +1 -1
  69. package/dist/epistemicQuestions.evidence.js +1 -12
  70. package/dist/epistemicQuestions.evidence.js.map +1 -1
  71. package/dist/epistemicQuestions.js +1 -12
  72. package/dist/epistemicQuestions.js.map +1 -1
  73. package/dist/epistemicQuestions.tail.js +1 -12
  74. package/dist/epistemicQuestions.tail.js.map +1 -1
  75. package/dist/epistemicSources.js +1 -12
  76. package/dist/epistemicSources.js.map +1 -1
  77. package/dist/evaluators/index.js +1 -1
  78. package/dist/evaluators/index.js.map +1 -1
  79. package/dist/globalId-4y9SPpC_.d.ts +10 -0
  80. package/dist/globalId.d.ts +1 -1
  81. package/dist/globalId.js +1 -13
  82. package/dist/globalId.js.map +1 -1
  83. package/dist/helpers.js +1 -12
  84. package/dist/helpers.js.map +1 -1
  85. package/dist/index.d.ts +4 -3
  86. package/dist/index.js +771 -247
  87. package/dist/index.js.map +1 -1
  88. package/dist/invariantEnforcement.js +2 -2
  89. package/dist/invariantEnforcement.js.map +1 -1
  90. package/dist/proof-attestation.json +3 -3
  91. package/package.json +4 -4
  92. package/dist/globalId-DKh9d_uD.d.ts +0 -20
@@ -4,6 +4,7 @@ import { listAudienceRegistryRows } from '@lucern/access-control/audienceRegistr
4
4
  import { assertSchemaEnumValue } from '@lucern/contracts/schema-helpers/enumValidation';
5
5
  import { permissiveReturn } from '@lucern/contracts/schema-helpers/validators';
6
6
  import { componentsGeneric, anyApi, internalQueryGeneric, internalMutationGeneric } from 'convex/server';
7
+ import { generateGlobalId } from '@lucern/contracts/ids';
7
8
  import { isNodeType, getLayerForNodeType } from '@lucern/contracts/schema-helpers/spine/tables/epistemicNodes';
8
9
  import { normalizeTupleContradictionPolicy, confidenceFromSL } from '@lucern/confidence';
9
10
  import '@lucern/access-control/access';
@@ -16,18 +17,6 @@ var internal = anyApi;
16
17
  var internalMutation = internalMutationGeneric;
17
18
  var internalQuery = internalQueryGeneric;
18
19
 
19
- // src/globalId.ts
20
- function generateGlobalId() {
21
- const bytes = new Uint8Array(16);
22
- crypto.getRandomValues(bytes);
23
- bytes[6] = bytes[6] & 15 | 64;
24
- bytes[8] = bytes[8] & 63 | 128;
25
- const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join(
26
- ""
27
- );
28
- return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
29
- }
30
-
31
20
  // src/debug.ts
32
21
  function isGraphPrimitiveDebugEnabled() {
33
22
  const env = globalThis.process?.env;
@@ -264,6 +253,102 @@ var optionalScopeArgs = {
264
253
  projectId: v.optional(v.string()),
265
254
  topicId: v.optional(v.string())
266
255
  };
256
+
257
+ // src/epistemicBeliefs.topicAnchor.ts
258
+ function cleanString(value) {
259
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
260
+ }
261
+ function topicNodeCandidates(topicRef) {
262
+ const normalized = topicRef.trim();
263
+ if (!normalized) {
264
+ return [];
265
+ }
266
+ const candidates = [normalized];
267
+ if (normalized.startsWith("top_")) {
268
+ candidates.push(normalized.slice(4));
269
+ }
270
+ return [...new Set(candidates)];
271
+ }
272
+ function readTopicNodeRef(args) {
273
+ return cleanString(args.topicGlobalId) ?? cleanString(args.topicNodeId) ?? cleanString(args.topicId);
274
+ }
275
+ async function resolveRequiredTopicAnchor(ctx, topicRef) {
276
+ for (const candidate of topicNodeCandidates(topicRef)) {
277
+ try {
278
+ const direct = await ctx.db.get(candidate);
279
+ if (direct?.nodeType === "topic" && cleanString(direct.globalId)) {
280
+ return direct;
281
+ }
282
+ } catch (_) {
283
+ }
284
+ const byGlobalId = await ctx.db.query("epistemicNodes").withIndex("by_globalId", (q) => q.eq("globalId", candidate)).first();
285
+ if (byGlobalId?.nodeType === "topic" && cleanString(byGlobalId.globalId)) {
286
+ return byGlobalId;
287
+ }
288
+ }
289
+ throw new Error(
290
+ "Belief creation requires topicGlobalId or topicNodeId for a topic node in epistemicNodes. Legacy topics-table IDs are not valid belief anchors."
291
+ );
292
+ }
293
+ function scopeFromTopicAnchor(topicNode) {
294
+ return {
295
+ topicId: topicNode.globalId,
296
+ projectId: cleanString(topicNode.projectId),
297
+ tenantId: cleanString(topicNode.tenantId),
298
+ workspaceId: cleanString(topicNode.workspaceId),
299
+ source: "topic"
300
+ };
301
+ }
302
+ async function createRequiredBeliefTopicEdge(ctx, args) {
303
+ const topicGlobalId = args.topicNode.globalId;
304
+ const edgeGlobalId = `edge:${args.beliefGlobalId}:${topicGlobalId}:scoped_by`;
305
+ const now = Date.now();
306
+ const existing = await ctx.db.query("epistemicEdges").withIndex("by_globalId", (q) => q.eq("globalId", edgeGlobalId)).first();
307
+ if (!existing) {
308
+ await ctx.db.insert("epistemicEdges", {
309
+ globalId: edgeGlobalId,
310
+ fromNodeId: String(args.beliefNodeId),
311
+ toNodeId: String(args.topicNode._id),
312
+ sourceGlobalId: args.beliefGlobalId,
313
+ targetGlobalId: topicGlobalId,
314
+ edgeType: "scoped_by",
315
+ weight: 1,
316
+ confidence: 1,
317
+ context: "Belief creation topic anchor invariant.",
318
+ reasoningMethod: "implicit",
319
+ derivationType: "topic_scope_invariant",
320
+ metadata: { invariant: "belief.topic_edge_required" },
321
+ createdBy: args.createdBy,
322
+ createdAt: now,
323
+ updatedAt: now,
324
+ projectId: cleanString(args.topicNode.projectId),
325
+ topicId: topicGlobalId,
326
+ tenantId: cleanString(args.topicNode.tenantId),
327
+ workspaceId: cleanString(args.topicNode.workspaceId),
328
+ fromNodeType: "belief",
329
+ toNodeType: "topic",
330
+ fromLayer: "L3",
331
+ toLayer: args.topicNode.epistemicLayer ?? "ontological"
332
+ });
333
+ }
334
+ await ctx.scheduler.runAfter(0, internal.neo4jEdgeAPI.createEdge, {
335
+ globalId: edgeGlobalId,
336
+ fromGlobalId: args.beliefGlobalId,
337
+ toGlobalId: topicGlobalId,
338
+ edgeType: "scoped_by",
339
+ weight: 1,
340
+ confidence: 1,
341
+ context: "Belief creation topic anchor invariant.",
342
+ projectId: cleanString(args.topicNode.projectId),
343
+ topicId: topicGlobalId,
344
+ createdBy: args.createdBy,
345
+ fromNodeType: "belief",
346
+ toNodeType: "topic",
347
+ fromLayer: "L3",
348
+ toLayer: args.topicNode.epistemicLayer ?? "ontological",
349
+ metadata: { invariant: "belief.topic_edge_required" }
350
+ });
351
+ }
267
352
  function normalizeScopeValue2(value) {
268
353
  if (typeof value !== "string") {
269
354
  return;
@@ -362,18 +447,32 @@ function assertTenantPackWorkspaceMutationAllowed(args) {
362
447
  var BELIEF_STATUS_VALUES = [
363
448
  "assumption",
364
449
  "hypothesis",
365
- "belief",
366
- "fact"
367
- ];
368
- var RESOLVED_PREDICTION_OUTCOMES = [
369
- "confirmed",
370
- "disconfirmed",
371
- "partial",
372
- "expired"
450
+ "active",
451
+ "superseded",
452
+ "resolved_true",
453
+ "resolved_false"
373
454
  ];
374
455
  function isBeliefLifecycleStatus(value) {
375
456
  return typeof value === "string" && BELIEF_STATUS_VALUES.includes(value);
376
457
  }
458
+ function normalizeLegacyBeliefStatus(value) {
459
+ if (isBeliefLifecycleStatus(value)) {
460
+ return value;
461
+ }
462
+ if (value === "belief" || value === "established" || value === "emerging") {
463
+ return "active";
464
+ }
465
+ if (value === "fact" || value === "confirmed") {
466
+ return "resolved_true";
467
+ }
468
+ if (value === "disconfirmed" || value === "expired") {
469
+ return "resolved_false";
470
+ }
471
+ if (value === "deprecated") {
472
+ return "superseded";
473
+ }
474
+ return null;
475
+ }
377
476
  function normalizeBeliefConfidence(confidence) {
378
477
  if (typeof confidence !== "number" || !Number.isFinite(confidence)) {
379
478
  return null;
@@ -393,47 +492,61 @@ function isResolvedByConfidence(confidence) {
393
492
  }
394
493
  return normalized <= 0 || normalized >= 1;
395
494
  }
396
- function hasResolvedPredictionOutcome(predictionMeta) {
495
+ function getPredictionMetaFromMetadata(metadata) {
496
+ return metadata?.predictionMeta;
497
+ }
498
+ function resolvedPredictionStatus(predictionMeta) {
397
499
  if (!predictionMeta || typeof predictionMeta !== "object") {
398
- return false;
500
+ return null;
399
501
  }
400
502
  const outcome = predictionMeta.outcome;
401
- return typeof outcome === "string" && RESOLVED_PREDICTION_OUTCOMES.includes(outcome);
402
- }
403
- function getPredictionMetaFromMetadata(metadata) {
404
- return metadata?.predictionMeta;
503
+ if (outcome === "confirmed") {
504
+ return "resolved_true";
505
+ }
506
+ if (outcome === "disconfirmed" || outcome === "expired") {
507
+ return "resolved_false";
508
+ }
509
+ return null;
405
510
  }
406
- function shouldTreatBeliefAsFact(opts) {
511
+ function shouldTreatBeliefAsResolved(opts) {
407
512
  if (isResolvedByConfidence(opts.confidence)) {
408
- return true;
513
+ const normalized = normalizeBeliefConfidence(opts.confidence);
514
+ return normalized === 0 ? "resolved_false" : "resolved_true";
409
515
  }
410
- if (hasResolvedPredictionOutcome(opts.predictionMeta)) {
411
- return true;
516
+ const directPredictionStatus = resolvedPredictionStatus(opts.predictionMeta);
517
+ if (directPredictionStatus) {
518
+ return directPredictionStatus;
412
519
  }
413
- if (hasResolvedPredictionOutcome(getPredictionMetaFromMetadata(opts.metadata))) {
414
- return true;
520
+ const metadataPredictionStatus = resolvedPredictionStatus(
521
+ getPredictionMetaFromMetadata(opts.metadata)
522
+ );
523
+ if (metadataPredictionStatus) {
524
+ return metadataPredictionStatus;
415
525
  }
416
- return false;
526
+ return null;
417
527
  }
418
528
  function resolveBeliefLifecycleStatus(opts) {
419
- if (shouldTreatBeliefAsFact(opts)) {
420
- return "fact";
529
+ const resolvedStatus = shouldTreatBeliefAsResolved(opts);
530
+ if (resolvedStatus) {
531
+ return resolvedStatus;
421
532
  }
422
533
  const direct = opts.beliefStatus;
423
- if (isBeliefLifecycleStatus(direct)) {
534
+ const normalizedDirect = normalizeLegacyBeliefStatus(direct);
535
+ if (normalizedDirect) {
424
536
  const normalized = normalizeBeliefConfidence(opts.confidence);
425
- if (normalized !== null && isPreValidationBeliefStatus(direct)) {
426
- return "belief";
537
+ if (normalized !== null && isPreValidationBeliefStatus(normalizedDirect)) {
538
+ return "active";
427
539
  }
428
- return direct;
540
+ return normalizedDirect;
429
541
  }
430
542
  const metaStatus = opts.metadata?.beliefStatus;
431
- if (isBeliefLifecycleStatus(metaStatus)) {
543
+ const normalizedMetaStatus = normalizeLegacyBeliefStatus(metaStatus);
544
+ if (normalizedMetaStatus) {
432
545
  const normalized = normalizeBeliefConfidence(opts.confidence);
433
- if (normalized !== null && isPreValidationBeliefStatus(metaStatus)) {
434
- return "belief";
546
+ if (normalized !== null && isPreValidationBeliefStatus(normalizedMetaStatus)) {
547
+ return "active";
435
548
  }
436
- return metaStatus;
549
+ return normalizedMetaStatus;
437
550
  }
438
551
  return "assumption";
439
552
  }
@@ -811,7 +924,7 @@ function buildBeliefConfidenceRow(args) {
811
924
  disbelief: args.disbelief,
812
925
  uncertainty: args.uncertainty,
813
926
  baseRate: args.baseRate,
814
- slOperator: args.slOperator ?? "manual_assessment",
927
+ slOperator: args.slOperator ?? "prior_seed",
815
928
  trigger: args.trigger,
816
929
  ...args.rationale ? { rationale: args.rationale } : {},
817
930
  assessedBy: args.assessedBy,
@@ -1131,6 +1244,8 @@ var internalGetById = internalQuery({
1131
1244
  var internalCreate = internalMutation({
1132
1245
  args: {
1133
1246
  ...optionalBeliefScopeArgs,
1247
+ topicNodeId: v.optional(v.string()),
1248
+ topicGlobalId: v.optional(v.string()),
1134
1249
  formulation: v.string(),
1135
1250
  baseRate: v.optional(v.number()),
1136
1251
  confidence: v.optional(
@@ -1169,10 +1284,14 @@ var internalCreate = internalMutation({
1169
1284
  handler: async (ctx, args) => {
1170
1285
  const now = Date.now();
1171
1286
  const baseRate = assertBaseRateInRange(args.baseRate ?? 0.5);
1172
- const scope = await resolveTopicProjectScope(ctx, {
1173
- topicId: args.topicId,
1174
- projectId: args.projectId
1175
- });
1287
+ const topicRef = readTopicNodeRef(args);
1288
+ if (!topicRef) {
1289
+ throw new Error(
1290
+ "Belief creation requires topicGlobalId or topicNodeId for a topic node in epistemicNodes."
1291
+ );
1292
+ }
1293
+ const topicNode = await resolveRequiredTopicAnchor(ctx, topicRef);
1294
+ const scope = scopeFromTopicAnchor(topicNode);
1176
1295
  assertWorkspaceScopedEpistemicNodeScope({
1177
1296
  scope,
1178
1297
  nodeType: "belief",
@@ -1188,11 +1307,10 @@ var internalCreate = internalMutation({
1188
1307
  },
1189
1308
  mutationName: "epistemicBeliefs.internalCreate"
1190
1309
  });
1191
- const topic = await ctx.db.get(scope.topicId);
1192
1310
  const normalizedBeliefType = await assertSchemaEnumValue(ctx, {
1193
1311
  category: "belief_type",
1194
1312
  value: args.beliefType,
1195
- tenantId: topic?.tenantId,
1313
+ tenantId: scope.tenantId,
1196
1314
  context: "epistemicBeliefs.internalCreate"
1197
1315
  });
1198
1316
  const globalId = generateGlobalId();
@@ -1256,9 +1374,15 @@ var internalCreate = internalMutation({
1256
1374
  rationale: "LKC-2 mandatory prior: seeded vacuous opinion at belief creation.",
1257
1375
  assessedBy: args.userId,
1258
1376
  assessedAt: now,
1259
- slOperator: "manual_assessment"
1377
+ slOperator: "prior_seed"
1260
1378
  })
1261
1379
  );
1380
+ await createRequiredBeliefTopicEdge(ctx, {
1381
+ beliefNodeId: nodeId,
1382
+ beliefGlobalId: globalId,
1383
+ topicNode,
1384
+ createdBy: args.userId
1385
+ });
1262
1386
  await ctx.scheduler.runAfter(0, internal.neo4jSync.syncNodeToNeo4j, {
1263
1387
  nodeId,
1264
1388
  operation: "upsert"