@lucern/graph-primitives 1.0.23 → 1.0.25

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/beliefDecay.js +3 -0
  2. package/dist/beliefDecay.js.map +1 -1
  3. package/dist/beliefEvidenceLinks.js +15 -3
  4. package/dist/beliefEvidenceLinks.js.map +1 -1
  5. package/dist/beliefEvidenceLinks.operational.js +12 -3
  6. package/dist/beliefEvidenceLinks.operational.js.map +1 -1
  7. package/dist/entityCanonicalMatch.d.ts +40 -0
  8. package/dist/entityCanonicalMatch.js +33 -0
  9. package/dist/entityCanonicalMatch.js.map +1 -0
  10. package/dist/entityLifecycle.js +62 -37
  11. package/dist/entityLifecycle.js.map +1 -1
  12. package/dist/epistemicAnswers.js.map +1 -1
  13. package/dist/epistemicBeliefs.admin.js +17 -6
  14. package/dist/epistemicBeliefs.admin.js.map +1 -1
  15. package/dist/epistemicBeliefs.backfills.js +13 -2
  16. package/dist/epistemicBeliefs.backfills.js.map +1 -1
  17. package/dist/epistemicBeliefs.confidence.js +17 -6
  18. package/dist/epistemicBeliefs.confidence.js.map +1 -1
  19. package/dist/epistemicBeliefs.core.js +32 -9
  20. package/dist/epistemicBeliefs.core.js.map +1 -1
  21. package/dist/epistemicBeliefs.forkEvidence.js +13 -2
  22. package/dist/epistemicBeliefs.forkEvidence.js.map +1 -1
  23. package/dist/epistemicBeliefs.helpers.d.ts +16 -1
  24. package/dist/epistemicBeliefs.helpers.js +20 -6
  25. package/dist/epistemicBeliefs.helpers.js.map +1 -1
  26. package/dist/epistemicBeliefs.internal.js +28 -5
  27. package/dist/epistemicBeliefs.internal.js.map +1 -1
  28. package/dist/epistemicBeliefs.js +32 -9
  29. package/dist/epistemicBeliefs.js.map +1 -1
  30. package/dist/epistemicBeliefs.lifecycle.js +17 -6
  31. package/dist/epistemicBeliefs.lifecycle.js.map +1 -1
  32. package/dist/epistemicBeliefs.links.js +29 -9
  33. package/dist/epistemicBeliefs.links.js.map +1 -1
  34. package/dist/epistemicBeliefs.topicAnchor.js +12 -3
  35. package/dist/epistemicBeliefs.topicAnchor.js.map +1 -1
  36. package/dist/epistemicContracts.evaluators.js +17 -6
  37. package/dist/epistemicContracts.evaluators.js.map +1 -1
  38. package/dist/epistemicContracts.handlers.js +17 -6
  39. package/dist/epistemicContracts.handlers.js.map +1 -1
  40. package/dist/epistemicContracts.js +17 -6
  41. package/dist/epistemicContracts.js.map +1 -1
  42. package/dist/epistemicEdges.handlers.js +12 -3
  43. package/dist/epistemicEdges.handlers.js.map +1 -1
  44. package/dist/epistemicEdges.helpers.d.ts +2 -2
  45. package/dist/epistemicEdges.js +15 -3
  46. package/dist/epistemicEdges.js.map +1 -1
  47. package/dist/epistemicEdges.mutations.js +3 -0
  48. package/dist/epistemicEdges.mutations.js.map +1 -1
  49. package/dist/epistemicEvidence.js +15 -3
  50. package/dist/epistemicEvidence.js.map +1 -1
  51. package/dist/epistemicEvidenceHelpers.js +3 -0
  52. package/dist/epistemicEvidenceHelpers.js.map +1 -1
  53. package/dist/epistemicEvidenceMutations.js +15 -3
  54. package/dist/epistemicEvidenceMutations.js.map +1 -1
  55. package/dist/epistemicEvidenceQueries.js +3 -0
  56. package/dist/epistemicEvidenceQueries.js.map +1 -1
  57. package/dist/epistemicHelpers.js.map +1 -1
  58. package/dist/epistemicInsert.js +12 -3
  59. package/dist/epistemicInsert.js.map +1 -1
  60. package/dist/epistemicNodeCreation.js.map +1 -1
  61. package/dist/epistemicNodes.internal.js.map +1 -1
  62. package/dist/epistemicNodes.js.map +1 -1
  63. package/dist/epistemicNodes.mutations.js.map +1 -1
  64. package/dist/epistemicNodes.validators.d.ts +2 -2
  65. package/dist/epistemicQuestions.conviction.js +3 -0
  66. package/dist/epistemicQuestions.conviction.js.map +1 -1
  67. package/dist/epistemicQuestions.create.js +3 -0
  68. package/dist/epistemicQuestions.create.js.map +1 -1
  69. package/dist/epistemicQuestions.evidence.js +3 -0
  70. package/dist/epistemicQuestions.evidence.js.map +1 -1
  71. package/dist/epistemicQuestions.helpers.js +3 -0
  72. package/dist/epistemicQuestions.helpers.js.map +1 -1
  73. package/dist/epistemicQuestions.js +3 -0
  74. package/dist/epistemicQuestions.js.map +1 -1
  75. package/dist/epistemicQuestions.lifecycle.js +3 -0
  76. package/dist/epistemicQuestions.lifecycle.js.map +1 -1
  77. package/dist/epistemicQuestions.queries.js +3 -0
  78. package/dist/epistemicQuestions.queries.js.map +1 -1
  79. package/dist/epistemicQuestions.tail.js +3 -0
  80. package/dist/epistemicQuestions.tail.js.map +1 -1
  81. package/dist/epistemicSources.js.map +1 -1
  82. package/dist/index.js +78 -42
  83. package/dist/index.js.map +1 -1
  84. package/dist/proof-attestation.json +1 -1
  85. package/dist/questionEvidenceLinks.js +3 -0
  86. package/dist/questionEvidenceLinks.js.map +1 -1
  87. package/dist/resolvers.js +3 -0
  88. package/dist/resolvers.js.map +1 -1
  89. package/dist/topicProjectOverlay.d.ts +4 -0
  90. package/dist/topicProjectOverlay.js +3 -0
  91. package/dist/topicProjectOverlay.js.map +1 -1
  92. package/package.json +4 -4
@@ -1,4 +1,4 @@
1
- import { v } from 'convex/values';
1
+ import { v, ConvexError } from 'convex/values';
2
2
  import { normalizeTupleContradictionPolicy, mkOpinion, createInheritedContractRecord, confidenceFromSL, conditionalDeduction, project, dampedDependencyCascade, hasProjectedOpinionChanged, detectTupleContradiction, evaluateTupleContradictionTransition, readOpinionFromRecord, trustDiscount, applyNegativeSupport, cumulativeFusion, applyNegativeEvidence } from '@lucern/confidence';
3
3
  import { checkScopeAccess, checkProjectAccess } from '@lucern/access-control/access';
4
4
  import { canAudienceClassAccess, normalizeAudienceKey, classFromAudienceKey } from '@lucern/access-control/audience';
@@ -7,7 +7,7 @@ import { componentsGeneric, anyApi, internalMutationGeneric, mutationGeneric, qu
7
7
  import { isNodeType, getLayerForNodeType } from '@lucern/contracts/schema-helpers/spine/tables/epistemicNodes';
8
8
  import { permissiveReturn } from '@lucern/contracts/schema-helpers/validators';
9
9
  import { assertSchemaEnumValue } from '@lucern/contracts/schema-helpers/enumValidation';
10
- import { generateGlobalId, assertUuidV7Identity, generateUuidV7, assertStorageEdgeVocabulary, assertCanonicalEdgeEndpoint } from '@lucern/contracts/ids';
10
+ import { generateGlobalId, assertUuidV7Identity, generateUuidV7, assertStorageEdgeVocabulary, assertUuidShapedEdgeEndpoint } from '@lucern/contracts/ids';
11
11
  import { assertEdgePolicyAllowed, edgePolicyManifest } from '@lucern/contracts';
12
12
  import { listAudienceRegistryRows } from '@lucern/access-control/audienceRegistry';
13
13
 
@@ -286,6 +286,9 @@ function materializeTopicProjectOverlay(topic, idMode = "legacy") {
286
286
  type: mapProjectType(topic, metadata),
287
287
  description: readNonEmptyString(topic.description),
288
288
  ownerId: readNonEmptyString(metadata.ownerId) || readNonEmptyString(topic.createdBy) || "system",
289
+ // FR.7 creator-grant: surface the principal-shaped owner field (column-first,
290
+ // metadata fallback for legacy rows that recorded it in metadata).
291
+ ownerPrincipalId: readNonEmptyString(topic.ownerPrincipalId) || readNonEmptyString(metadata.ownerPrincipalId),
289
292
  sharedWith: readStringArray(metadata.sharedWith),
290
293
  visibility,
291
294
  tenantId: readNonEmptyString(topic.tenantId) || readNonEmptyString(metadata.tenantId),
@@ -907,7 +910,18 @@ var DEFAULT_CONFIDENCE_POLICY = {
907
910
  tupleContradiction: normalizeTupleContradictionPolicy()
908
911
  };
909
912
  function throwStructuredMutationError(args) {
910
- const error = new Error(args.message);
913
+ const data = {
914
+ structuredMutationError: true,
915
+ message: args.message,
916
+ status: args.status,
917
+ code: args.code,
918
+ invariantCode: args.invariantCode,
919
+ suggestion: args.suggestion,
920
+ details: args.details
921
+ };
922
+ const error = new ConvexError(
923
+ data
924
+ );
911
925
  error.status = args.status;
912
926
  error.code = args.code;
913
927
  error.invariantCode = args.invariantCode;
@@ -1256,12 +1270,12 @@ async function requireProjectWriteAccess(ctx, projectId, userId) {
1256
1270
  );
1257
1271
  if (!hasAccess) {
1258
1272
  throwStructuredMutationError({
1259
- message: "Project access required.",
1273
+ message: `Project write access denied for topic ${projectId}.`,
1260
1274
  status: 403,
1261
- code: "FORBIDDEN",
1275
+ code: "PROJECT_ACCESS_DENIED",
1262
1276
  invariantCode: "policy.scope_required",
1263
- suggestion: "Request write access for the project and retry.",
1264
- details: { projectId, userId }
1277
+ suggestion: "The acting principal lacks project-write access to this topic. Request a topic grant (or, if the principal created this topic, run the creator-grant backfill) and retry.",
1278
+ details: { topicId: projectId, principalId: userId }
1265
1279
  });
1266
1280
  }
1267
1281
  }
@@ -2085,6 +2099,15 @@ async function insertEpistemicNode(ctx, doc) {
2085
2099
  assertUuidV7Identity("epistemicNodes", doc.globalId);
2086
2100
  return ctx.db.insert("epistemicNodes", doc);
2087
2101
  }
2102
+ async function assertExistingNodeEndpoint(ctx, endpointRole, endpoint) {
2103
+ assertUuidShapedEdgeEndpoint(endpointRole, endpoint);
2104
+ const node = await ctx.db.query("epistemicNodes").withIndex("by_globalId", (q) => q.eq("globalId", endpoint)).first();
2105
+ if (!node) {
2106
+ throw new Error(
2107
+ `edge_endpoint_not_canonical: epistemicEdges insert requires ${endpointRole} to be the globalId of an existing epistemicNodes row, received ${endpoint} (no node with that globalId)`
2108
+ );
2109
+ }
2110
+ }
2088
2111
  async function insertEpistemicEdge(ctx, doc) {
2089
2112
  assertUuidV7Identity("epistemicEdges", doc.globalId);
2090
2113
  assertStorageEdgeVocabulary(doc.edgeType);
@@ -2098,8 +2121,8 @@ async function insertEpistemicEdge(ctx, doc) {
2098
2121
  "edge_endpoint_missing: epistemicEdges insert requires a non-empty toNodeId"
2099
2122
  );
2100
2123
  }
2101
- assertCanonicalEdgeEndpoint("fromNodeId", doc.fromNodeId);
2102
- assertCanonicalEdgeEndpoint("toNodeId", doc.toNodeId);
2124
+ await assertExistingNodeEndpoint(ctx, "fromNodeId", doc.fromNodeId);
2125
+ await assertExistingNodeEndpoint(ctx, "toNodeId", doc.toNodeId);
2103
2126
  if (doc.fromNodeType && doc.toNodeType && doc.edgeType !== "extracted_from") {
2104
2127
  assertEdgePolicyAllowed(
2105
2128
  edgePolicyManifest,