@lucern/graph-primitives 0.1.0-alpha.4 → 0.3.0-alpha.0

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 (38) hide show
  1. package/dist/beliefDecay.js +199 -18
  2. package/dist/beliefDecay.js.map +1 -1
  3. package/dist/beliefEvidenceLinks.js.map +1 -1
  4. package/dist/confidencePropagationDispatch.js.map +1 -1
  5. package/dist/contradictions.js.map +1 -1
  6. package/dist/entityBridge.js.map +1 -1
  7. package/dist/entityLifecycle.js.map +1 -1
  8. package/dist/epistemicAnswers.js +21 -36
  9. package/dist/epistemicAnswers.js.map +1 -1
  10. package/dist/epistemicBeliefs.js +92 -651
  11. package/dist/epistemicBeliefs.js.map +1 -1
  12. package/dist/epistemicContracts.js +65 -624
  13. package/dist/epistemicContracts.js.map +1 -1
  14. package/dist/epistemicEdges.js.map +1 -1
  15. package/dist/epistemicEvidence.js +71 -630
  16. package/dist/epistemicEvidence.js.map +1 -1
  17. package/dist/epistemicHelpers.js +3 -2
  18. package/dist/epistemicHelpers.js.map +1 -1
  19. package/dist/epistemicLinking.js.map +1 -1
  20. package/dist/epistemicNodes.js +49 -585
  21. package/dist/epistemicNodes.js.map +1 -1
  22. package/dist/epistemicQuestions.js +46 -590
  23. package/dist/epistemicQuestions.js.map +1 -1
  24. package/dist/epistemicSources.js +29 -565
  25. package/dist/epistemicSources.js.map +1 -1
  26. package/dist/evaluators/index.js +65 -624
  27. package/dist/evaluators/index.js.map +1 -1
  28. package/dist/index.js +304 -905
  29. package/dist/index.js.map +1 -1
  30. package/dist/ontologyApproval.js.map +1 -1
  31. package/dist/ontologyDefinitions.js.map +1 -1
  32. package/dist/ontologyRegistry.js.map +1 -1
  33. package/dist/projectionReconciliation.js.map +1 -1
  34. package/dist/questionEvidenceLinks.js +188 -2
  35. package/dist/questionEvidenceLinks.js.map +1 -1
  36. package/dist/workspaceIsolation.js +30 -581
  37. package/dist/workspaceIsolation.js.map +1 -1
  38. package/package.json +5 -6
@@ -1366,6 +1366,188 @@ function resolveGraphPrimitivesAppResolvers(_ctx) {
1366
1366
  ...resolverOverrides2
1367
1367
  };
1368
1368
  }
1369
+ var LEGACY_SCOPE_FIELD3 = "graphScopeProjectId";
1370
+ function asMappedProjectId(topic) {
1371
+ if (!topic) {
1372
+ return;
1373
+ }
1374
+ const directLegacyProjectId = normalizeScopeValue(topic[LEGACY_SCOPE_FIELD3]);
1375
+ if (directLegacyProjectId) {
1376
+ return directLegacyProjectId;
1377
+ }
1378
+ const metadata = topic.metadata || {};
1379
+ const candidate = metadata[LEGACY_SCOPE_FIELD3] || metadata.legacyProjectId || metadata.projectId || metadata.scopeProjectId;
1380
+ return candidate ? candidate : void 0;
1381
+ }
1382
+ function normalizeScopeValue(value) {
1383
+ if (typeof value !== "string") {
1384
+ return;
1385
+ }
1386
+ const normalized = value.trim();
1387
+ return normalized.length > 0 ? normalized : void 0;
1388
+ }
1389
+ function pickPrimaryTopic(candidates) {
1390
+ return [...candidates].sort((a, b) => {
1391
+ const depthA = a.depth ?? 9999;
1392
+ const depthB = b.depth ?? 9999;
1393
+ if (depthA !== depthB) {
1394
+ return depthA - depthB;
1395
+ }
1396
+ const createdA = a.createdAt ?? Number.MAX_SAFE_INTEGER;
1397
+ const createdB = b.createdAt ?? Number.MAX_SAFE_INTEGER;
1398
+ if (createdA !== createdB) {
1399
+ return createdA - createdB;
1400
+ }
1401
+ return String(a.name || "").localeCompare(String(b.name || ""));
1402
+ })[0];
1403
+ }
1404
+ async function findTopicsByScopeAlias(ctx, scopeId) {
1405
+ try {
1406
+ return await ctx.db.query("topics").withIndex(
1407
+ "by_graph_scope_project",
1408
+ (q) => q.eq(LEGACY_SCOPE_FIELD3, scopeId)
1409
+ ).collect();
1410
+ } catch {
1411
+ const topics = await ctx.db.query("topics").collect();
1412
+ return topics.filter((topic) => {
1413
+ const normalizedGlobalId = normalizeScopeValue(topic.globalId);
1414
+ const mappedProjectId = asMappedProjectId(topic);
1415
+ return String(topic._id) === scopeId || normalizedGlobalId === scopeId || mappedProjectId === scopeId;
1416
+ });
1417
+ }
1418
+ }
1419
+ async function tryResolveHostTopicById(ctx, topicId) {
1420
+ if (typeof ctx.runQuery !== "function") {
1421
+ return null;
1422
+ }
1423
+ try {
1424
+ return await ctx.runQuery(api2.topics.get, {
1425
+ id: topicId
1426
+ }) ?? null;
1427
+ } catch {
1428
+ return null;
1429
+ }
1430
+ }
1431
+ async function tryResolveHostTopicByLegacyScope(ctx, legacyScopeId) {
1432
+ if (typeof ctx.runQuery !== "function") {
1433
+ return null;
1434
+ }
1435
+ try {
1436
+ return await ctx.runQuery(api2.topics.getByLegacyScopeId, {
1437
+ projectId: legacyScopeId
1438
+ }) ?? null;
1439
+ } catch {
1440
+ return null;
1441
+ }
1442
+ }
1443
+ async function resolveInheritedWorkspaceScope(ctx, topic) {
1444
+ const MAX_DEPTH = 10;
1445
+ let tenantId = normalizeScopeValue(topic.tenantId);
1446
+ let workspaceId = normalizeScopeValue(topic.workspaceId);
1447
+ if (tenantId && workspaceId) {
1448
+ return { tenantId, workspaceId };
1449
+ }
1450
+ let current = topic;
1451
+ for (let i = 0; i < MAX_DEPTH && current?.parentTopicId; i++) {
1452
+ current = await ctx.db.get(current.parentTopicId);
1453
+ if (!current) break;
1454
+ if (!tenantId) {
1455
+ tenantId = normalizeScopeValue(current.tenantId);
1456
+ }
1457
+ if (!workspaceId) {
1458
+ workspaceId = normalizeScopeValue(current.workspaceId);
1459
+ }
1460
+ if (tenantId && workspaceId) break;
1461
+ }
1462
+ return { tenantId, workspaceId };
1463
+ }
1464
+ async function resolveTopicProjectScope(ctx, args) {
1465
+ if (args.topicId) {
1466
+ let topic = null;
1467
+ try {
1468
+ topic = await ctx.db.get(args.topicId);
1469
+ } catch {
1470
+ }
1471
+ if (!topic) {
1472
+ topic = await tryResolveHostTopicById(ctx, String(args.topicId));
1473
+ }
1474
+ if (!topic) {
1475
+ topic = pickPrimaryTopic(
1476
+ await findTopicsByScopeAlias(ctx, String(args.topicId))
1477
+ ) ?? null;
1478
+ }
1479
+ if (!topic) {
1480
+ throw new Error(`Topic not found: ${String(args.topicId)}`);
1481
+ }
1482
+ const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
1483
+ const mapped = asMappedProjectId(topic);
1484
+ if (mapped) {
1485
+ return {
1486
+ topicId: topic._id,
1487
+ projectId: mapped,
1488
+ tenantId: inherited.tenantId,
1489
+ workspaceId: inherited.workspaceId,
1490
+ source: "topic"
1491
+ };
1492
+ }
1493
+ return {
1494
+ topicId: topic._id,
1495
+ tenantId: inherited.tenantId,
1496
+ workspaceId: inherited.workspaceId,
1497
+ source: "topic"
1498
+ };
1499
+ }
1500
+ if (args.projectId) {
1501
+ let directTopic = null;
1502
+ try {
1503
+ directTopic = await ctx.db.get(
1504
+ args.projectId
1505
+ );
1506
+ } catch {
1507
+ }
1508
+ if (directTopic) {
1509
+ const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
1510
+ const mapped = asMappedProjectId(directTopic);
1511
+ return {
1512
+ topicId: directTopic._id,
1513
+ projectId: mapped ?? args.projectId,
1514
+ tenantId: inherited.tenantId,
1515
+ workspaceId: inherited.workspaceId,
1516
+ source: "topic_inferred"
1517
+ };
1518
+ }
1519
+ directTopic = await tryResolveHostTopicByLegacyScope(ctx, args.projectId);
1520
+ if (directTopic) {
1521
+ const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
1522
+ const mapped = asMappedProjectId(directTopic);
1523
+ return {
1524
+ topicId: directTopic._id,
1525
+ projectId: mapped ?? args.projectId,
1526
+ tenantId: inherited.tenantId,
1527
+ workspaceId: inherited.workspaceId,
1528
+ source: "topic_inferred"
1529
+ };
1530
+ }
1531
+ const topics = await findTopicsByScopeAlias(ctx, args.projectId);
1532
+ const primary = pickPrimaryTopic(topics);
1533
+ if (primary) {
1534
+ const inherited = await resolveInheritedWorkspaceScope(ctx, primary);
1535
+ return {
1536
+ topicId: primary._id,
1537
+ projectId: args.projectId,
1538
+ tenantId: inherited.tenantId,
1539
+ workspaceId: inherited.workspaceId,
1540
+ source: "project_mapped_topic"
1541
+ };
1542
+ }
1543
+ throw new Error(
1544
+ `Legacy project scope ${String(args.projectId)} has no mapped topic.`
1545
+ );
1546
+ }
1547
+ throw new Error(
1548
+ "Missing scope: provide topicId (preferred) or legacy projectId alias."
1549
+ );
1550
+ }
1369
1551
  var optionalScopeArgs = {
1370
1552
  projectId: v.optional(v.string()),
1371
1553
  topicId: v.optional(v.string())
@@ -1388,7 +1570,11 @@ var identifyBeliefsNeedingRescore = query({
1388
1570
  },
1389
1571
  returns: permissiveReturn,
1390
1572
  handler: async (ctx, args) => {
1391
- const { projectId, maxResults = 20, minPriority = "medium" } = args;
1573
+ const { maxResults = 20, minPriority = "medium" } = args;
1574
+ const scope = await resolveTopicProjectScope(ctx, args).catch(() => null);
1575
+ if (!scope) {
1576
+ return [];
1577
+ }
1392
1578
  const priorityRank = {
1393
1579
  critical: 4,
1394
1580
  high: 3,
@@ -1397,8 +1583,8 @@ var identifyBeliefsNeedingRescore = query({
1397
1583
  };
1398
1584
  const minRank = priorityRank[minPriority] ?? 2;
1399
1585
  const beliefs = await ctx.db.query("epistemicNodes").withIndex(
1400
- args.topicId ? "by_topic_type" : "by_project_type",
1401
- (q) => args.topicId ? q.eq("topicId", args.topicId).eq("nodeType", "belief") : q.eq("projectId", projectId).eq("nodeType", "belief")
1586
+ "by_topic_type",
1587
+ (q) => q.eq("topicId", scope.topicId).eq("nodeType", "belief")
1402
1588
  ).collect();
1403
1589
  const activeBeliefs = beliefs.filter((b) => b.status === "active");
1404
1590
  const results = [];
@@ -1488,21 +1674,16 @@ var getGlobalBeliefHealth = query({
1488
1674
  );
1489
1675
  const allResults = [];
1490
1676
  for (const project2 of accessibleProjects.slice(0, 20)) {
1491
- const [topicBeliefs, projectBeliefs] = await Promise.all([
1492
- ctx.db.query("epistemicNodes").withIndex(
1493
- "by_topic_type",
1494
- (q) => q.eq("topicId", project2._id).eq("nodeType", "belief")
1495
- ).collect(),
1496
- ctx.db.query("epistemicNodes").withIndex(
1497
- "by_project_type",
1498
- (q) => q.eq("projectId", project2._id).eq("nodeType", "belief")
1499
- ).collect()
1500
- ]);
1501
- const beliefs = Array.from(
1502
- new Map(
1503
- [...topicBeliefs, ...projectBeliefs].map((b) => [String(b._id), b])
1504
- ).values()
1505
- );
1677
+ const scope = await resolveTopicProjectScope(ctx, {
1678
+ projectId: String(project2._id)
1679
+ }).catch(() => null);
1680
+ if (!scope) {
1681
+ continue;
1682
+ }
1683
+ const beliefs = await ctx.db.query("epistemicNodes").withIndex(
1684
+ "by_topic_type",
1685
+ (q) => q.eq("topicId", scope.topicId).eq("nodeType", "belief")
1686
+ ).collect();
1506
1687
  const activeBeliefs = beliefs.filter((b) => b.status === "active");
1507
1688
  for (const belief of activeBeliefs) {
1508
1689
  const metadata = belief.metadata || {};