@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,11 +1,12 @@
|
|
|
1
|
-
import { v } from 'convex/values';
|
|
1
|
+
import { v, ConvexError } from 'convex/values';
|
|
2
2
|
import { permissiveReturn } from '@lucern/contracts/schema-helpers/validators';
|
|
3
3
|
import { componentsGeneric, anyApi, mutationGeneric, queryGeneric } from 'convex/server';
|
|
4
|
-
import { generateGlobalId } from '@lucern/contracts/ids';
|
|
4
|
+
import { generateGlobalId, assertUuidV7Identity, assertStorageEdgeVocabulary, assertUuidShapedEdgeEndpoint } from '@lucern/contracts/ids';
|
|
5
5
|
import { normalizeTupleContradictionPolicy } from '@lucern/confidence';
|
|
6
6
|
import { checkProjectAccess } from '@lucern/access-control/access';
|
|
7
7
|
import '@lucern/access-control/audience';
|
|
8
8
|
import { getCurrentUserId } from '@lucern/access-control/auth';
|
|
9
|
+
import { assertEdgePolicyAllowed, edgePolicyManifest } from '@lucern/contracts';
|
|
9
10
|
|
|
10
11
|
// src/epistemicBeliefs.links.ts
|
|
11
12
|
var api = anyApi;
|
|
@@ -87,6 +88,35 @@ function debugGraphPrimitiveFallback(message, context) {
|
|
|
87
88
|
console.debug(message, context ?? {});
|
|
88
89
|
}
|
|
89
90
|
var LEGACY_SCOPE_FIELD = "graphScopeProjectId";
|
|
91
|
+
async function resolveTopicNodeScopeOrNull(ctx, ref) {
|
|
92
|
+
if (!ctx?.db || typeof ctx.db.query !== "function") {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
let node = null;
|
|
96
|
+
try {
|
|
97
|
+
const byGlobalId = await ctx.db.query("epistemicNodes").withIndex("by_globalId", (q) => q.eq("globalId", ref)).first();
|
|
98
|
+
if (byGlobalId && byGlobalId.nodeType === "topic") {
|
|
99
|
+
node = byGlobalId;
|
|
100
|
+
}
|
|
101
|
+
} catch (error) {
|
|
102
|
+
debugGraphPrimitiveFallback(
|
|
103
|
+
"[topicScope] topic-node scope lookup by globalId failed",
|
|
104
|
+
{ error, ref }
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
if (!node) {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
const scopeKey = normalizeScopeValue(node.topicId) ?? normalizeScopeValue(node.globalId);
|
|
111
|
+
if (!scopeKey) {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
return {
|
|
115
|
+
topicId: scopeKey,
|
|
116
|
+
projectId: asMappedProjectId(node),
|
|
117
|
+
source: "topic_node"
|
|
118
|
+
};
|
|
119
|
+
}
|
|
90
120
|
function asMappedProjectId(topic) {
|
|
91
121
|
if (!topic) {
|
|
92
122
|
return;
|
|
@@ -227,6 +257,13 @@ async function resolveTopicProjectScope(ctx, args) {
|
|
|
227
257
|
) ?? null;
|
|
228
258
|
}
|
|
229
259
|
if (!topic) {
|
|
260
|
+
const nodeScope = await resolveTopicNodeScopeOrNull(
|
|
261
|
+
ctx,
|
|
262
|
+
String(args.topicId)
|
|
263
|
+
);
|
|
264
|
+
if (nodeScope) {
|
|
265
|
+
return nodeScope;
|
|
266
|
+
}
|
|
230
267
|
throw new Error(`Topic not found: ${String(args.topicId)}`);
|
|
231
268
|
}
|
|
232
269
|
const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
|
|
@@ -297,6 +334,16 @@ async function resolveTopicProjectScope(ctx, args) {
|
|
|
297
334
|
source: "project_mapped_topic"
|
|
298
335
|
};
|
|
299
336
|
}
|
|
337
|
+
const nodeScope = await resolveTopicNodeScopeOrNull(
|
|
338
|
+
ctx,
|
|
339
|
+
String(args.projectId)
|
|
340
|
+
);
|
|
341
|
+
if (nodeScope) {
|
|
342
|
+
return {
|
|
343
|
+
...nodeScope,
|
|
344
|
+
projectId: nodeScope.projectId ?? String(args.projectId)
|
|
345
|
+
};
|
|
346
|
+
}
|
|
300
347
|
throw new Error(
|
|
301
348
|
`Legacy project scope ${String(args.projectId)} has no mapped topic.`
|
|
302
349
|
);
|
|
@@ -317,7 +364,18 @@ var optionalBeliefScopeArgs = optionalScopeArgs;
|
|
|
317
364
|
tupleContradiction: normalizeTupleContradictionPolicy()
|
|
318
365
|
});
|
|
319
366
|
function throwStructuredMutationError(args) {
|
|
320
|
-
const
|
|
367
|
+
const data = {
|
|
368
|
+
structuredMutationError: true,
|
|
369
|
+
message: args.message,
|
|
370
|
+
status: args.status,
|
|
371
|
+
code: args.code,
|
|
372
|
+
invariantCode: args.invariantCode,
|
|
373
|
+
suggestion: args.suggestion,
|
|
374
|
+
details: args.details
|
|
375
|
+
};
|
|
376
|
+
const error = new ConvexError(
|
|
377
|
+
data
|
|
378
|
+
);
|
|
321
379
|
error.status = args.status;
|
|
322
380
|
error.code = args.code;
|
|
323
381
|
error.invariantCode = args.invariantCode;
|
|
@@ -378,15 +436,57 @@ async function requireProjectWriteAccess(ctx, projectId, userId) {
|
|
|
378
436
|
);
|
|
379
437
|
if (!hasAccess) {
|
|
380
438
|
throwStructuredMutationError({
|
|
381
|
-
message:
|
|
439
|
+
message: `Project write access denied for topic ${projectId}.`,
|
|
382
440
|
status: 403,
|
|
383
|
-
code: "
|
|
441
|
+
code: "PROJECT_ACCESS_DENIED",
|
|
384
442
|
invariantCode: "policy.scope_required",
|
|
385
|
-
suggestion: "
|
|
386
|
-
details: { projectId, userId }
|
|
443
|
+
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.",
|
|
444
|
+
details: { topicId: projectId, principalId: userId }
|
|
387
445
|
});
|
|
388
446
|
}
|
|
389
447
|
}
|
|
448
|
+
async function assertExistingNodeEndpoint(ctx, endpointRole, endpoint) {
|
|
449
|
+
assertUuidShapedEdgeEndpoint(endpointRole, endpoint);
|
|
450
|
+
const node = await ctx.db.query("epistemicNodes").withIndex("by_globalId", (q) => q.eq("globalId", endpoint)).first();
|
|
451
|
+
if (!node) {
|
|
452
|
+
throw new Error(
|
|
453
|
+
`edge_endpoint_not_canonical: epistemicEdges insert requires ${endpointRole} to be the globalId of an existing epistemicNodes row, received ${endpoint} (no node with that globalId)`
|
|
454
|
+
);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
async function insertEpistemicEdge(ctx, doc) {
|
|
458
|
+
assertUuidV7Identity("epistemicEdges", doc.globalId);
|
|
459
|
+
assertStorageEdgeVocabulary(doc.edgeType);
|
|
460
|
+
if (!doc.fromNodeId || typeof doc.fromNodeId !== "string") {
|
|
461
|
+
throw new Error(
|
|
462
|
+
"edge_endpoint_missing: epistemicEdges insert requires a non-empty fromNodeId"
|
|
463
|
+
);
|
|
464
|
+
}
|
|
465
|
+
if (!doc.toNodeId || typeof doc.toNodeId !== "string") {
|
|
466
|
+
throw new Error(
|
|
467
|
+
"edge_endpoint_missing: epistemicEdges insert requires a non-empty toNodeId"
|
|
468
|
+
);
|
|
469
|
+
}
|
|
470
|
+
await assertExistingNodeEndpoint(ctx, "fromNodeId", doc.fromNodeId);
|
|
471
|
+
await assertExistingNodeEndpoint(ctx, "toNodeId", doc.toNodeId);
|
|
472
|
+
if (doc.fromNodeType && doc.toNodeType && doc.edgeType !== "extracted_from") {
|
|
473
|
+
assertEdgePolicyAllowed(
|
|
474
|
+
edgePolicyManifest,
|
|
475
|
+
doc.edgeType,
|
|
476
|
+
{
|
|
477
|
+
kind: "epistemic_node",
|
|
478
|
+
nodeId: doc.fromNodeId,
|
|
479
|
+
nodeType: doc.fromNodeType
|
|
480
|
+
},
|
|
481
|
+
{
|
|
482
|
+
kind: "epistemic_node",
|
|
483
|
+
nodeId: doc.toNodeId,
|
|
484
|
+
nodeType: doc.toNodeType
|
|
485
|
+
}
|
|
486
|
+
);
|
|
487
|
+
}
|
|
488
|
+
return ctx.db.insert("epistemicEdges", doc);
|
|
489
|
+
}
|
|
390
490
|
|
|
391
491
|
// src/epistemicBeliefs.links.ts
|
|
392
492
|
function assertSignedImpactScore(value, context) {
|
|
@@ -609,10 +709,11 @@ var linkEvidence = mutation({
|
|
|
609
709
|
const edgeType = "informs";
|
|
610
710
|
const logicalRole = evidenceNodeId ? await computeLogicalRole(ctx, evidenceNodeId, args.beliefNodeId) : "contributory";
|
|
611
711
|
const edgeGlobalId = generateGlobalId();
|
|
612
|
-
await ctx
|
|
712
|
+
await insertEpistemicEdge(ctx, {
|
|
613
713
|
globalId: edgeGlobalId,
|
|
614
|
-
|
|
615
|
-
|
|
714
|
+
// C2-RR.4 Defect E — canonical UUIDv7 endpoints, not Convex doc ids.
|
|
715
|
+
fromNodeId: evidenceGlobalId,
|
|
716
|
+
toNodeId: belief.globalId,
|
|
616
717
|
sourceGlobalId: evidenceGlobalId,
|
|
617
718
|
targetGlobalId: belief.globalId,
|
|
618
719
|
edgeType,
|