@lucern/graph-primitives 1.0.27 → 1.0.29
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.map +1 -1
- package/dist/beliefEvidenceLinks.js.map +1 -1
- package/dist/beliefEvidenceLinks.operational.js.map +1 -1
- package/dist/contradictions.js +3 -3
- package/dist/contradictions.js.map +1 -1
- package/dist/convex.js.map +1 -1
- package/dist/entityBridge.js.map +1 -1
- package/dist/entityLifecycle.js +7 -39
- package/dist/entityLifecycle.js.map +1 -1
- package/dist/epistemicAnswers.js.map +1 -1
- package/dist/epistemicBeliefs.admin.js +6 -42
- package/dist/epistemicBeliefs.admin.js.map +1 -1
- package/dist/epistemicBeliefs.backfills.js +2 -21
- package/dist/epistemicBeliefs.backfills.js.map +1 -1
- package/dist/epistemicBeliefs.confidence.d.ts +1 -0
- package/dist/epistemicBeliefs.confidence.js +4 -40
- package/dist/epistemicBeliefs.confidence.js.map +1 -1
- package/dist/epistemicBeliefs.core.js +6 -44
- package/dist/epistemicBeliefs.core.js.map +1 -1
- package/dist/epistemicBeliefs.d.ts +1 -0
- package/dist/epistemicBeliefs.forkEvidence.js +2 -22
- package/dist/epistemicBeliefs.forkEvidence.js.map +1 -1
- package/dist/epistemicBeliefs.helpers.d.ts +3 -27
- package/dist/epistemicBeliefs.helpers.js +4 -40
- package/dist/epistemicBeliefs.helpers.js.map +1 -1
- package/dist/epistemicBeliefs.internal.js +2 -22
- package/dist/epistemicBeliefs.internal.js.map +1 -1
- package/dist/epistemicBeliefs.js +17 -55
- package/dist/epistemicBeliefs.js.map +1 -1
- package/dist/epistemicBeliefs.lifecycle.js +7 -45
- package/dist/epistemicBeliefs.lifecycle.js.map +1 -1
- package/dist/epistemicBeliefs.links.js +7 -43
- package/dist/epistemicBeliefs.links.js.map +1 -1
- package/dist/epistemicBeliefs.queries.js.map +1 -1
- package/dist/epistemicBeliefs.topicAnchor.js.map +1 -1
- package/dist/epistemicContracts.evaluators.js +4 -40
- package/dist/epistemicContracts.evaluators.js.map +1 -1
- package/dist/epistemicContracts.handlers.js +4 -40
- package/dist/epistemicContracts.handlers.js.map +1 -1
- package/dist/epistemicContracts.js +4 -40
- package/dist/epistemicContracts.js.map +1 -1
- package/dist/epistemicEdgeCreation.js.map +1 -1
- package/dist/epistemicEdges.handlers.js.map +1 -1
- package/dist/epistemicEdges.js +4 -4
- package/dist/epistemicEdges.js.map +1 -1
- package/dist/epistemicEdges.mutations.js +4 -4
- package/dist/epistemicEdges.mutations.js.map +1 -1
- package/dist/epistemicEdges.queries.js.map +1 -1
- package/dist/epistemicEvidence.js +5 -5
- package/dist/epistemicEvidence.js.map +1 -1
- package/dist/epistemicEvidenceHelpers.js.map +1 -1
- package/dist/epistemicEvidenceMutations.js +5 -5
- package/dist/epistemicEvidenceMutations.js.map +1 -1
- package/dist/epistemicEvidenceQueries.js.map +1 -1
- package/dist/epistemicHelpers.js.map +1 -1
- package/dist/epistemicLinking.js.map +1 -1
- package/dist/epistemicNodeCreation.js.map +1 -1
- package/dist/epistemicNodes.internal.js.map +1 -1
- package/dist/epistemicNodes.js +4 -4
- package/dist/epistemicNodes.js.map +1 -1
- package/dist/epistemicNodes.mutations.js +4 -4
- package/dist/epistemicNodes.mutations.js.map +1 -1
- package/dist/epistemicNodes.queries.js.map +1 -1
- package/dist/epistemicQuestions.conviction.js.map +1 -1
- package/dist/epistemicQuestions.create.js.map +1 -1
- package/dist/epistemicQuestions.evidence.js.map +1 -1
- package/dist/epistemicQuestions.helpers.js.map +1 -1
- package/dist/epistemicQuestions.js.map +1 -1
- package/dist/epistemicQuestions.lifecycle.js.map +1 -1
- package/dist/epistemicQuestions.queries.js.map +1 -1
- package/dist/epistemicQuestions.sprint.js.map +1 -1
- package/dist/epistemicQuestions.tail.js.map +1 -1
- package/dist/epistemicSources.js +2 -2
- package/dist/epistemicSources.js.map +1 -1
- package/dist/helpers.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +50 -121
- package/dist/index.js.map +1 -1
- package/dist/ontologyApproval.js.map +1 -1
- package/dist/ontologyDefinitions.js.map +1 -1
- package/dist/ontologyRegistry.js.map +1 -1
- package/dist/projectionReconciliation.js.map +1 -1
- package/dist/proof-attestation.json +1 -1
- package/dist/questionEvidenceLinks.js.map +1 -1
- package/dist/resolvers.js.map +1 -1
- package/dist/scopeResolverCompat.js.map +1 -1
- package/dist/topicProjectOverlay.js.map +1 -1
- package/dist/topicScope.js.map +1 -1
- package/dist/workflowBridge.js.map +1 -1
- package/dist/workspaceIsolation.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { normalizeTupleContradictionPolicy, mkOpinion, createInheritedContractRecord, confidenceFromSL, getRescoringSchedule, conditionalDeduction, project, dampedDependencyCascade, hasProjectedOpinionChanged, detectTupleContradiction, evaluateTupleContradictionTransition, readOpinionFromRecord, trustDiscount, applyNegativeSupport, cumulativeFusion, applyNegativeEvidence, computeEffectiveDecay, computeDeadlineUrgency, computeBaseDecay, bayesianUpdate, DECAY_TIERS, DEADLINE_URGENCY, parseEvidentialEvaluatorConfig, compareMetricValue, buildEvidentialRationale, parseMetricCheckerConfig, getEvaluatorInputRecord, pickFiniteNumber, resolveComparisonResult, buildComparisonRationale, parseReferenceCheckCounterConfig, parseTemporalDeadlineConfig, parseMarketIndexComparatorConfig } from '@lucern/confidence';
|
|
2
|
-
import { v
|
|
3
|
-
import {
|
|
2
|
+
import { v } from 'convex/values';
|
|
3
|
+
import { throwStructuredMutationError } from '@lucern/access-control/structuredMutationError';
|
|
4
4
|
import { canAudienceClassAccess, normalizeAudienceKey, classFromAudienceKey } from '@lucern/access-control/audience';
|
|
5
5
|
import { getCurrentUserId } from '@lucern/access-control/auth';
|
|
6
6
|
import { componentsGeneric, anyApi, internalMutationGeneric, mutationGeneric, queryGeneric, internalQueryGeneric, internalActionGeneric } from 'convex/server';
|
|
7
7
|
import { isNodeType, getLayerForNodeType } from '@lucern/contracts/schema-helpers/spine/tables/epistemicNodes';
|
|
8
|
+
import { requireScopeWriteAccess, checkScopeAccess, getAccessibleProjectIds, checkProjectAccess } from '@lucern/access-control/access';
|
|
8
9
|
import { permissiveReturn } from '@lucern/contracts/schema-helpers/validators';
|
|
9
10
|
import { assertSchemaEnumValue } from '@lucern/contracts/schema-helpers/enumValidation';
|
|
10
11
|
import { generateGlobalId, assertUuidV7Identity, generateUuidV7, assertStorageEdgeVocabulary, assertUuidShapedEdgeEndpoint, isUuidV7 } from '@lucern/contracts/ids';
|
|
@@ -1745,26 +1746,6 @@ var DEFAULT_CONFIDENCE_POLICY = {
|
|
|
1745
1746
|
scoringMode: "after_worktree",
|
|
1746
1747
|
tupleContradiction: normalizeTupleContradictionPolicy()
|
|
1747
1748
|
};
|
|
1748
|
-
function throwStructuredMutationError(args) {
|
|
1749
|
-
const data = {
|
|
1750
|
-
structuredMutationError: true,
|
|
1751
|
-
message: args.message,
|
|
1752
|
-
status: args.status,
|
|
1753
|
-
code: args.code,
|
|
1754
|
-
invariantCode: args.invariantCode,
|
|
1755
|
-
suggestion: args.suggestion,
|
|
1756
|
-
details: args.details
|
|
1757
|
-
};
|
|
1758
|
-
const error = new ConvexError(
|
|
1759
|
-
data
|
|
1760
|
-
);
|
|
1761
|
-
error.status = args.status;
|
|
1762
|
-
error.code = args.code;
|
|
1763
|
-
error.invariantCode = args.invariantCode;
|
|
1764
|
-
error.suggestion = args.suggestion;
|
|
1765
|
-
error.details = args.details;
|
|
1766
|
-
throw error;
|
|
1767
|
-
}
|
|
1768
1749
|
function readFiniteNumber(value) {
|
|
1769
1750
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
1770
1751
|
}
|
|
@@ -2098,23 +2079,6 @@ async function requireAuthenticatedUserId(ctx) {
|
|
|
2098
2079
|
}
|
|
2099
2080
|
return userId;
|
|
2100
2081
|
}
|
|
2101
|
-
async function requireProjectWriteAccess(ctx, projectId, userId) {
|
|
2102
|
-
const hasAccess = await checkProjectAccess(
|
|
2103
|
-
ctx,
|
|
2104
|
-
projectId,
|
|
2105
|
-
userId
|
|
2106
|
-
);
|
|
2107
|
-
if (!hasAccess) {
|
|
2108
|
-
throwStructuredMutationError({
|
|
2109
|
-
message: `Project write access denied for topic ${projectId}.`,
|
|
2110
|
-
status: 403,
|
|
2111
|
-
code: "PROJECT_ACCESS_DENIED",
|
|
2112
|
-
invariantCode: "policy.scope_required",
|
|
2113
|
-
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.",
|
|
2114
|
-
details: { topicId: projectId, principalId: userId }
|
|
2115
|
-
});
|
|
2116
|
-
}
|
|
2117
|
-
}
|
|
2118
2082
|
function resolveTraversalTargetNodeId(edge, direction) {
|
|
2119
2083
|
const targetNodeId = direction === "outgoing" ? edge.toNodeId : edge.fromNodeId;
|
|
2120
2084
|
return targetNodeId ?? void 0;
|
|
@@ -2275,7 +2239,7 @@ async function applyBeliefConfidenceChange(ctx, args) {
|
|
|
2275
2239
|
details: { nodeId: args.nodeId }
|
|
2276
2240
|
});
|
|
2277
2241
|
}
|
|
2278
|
-
await
|
|
2242
|
+
await requireScopeWriteAccess(
|
|
2279
2243
|
ctx,
|
|
2280
2244
|
node.projectId,
|
|
2281
2245
|
args.authenticatedUserId
|
|
@@ -2839,8 +2803,6 @@ async function scheduleEmbeddingGeneration(args) {
|
|
|
2839
2803
|
);
|
|
2840
2804
|
}
|
|
2841
2805
|
}
|
|
2842
|
-
|
|
2843
|
-
// src/epistemicBeliefs.core.ts
|
|
2844
2806
|
var create = mutation({
|
|
2845
2807
|
args: {
|
|
2846
2808
|
...optionalBeliefScopeArgs,
|
|
@@ -2919,7 +2881,7 @@ var create = mutation({
|
|
|
2919
2881
|
context: "epistemicBeliefs.create"
|
|
2920
2882
|
});
|
|
2921
2883
|
if (scope.projectId) {
|
|
2922
|
-
await
|
|
2884
|
+
await requireScopeWriteAccess(
|
|
2923
2885
|
ctx,
|
|
2924
2886
|
scope.projectId,
|
|
2925
2887
|
authenticatedUserId
|
|
@@ -3159,7 +3121,7 @@ var refineBelief = mutation({
|
|
|
3159
3121
|
details: { nodeId: args.nodeId }
|
|
3160
3122
|
});
|
|
3161
3123
|
}
|
|
3162
|
-
await
|
|
3124
|
+
await requireScopeWriteAccess(ctx, node.projectId, authenticatedUserId);
|
|
3163
3125
|
if (typeof node.confidence === "number" && Number.isFinite(node.confidence)) {
|
|
3164
3126
|
throwStructuredMutationError({
|
|
3165
3127
|
message: "Scored beliefs are immutable. Use forkBelief to evolve a scored belief.",
|
|
@@ -3379,7 +3341,7 @@ var forkBelief = mutation({
|
|
|
3379
3341
|
details: { parentNodeId: args.parentNodeId }
|
|
3380
3342
|
});
|
|
3381
3343
|
}
|
|
3382
|
-
await
|
|
3344
|
+
await requireScopeWriteAccess(ctx, parent.projectId, authenticatedUserId);
|
|
3383
3345
|
const metadata = parent.metadata;
|
|
3384
3346
|
const forkBeliefStatus = "hypothesis";
|
|
3385
3347
|
const forkMode = args.forkMode ?? "supersede";
|
|
@@ -3677,7 +3639,7 @@ var updateStatus = mutation({
|
|
|
3677
3639
|
if (!node.projectId) {
|
|
3678
3640
|
throw new Error("Belief has no project scope");
|
|
3679
3641
|
}
|
|
3680
|
-
await
|
|
3642
|
+
await requireScopeWriteAccess(ctx, node.projectId, authenticatedUserId);
|
|
3681
3643
|
const previousStatus = node.status;
|
|
3682
3644
|
const metadata = node.metadata || {};
|
|
3683
3645
|
await ctx.db.patch(args.nodeId, {
|
|
@@ -3722,7 +3684,7 @@ var archive = mutation({
|
|
|
3722
3684
|
if (!node.projectId) {
|
|
3723
3685
|
throw new Error("Belief has no project scope");
|
|
3724
3686
|
}
|
|
3725
|
-
await
|
|
3687
|
+
await requireScopeWriteAccess(ctx, node.projectId, authenticatedUserId);
|
|
3726
3688
|
return await ctx.runMutation(
|
|
3727
3689
|
// Use updateStatus internally
|
|
3728
3690
|
internal.epistemicBeliefs.updateStatusInternal,
|
|
@@ -3752,7 +3714,7 @@ var updateRationale = mutation({
|
|
|
3752
3714
|
if (!node.projectId) {
|
|
3753
3715
|
throw new Error("Belief has no project scope");
|
|
3754
3716
|
}
|
|
3755
|
-
await
|
|
3717
|
+
await requireScopeWriteAccess(ctx, node.projectId, authenticatedUserId);
|
|
3756
3718
|
const metadata = node.metadata || {};
|
|
3757
3719
|
const previousRationale = typeof metadata.rationale === "string" ? metadata.rationale : void 0;
|
|
3758
3720
|
const nextRationale = args.rationale?.trim();
|
|
@@ -4015,7 +3977,7 @@ var updatePillar = mutation({
|
|
|
4015
3977
|
if (!existingNode.projectId) {
|
|
4016
3978
|
throw new Error("Belief has no project scope");
|
|
4017
3979
|
}
|
|
4018
|
-
await
|
|
3980
|
+
await requireScopeWriteAccess(
|
|
4019
3981
|
ctx,
|
|
4020
3982
|
existingNode.projectId,
|
|
4021
3983
|
authenticatedUserId
|
|
@@ -4121,7 +4083,7 @@ var linkBeliefs = mutation({
|
|
|
4121
4083
|
if (!fromNode.projectId) {
|
|
4122
4084
|
throw new Error("Belief has no project scope");
|
|
4123
4085
|
}
|
|
4124
|
-
await
|
|
4086
|
+
await requireScopeWriteAccess(
|
|
4125
4087
|
ctx,
|
|
4126
4088
|
fromNode.projectId,
|
|
4127
4089
|
authenticatedUserId
|
|
@@ -4177,7 +4139,7 @@ var linkEvidence = mutation({
|
|
|
4177
4139
|
if (!belief.projectId) {
|
|
4178
4140
|
throw new Error("Belief has no project scope");
|
|
4179
4141
|
}
|
|
4180
|
-
await
|
|
4142
|
+
await requireScopeWriteAccess(ctx, belief.projectId, authenticatedUserId);
|
|
4181
4143
|
const insight = await ctx.db.get(args.insightId);
|
|
4182
4144
|
if (!insight || insight.nodeType !== "evidence") {
|
|
4183
4145
|
throw new Error("Insight not found");
|
|
@@ -4268,7 +4230,7 @@ var unlinkEvidence = mutation({
|
|
|
4268
4230
|
if (!evidenceNode.projectId) {
|
|
4269
4231
|
throw new Error("Evidence has no project scope");
|
|
4270
4232
|
}
|
|
4271
|
-
await
|
|
4233
|
+
await requireScopeWriteAccess(
|
|
4272
4234
|
ctx,
|
|
4273
4235
|
evidenceNode.projectId,
|
|
4274
4236
|
authenticatedUserId
|
|
@@ -4449,7 +4411,7 @@ var deleteRelationship = mutation({
|
|
|
4449
4411
|
if (!edge.projectId) {
|
|
4450
4412
|
throw new Error("Edge has no project scope");
|
|
4451
4413
|
}
|
|
4452
|
-
await
|
|
4414
|
+
await requireScopeWriteAccess(ctx, edge.projectId, authenticatedUserId);
|
|
4453
4415
|
const previousState = {
|
|
4454
4416
|
fromNodeId: edge.fromNodeId,
|
|
4455
4417
|
toNodeId: edge.toNodeId,
|
|
@@ -4496,7 +4458,7 @@ var updateCriticality = mutation({
|
|
|
4496
4458
|
if (!node.projectId) {
|
|
4497
4459
|
throw new Error("Belief has no project scope");
|
|
4498
4460
|
}
|
|
4499
|
-
await
|
|
4461
|
+
await requireScopeWriteAccess(ctx, node.projectId, authenticatedUserId);
|
|
4500
4462
|
const metadata = node.metadata || {};
|
|
4501
4463
|
const previousCriticality = metadata.criticality;
|
|
4502
4464
|
await ctx.db.patch(args.nodeId, {
|
|
@@ -4565,7 +4527,7 @@ var batchUpdateCriticality = mutation({
|
|
|
4565
4527
|
results.push({ beliefId: update5.beliefId, success: false });
|
|
4566
4528
|
continue;
|
|
4567
4529
|
}
|
|
4568
|
-
await
|
|
4530
|
+
await requireScopeWriteAccess(
|
|
4569
4531
|
ctx,
|
|
4570
4532
|
node.projectId,
|
|
4571
4533
|
authenticatedUserId
|
|
@@ -7953,7 +7915,7 @@ var updateStatus2 = mutation({
|
|
|
7953
7915
|
throw new Error("Contradiction not found");
|
|
7954
7916
|
}
|
|
7955
7917
|
if (existing.projectId && args.userId) {
|
|
7956
|
-
await
|
|
7918
|
+
await requireScopeWriteAccess(ctx, existing.projectId, args.userId);
|
|
7957
7919
|
}
|
|
7958
7920
|
const now = Date.now();
|
|
7959
7921
|
const update5 = { status: args.status };
|
|
@@ -8004,7 +7966,7 @@ var resolve = mutation({
|
|
|
8004
7966
|
throw new Error("Contradiction not found");
|
|
8005
7967
|
}
|
|
8006
7968
|
if (existing.projectId) {
|
|
8007
|
-
await
|
|
7969
|
+
await requireScopeWriteAccess(ctx, existing.projectId, args.resolvedBy);
|
|
8008
7970
|
}
|
|
8009
7971
|
const now = Date.now();
|
|
8010
7972
|
await ctx.db.patch(args.contradictionId, {
|
|
@@ -8756,30 +8718,10 @@ async function validateEntityTypeForTopic(ctx, topicId, nodeType) {
|
|
|
8756
8718
|
}
|
|
8757
8719
|
|
|
8758
8720
|
// src/entityLifecycle.ts
|
|
8759
|
-
function throwStructuredMutationError2(args) {
|
|
8760
|
-
const data = {
|
|
8761
|
-
structuredMutationError: true,
|
|
8762
|
-
message: args.message,
|
|
8763
|
-
status: args.status,
|
|
8764
|
-
code: args.code,
|
|
8765
|
-
invariantCode: args.invariantCode,
|
|
8766
|
-
suggestion: args.suggestion,
|
|
8767
|
-
details: args.details
|
|
8768
|
-
};
|
|
8769
|
-
const error = new ConvexError(
|
|
8770
|
-
data
|
|
8771
|
-
);
|
|
8772
|
-
error.status = args.status;
|
|
8773
|
-
error.code = args.code;
|
|
8774
|
-
error.invariantCode = args.invariantCode;
|
|
8775
|
-
error.suggestion = args.suggestion;
|
|
8776
|
-
error.details = args.details;
|
|
8777
|
-
throw error;
|
|
8778
|
-
}
|
|
8779
8721
|
async function requireAuthenticatedUserId3(ctx) {
|
|
8780
8722
|
const userId = await getCurrentUserId(ctx);
|
|
8781
8723
|
if (!userId) {
|
|
8782
|
-
|
|
8724
|
+
throwStructuredMutationError({
|
|
8783
8725
|
message: "Authentication required.",
|
|
8784
8726
|
status: 401,
|
|
8785
8727
|
code: "AUTHENTICATION_REQUIRED",
|
|
@@ -8789,19 +8731,6 @@ async function requireAuthenticatedUserId3(ctx) {
|
|
|
8789
8731
|
}
|
|
8790
8732
|
return userId;
|
|
8791
8733
|
}
|
|
8792
|
-
async function requireProjectWriteAccess3(ctx, projectId, userId) {
|
|
8793
|
-
const hasAccess = await checkProjectAccess(ctx, projectId, userId);
|
|
8794
|
-
if (!hasAccess) {
|
|
8795
|
-
throwStructuredMutationError2({
|
|
8796
|
-
message: `Project write access denied for topic ${projectId}.`,
|
|
8797
|
-
status: 403,
|
|
8798
|
-
code: "PROJECT_ACCESS_DENIED",
|
|
8799
|
-
invariantCode: "policy.scope_required",
|
|
8800
|
-
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.",
|
|
8801
|
-
details: { topicId: projectId, principalId: userId }
|
|
8802
|
-
});
|
|
8803
|
-
}
|
|
8804
|
-
}
|
|
8805
8734
|
function generateContentHash3(nodeType, text) {
|
|
8806
8735
|
const content = `${nodeType}:${text.trim().toLowerCase().replace(/\s+/g, " ")}`;
|
|
8807
8736
|
let hash = 5381;
|
|
@@ -8928,7 +8857,7 @@ var createEntity = mutation({
|
|
|
8928
8857
|
const now = Date.now();
|
|
8929
8858
|
const canonicalText = args.canonicalText.trim();
|
|
8930
8859
|
if (!canonicalText) {
|
|
8931
|
-
|
|
8860
|
+
throwStructuredMutationError({
|
|
8932
8861
|
message: "canonicalText is required.",
|
|
8933
8862
|
status: 400,
|
|
8934
8863
|
code: "INVALID_REQUEST",
|
|
@@ -8936,7 +8865,7 @@ var createEntity = mutation({
|
|
|
8936
8865
|
});
|
|
8937
8866
|
}
|
|
8938
8867
|
if (!isOntologicalNodeType(args.nodeType)) {
|
|
8939
|
-
|
|
8868
|
+
throwStructuredMutationError({
|
|
8940
8869
|
message: `"${args.nodeType}" is not an ontological entity type. Use epistemicBeliefs.create for epistemic nodes.`,
|
|
8941
8870
|
status: 400,
|
|
8942
8871
|
code: "INVALID_NODE_TYPE",
|
|
@@ -8949,7 +8878,7 @@ var createEntity = mutation({
|
|
|
8949
8878
|
projectId: args.projectId
|
|
8950
8879
|
});
|
|
8951
8880
|
if (scope.projectId) {
|
|
8952
|
-
await
|
|
8881
|
+
await requireScopeWriteAccess(
|
|
8953
8882
|
ctx,
|
|
8954
8883
|
scope.projectId,
|
|
8955
8884
|
authenticatedUserId
|
|
@@ -8962,7 +8891,7 @@ var createEntity = mutation({
|
|
|
8962
8891
|
args.nodeType
|
|
8963
8892
|
);
|
|
8964
8893
|
if (!ontologyValidation.valid) {
|
|
8965
|
-
|
|
8894
|
+
throwStructuredMutationError({
|
|
8966
8895
|
message: `Ontology validation failed: ${ontologyValidation.error}`,
|
|
8967
8896
|
status: 400,
|
|
8968
8897
|
code: "ONTOLOGY_VALIDATION_ERROR",
|
|
@@ -8980,7 +8909,7 @@ var createEntity = mutation({
|
|
|
8980
8909
|
scope.tenantId
|
|
8981
8910
|
);
|
|
8982
8911
|
if (!validation.valid) {
|
|
8983
|
-
|
|
8912
|
+
throwStructuredMutationError({
|
|
8984
8913
|
message: `Entity metadata validation failed: ${validation.errors.join("; ")}`,
|
|
8985
8914
|
status: 400,
|
|
8986
8915
|
code: "VALIDATION_ERROR",
|
|
@@ -9074,7 +9003,7 @@ var updateEntityAttributes = mutation({
|
|
|
9074
9003
|
const now = Date.now();
|
|
9075
9004
|
const node = await ctx.db.get(args.nodeId);
|
|
9076
9005
|
if (!node) {
|
|
9077
|
-
|
|
9006
|
+
throwStructuredMutationError({
|
|
9078
9007
|
message: "Entity not found.",
|
|
9079
9008
|
status: 404,
|
|
9080
9009
|
code: "NOT_FOUND",
|
|
@@ -9082,7 +9011,7 @@ var updateEntityAttributes = mutation({
|
|
|
9082
9011
|
});
|
|
9083
9012
|
}
|
|
9084
9013
|
if (!isOntologicalNodeType(node.nodeType)) {
|
|
9085
|
-
|
|
9014
|
+
throwStructuredMutationError({
|
|
9086
9015
|
message: `Node "${args.nodeId}" is a ${node.nodeType}, not an entity. Use belief/question APIs for epistemic nodes.`,
|
|
9087
9016
|
status: 400,
|
|
9088
9017
|
code: "LIFECYCLE_VIOLATION",
|
|
@@ -9092,7 +9021,7 @@ var updateEntityAttributes = mutation({
|
|
|
9092
9021
|
}
|
|
9093
9022
|
const scopeProjectId = typeof node.projectId === "string" && node.projectId.trim().length > 0 ? node.projectId : void 0;
|
|
9094
9023
|
if (scopeProjectId) {
|
|
9095
|
-
await
|
|
9024
|
+
await requireScopeWriteAccess(ctx, scopeProjectId, authenticatedUserId);
|
|
9096
9025
|
}
|
|
9097
9026
|
const existingMetadata = node.metadata || {};
|
|
9098
9027
|
const newMetadataFields = args.metadata !== void 0 ? args.metadata || {} : {};
|
|
@@ -9101,7 +9030,7 @@ var updateEntityAttributes = mutation({
|
|
|
9101
9030
|
mergedMetadata.subtype = args.subtype;
|
|
9102
9031
|
}
|
|
9103
9032
|
if (args.canonicalText !== void 0 && args.canonicalText.trim().length === 0) {
|
|
9104
|
-
|
|
9033
|
+
throwStructuredMutationError({
|
|
9105
9034
|
message: "canonicalText cannot be empty.",
|
|
9106
9035
|
status: 400,
|
|
9107
9036
|
code: "INVALID_REQUEST",
|
|
@@ -9116,7 +9045,7 @@ var updateEntityAttributes = mutation({
|
|
|
9116
9045
|
tenantId: typeof node.tenantId === "string" ? node.tenantId : void 0
|
|
9117
9046
|
});
|
|
9118
9047
|
if (duplicate && String(duplicate._id) !== String(args.nodeId)) {
|
|
9119
|
-
|
|
9048
|
+
throwStructuredMutationError({
|
|
9120
9049
|
message: "A canonical entity with this name already exists in the tenant scope.",
|
|
9121
9050
|
status: 409,
|
|
9122
9051
|
code: "CONFLICT",
|
|
@@ -9137,7 +9066,7 @@ var updateEntityAttributes = mutation({
|
|
|
9137
9066
|
typeof node.tenantId === "string" ? node.tenantId : void 0
|
|
9138
9067
|
);
|
|
9139
9068
|
if (!validation.valid) {
|
|
9140
|
-
|
|
9069
|
+
throwStructuredMutationError({
|
|
9141
9070
|
message: `Entity metadata validation failed: ${validation.errors.join("; ")}`,
|
|
9142
9071
|
status: 400,
|
|
9143
9072
|
code: "VALIDATION_ERROR",
|
|
@@ -9211,7 +9140,7 @@ var mergeEntities = mutation({
|
|
|
9211
9140
|
const canonical = await ctx.db.get(args.canonicalNodeId);
|
|
9212
9141
|
const duplicate = await ctx.db.get(args.duplicateNodeId);
|
|
9213
9142
|
if (!canonical || !duplicate) {
|
|
9214
|
-
|
|
9143
|
+
throwStructuredMutationError({
|
|
9215
9144
|
message: "One or both entity nodes not found.",
|
|
9216
9145
|
status: 404,
|
|
9217
9146
|
code: "NOT_FOUND",
|
|
@@ -9222,7 +9151,7 @@ var mergeEntities = mutation({
|
|
|
9222
9151
|
});
|
|
9223
9152
|
}
|
|
9224
9153
|
if (!isOntologicalNodeType(canonical.nodeType) || !isOntologicalNodeType(duplicate.nodeType)) {
|
|
9225
|
-
|
|
9154
|
+
throwStructuredMutationError({
|
|
9226
9155
|
message: "Both nodes must be ontological entities to merge.",
|
|
9227
9156
|
status: 400,
|
|
9228
9157
|
code: "LIFECYCLE_VIOLATION",
|
|
@@ -9230,7 +9159,7 @@ var mergeEntities = mutation({
|
|
|
9230
9159
|
});
|
|
9231
9160
|
}
|
|
9232
9161
|
if (args.canonicalNodeId === args.duplicateNodeId) {
|
|
9233
|
-
|
|
9162
|
+
throwStructuredMutationError({
|
|
9234
9163
|
message: "Cannot merge an entity with itself.",
|
|
9235
9164
|
status: 400,
|
|
9236
9165
|
code: "SELF_MERGE",
|
|
@@ -9240,14 +9169,14 @@ var mergeEntities = mutation({
|
|
|
9240
9169
|
});
|
|
9241
9170
|
}
|
|
9242
9171
|
if (canonical.nodeType !== duplicate.nodeType) {
|
|
9243
|
-
|
|
9172
|
+
throwStructuredMutationError({
|
|
9244
9173
|
message: `Cannot merge different entity types: ${canonical.nodeType} vs ${duplicate.nodeType}.`,
|
|
9245
9174
|
status: 400,
|
|
9246
9175
|
code: "TYPE_MISMATCH"
|
|
9247
9176
|
});
|
|
9248
9177
|
}
|
|
9249
9178
|
if (canonical.projectId) {
|
|
9250
|
-
await
|
|
9179
|
+
await requireScopeWriteAccess(
|
|
9251
9180
|
ctx,
|
|
9252
9181
|
canonical.projectId,
|
|
9253
9182
|
authenticatedUserId
|
|
@@ -9363,7 +9292,7 @@ var archiveEntity = mutation({
|
|
|
9363
9292
|
const now = Date.now();
|
|
9364
9293
|
const node = await ctx.db.get(args.nodeId);
|
|
9365
9294
|
if (!node) {
|
|
9366
|
-
|
|
9295
|
+
throwStructuredMutationError({
|
|
9367
9296
|
message: "Entity not found.",
|
|
9368
9297
|
status: 404,
|
|
9369
9298
|
code: "NOT_FOUND",
|
|
@@ -9371,7 +9300,7 @@ var archiveEntity = mutation({
|
|
|
9371
9300
|
});
|
|
9372
9301
|
}
|
|
9373
9302
|
if (!isOntologicalNodeType(node.nodeType)) {
|
|
9374
|
-
|
|
9303
|
+
throwStructuredMutationError({
|
|
9375
9304
|
message: `Node "${args.nodeId}" is a ${node.nodeType}, not an entity. Use belief archive APIs for epistemic nodes.`,
|
|
9376
9305
|
status: 400,
|
|
9377
9306
|
code: "LIFECYCLE_VIOLATION",
|
|
@@ -9379,7 +9308,7 @@ var archiveEntity = mutation({
|
|
|
9379
9308
|
});
|
|
9380
9309
|
}
|
|
9381
9310
|
if (node.projectId) {
|
|
9382
|
-
await
|
|
9311
|
+
await requireScopeWriteAccess(
|
|
9383
9312
|
ctx,
|
|
9384
9313
|
node.projectId,
|
|
9385
9314
|
authenticatedUserId
|
|
@@ -11670,7 +11599,7 @@ var create5 = mutation({
|
|
|
11670
11599
|
}) : void 0;
|
|
11671
11600
|
const resolvedProjectId = resolvedScope?.projectId ?? args.projectId;
|
|
11672
11601
|
if (resolvedProjectId) {
|
|
11673
|
-
await
|
|
11602
|
+
await requireScopeWriteAccess(ctx, resolvedProjectId, args.createdBy);
|
|
11674
11603
|
}
|
|
11675
11604
|
const fromLayer = fromNode.epistemicLayer || getNodeLayer(fromNode.nodeType);
|
|
11676
11605
|
const toLayer = toNode.epistemicLayer || getNodeLayer(toNode.nodeType);
|
|
@@ -11772,7 +11701,7 @@ var update2 = mutation({
|
|
|
11772
11701
|
throw new Error("Edge not found");
|
|
11773
11702
|
}
|
|
11774
11703
|
if (edge.projectId && userId) {
|
|
11775
|
-
await
|
|
11704
|
+
await requireScopeWriteAccess(ctx, edge.projectId, userId);
|
|
11776
11705
|
}
|
|
11777
11706
|
const cleanUpdates = {};
|
|
11778
11707
|
for (const [key, value] of Object.entries(updates)) {
|
|
@@ -11813,7 +11742,7 @@ var remove2 = mutation({
|
|
|
11813
11742
|
return buildEdgeNotFoundResult();
|
|
11814
11743
|
}
|
|
11815
11744
|
if (edge.projectId && args.userId) {
|
|
11816
|
-
await
|
|
11745
|
+
await requireScopeWriteAccess(ctx, edge.projectId, args.userId);
|
|
11817
11746
|
}
|
|
11818
11747
|
if (edge.projectId) {
|
|
11819
11748
|
await ctx.db.insert("epistemicAudit", {
|
|
@@ -12548,7 +12477,7 @@ var create6 = mutation({
|
|
|
12548
12477
|
mutationName: "epistemicEvidence.create"
|
|
12549
12478
|
});
|
|
12550
12479
|
if (scope.projectId) {
|
|
12551
|
-
await
|
|
12480
|
+
await requireScopeWriteAccess(ctx, scope.projectId, args.userId);
|
|
12552
12481
|
}
|
|
12553
12482
|
const now = Date.now();
|
|
12554
12483
|
const globalId = generateGlobalId();
|
|
@@ -12718,7 +12647,7 @@ var createAndLink = mutation({
|
|
|
12718
12647
|
if (!scope) {
|
|
12719
12648
|
throw new Error("Invalid scope: projectId or topicId is required");
|
|
12720
12649
|
}
|
|
12721
|
-
await
|
|
12650
|
+
await requireScopeWriteAccess(ctx, String(scope.topicId), args.userId);
|
|
12722
12651
|
const now = Date.now();
|
|
12723
12652
|
const globalId = generateGlobalId();
|
|
12724
12653
|
const contentHash = generateContentHash5(args.text);
|
|
@@ -13054,7 +12983,7 @@ var update3 = mutation({
|
|
|
13054
12983
|
if (!node.projectId) {
|
|
13055
12984
|
throw new Error("Evidence has no project scope");
|
|
13056
12985
|
}
|
|
13057
|
-
await
|
|
12986
|
+
await requireScopeWriteAccess(ctx, node.projectId, args.userId);
|
|
13058
12987
|
const now = Date.now();
|
|
13059
12988
|
const existingMeta = node.metadata || {};
|
|
13060
12989
|
const metaUpdates = { ...existingMeta };
|
|
@@ -13121,7 +13050,7 @@ var flagAsIncorrect = mutation({
|
|
|
13121
13050
|
if (!node.projectId) {
|
|
13122
13051
|
throw new Error("Evidence has no project scope");
|
|
13123
13052
|
}
|
|
13124
|
-
await
|
|
13053
|
+
await requireScopeWriteAccess(ctx, node.projectId, args.userId);
|
|
13125
13054
|
const existingMeta = node.metadata || {};
|
|
13126
13055
|
await ctx.db.patch(node._id, {
|
|
13127
13056
|
verificationStatus: "contradicted",
|
|
@@ -14596,7 +14525,7 @@ var update4 = mutation({
|
|
|
14596
14525
|
throw new Error("Node not found");
|
|
14597
14526
|
}
|
|
14598
14527
|
if (node.projectId && userId) {
|
|
14599
|
-
await
|
|
14528
|
+
await requireScopeWriteAccess(ctx, node.projectId, userId);
|
|
14600
14529
|
}
|
|
14601
14530
|
const cleanUpdates = {};
|
|
14602
14531
|
for (const [key, value] of Object.entries(updates)) {
|
|
@@ -14657,7 +14586,7 @@ var supersede = mutation({
|
|
|
14657
14586
|
throw new Error("Node not found");
|
|
14658
14587
|
}
|
|
14659
14588
|
if (oldNode.projectId) {
|
|
14660
|
-
await
|
|
14589
|
+
await requireScopeWriteAccess(ctx, oldNode.projectId, args.createdBy);
|
|
14661
14590
|
}
|
|
14662
14591
|
assertBeliefNodeSupersedeAllowed({
|
|
14663
14592
|
node: oldNode,
|
|
@@ -14733,7 +14662,7 @@ var archive2 = mutation({
|
|
|
14733
14662
|
throw new Error("Node not found");
|
|
14734
14663
|
}
|
|
14735
14664
|
if (node.projectId && args.userId) {
|
|
14736
|
-
await
|
|
14665
|
+
await requireScopeWriteAccess(ctx, node.projectId, args.userId);
|
|
14737
14666
|
}
|
|
14738
14667
|
assertBeliefNodeArchiveAllowed({
|
|
14739
14668
|
node,
|
|
@@ -18374,7 +18303,7 @@ var upsertSource = mutation({
|
|
|
18374
18303
|
mutationName: "epistemicSources.upsertSource"
|
|
18375
18304
|
});
|
|
18376
18305
|
if (scope.projectId) {
|
|
18377
|
-
await
|
|
18306
|
+
await requireScopeWriteAccess(ctx, scope.projectId, args.userId);
|
|
18378
18307
|
}
|
|
18379
18308
|
const globalId = generateGlobalId();
|
|
18380
18309
|
const title = normalizeString(args.title);
|