@lucern/graph-primitives 1.0.22 → 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.
- package/dist/beliefDecay.js +49 -0
- package/dist/beliefDecay.js.map +1 -1
- package/dist/beliefEvidenceLinks.js +99 -5
- package/dist/beliefEvidenceLinks.js.map +1 -1
- package/dist/beliefEvidenceLinks.operational.js +50 -5
- package/dist/beliefEvidenceLinks.operational.js.map +1 -1
- package/dist/contradictions.js +46 -0
- package/dist/contradictions.js.map +1 -1
- package/dist/edgeValidation.js +66 -1
- package/dist/edgeValidation.js.map +1 -1
- package/dist/entityBridge.js +66 -1
- package/dist/entityBridge.js.map +1 -1
- package/dist/entityCanonicalMatch.d.ts +40 -0
- package/dist/entityCanonicalMatch.js +33 -0
- package/dist/entityCanonicalMatch.js.map +1 -0
- package/dist/entityLifecycle.js +149 -39
- package/dist/entityLifecycle.js.map +1 -1
- package/dist/epistemicAnswers.js +64 -11
- package/dist/epistemicAnswers.js.map +1 -1
- package/dist/epistemicBeliefs.admin.js +63 -6
- package/dist/epistemicBeliefs.admin.js.map +1 -1
- package/dist/epistemicBeliefs.backfills.js +59 -2
- package/dist/epistemicBeliefs.backfills.js.map +1 -1
- package/dist/epistemicBeliefs.confidence.d.ts +1 -1
- package/dist/epistemicBeliefs.confidence.js +70 -12
- package/dist/epistemicBeliefs.confidence.js.map +1 -1
- package/dist/epistemicBeliefs.core.js +120 -17
- package/dist/epistemicBeliefs.core.js.map +1 -1
- package/dist/epistemicBeliefs.d.ts +1 -1
- package/dist/epistemicBeliefs.forkEvidence.js +13 -2
- package/dist/epistemicBeliefs.forkEvidence.js.map +1 -1
- package/dist/epistemicBeliefs.helpers.d.ts +18 -3
- package/dist/epistemicBeliefs.helpers.js +66 -6
- package/dist/epistemicBeliefs.helpers.js.map +1 -1
- package/dist/epistemicBeliefs.internal.js +115 -12
- package/dist/epistemicBeliefs.internal.js.map +1 -1
- package/dist/epistemicBeliefs.js +132 -28
- package/dist/epistemicBeliefs.js.map +1 -1
- package/dist/epistemicBeliefs.lifecycle.js +70 -12
- package/dist/epistemicBeliefs.lifecycle.js.map +1 -1
- package/dist/epistemicBeliefs.links.js +111 -10
- package/dist/epistemicBeliefs.links.js.map +1 -1
- package/dist/epistemicBeliefs.topicAnchor.js +48 -8
- package/dist/epistemicBeliefs.topicAnchor.js.map +1 -1
- package/dist/epistemicContracts.evaluators.js +70 -12
- package/dist/epistemicContracts.evaluators.js.map +1 -1
- package/dist/epistemicContracts.handlers.js +71 -16
- package/dist/epistemicContracts.handlers.js.map +1 -1
- package/dist/epistemicContracts.js +71 -16
- package/dist/epistemicContracts.js.map +1 -1
- package/dist/epistemicEdges.d.ts +1 -1
- package/dist/epistemicEdges.handlers.js +57 -3
- package/dist/epistemicEdges.handlers.js.map +1 -1
- package/dist/epistemicEdges.helpers.d.ts +2 -2
- package/dist/epistemicEdges.js +174 -4
- package/dist/epistemicEdges.js.map +1 -1
- package/dist/epistemicEdges.mutations.js +115 -1
- package/dist/epistemicEdges.mutations.js.map +1 -1
- package/dist/epistemicEdges.queries.js +46 -0
- package/dist/epistemicEdges.queries.js.map +1 -1
- package/dist/epistemicEdges.types.d.ts +1 -1
- package/dist/epistemicEvidence.d.ts +1 -1
- package/dist/epistemicEvidence.js +180 -14
- package/dist/epistemicEvidence.js.map +1 -1
- package/dist/epistemicEvidenceHelpers.d.ts +1 -1
- package/dist/epistemicEvidenceHelpers.js +49 -0
- package/dist/epistemicEvidenceHelpers.js.map +1 -1
- package/dist/epistemicEvidenceMutations.js +180 -14
- package/dist/epistemicEvidenceMutations.js.map +1 -1
- package/dist/epistemicEvidenceQueries.js +49 -0
- package/dist/epistemicEvidenceQueries.js.map +1 -1
- package/dist/epistemicHelpers.js +11 -6
- package/dist/epistemicHelpers.js.map +1 -1
- package/dist/epistemicInsert.d.ts +8 -0
- package/dist/epistemicInsert.js +54 -0
- package/dist/epistemicInsert.js.map +1 -0
- package/dist/epistemicNodeCreation.js +11 -6
- package/dist/epistemicNodeCreation.js.map +1 -1
- package/dist/epistemicNodes.helpers.d.ts +1 -1
- package/dist/epistemicNodes.internal.js +53 -1
- package/dist/epistemicNodes.internal.js.map +1 -1
- package/dist/epistemicNodes.js +56 -4
- package/dist/epistemicNodes.js.map +1 -1
- package/dist/epistemicNodes.mutations.js +55 -3
- package/dist/epistemicNodes.mutations.js.map +1 -1
- package/dist/epistemicNodes.queries.js +46 -0
- package/dist/epistemicNodes.queries.js.map +1 -1
- package/dist/epistemicNodes.validators.d.ts +1 -1
- package/dist/epistemicQuestions.conviction.js +49 -0
- package/dist/epistemicQuestions.conviction.js.map +1 -1
- package/dist/epistemicQuestions.create.js +61 -7
- package/dist/epistemicQuestions.create.js.map +1 -1
- package/dist/epistemicQuestions.d.ts +1 -1
- package/dist/epistemicQuestions.evidence.js +56 -2
- package/dist/epistemicQuestions.evidence.js.map +1 -1
- package/dist/epistemicQuestions.helpers.d.ts +1 -1
- package/dist/epistemicQuestions.helpers.js +49 -0
- package/dist/epistemicQuestions.helpers.js.map +1 -1
- package/dist/epistemicQuestions.js +63 -9
- package/dist/epistemicQuestions.js.map +1 -1
- package/dist/epistemicQuestions.lifecycle.js +49 -0
- package/dist/epistemicQuestions.lifecycle.js.map +1 -1
- package/dist/epistemicQuestions.queries.js +49 -0
- package/dist/epistemicQuestions.queries.js.map +1 -1
- package/dist/epistemicQuestions.sprint.js +46 -0
- package/dist/epistemicQuestions.sprint.js.map +1 -1
- package/dist/epistemicQuestions.tail.js +56 -2
- package/dist/epistemicQuestions.tail.js.map +1 -1
- package/dist/epistemicSources.js +53 -2
- package/dist/epistemicSources.js.map +1 -1
- package/dist/helpers.js +66 -1
- package/dist/helpers.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +379 -115
- package/dist/index.js.map +1 -1
- package/dist/proof-attestation.json +1 -1
- package/dist/questionEvidenceLinks.js +49 -0
- package/dist/questionEvidenceLinks.js.map +1 -1
- package/dist/resolvers.js +3 -0
- package/dist/resolvers.js.map +1 -1
- package/dist/scopeResolverCompat.d.ts +1 -1
- package/dist/scopeResolverCompat.js +46 -0
- package/dist/scopeResolverCompat.js.map +1 -1
- package/dist/topicProjectOverlay.d.ts +4 -0
- package/dist/topicProjectOverlay.js +3 -0
- package/dist/topicProjectOverlay.js.map +1 -1
- package/dist/{topicScope-By_zp4tt.d.ts → topicScope-7zhyeGl7.d.ts} +1 -1
- package/dist/topicScope.d.ts +1 -1
- package/dist/topicScope.js +46 -0
- package/dist/topicScope.js.map +1 -1
- package/dist/workflowBridge.js +46 -0
- package/dist/workflowBridge.js.map +1 -1
- package/dist/workspaceIsolation.d.ts +1 -1
- package/dist/workspaceIsolation.js +46 -0
- package/dist/workspaceIsolation.js.map +1 -1
- package/package.json +4 -4
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { v } from 'convex/values';
|
|
1
|
+
import { v, ConvexError } from 'convex/values';
|
|
2
2
|
import { canAudienceClassAccess, normalizeAudienceKey, classFromAudienceKey } from '@lucern/access-control/audience';
|
|
3
3
|
import { listAudienceRegistryRows } from '@lucern/access-control/audienceRegistry';
|
|
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, generateUuidV7 } from '@lucern/contracts/ids';
|
|
7
|
+
import { generateGlobalId, assertUuidV7Identity, generateUuidV7, assertStorageEdgeVocabulary, assertUuidShapedEdgeEndpoint } from '@lucern/contracts/ids';
|
|
8
|
+
import { assertEdgePolicyAllowed, edgePolicyManifest } from '@lucern/contracts';
|
|
8
9
|
import { isNodeType, getLayerForNodeType } from '@lucern/contracts/schema-helpers/spine/tables/epistemicNodes';
|
|
9
10
|
import { normalizeTupleContradictionPolicy, confidenceFromSL } from '@lucern/confidence';
|
|
10
11
|
import '@lucern/access-control/access';
|
|
@@ -31,6 +32,35 @@ function debugGraphPrimitiveFallback(message, context) {
|
|
|
31
32
|
|
|
32
33
|
// src/topicScope.ts
|
|
33
34
|
var LEGACY_SCOPE_FIELD = "graphScopeProjectId";
|
|
35
|
+
async function resolveTopicNodeScopeOrNull(ctx, ref) {
|
|
36
|
+
if (!ctx?.db || typeof ctx.db.query !== "function") {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
let node = null;
|
|
40
|
+
try {
|
|
41
|
+
const byGlobalId = await ctx.db.query("epistemicNodes").withIndex("by_globalId", (q) => q.eq("globalId", ref)).first();
|
|
42
|
+
if (byGlobalId && byGlobalId.nodeType === "topic") {
|
|
43
|
+
node = byGlobalId;
|
|
44
|
+
}
|
|
45
|
+
} catch (error) {
|
|
46
|
+
debugGraphPrimitiveFallback(
|
|
47
|
+
"[topicScope] topic-node scope lookup by globalId failed",
|
|
48
|
+
{ error, ref }
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
if (!node) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
const scopeKey = normalizeScopeValue(node.topicId) ?? normalizeScopeValue(node.globalId);
|
|
55
|
+
if (!scopeKey) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
topicId: scopeKey,
|
|
60
|
+
projectId: asMappedProjectId(node),
|
|
61
|
+
source: "topic_node"
|
|
62
|
+
};
|
|
63
|
+
}
|
|
34
64
|
function asMappedProjectId(topic) {
|
|
35
65
|
if (!topic) {
|
|
36
66
|
return;
|
|
@@ -171,6 +201,13 @@ async function resolveTopicProjectScope(ctx, args) {
|
|
|
171
201
|
) ?? null;
|
|
172
202
|
}
|
|
173
203
|
if (!topic) {
|
|
204
|
+
const nodeScope = await resolveTopicNodeScopeOrNull(
|
|
205
|
+
ctx,
|
|
206
|
+
String(args.topicId)
|
|
207
|
+
);
|
|
208
|
+
if (nodeScope) {
|
|
209
|
+
return nodeScope;
|
|
210
|
+
}
|
|
174
211
|
throw new Error(`Topic not found: ${String(args.topicId)}`);
|
|
175
212
|
}
|
|
176
213
|
const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
|
|
@@ -241,6 +278,16 @@ async function resolveTopicProjectScope(ctx, args) {
|
|
|
241
278
|
source: "project_mapped_topic"
|
|
242
279
|
};
|
|
243
280
|
}
|
|
281
|
+
const nodeScope = await resolveTopicNodeScopeOrNull(
|
|
282
|
+
ctx,
|
|
283
|
+
String(args.projectId)
|
|
284
|
+
);
|
|
285
|
+
if (nodeScope) {
|
|
286
|
+
return {
|
|
287
|
+
...nodeScope,
|
|
288
|
+
projectId: nodeScope.projectId ?? String(args.projectId)
|
|
289
|
+
};
|
|
290
|
+
}
|
|
244
291
|
throw new Error(
|
|
245
292
|
`Legacy project scope ${String(args.projectId)} has no mapped topic.`
|
|
246
293
|
);
|
|
@@ -253,6 +300,52 @@ var optionalScopeArgs = {
|
|
|
253
300
|
projectId: v.optional(v.string()),
|
|
254
301
|
topicId: v.optional(v.string())
|
|
255
302
|
};
|
|
303
|
+
async function insertEpistemicNode(ctx, doc) {
|
|
304
|
+
assertUuidV7Identity("epistemicNodes", doc.globalId);
|
|
305
|
+
return ctx.db.insert("epistemicNodes", doc);
|
|
306
|
+
}
|
|
307
|
+
async function assertExistingNodeEndpoint(ctx, endpointRole, endpoint) {
|
|
308
|
+
assertUuidShapedEdgeEndpoint(endpointRole, endpoint);
|
|
309
|
+
const node = await ctx.db.query("epistemicNodes").withIndex("by_globalId", (q) => q.eq("globalId", endpoint)).first();
|
|
310
|
+
if (!node) {
|
|
311
|
+
throw new Error(
|
|
312
|
+
`edge_endpoint_not_canonical: epistemicEdges insert requires ${endpointRole} to be the globalId of an existing epistemicNodes row, received ${endpoint} (no node with that globalId)`
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
async function insertEpistemicEdge(ctx, doc) {
|
|
317
|
+
assertUuidV7Identity("epistemicEdges", doc.globalId);
|
|
318
|
+
assertStorageEdgeVocabulary(doc.edgeType);
|
|
319
|
+
if (!doc.fromNodeId || typeof doc.fromNodeId !== "string") {
|
|
320
|
+
throw new Error(
|
|
321
|
+
"edge_endpoint_missing: epistemicEdges insert requires a non-empty fromNodeId"
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
if (!doc.toNodeId || typeof doc.toNodeId !== "string") {
|
|
325
|
+
throw new Error(
|
|
326
|
+
"edge_endpoint_missing: epistemicEdges insert requires a non-empty toNodeId"
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
await assertExistingNodeEndpoint(ctx, "fromNodeId", doc.fromNodeId);
|
|
330
|
+
await assertExistingNodeEndpoint(ctx, "toNodeId", doc.toNodeId);
|
|
331
|
+
if (doc.fromNodeType && doc.toNodeType && doc.edgeType !== "extracted_from") {
|
|
332
|
+
assertEdgePolicyAllowed(
|
|
333
|
+
edgePolicyManifest,
|
|
334
|
+
doc.edgeType,
|
|
335
|
+
{
|
|
336
|
+
kind: "epistemic_node",
|
|
337
|
+
nodeId: doc.fromNodeId,
|
|
338
|
+
nodeType: doc.fromNodeType
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
kind: "epistemic_node",
|
|
342
|
+
nodeId: doc.toNodeId,
|
|
343
|
+
nodeType: doc.toNodeType
|
|
344
|
+
}
|
|
345
|
+
);
|
|
346
|
+
}
|
|
347
|
+
return ctx.db.insert("epistemicEdges", doc);
|
|
348
|
+
}
|
|
256
349
|
|
|
257
350
|
// src/epistemicBeliefs.topicAnchor.ts
|
|
258
351
|
function cleanString(value) {
|
|
@@ -304,18 +397,15 @@ async function createRequiredBeliefTopicEdge(ctx, args) {
|
|
|
304
397
|
const now = Date.now();
|
|
305
398
|
const existingEdges = await ctx.db.query("epistemicEdges").withIndex(
|
|
306
399
|
"by_from_to",
|
|
307
|
-
(q) => q.eq("fromNodeId",
|
|
308
|
-
"toNodeId",
|
|
309
|
-
String(args.topicNode._id)
|
|
310
|
-
)
|
|
400
|
+
(q) => q.eq("fromNodeId", args.beliefGlobalId).eq("toNodeId", topicGlobalId)
|
|
311
401
|
).collect();
|
|
312
402
|
const existing = existingEdges.find((edge) => edge.edgeType === "belongs_to");
|
|
313
403
|
const edgeGlobalId = cleanString(existing?.globalId) ?? generateUuidV7();
|
|
314
404
|
if (!existing) {
|
|
315
|
-
await ctx
|
|
405
|
+
await insertEpistemicEdge(ctx, {
|
|
316
406
|
globalId: edgeGlobalId,
|
|
317
|
-
fromNodeId:
|
|
318
|
-
toNodeId:
|
|
407
|
+
fromNodeId: args.beliefGlobalId,
|
|
408
|
+
toNodeId: topicGlobalId,
|
|
319
409
|
sourceGlobalId: args.beliefGlobalId,
|
|
320
410
|
targetGlobalId: topicGlobalId,
|
|
321
411
|
edgeType: "belongs_to",
|
|
@@ -704,6 +794,9 @@ function materializeTopicProjectOverlay(topic, idMode = "legacy") {
|
|
|
704
794
|
type: mapProjectType(topic, metadata),
|
|
705
795
|
description: readNonEmptyString(topic.description),
|
|
706
796
|
ownerId: readNonEmptyString(metadata.ownerId) || readNonEmptyString(topic.createdBy) || "system",
|
|
797
|
+
// FR.7 creator-grant: surface the principal-shaped owner field (column-first,
|
|
798
|
+
// metadata fallback for legacy rows that recorded it in metadata).
|
|
799
|
+
ownerPrincipalId: readNonEmptyString(topic.ownerPrincipalId) || readNonEmptyString(metadata.ownerPrincipalId),
|
|
707
800
|
sharedWith: readStringArray(metadata.sharedWith),
|
|
708
801
|
visibility,
|
|
709
802
|
tenantId: readNonEmptyString(topic.tenantId) || readNonEmptyString(metadata.tenantId),
|
|
@@ -907,7 +1000,18 @@ var optionalBeliefScopeArgs = optionalScopeArgs;
|
|
|
907
1000
|
tupleContradiction: normalizeTupleContradictionPolicy()
|
|
908
1001
|
});
|
|
909
1002
|
function throwStructuredMutationError(args) {
|
|
910
|
-
const
|
|
1003
|
+
const data = {
|
|
1004
|
+
structuredMutationError: true,
|
|
1005
|
+
message: args.message,
|
|
1006
|
+
status: args.status,
|
|
1007
|
+
code: args.code,
|
|
1008
|
+
invariantCode: args.invariantCode,
|
|
1009
|
+
suggestion: args.suggestion,
|
|
1010
|
+
details: args.details
|
|
1011
|
+
};
|
|
1012
|
+
const error = new ConvexError(
|
|
1013
|
+
data
|
|
1014
|
+
);
|
|
911
1015
|
error.status = args.status;
|
|
912
1016
|
error.code = args.code;
|
|
913
1017
|
error.invariantCode = args.invariantCode;
|
|
@@ -1339,7 +1443,7 @@ var internalCreate = internalMutation({
|
|
|
1339
1443
|
opinion_u: 1,
|
|
1340
1444
|
opinion_a: baseRate
|
|
1341
1445
|
};
|
|
1342
|
-
const nodeId = await ctx
|
|
1446
|
+
const nodeId = await insertEpistemicNode(ctx, {
|
|
1343
1447
|
globalId,
|
|
1344
1448
|
topicId: scope.topicId,
|
|
1345
1449
|
projectId: scope.projectId,
|
|
@@ -1395,7 +1499,6 @@ var internalCreate = internalMutation({
|
|
|
1395
1499
|
})
|
|
1396
1500
|
);
|
|
1397
1501
|
await createRequiredBeliefTopicEdge(ctx, {
|
|
1398
|
-
beliefNodeId: nodeId,
|
|
1399
1502
|
beliefGlobalId: globalId,
|
|
1400
1503
|
topicNode,
|
|
1401
1504
|
createdBy: args.userId
|