@lucern/graph-primitives 1.0.23 → 1.0.24

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 { checkScopeAccess, checkProjectAccess } from '@lucern/access-control/access';
3
3
  import { assertSchemaEnumValue } from '@lucern/contracts/schema-helpers/enumValidation';
4
4
  import { permissiveReturn } from '@lucern/contracts/schema-helpers/validators';
@@ -7,7 +7,7 @@ import { normalizeTupleContradictionPolicy, createInheritedContractRecord, confi
7
7
  import '@lucern/access-control/audience';
8
8
  import { getCurrentUserId } from '@lucern/access-control/auth';
9
9
  import { isNodeType, getLayerForNodeType } from '@lucern/contracts/schema-helpers/spine/tables/epistemicNodes';
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
 
13
13
  // src/epistemicBeliefs.core.ts
@@ -273,6 +273,9 @@ function materializeTopicProjectOverlay(topic, idMode = "legacy") {
273
273
  type: mapProjectType(topic, metadata),
274
274
  description: readNonEmptyString(topic.description),
275
275
  ownerId: readNonEmptyString(metadata.ownerId) || readNonEmptyString(topic.createdBy) || "system",
276
+ // FR.7 creator-grant: surface the principal-shaped owner field (column-first,
277
+ // metadata fallback for legacy rows that recorded it in metadata).
278
+ ownerPrincipalId: readNonEmptyString(topic.ownerPrincipalId) || readNonEmptyString(metadata.ownerPrincipalId),
276
279
  sharedWith: readStringArray(metadata.sharedWith),
277
280
  visibility,
278
281
  tenantId: readNonEmptyString(topic.tenantId) || readNonEmptyString(metadata.tenantId),
@@ -806,7 +809,18 @@ var DEFAULT_CONFIDENCE_POLICY = {
806
809
  tupleContradiction: normalizeTupleContradictionPolicy()
807
810
  };
808
811
  function throwStructuredMutationError(args) {
809
- const error = new Error(args.message);
812
+ const data = {
813
+ structuredMutationError: true,
814
+ message: args.message,
815
+ status: args.status,
816
+ code: args.code,
817
+ invariantCode: args.invariantCode,
818
+ suggestion: args.suggestion,
819
+ details: args.details
820
+ };
821
+ const error = new ConvexError(
822
+ data
823
+ );
810
824
  error.status = args.status;
811
825
  error.code = args.code;
812
826
  error.invariantCode = args.invariantCode;
@@ -964,12 +978,12 @@ async function requireProjectWriteAccess(ctx, projectId, userId) {
964
978
  );
965
979
  if (!hasAccess) {
966
980
  throwStructuredMutationError({
967
- message: "Project access required.",
981
+ message: `Project write access denied for topic ${projectId}.`,
968
982
  status: 403,
969
- code: "FORBIDDEN",
983
+ code: "PROJECT_ACCESS_DENIED",
970
984
  invariantCode: "policy.scope_required",
971
- suggestion: "Request write access for the project and retry.",
972
- details: { projectId, userId }
985
+ 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.",
986
+ details: { topicId: projectId, principalId: userId }
973
987
  });
974
988
  }
975
989
  }
@@ -1074,6 +1088,15 @@ async function insertEpistemicNode(ctx, doc) {
1074
1088
  assertUuidV7Identity("epistemicNodes", doc.globalId);
1075
1089
  return ctx.db.insert("epistemicNodes", doc);
1076
1090
  }
1091
+ async function assertExistingNodeEndpoint(ctx, endpointRole, endpoint) {
1092
+ assertUuidShapedEdgeEndpoint(endpointRole, endpoint);
1093
+ const node = await ctx.db.query("epistemicNodes").withIndex("by_globalId", (q) => q.eq("globalId", endpoint)).first();
1094
+ if (!node) {
1095
+ throw new Error(
1096
+ `edge_endpoint_not_canonical: epistemicEdges insert requires ${endpointRole} to be the globalId of an existing epistemicNodes row, received ${endpoint} (no node with that globalId)`
1097
+ );
1098
+ }
1099
+ }
1077
1100
  async function insertEpistemicEdge(ctx, doc) {
1078
1101
  assertUuidV7Identity("epistemicEdges", doc.globalId);
1079
1102
  assertStorageEdgeVocabulary(doc.edgeType);
@@ -1087,8 +1110,8 @@ async function insertEpistemicEdge(ctx, doc) {
1087
1110
  "edge_endpoint_missing: epistemicEdges insert requires a non-empty toNodeId"
1088
1111
  );
1089
1112
  }
1090
- assertCanonicalEdgeEndpoint("fromNodeId", doc.fromNodeId);
1091
- assertCanonicalEdgeEndpoint("toNodeId", doc.toNodeId);
1113
+ await assertExistingNodeEndpoint(ctx, "fromNodeId", doc.fromNodeId);
1114
+ await assertExistingNodeEndpoint(ctx, "toNodeId", doc.toNodeId);
1092
1115
  if (doc.fromNodeType && doc.toNodeType && doc.edgeType !== "extracted_from") {
1093
1116
  assertEdgePolicyAllowed(
1094
1117
  edgePolicyManifest,