@lucern/graph-primitives 1.0.29 → 1.0.30
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-DZ6tkLYq.d.ts → beliefDecay-BmkEk5OJ.d.ts} +3 -3
- package/dist/beliefDecay.d.ts +1 -1
- package/dist/beliefDecay.js +448 -314
- package/dist/beliefDecay.js.map +1 -1
- package/dist/{beliefEvidenceLinks-CWOXxxJg.d.ts → beliefEvidenceLinks-BzfjON_6.d.ts} +13 -13
- package/dist/beliefEvidenceLinks.d.ts +1 -1
- package/dist/beliefEvidenceLinks.js +843 -624
- package/dist/beliefEvidenceLinks.js.map +1 -1
- package/dist/beliefEvidenceLinks.operational.d.ts +7 -5
- package/dist/beliefEvidenceLinks.operational.js +91 -18
- package/dist/beliefEvidenceLinks.operational.js.map +1 -1
- package/dist/beliefLifecycle.js.map +1 -1
- package/dist/confidencePropagationDispatch.d.ts +28 -27
- package/dist/confidencePropagationDispatch.js +157 -99
- package/dist/confidencePropagationDispatch.js.map +1 -1
- package/dist/{contradictions-51VLsESq.d.ts → contradictions-BATPuZTL.d.ts} +10 -10
- package/dist/contradictions.d.ts +1 -1
- package/dist/contradictions.js +395 -225
- package/dist/contradictions.js.map +1 -1
- package/dist/convex.d.ts +65 -30
- package/dist/convex.js +7 -3
- package/dist/convex.js.map +1 -1
- package/dist/debug.js.map +1 -1
- package/dist/edgeValidation.js +293 -85
- package/dist/edgeValidation.js.map +1 -1
- package/dist/edges/contains.d.ts +1 -1
- package/dist/edges/contains.js.map +1 -1
- package/dist/edges/contradicts.d.ts +1 -1
- package/dist/edges/contradicts.js.map +1 -1
- package/dist/edges/{dependsOn.d.ts → depends-on.d.ts} +1 -1
- package/dist/edges/{dependsOn.js → depends-on.js} +4 -4
- package/dist/edges/depends-on.js.map +1 -0
- package/dist/edges/{derivedFrom.d.ts → derived-from.d.ts} +1 -1
- package/dist/edges/{derivedFrom.js → derived-from.js} +3 -3
- package/dist/edges/derived-from.js.map +1 -0
- package/dist/edges/elaborates.d.ts +1 -1
- package/dist/edges/elaborates.js.map +1 -1
- package/dist/edges/index.d.ts +7 -3
- package/dist/edges/index.js +7 -4
- package/dist/edges/index.js.map +1 -1
- package/dist/edges/informs.d.ts +1 -1
- package/dist/edges/informs.js.map +1 -1
- package/dist/edges/{propagationTypes.d.ts → propagation-types.d.ts} +14 -14
- package/dist/edges/{propagationTypes.js → propagation-types.js} +3 -3
- package/dist/edges/propagation-types.js.map +1 -0
- package/dist/edges/refutes.d.ts +1 -1
- package/dist/edges/refutes.js.map +1 -1
- package/dist/edges/supports.d.ts +1 -1
- package/dist/edges/supports.js.map +1 -1
- package/dist/edges/tests.d.ts +1 -1
- package/dist/edges/tests.js.map +1 -1
- package/dist/edges/utils.d.ts +1 -1
- package/dist/edges/utils.js.map +1 -1
- package/dist/embeddingTrigger.d.ts +14 -6
- package/dist/embeddingTrigger.js +11 -14
- package/dist/embeddingTrigger.js.map +1 -1
- package/dist/{entityBridge-DMaKooYn.d.ts → entityBridge-BhVDM3pc.d.ts} +5 -5
- package/dist/entityBridge.d.ts +1 -1
- package/dist/entityBridge.js +602 -225
- package/dist/entityBridge.js.map +1 -1
- package/dist/entityCanonicalMatch.d.ts +14 -12
- package/dist/entityCanonicalMatch.js.map +1 -1
- package/dist/{entityLifecycle-CvgSK5FV.d.ts → entityLifecycle-BsfCz9pS.d.ts} +5 -9
- package/dist/entityLifecycle.d.ts +1 -1
- package/dist/entityLifecycle.js +854 -480
- package/dist/entityLifecycle.js.map +1 -1
- package/dist/{entityValidation-KLZ_Xl2D.d.ts → entityValidation-B1yNEHJx.d.ts} +7 -6
- package/dist/entityValidation.d.ts +3 -1
- package/dist/entityValidation.js +60 -8
- package/dist/entityValidation.js.map +1 -1
- package/dist/{epistemicAnswers-C5ib4z6_.d.ts → epistemicAnswers-f47YMu9U.d.ts} +6 -6
- package/dist/epistemicAnswers.d.ts +1 -1
- package/dist/epistemicAnswers.js +587 -545
- package/dist/epistemicAnswers.js.map +1 -1
- package/dist/epistemicBeliefs.admin.d.ts +8 -8
- package/dist/epistemicBeliefs.admin.js +365 -166
- package/dist/epistemicBeliefs.admin.js.map +1 -1
- package/dist/epistemicBeliefs.backfills.d.ts +8 -8
- package/dist/epistemicBeliefs.backfills.js +655 -289
- package/dist/epistemicBeliefs.backfills.js.map +1 -1
- package/dist/epistemicBeliefs.confidence.d.ts +19 -15
- package/dist/epistemicBeliefs.confidence.js +633 -386
- package/dist/epistemicBeliefs.confidence.js.map +1 -1
- package/dist/epistemicBeliefs.core.d.ts +6 -6
- package/dist/epistemicBeliefs.core.js +717 -371
- package/dist/epistemicBeliefs.core.js.map +1 -1
- package/dist/epistemicBeliefs.d.ts +11 -9
- package/dist/epistemicBeliefs.forkEvidence.d.ts +2 -0
- package/dist/epistemicBeliefs.forkEvidence.js +8 -8
- package/dist/epistemicBeliefs.forkEvidence.js.map +1 -1
- package/dist/epistemicBeliefs.helpers.d.ts +68 -49
- package/dist/epistemicBeliefs.helpers.js +358 -211
- package/dist/epistemicBeliefs.helpers.js.map +1 -1
- package/dist/epistemicBeliefs.internal.d.ts +5 -5
- package/dist/epistemicBeliefs.internal.js +1248 -1026
- package/dist/epistemicBeliefs.internal.js.map +1 -1
- package/dist/epistemicBeliefs.js +4942 -3590
- package/dist/epistemicBeliefs.js.map +1 -1
- package/dist/epistemicBeliefs.lifecycle.d.ts +5 -5
- package/dist/epistemicBeliefs.lifecycle.js +1138 -781
- package/dist/epistemicBeliefs.lifecycle.js.map +1 -1
- package/dist/epistemicBeliefs.links.d.ts +7 -7
- package/dist/epistemicBeliefs.links.js +404 -267
- package/dist/epistemicBeliefs.links.js.map +1 -1
- package/dist/epistemicBeliefs.queries.d.ts +4 -4
- package/dist/epistemicBeliefs.queries.js +175 -20
- package/dist/epistemicBeliefs.queries.js.map +1 -1
- package/dist/epistemicBeliefs.topicAnchor.d.ts +6 -4
- package/dist/epistemicBeliefs.topicAnchor.js +12 -5
- package/dist/epistemicBeliefs.topicAnchor.js.map +1 -1
- package/dist/epistemicContracts.d.ts +28 -3
- package/dist/epistemicContracts.evaluators.d.ts +2 -0
- package/dist/epistemicContracts.evaluators.js +1062 -576
- package/dist/epistemicContracts.evaluators.js.map +1 -1
- package/dist/epistemicContracts.handlers.d.ts +15 -32
- package/dist/epistemicContracts.handlers.js +1829 -1351
- package/dist/epistemicContracts.handlers.js.map +1 -1
- package/dist/epistemicContracts.js +1131 -636
- package/dist/epistemicContracts.js.map +1 -1
- package/dist/epistemicContracts.metrics.d.ts +2 -0
- package/dist/epistemicContracts.metrics.js +375 -158
- package/dist/epistemicContracts.metrics.js.map +1 -1
- package/dist/epistemicContracts.types.d.ts +87 -81
- package/dist/epistemicEdgeCreation.d.ts +2 -0
- package/dist/epistemicEdgeCreation.js +87 -16
- package/dist/epistemicEdgeCreation.js.map +1 -1
- package/dist/{epistemicEdges-BF-cn4i3.d.ts → epistemicEdges-BGBh0QSP.d.ts} +4 -7
- package/dist/epistemicEdges.d.ts +6 -5
- package/dist/epistemicEdges.handlers.d.ts +3 -3
- package/dist/epistemicEdges.handlers.js +129 -24
- package/dist/epistemicEdges.handlers.js.map +1 -1
- package/dist/epistemicEdges.helpers.d.ts +6 -4
- package/dist/epistemicEdges.helpers.js +37 -2
- package/dist/epistemicEdges.helpers.js.map +1 -1
- package/dist/epistemicEdges.js +1966 -1202
- package/dist/epistemicEdges.js.map +1 -1
- package/dist/epistemicEdges.mutations.d.ts +7 -7
- package/dist/epistemicEdges.mutations.js +956 -579
- package/dist/epistemicEdges.mutations.js.map +1 -1
- package/dist/epistemicEdges.queries.d.ts +16 -16
- package/dist/epistemicEdges.queries.js +639 -367
- package/dist/epistemicEdges.queries.js.map +1 -1
- package/dist/epistemicEdges.types.d.ts +10 -8
- package/dist/epistemicEvidence.d.ts +4 -1
- package/dist/epistemicEvidence.js +933 -532
- package/dist/epistemicEvidence.js.map +1 -1
- package/dist/epistemicEvidenceHelpers.d.ts +26 -10
- package/dist/epistemicEvidenceHelpers.js +239 -200
- package/dist/epistemicEvidenceHelpers.js.map +1 -1
- package/dist/epistemicEvidenceMutations.d.ts +8 -8
- package/dist/epistemicEvidenceMutations.js +840 -692
- package/dist/epistemicEvidenceMutations.js.map +1 -1
- package/dist/epistemicEvidenceQueries.d.ts +8 -8
- package/dist/epistemicEvidenceQueries.js +514 -238
- package/dist/epistemicEvidenceQueries.js.map +1 -1
- package/dist/epistemicHelpers.d.ts +4 -2
- package/dist/epistemicHelpers.js +308 -134
- package/dist/epistemicHelpers.js.map +1 -1
- package/dist/epistemicInsert.d.ts +16 -4
- package/dist/epistemicInsert.js +6 -3
- package/dist/epistemicInsert.js.map +1 -1
- package/dist/epistemicLayerRules.d.ts +10 -8
- package/dist/epistemicLayerRules.js +1 -5
- package/dist/epistemicLayerRules.js.map +1 -1
- package/dist/{epistemicLinking-CfE00tHJ.d.ts → epistemicLinking-CsCDv2cN.d.ts} +3 -3
- package/dist/epistemicLinking.d.ts +1 -1
- package/dist/epistemicLinking.js +177 -100
- package/dist/epistemicLinking.js.map +1 -1
- package/dist/epistemicNodeCreation.d.ts +2 -0
- package/dist/epistemicNodeCreation.js +203 -40
- package/dist/epistemicNodeCreation.js.map +1 -1
- package/dist/{epistemicNodes-BCQxpYx_.d.ts → epistemicNodes-CokAgBHg.d.ts} +3 -3
- package/dist/epistemicNodes.d.ts +3 -3
- package/dist/epistemicNodes.helpers.d.ts +24 -15
- package/dist/epistemicNodes.helpers.js.map +1 -1
- package/dist/epistemicNodes.internal.d.ts +6 -6
- package/dist/epistemicNodes.internal.js +389 -319
- package/dist/epistemicNodes.internal.js.map +1 -1
- package/dist/epistemicNodes.js +700 -504
- package/dist/epistemicNodes.js.map +1 -1
- package/dist/epistemicNodes.mutations.d.ts +6 -6
- package/dist/epistemicNodes.mutations.js +560 -463
- package/dist/epistemicNodes.mutations.js.map +1 -1
- package/dist/epistemicNodes.queries.d.ts +8 -8
- package/dist/epistemicNodes.queries.js +311 -314
- package/dist/epistemicNodes.queries.js.map +1 -1
- package/dist/epistemicNodes.validators.d.ts +2 -2
- package/dist/epistemicNodes.validators.js.map +1 -1
- package/dist/epistemicQuestions.conviction.d.ts +8 -8
- package/dist/epistemicQuestions.conviction.js +665 -484
- package/dist/epistemicQuestions.conviction.js.map +1 -1
- package/dist/epistemicQuestions.create.d.ts +4 -4
- package/dist/epistemicQuestions.create.js +640 -612
- package/dist/epistemicQuestions.create.js.map +1 -1
- package/dist/epistemicQuestions.d.ts +8 -5
- package/dist/epistemicQuestions.evidence.d.ts +2 -2
- package/dist/epistemicQuestions.evidence.js +475 -383
- package/dist/epistemicQuestions.evidence.js.map +1 -1
- package/dist/epistemicQuestions.helpers.d.ts +125 -24
- package/dist/epistemicQuestions.helpers.js +240 -209
- package/dist/epistemicQuestions.helpers.js.map +1 -1
- package/dist/epistemicQuestions.js +3474 -2823
- package/dist/epistemicQuestions.js.map +1 -1
- package/dist/epistemicQuestions.lifecycle.d.ts +2 -2
- package/dist/epistemicQuestions.lifecycle.js +607 -546
- package/dist/epistemicQuestions.lifecycle.js.map +1 -1
- package/dist/epistemicQuestions.queries.d.ts +12 -7
- package/dist/epistemicQuestions.queries.js +305 -244
- package/dist/epistemicQuestions.queries.js.map +1 -1
- package/dist/epistemicQuestions.sprint.d.ts +2 -2
- package/dist/epistemicQuestions.sprint.js +600 -394
- package/dist/epistemicQuestions.sprint.js.map +1 -1
- package/dist/epistemicQuestions.tail.d.ts +6 -6
- package/dist/epistemicQuestions.tail.js +572 -433
- package/dist/epistemicQuestions.tail.js.map +1 -1
- package/dist/{epistemicSources-dlKj58Jp.d.ts → epistemicSources-DQtaEkWs.d.ts} +4 -4
- package/dist/epistemicSources.d.ts +1 -1
- package/dist/epistemicSources.js +351 -311
- package/dist/epistemicSources.js.map +1 -1
- package/dist/evaluators/index.d.ts +8 -6
- package/dist/evaluators/index.js +399 -167
- package/dist/evaluators/index.js.map +1 -1
- package/dist/evaluators/lint-checker-evaluator.d.ts +16 -0
- package/dist/evaluators/{lintCheckerEvaluator.js → lint-checker-evaluator.js} +10 -5
- package/dist/evaluators/lint-checker-evaluator.js.map +1 -0
- package/dist/evaluators/{sentryCheckerEvaluator.d.ts → sentry-checker-evaluator.d.ts} +7 -2
- package/dist/evaluators/{sentryCheckerEvaluator.js → sentry-checker-evaluator.js} +3 -3
- package/dist/evaluators/sentry-checker-evaluator.js.map +1 -0
- package/dist/evaluators/shared.d.ts +2 -2
- package/dist/evaluators/shared.js +3 -1
- package/dist/evaluators/shared.js.map +1 -1
- package/dist/evaluators/{testRunnerEvaluator.d.ts → test-runner-evaluator.d.ts} +6 -1
- package/dist/evaluators/{testRunnerEvaluator.js → test-runner-evaluator.js} +6 -4
- package/dist/evaluators/test-runner-evaluator.js.map +1 -0
- package/dist/evaluators/tsc-checker-evaluator.d.ts +16 -0
- package/dist/evaluators/{tscCheckerEvaluator.js → tsc-checker-evaluator.js} +10 -5
- package/dist/evaluators/tsc-checker-evaluator.js.map +1 -0
- package/dist/graphTypes.js +6 -2
- package/dist/graphTypes.js.map +1 -1
- package/dist/helpers.d.ts +2 -0
- package/dist/helpers.js +313 -93
- package/dist/helpers.js.map +1 -1
- package/dist/{index-C-Kyd7hD.d.ts → index-DZxyC9Pb.d.ts} +7 -6
- package/dist/index.d.ts +86 -83
- package/dist/index.js +16914 -11760
- package/dist/index.js.map +1 -1
- package/dist/invariantEnforcement.d.ts +3 -3
- package/dist/invariantEnforcement.js.map +1 -1
- package/dist/logicalRoleInference.d.ts +2 -0
- package/dist/logicalRoleInference.js +1 -1
- package/dist/logicalRoleInference.js.map +1 -1
- package/dist/matcherFeedbackUtils.d.ts +2 -2
- package/dist/matcherFeedbackUtils.js.map +1 -1
- package/dist/{ontology-matching-C6rrz2VP.d.ts → ontology-matching-C-mYFrir.d.ts} +16 -16
- package/dist/ontology-matching.d.ts +1 -1
- package/dist/{ontologyApproval-CFYmqKmk.d.ts → ontologyApproval-BVt0feJi.d.ts} +10 -10
- package/dist/ontologyApproval.d.ts +1 -1
- package/dist/ontologyApproval.js +7 -1
- package/dist/ontologyApproval.js.map +1 -1
- package/dist/ontologyDefinitions.d.ts +14 -24
- package/dist/ontologyDefinitions.js +269 -34
- package/dist/ontologyDefinitions.js.map +1 -1
- package/dist/ontologyHelpers.d.ts +13 -13
- package/dist/ontologyHelpers.js.map +1 -1
- package/dist/{ontologyRegistry-B67rPJ16.d.ts → ontologyRegistry-CljS-ENv.d.ts} +2 -2
- package/dist/ontologyRegistry.d.ts +1 -1
- package/dist/ontologyRegistry.js +34 -6
- package/dist/ontologyRegistry.js.map +1 -1
- package/dist/{projectionReconciliation-jww2fBI0.d.ts → projectionReconciliation-DnrSgHSQ.d.ts} +4 -4
- package/dist/projectionReconciliation.d.ts +1 -1
- package/dist/projectionReconciliation.js +57 -10
- package/dist/projectionReconciliation.js.map +1 -1
- package/dist/{projectionStaleness-CmdbpjVK.d.ts → projectionStaleness-C8ImQ2zP.d.ts} +17 -17
- package/dist/projectionStaleness.d.ts +1 -1
- package/dist/projectionStaleness.js +8 -2
- package/dist/projectionStaleness.js.map +1 -1
- package/dist/proof-attestation.json +1 -1
- package/dist/{questionEvidenceLinks-DFlyPpAj.d.ts → questionEvidenceLinks-_nPRa-LY.d.ts} +10 -10
- package/dist/questionEvidenceLinks.d.ts +1 -1
- package/dist/questionEvidenceLinks.js +564 -347
- package/dist/questionEvidenceLinks.js.map +1 -1
- package/dist/{resolverTypes-CC8Ea2E2.d.ts → resolverTypes-BOXPxLET.d.ts} +8 -7
- package/dist/resolverTypes.d.ts +4 -2
- package/dist/{resolvers-Br1a6eLV.d.ts → resolvers-B1TIBmRO.d.ts} +3 -1
- package/dist/resolvers.d.ts +5 -3
- package/dist/resolvers.js +121 -77
- package/dist/resolvers.js.map +1 -1
- package/dist/scopeResolverCompat.d.ts +10 -7
- package/dist/scopeResolverCompat.js +106 -123
- package/dist/scopeResolverCompat.js.map +1 -1
- package/dist/{text-matching-DNg4M5Wd.d.ts → text-matching-DzFooju6.d.ts} +7 -7
- package/dist/text-matching.d.ts +1 -1
- package/dist/topicOntologyResolver.d.ts +22 -21
- package/dist/topicOntologyResolver.js +54 -32
- package/dist/topicOntologyResolver.js.map +1 -1
- package/dist/topicProjectOverlay.d.ts +30 -20
- package/dist/topicProjectOverlay.js +120 -76
- package/dist/topicProjectOverlay.js.map +1 -1
- package/dist/{topicScope-7zhyeGl7.d.ts → topicScope-DJVa0mLa.d.ts} +22 -7
- package/dist/topicScope.d.ts +3 -1
- package/dist/topicScope.js +104 -119
- package/dist/topicScope.js.map +1 -1
- package/dist/workflowBridge.d.ts +26 -15
- package/dist/workflowBridge.js +140 -144
- package/dist/workflowBridge.js.map +1 -1
- package/dist/workspaceIsolation.d.ts +14 -12
- package/dist/workspaceIsolation.js +108 -122
- package/dist/workspaceIsolation.js.map +1 -1
- package/package.json +4 -4
- package/dist/edges/dependsOn.js.map +0 -1
- package/dist/edges/derivedFrom.js.map +0 -1
- package/dist/edges/propagationTypes.js.map +0 -1
- package/dist/evaluators/lintCheckerEvaluator.d.ts +0 -11
- package/dist/evaluators/lintCheckerEvaluator.js.map +0 -1
- package/dist/evaluators/sentryCheckerEvaluator.js.map +0 -1
- package/dist/evaluators/testRunnerEvaluator.js.map +0 -1
- package/dist/evaluators/tscCheckerEvaluator.d.ts +0 -11
- package/dist/evaluators/tscCheckerEvaluator.js.map +0 -1
- package/dist/{epistemicQuestions-bwHd2FWE.d.ts → epistemicQuestions-Do1fhYm5.d.ts} +4 -4
|
@@ -1,15 +1,19 @@
|
|
|
1
|
-
import { v } from 'convex/values';
|
|
2
1
|
import { requireScopeWriteAccess } from '@lucern/access-control/access';
|
|
3
2
|
import { permissiveReturn } from '@lucern/contracts/schema-helpers/validators';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
3
|
+
import { v } from 'convex/values';
|
|
4
|
+
import { unsafeConvexAnyApi } from '@lucern/contracts/convex/unsafeAnyApi';
|
|
5
|
+
import { componentsGeneric, mutationGeneric } from 'convex/server';
|
|
7
6
|
import '@lucern/contracts';
|
|
7
|
+
import { assertUuidV7Identity } from '@lucern/contracts/ids';
|
|
8
|
+
import { isNodeType, getLayerForNodeType } from '@lucern/contracts/schema-helpers/spine/tables/epistemicNodes';
|
|
8
9
|
|
|
9
10
|
// src/epistemicNodes.mutations.ts
|
|
10
|
-
var
|
|
11
|
+
var unsafeApi = unsafeConvexAnyApi(
|
|
12
|
+
"graph-primitives top-level module bundle lacks a committed Convex _generated/api surface"
|
|
13
|
+
);
|
|
14
|
+
var api = unsafeApi;
|
|
11
15
|
componentsGeneric();
|
|
12
|
-
var internal =
|
|
16
|
+
var internal = unsafeApi;
|
|
13
17
|
var mutation = mutationGeneric;
|
|
14
18
|
|
|
15
19
|
// src/debug.ts
|
|
@@ -23,6 +27,119 @@ function debugGraphPrimitiveFallback(message, context) {
|
|
|
23
27
|
}
|
|
24
28
|
console.debug(message, context ?? {});
|
|
25
29
|
}
|
|
30
|
+
function insertEpistemicNode(ctx, doc) {
|
|
31
|
+
assertUuidV7Identity("epistemicNodes", doc.globalId);
|
|
32
|
+
return ctx.db.insert("epistemicNodes", doc);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// src/epistemicNodes.helpers.ts
|
|
36
|
+
function buildNodeStatusSuccessResult() {
|
|
37
|
+
return { success: true };
|
|
38
|
+
}
|
|
39
|
+
function buildNodeArchivedResult() {
|
|
40
|
+
return {
|
|
41
|
+
success: true,
|
|
42
|
+
effectiveStatus: "archived"
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
v.union(
|
|
46
|
+
v.literal("L4"),
|
|
47
|
+
v.literal("L3"),
|
|
48
|
+
v.literal("L2"),
|
|
49
|
+
v.literal("L1"),
|
|
50
|
+
v.literal("ontological"),
|
|
51
|
+
v.literal("organizational")
|
|
52
|
+
);
|
|
53
|
+
v.union(v.literal("decision"));
|
|
54
|
+
v.union(
|
|
55
|
+
v.literal("belief"),
|
|
56
|
+
v.literal("question"),
|
|
57
|
+
v.literal("theme"),
|
|
58
|
+
v.literal("deal")
|
|
59
|
+
);
|
|
60
|
+
v.union(
|
|
61
|
+
v.literal("claim"),
|
|
62
|
+
v.literal("evidence"),
|
|
63
|
+
v.literal("synthesis")
|
|
64
|
+
);
|
|
65
|
+
v.union(
|
|
66
|
+
v.literal("atomic_fact"),
|
|
67
|
+
v.literal("excerpt"),
|
|
68
|
+
v.literal("source")
|
|
69
|
+
);
|
|
70
|
+
v.union(
|
|
71
|
+
// L4: Audit targets
|
|
72
|
+
v.literal("decision"),
|
|
73
|
+
// L3: Traversal anchors
|
|
74
|
+
v.literal("belief"),
|
|
75
|
+
v.literal("question"),
|
|
76
|
+
v.literal("theme"),
|
|
77
|
+
v.literal("deal"),
|
|
78
|
+
// L2: Compression boundary
|
|
79
|
+
v.literal("claim"),
|
|
80
|
+
v.literal("evidence"),
|
|
81
|
+
v.literal("synthesis"),
|
|
82
|
+
v.literal("answer"),
|
|
83
|
+
// L1: Terminal leaves
|
|
84
|
+
v.literal("atomic_fact"),
|
|
85
|
+
v.literal("excerpt"),
|
|
86
|
+
v.literal("source")
|
|
87
|
+
);
|
|
88
|
+
v.union(
|
|
89
|
+
v.literal("company"),
|
|
90
|
+
v.literal("person"),
|
|
91
|
+
v.literal("investor"),
|
|
92
|
+
v.literal("function"),
|
|
93
|
+
v.literal("value_chain")
|
|
94
|
+
);
|
|
95
|
+
v.union(v.literal("topic"));
|
|
96
|
+
var nodeTypeValidator = v.union(
|
|
97
|
+
// L4: Audit targets
|
|
98
|
+
v.literal("decision"),
|
|
99
|
+
// L3: Traversal anchors
|
|
100
|
+
v.literal("belief"),
|
|
101
|
+
v.literal("question"),
|
|
102
|
+
v.literal("theme"),
|
|
103
|
+
v.literal("deal"),
|
|
104
|
+
// L2: Compression boundary
|
|
105
|
+
v.literal("claim"),
|
|
106
|
+
v.literal("evidence"),
|
|
107
|
+
v.literal("synthesis"),
|
|
108
|
+
v.literal("answer"),
|
|
109
|
+
// L1: Terminal leaves
|
|
110
|
+
v.literal("atomic_fact"),
|
|
111
|
+
v.literal("excerpt"),
|
|
112
|
+
v.literal("source"),
|
|
113
|
+
// Ontological
|
|
114
|
+
v.literal("company"),
|
|
115
|
+
v.literal("person"),
|
|
116
|
+
v.literal("investor"),
|
|
117
|
+
v.literal("function"),
|
|
118
|
+
v.literal("value_chain"),
|
|
119
|
+
// Organizational
|
|
120
|
+
v.literal("topic")
|
|
121
|
+
);
|
|
122
|
+
var sourceTypeValidator = v.union(
|
|
123
|
+
v.literal("human"),
|
|
124
|
+
v.literal("ai_extracted"),
|
|
125
|
+
v.literal("ai_generated"),
|
|
126
|
+
v.literal("imported"),
|
|
127
|
+
v.literal("system")
|
|
128
|
+
// System-generated (migrations, classifiers)
|
|
129
|
+
);
|
|
130
|
+
var statusValidator = v.union(
|
|
131
|
+
v.literal("active"),
|
|
132
|
+
v.literal("superseded"),
|
|
133
|
+
v.literal("archived"),
|
|
134
|
+
v.literal("deleted")
|
|
135
|
+
);
|
|
136
|
+
var verificationStatusValidator = v.union(
|
|
137
|
+
v.literal("unverified"),
|
|
138
|
+
v.literal("human_verified"),
|
|
139
|
+
v.literal("ai_verified"),
|
|
140
|
+
v.literal("contradicted"),
|
|
141
|
+
v.literal("outdated")
|
|
142
|
+
);
|
|
26
143
|
|
|
27
144
|
// src/graphTypes.ts
|
|
28
145
|
function getNodeLayer(nodeType) {
|
|
@@ -59,6 +176,209 @@ function getNodeLayer(nodeType) {
|
|
|
59
176
|
console.warn(`[GraphTypes] Unknown nodeType "${nodeType}", defaulting to L2`);
|
|
60
177
|
return "L2";
|
|
61
178
|
}
|
|
179
|
+
|
|
180
|
+
// src/beliefLifecycle.ts
|
|
181
|
+
var RESOLVED_PREDICTION_OUTCOMES = [
|
|
182
|
+
"confirmed",
|
|
183
|
+
"disconfirmed",
|
|
184
|
+
"partial",
|
|
185
|
+
"expired"
|
|
186
|
+
];
|
|
187
|
+
function hasResolvedPredictionOutcome(predictionMeta) {
|
|
188
|
+
if (!predictionMeta || typeof predictionMeta !== "object") {
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
const outcome = predictionMeta.outcome;
|
|
192
|
+
return typeof outcome === "string" && RESOLVED_PREDICTION_OUTCOMES.includes(outcome);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// src/invariantEnforcement.ts
|
|
196
|
+
var FORBIDDEN_GENERIC_BELIEF_METADATA_KEYS = /* @__PURE__ */ new Set([
|
|
197
|
+
"beliefStatus",
|
|
198
|
+
"epistemicStatus",
|
|
199
|
+
"forkedBy",
|
|
200
|
+
"forkedFrom",
|
|
201
|
+
"forkReason",
|
|
202
|
+
"forkTimestamp",
|
|
203
|
+
"status",
|
|
204
|
+
"supersededBy",
|
|
205
|
+
"supersedes"
|
|
206
|
+
]);
|
|
207
|
+
var ONTOLOGICAL_NODE_TYPES = /* @__PURE__ */ new Set([
|
|
208
|
+
"company",
|
|
209
|
+
"person",
|
|
210
|
+
"investor",
|
|
211
|
+
"function",
|
|
212
|
+
"value_chain"
|
|
213
|
+
]);
|
|
214
|
+
function throwInvariantError(args) {
|
|
215
|
+
const error = new Error(args.message);
|
|
216
|
+
error.status = args.status ?? 409;
|
|
217
|
+
error.code = args.code ?? "INVARIANT_VIOLATION";
|
|
218
|
+
error.invariantCode = args.invariantCode;
|
|
219
|
+
error.suggestion = args.suggestion;
|
|
220
|
+
error.details = args.details;
|
|
221
|
+
throw error;
|
|
222
|
+
}
|
|
223
|
+
function isBeliefNode(node) {
|
|
224
|
+
return node?.nodeType === "belief";
|
|
225
|
+
}
|
|
226
|
+
function isOntologicalNode(node) {
|
|
227
|
+
return typeof node?.nodeType === "string" && ONTOLOGICAL_NODE_TYPES.has(node.nodeType);
|
|
228
|
+
}
|
|
229
|
+
function isScoredBeliefNode(node) {
|
|
230
|
+
if (!isBeliefNode(node)) {
|
|
231
|
+
return false;
|
|
232
|
+
}
|
|
233
|
+
const metadata = node.metadata && typeof node.metadata === "object" ? node.metadata : void 0;
|
|
234
|
+
const numericConfidence = typeof node.confidence === "number" && Number.isFinite(node.confidence);
|
|
235
|
+
if (numericConfidence) {
|
|
236
|
+
return true;
|
|
237
|
+
}
|
|
238
|
+
return hasResolvedPredictionOutcome(node.predictionMeta) || hasResolvedPredictionOutcome(metadata?.predictionMeta);
|
|
239
|
+
}
|
|
240
|
+
function getForbiddenMetadataKeys(metadata) {
|
|
241
|
+
if (!metadata || typeof metadata !== "object" || Array.isArray(metadata)) {
|
|
242
|
+
return [];
|
|
243
|
+
}
|
|
244
|
+
return Object.keys(metadata).filter(
|
|
245
|
+
(key) => FORBIDDEN_GENERIC_BELIEF_METADATA_KEYS.has(key)
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
function assertBeliefNodeGenericUpdateAllowed(args) {
|
|
249
|
+
if (!isBeliefNode(args.node)) {
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
if (Object.hasOwn(args.updates, "confidence")) {
|
|
253
|
+
throwInvariantError({
|
|
254
|
+
message: "Belief confidence is append-only. Generic node updates cannot set confidence directly.",
|
|
255
|
+
invariantCode: "belief.confidence_append_only",
|
|
256
|
+
suggestion: "Use epistemicBeliefs.appendSlScoring() so the beliefConfidence ledger and audit trail are updated together.",
|
|
257
|
+
details: { mutationName: args.mutationName, nodeId: args.node._id }
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
if (Object.hasOwn(args.updates, "status")) {
|
|
261
|
+
throwInvariantError({
|
|
262
|
+
message: "Belief status transitions must use the dedicated belief lifecycle APIs.",
|
|
263
|
+
invariantCode: "belief.status_transition_requires_belief_api",
|
|
264
|
+
suggestion: "Use epistemicBeliefs.updateStatus() or epistemicBeliefs.archive() so status transitions emit the correct audit event.",
|
|
265
|
+
details: { mutationName: args.mutationName, nodeId: args.node._id }
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
const forbiddenMetadataKeys = getForbiddenMetadataKeys(args.updates.metadata);
|
|
269
|
+
if (forbiddenMetadataKeys.length > 0) {
|
|
270
|
+
throwInvariantError({
|
|
271
|
+
message: "Belief lineage and lifecycle metadata cannot be rewritten through generic node updates.",
|
|
272
|
+
invariantCode: "belief.lineage_requires_fork_belief",
|
|
273
|
+
suggestion: "Use epistemicBeliefs.forkBelief() for lineage changes and dedicated belief lifecycle mutations for status changes.",
|
|
274
|
+
details: {
|
|
275
|
+
mutationName: args.mutationName,
|
|
276
|
+
nodeId: args.node._id,
|
|
277
|
+
forbiddenMetadataKeys
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
if (isScoredBeliefNode(args.node) && (Object.hasOwn(args.updates, "canonicalText") || Object.hasOwn(args.updates, "contentHash"))) {
|
|
282
|
+
throwInvariantError({
|
|
283
|
+
message: "Cannot refine a scored belief in place. Scored formulations are immutable.",
|
|
284
|
+
invariantCode: "belief.formulation_immutable_after_scoring",
|
|
285
|
+
suggestion: "Use epistemicBeliefs.forkBelief() to evolve the formulation while preserving lineage.",
|
|
286
|
+
details: { mutationName: args.mutationName, nodeId: args.node._id }
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
function assertBeliefNodeArchiveAllowed(args) {
|
|
291
|
+
if (!isBeliefNode(args.node)) {
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
throwInvariantError({
|
|
295
|
+
message: "Belief archiving must go through the dedicated belief lifecycle API.",
|
|
296
|
+
invariantCode: "belief.status_transition_requires_belief_api",
|
|
297
|
+
suggestion: "Use epistemicBeliefs.archive() so the belief lifecycle audit trail stays consistent.",
|
|
298
|
+
details: { mutationName: args.mutationName, nodeId: args.node._id }
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
function assertBeliefNodeVerifyAllowed(args) {
|
|
302
|
+
if (!isBeliefNode(args.node) || args.confidence === void 0) {
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
throwInvariantError({
|
|
306
|
+
message: "Belief verification cannot set confidence directly. Confidence changes must stay append-only.",
|
|
307
|
+
invariantCode: "belief.confidence_append_only",
|
|
308
|
+
suggestion: "Call epistemicBeliefs.appendSlScoring() after verification so the confidence history is preserved.",
|
|
309
|
+
details: { mutationName: args.mutationName, nodeId: args.node._id }
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
function assertBeliefNodeSupersedeAllowed(args) {
|
|
313
|
+
if (!isBeliefNode(args.node)) {
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
throwInvariantError({
|
|
317
|
+
message: "Belief lineage changes must use forkBelief(), not the generic supersede path.",
|
|
318
|
+
invariantCode: "belief.lineage_requires_fork_belief",
|
|
319
|
+
suggestion: "Use epistemicBeliefs.forkBelief() so the child belief, supersedes edge, and audit trail are created together.",
|
|
320
|
+
details: { mutationName: args.mutationName, nodeId: args.node._id }
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
function assertOntologicalNodeGenericCreateAllowed(args) {
|
|
324
|
+
if (!ONTOLOGICAL_NODE_TYPES.has(args.nodeType)) {
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
throwInvariantError({
|
|
328
|
+
message: "Ontological entities must be created through the dedicated entity lifecycle API.",
|
|
329
|
+
invariantCode: "entity.create_requires_entity_lifecycle",
|
|
330
|
+
suggestion: "Use entityLifecycle.createEntity() so tenant-global canonical scope and deduplication are enforced.",
|
|
331
|
+
details: {
|
|
332
|
+
mutationName: args.mutationName,
|
|
333
|
+
nodeType: args.nodeType
|
|
334
|
+
}
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
function assertOntologicalNodeGenericUpdateAllowed(args) {
|
|
338
|
+
if (!isOntologicalNode(args.node)) {
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
throwInvariantError({
|
|
342
|
+
message: "Ontological entities must be updated through the dedicated entity lifecycle API.",
|
|
343
|
+
invariantCode: "entity.update_requires_entity_lifecycle",
|
|
344
|
+
suggestion: "Use entityLifecycle.updateEntityAttributes() so canonical entity mutations stay type-safe and audited.",
|
|
345
|
+
details: {
|
|
346
|
+
mutationName: args.mutationName,
|
|
347
|
+
nodeId: args.node._id,
|
|
348
|
+
nodeType: args.node.nodeType
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
function assertOntologicalNodeArchiveAllowed(args) {
|
|
353
|
+
if (!isOntologicalNode(args.node)) {
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
throwInvariantError({
|
|
357
|
+
message: "Ontological entities must be archived through the dedicated entity lifecycle API.",
|
|
358
|
+
invariantCode: "entity.archive_requires_entity_lifecycle",
|
|
359
|
+
suggestion: "Use entityLifecycle.archiveEntity() so entity archival emits the correct audit trail and review hooks.",
|
|
360
|
+
details: {
|
|
361
|
+
mutationName: args.mutationName,
|
|
362
|
+
nodeId: args.node._id,
|
|
363
|
+
nodeType: args.node.nodeType
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
function assertOntologicalNodeSupersedeAllowed(args) {
|
|
368
|
+
if (!isOntologicalNode(args.node)) {
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
throwInvariantError({
|
|
372
|
+
message: "Ontological entities do not use the generic supersede path.",
|
|
373
|
+
invariantCode: "entity.supersede_requires_entity_lifecycle",
|
|
374
|
+
suggestion: "Use entityLifecycle.updateEntityAttributes() to edit an entity in place or entityLifecycle.mergeEntities() to collapse duplicates.",
|
|
375
|
+
details: {
|
|
376
|
+
mutationName: args.mutationName,
|
|
377
|
+
nodeId: args.node._id,
|
|
378
|
+
nodeType: args.node.nodeType
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
}
|
|
62
382
|
var LEGACY_SCOPE_FIELD = "graphScopeProjectId";
|
|
63
383
|
async function resolveTopicNodeScopeOrNull(ctx, ref) {
|
|
64
384
|
if (!ctx?.db || typeof ctx.db.query !== "function") {
|
|
@@ -93,13 +413,15 @@ function asMappedProjectId(topic) {
|
|
|
93
413
|
if (!topic) {
|
|
94
414
|
return;
|
|
95
415
|
}
|
|
96
|
-
const directLegacyProjectId = normalizeScopeValue(
|
|
416
|
+
const directLegacyProjectId = normalizeScopeValue(
|
|
417
|
+
topic[LEGACY_SCOPE_FIELD]
|
|
418
|
+
);
|
|
97
419
|
if (directLegacyProjectId) {
|
|
98
420
|
return directLegacyProjectId;
|
|
99
421
|
}
|
|
100
422
|
const metadata = topic.metadata || {};
|
|
101
423
|
const candidate = metadata[LEGACY_SCOPE_FIELD] || metadata.legacyProjectId || metadata.projectId || metadata.scopeProjectId;
|
|
102
|
-
return candidate ? candidate : void 0;
|
|
424
|
+
return typeof candidate === "string" ? normalizeScopeValue(candidate) : void 0;
|
|
103
425
|
}
|
|
104
426
|
function normalizeScopeValue(value) {
|
|
105
427
|
if (typeof value !== "string") {
|
|
@@ -124,8 +446,9 @@ function pickPrimaryTopic(candidates) {
|
|
|
124
446
|
})[0];
|
|
125
447
|
}
|
|
126
448
|
async function findTopicsByScopeAlias(ctx, scopeId) {
|
|
449
|
+
const query = ctx.db.query("topics");
|
|
127
450
|
try {
|
|
128
|
-
return await
|
|
451
|
+
return await query.withIndex(
|
|
129
452
|
"by_graph_scope_project",
|
|
130
453
|
(q) => q.eq(LEGACY_SCOPE_FIELD, scopeId)
|
|
131
454
|
).collect();
|
|
@@ -137,7 +460,7 @@ async function findTopicsByScopeAlias(ctx, scopeId) {
|
|
|
137
460
|
scopeId
|
|
138
461
|
}
|
|
139
462
|
);
|
|
140
|
-
const topics = await
|
|
463
|
+
const topics = await query.collect();
|
|
141
464
|
return topics.filter((topic) => {
|
|
142
465
|
const normalizedGlobalId = normalizeScopeValue(topic.globalId);
|
|
143
466
|
const mappedProjectId = asMappedProjectId(topic);
|
|
@@ -193,344 +516,119 @@ async function resolveInheritedWorkspaceScope(ctx, topic) {
|
|
|
193
516
|
let current = topic;
|
|
194
517
|
for (let i = 0; i < MAX_DEPTH && current?.parentTopicId; i++) {
|
|
195
518
|
current = await ctx.db.get(current.parentTopicId);
|
|
196
|
-
if (!current)
|
|
519
|
+
if (!current) {
|
|
520
|
+
break;
|
|
521
|
+
}
|
|
197
522
|
if (!tenantId) {
|
|
198
523
|
tenantId = normalizeScopeValue(current.tenantId);
|
|
199
524
|
}
|
|
200
525
|
if (!workspaceId) {
|
|
201
526
|
workspaceId = normalizeScopeValue(current.workspaceId);
|
|
202
527
|
}
|
|
203
|
-
if (tenantId && workspaceId)
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
}
|
|
207
|
-
async function resolveTopicProjectScope(ctx, args) {
|
|
208
|
-
if (args.topicId) {
|
|
209
|
-
let topic = null;
|
|
210
|
-
try {
|
|
211
|
-
topic = await ctx.db.get(
|
|
212
|
-
args.topicId
|
|
213
|
-
);
|
|
214
|
-
} catch (error) {
|
|
215
|
-
debugGraphPrimitiveFallback(
|
|
216
|
-
"[topicScope] Failed to load topic by direct id",
|
|
217
|
-
{
|
|
218
|
-
error,
|
|
219
|
-
topicId: args.topicId
|
|
220
|
-
}
|
|
221
|
-
);
|
|
222
|
-
}
|
|
223
|
-
if (!topic) {
|
|
224
|
-
topic = await tryResolveHostTopicById(ctx, String(args.topicId));
|
|
225
|
-
}
|
|
226
|
-
if (!topic) {
|
|
227
|
-
topic = pickPrimaryTopic(
|
|
228
|
-
await findTopicsByScopeAlias(ctx, String(args.topicId))
|
|
229
|
-
) ?? null;
|
|
230
|
-
}
|
|
231
|
-
if (!topic) {
|
|
232
|
-
const nodeScope = await resolveTopicNodeScopeOrNull(
|
|
233
|
-
ctx,
|
|
234
|
-
String(args.topicId)
|
|
235
|
-
);
|
|
236
|
-
if (nodeScope) {
|
|
237
|
-
return nodeScope;
|
|
238
|
-
}
|
|
239
|
-
throw new Error(`Topic not found: ${String(args.topicId)}`);
|
|
240
|
-
}
|
|
241
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
|
|
242
|
-
const mapped = asMappedProjectId(topic);
|
|
243
|
-
if (mapped) {
|
|
244
|
-
return {
|
|
245
|
-
topicId: topic._id,
|
|
246
|
-
projectId: mapped,
|
|
247
|
-
tenantId: inherited.tenantId,
|
|
248
|
-
workspaceId: inherited.workspaceId,
|
|
249
|
-
source: "topic"
|
|
250
|
-
};
|
|
251
|
-
}
|
|
252
|
-
return {
|
|
253
|
-
topicId: topic._id,
|
|
254
|
-
tenantId: inherited.tenantId,
|
|
255
|
-
workspaceId: inherited.workspaceId,
|
|
256
|
-
source: "topic"
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
if (args.projectId) {
|
|
260
|
-
let directTopic = null;
|
|
261
|
-
try {
|
|
262
|
-
directTopic = await ctx.db.get(
|
|
263
|
-
args.projectId
|
|
264
|
-
);
|
|
265
|
-
} catch (error) {
|
|
266
|
-
debugGraphPrimitiveFallback(
|
|
267
|
-
"[topicScope] Failed to load direct project topic",
|
|
268
|
-
{
|
|
269
|
-
error,
|
|
270
|
-
projectId: args.projectId
|
|
271
|
-
}
|
|
272
|
-
);
|
|
273
|
-
}
|
|
274
|
-
if (directTopic) {
|
|
275
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
|
|
276
|
-
const mapped = asMappedProjectId(directTopic);
|
|
277
|
-
return {
|
|
278
|
-
topicId: directTopic._id,
|
|
279
|
-
projectId: mapped ?? args.projectId,
|
|
280
|
-
tenantId: inherited.tenantId,
|
|
281
|
-
workspaceId: inherited.workspaceId,
|
|
282
|
-
source: "topic_inferred"
|
|
283
|
-
};
|
|
284
|
-
}
|
|
285
|
-
directTopic = await tryResolveHostTopicByLegacyScope(ctx, args.projectId);
|
|
286
|
-
if (directTopic) {
|
|
287
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
|
|
288
|
-
const mapped = asMappedProjectId(directTopic);
|
|
289
|
-
return {
|
|
290
|
-
topicId: directTopic._id,
|
|
291
|
-
projectId: mapped ?? args.projectId,
|
|
292
|
-
tenantId: inherited.tenantId,
|
|
293
|
-
workspaceId: inherited.workspaceId,
|
|
294
|
-
source: "topic_inferred"
|
|
295
|
-
};
|
|
296
|
-
}
|
|
297
|
-
const topics = await findTopicsByScopeAlias(ctx, args.projectId);
|
|
298
|
-
const primary = pickPrimaryTopic(topics);
|
|
299
|
-
if (primary) {
|
|
300
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, primary);
|
|
301
|
-
return {
|
|
302
|
-
topicId: primary._id,
|
|
303
|
-
projectId: args.projectId,
|
|
304
|
-
tenantId: inherited.tenantId,
|
|
305
|
-
workspaceId: inherited.workspaceId,
|
|
306
|
-
source: "project_mapped_topic"
|
|
307
|
-
};
|
|
308
|
-
}
|
|
309
|
-
const nodeScope = await resolveTopicNodeScopeOrNull(
|
|
310
|
-
ctx,
|
|
311
|
-
String(args.projectId)
|
|
312
|
-
);
|
|
313
|
-
if (nodeScope) {
|
|
314
|
-
return {
|
|
315
|
-
...nodeScope,
|
|
316
|
-
projectId: nodeScope.projectId ?? String(args.projectId)
|
|
317
|
-
};
|
|
318
|
-
}
|
|
319
|
-
throw new Error(
|
|
320
|
-
`Legacy project scope ${String(args.projectId)} has no mapped topic.`
|
|
321
|
-
);
|
|
322
|
-
}
|
|
323
|
-
throw new Error(
|
|
324
|
-
"Missing scope: provide topicId (preferred) or legacy projectId alias."
|
|
325
|
-
);
|
|
326
|
-
}
|
|
327
|
-
var optionalScopeArgs = {
|
|
328
|
-
projectId: v.optional(v.string()),
|
|
329
|
-
topicId: v.optional(v.string())
|
|
330
|
-
};
|
|
331
|
-
|
|
332
|
-
// src/beliefLifecycle.ts
|
|
333
|
-
var RESOLVED_PREDICTION_OUTCOMES = [
|
|
334
|
-
"confirmed",
|
|
335
|
-
"disconfirmed",
|
|
336
|
-
"partial",
|
|
337
|
-
"expired"
|
|
338
|
-
];
|
|
339
|
-
function hasResolvedPredictionOutcome(predictionMeta) {
|
|
340
|
-
if (!predictionMeta || typeof predictionMeta !== "object") {
|
|
341
|
-
return false;
|
|
342
|
-
}
|
|
343
|
-
const outcome = predictionMeta.outcome;
|
|
344
|
-
return typeof outcome === "string" && RESOLVED_PREDICTION_OUTCOMES.includes(outcome);
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
// src/invariantEnforcement.ts
|
|
348
|
-
var FORBIDDEN_GENERIC_BELIEF_METADATA_KEYS = /* @__PURE__ */ new Set([
|
|
349
|
-
"beliefStatus",
|
|
350
|
-
"epistemicStatus",
|
|
351
|
-
"forkedBy",
|
|
352
|
-
"forkedFrom",
|
|
353
|
-
"forkReason",
|
|
354
|
-
"forkTimestamp",
|
|
355
|
-
"status",
|
|
356
|
-
"supersededBy",
|
|
357
|
-
"supersedes"
|
|
358
|
-
]);
|
|
359
|
-
var ONTOLOGICAL_NODE_TYPES = /* @__PURE__ */ new Set([
|
|
360
|
-
"company",
|
|
361
|
-
"person",
|
|
362
|
-
"investor",
|
|
363
|
-
"function",
|
|
364
|
-
"value_chain"
|
|
365
|
-
]);
|
|
366
|
-
function throwInvariantError(args) {
|
|
367
|
-
const error = new Error(args.message);
|
|
368
|
-
error.status = args.status ?? 409;
|
|
369
|
-
error.code = args.code ?? "INVARIANT_VIOLATION";
|
|
370
|
-
error.invariantCode = args.invariantCode;
|
|
371
|
-
error.suggestion = args.suggestion;
|
|
372
|
-
error.details = args.details;
|
|
373
|
-
throw error;
|
|
374
|
-
}
|
|
375
|
-
function isBeliefNode(node) {
|
|
376
|
-
return node?.nodeType === "belief";
|
|
377
|
-
}
|
|
378
|
-
function isOntologicalNode(node) {
|
|
379
|
-
return typeof node?.nodeType === "string" && ONTOLOGICAL_NODE_TYPES.has(node.nodeType);
|
|
380
|
-
}
|
|
381
|
-
function isScoredBeliefNode(node) {
|
|
382
|
-
if (!isBeliefNode(node)) {
|
|
383
|
-
return false;
|
|
384
|
-
}
|
|
385
|
-
const metadata = node.metadata && typeof node.metadata === "object" ? node.metadata : void 0;
|
|
386
|
-
const numericConfidence = typeof node.confidence === "number" && Number.isFinite(node.confidence);
|
|
387
|
-
if (numericConfidence) {
|
|
388
|
-
return true;
|
|
389
|
-
}
|
|
390
|
-
return hasResolvedPredictionOutcome(node.predictionMeta) || hasResolvedPredictionOutcome(metadata?.predictionMeta);
|
|
391
|
-
}
|
|
392
|
-
function getForbiddenMetadataKeys(metadata) {
|
|
393
|
-
if (!metadata || typeof metadata !== "object" || Array.isArray(metadata)) {
|
|
394
|
-
return [];
|
|
395
|
-
}
|
|
396
|
-
return Object.keys(metadata).filter(
|
|
397
|
-
(key) => FORBIDDEN_GENERIC_BELIEF_METADATA_KEYS.has(key)
|
|
398
|
-
);
|
|
399
|
-
}
|
|
400
|
-
function assertBeliefNodeGenericUpdateAllowed(args) {
|
|
401
|
-
if (!isBeliefNode(args.node)) {
|
|
402
|
-
return;
|
|
403
|
-
}
|
|
404
|
-
if (Object.hasOwn(args.updates, "confidence")) {
|
|
405
|
-
throwInvariantError({
|
|
406
|
-
message: "Belief confidence is append-only. Generic node updates cannot set confidence directly.",
|
|
407
|
-
invariantCode: "belief.confidence_append_only",
|
|
408
|
-
suggestion: "Use epistemicBeliefs.appendSlScoring() so the beliefConfidence ledger and audit trail are updated together.",
|
|
409
|
-
details: { mutationName: args.mutationName, nodeId: args.node._id }
|
|
410
|
-
});
|
|
411
|
-
}
|
|
412
|
-
if (Object.hasOwn(args.updates, "status")) {
|
|
413
|
-
throwInvariantError({
|
|
414
|
-
message: "Belief status transitions must use the dedicated belief lifecycle APIs.",
|
|
415
|
-
invariantCode: "belief.status_transition_requires_belief_api",
|
|
416
|
-
suggestion: "Use epistemicBeliefs.updateStatus() or epistemicBeliefs.archive() so status transitions emit the correct audit event.",
|
|
417
|
-
details: { mutationName: args.mutationName, nodeId: args.node._id }
|
|
418
|
-
});
|
|
419
|
-
}
|
|
420
|
-
const forbiddenMetadataKeys = getForbiddenMetadataKeys(args.updates.metadata);
|
|
421
|
-
if (forbiddenMetadataKeys.length > 0) {
|
|
422
|
-
throwInvariantError({
|
|
423
|
-
message: "Belief lineage and lifecycle metadata cannot be rewritten through generic node updates.",
|
|
424
|
-
invariantCode: "belief.lineage_requires_fork_belief",
|
|
425
|
-
suggestion: "Use epistemicBeliefs.forkBelief() for lineage changes and dedicated belief lifecycle mutations for status changes.",
|
|
426
|
-
details: {
|
|
427
|
-
mutationName: args.mutationName,
|
|
428
|
-
nodeId: args.node._id,
|
|
429
|
-
forbiddenMetadataKeys
|
|
430
|
-
}
|
|
431
|
-
});
|
|
432
|
-
}
|
|
433
|
-
if (isScoredBeliefNode(args.node) && (Object.hasOwn(args.updates, "canonicalText") || Object.hasOwn(args.updates, "contentHash"))) {
|
|
434
|
-
throwInvariantError({
|
|
435
|
-
message: "Cannot refine a scored belief in place. Scored formulations are immutable.",
|
|
436
|
-
invariantCode: "belief.formulation_immutable_after_scoring",
|
|
437
|
-
suggestion: "Use epistemicBeliefs.forkBelief() to evolve the formulation while preserving lineage.",
|
|
438
|
-
details: { mutationName: args.mutationName, nodeId: args.node._id }
|
|
439
|
-
});
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
function assertBeliefNodeArchiveAllowed(args) {
|
|
443
|
-
if (!isBeliefNode(args.node)) {
|
|
444
|
-
return;
|
|
528
|
+
if (tenantId && workspaceId) {
|
|
529
|
+
break;
|
|
530
|
+
}
|
|
445
531
|
}
|
|
446
|
-
|
|
447
|
-
message: "Belief archiving must go through the dedicated belief lifecycle API.",
|
|
448
|
-
invariantCode: "belief.status_transition_requires_belief_api",
|
|
449
|
-
suggestion: "Use epistemicBeliefs.archive() so the belief lifecycle audit trail stays consistent.",
|
|
450
|
-
details: { mutationName: args.mutationName, nodeId: args.node._id }
|
|
451
|
-
});
|
|
532
|
+
return { tenantId, workspaceId };
|
|
452
533
|
}
|
|
453
|
-
function
|
|
454
|
-
if (
|
|
455
|
-
return;
|
|
534
|
+
async function resolveTopicProjectScope(ctx, args) {
|
|
535
|
+
if (args.topicId) {
|
|
536
|
+
return await resolveScopeFromTopicId(ctx, args.topicId);
|
|
456
537
|
}
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
invariantCode: "belief.confidence_append_only",
|
|
460
|
-
suggestion: "Call epistemicBeliefs.appendSlScoring() after verification so the confidence history is preserved.",
|
|
461
|
-
details: { mutationName: args.mutationName, nodeId: args.node._id }
|
|
462
|
-
});
|
|
463
|
-
}
|
|
464
|
-
function assertBeliefNodeSupersedeAllowed(args) {
|
|
465
|
-
if (!isBeliefNode(args.node)) {
|
|
466
|
-
return;
|
|
538
|
+
if (args.projectId) {
|
|
539
|
+
return await resolveScopeFromLegacyProjectId(ctx, args.projectId);
|
|
467
540
|
}
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
suggestion: "Use epistemicBeliefs.forkBelief() so the child belief, supersedes edge, and audit trail are created together.",
|
|
472
|
-
details: { mutationName: args.mutationName, nodeId: args.node._id }
|
|
473
|
-
});
|
|
541
|
+
throw new Error(
|
|
542
|
+
"Missing scope: provide topicId (preferred) or legacy projectId alias."
|
|
543
|
+
);
|
|
474
544
|
}
|
|
475
|
-
function
|
|
476
|
-
|
|
477
|
-
|
|
545
|
+
async function resolveScopeFromTopicId(ctx, topicId) {
|
|
546
|
+
const topic = await resolveTopicDocFromTopicId(ctx, topicId);
|
|
547
|
+
if (topic) {
|
|
548
|
+
return await buildTopicScope(ctx, topic, "topic");
|
|
478
549
|
}
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
suggestion: "Use entityLifecycle.createEntity() so tenant-global canonical scope and deduplication are enforced.",
|
|
483
|
-
details: {
|
|
484
|
-
mutationName: args.mutationName,
|
|
485
|
-
nodeType: args.nodeType
|
|
486
|
-
}
|
|
487
|
-
});
|
|
488
|
-
}
|
|
489
|
-
function assertOntologicalNodeGenericUpdateAllowed(args) {
|
|
490
|
-
if (!isOntologicalNode(args.node)) {
|
|
491
|
-
return;
|
|
550
|
+
const nodeScope = await resolveTopicNodeScopeOrNull(ctx, String(topicId));
|
|
551
|
+
if (nodeScope) {
|
|
552
|
+
return nodeScope;
|
|
492
553
|
}
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
nodeId: args.node._id,
|
|
500
|
-
nodeType: args.node.nodeType
|
|
501
|
-
}
|
|
554
|
+
throw new Error(`Topic not found: ${String(topicId)}`);
|
|
555
|
+
}
|
|
556
|
+
async function resolveTopicDocFromTopicId(ctx, topicId) {
|
|
557
|
+
const direct = await tryReadTopicDoc(ctx, topicId, {
|
|
558
|
+
failureLog: "[topicScope] Failed to load topic by direct id",
|
|
559
|
+
idLogKey: "topicId"
|
|
502
560
|
});
|
|
561
|
+
if (direct) {
|
|
562
|
+
return direct;
|
|
563
|
+
}
|
|
564
|
+
const hostTopic = await tryResolveHostTopicById(ctx, String(topicId));
|
|
565
|
+
if (hostTopic) {
|
|
566
|
+
return hostTopic;
|
|
567
|
+
}
|
|
568
|
+
return pickPrimaryTopic(await findTopicsByScopeAlias(ctx, String(topicId))) ?? null;
|
|
503
569
|
}
|
|
504
|
-
function
|
|
505
|
-
|
|
506
|
-
|
|
570
|
+
async function resolveScopeFromLegacyProjectId(ctx, legacyProjectId) {
|
|
571
|
+
const directTopic = await resolveDirectLegacyProjectTopic(
|
|
572
|
+
ctx,
|
|
573
|
+
legacyProjectId
|
|
574
|
+
);
|
|
575
|
+
if (directTopic) {
|
|
576
|
+
return await buildTopicScope(ctx, directTopic, "topic_inferred", {
|
|
577
|
+
fallbackProjectId: legacyProjectId
|
|
578
|
+
});
|
|
507
579
|
}
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
580
|
+
const primary = pickPrimaryTopic(
|
|
581
|
+
await findTopicsByScopeAlias(ctx, legacyProjectId)
|
|
582
|
+
);
|
|
583
|
+
if (primary) {
|
|
584
|
+
return await buildTopicScope(ctx, primary, "project_mapped_topic", {
|
|
585
|
+
fallbackProjectId: legacyProjectId
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
const nodeScope = await resolveTopicNodeScopeOrNull(ctx, legacyProjectId);
|
|
589
|
+
if (nodeScope) {
|
|
590
|
+
return {
|
|
591
|
+
...nodeScope,
|
|
592
|
+
projectId: nodeScope.projectId ?? legacyProjectId
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
throw new Error(
|
|
596
|
+
`Legacy project scope ${legacyProjectId} has no mapped topic.`
|
|
597
|
+
);
|
|
598
|
+
}
|
|
599
|
+
async function resolveDirectLegacyProjectTopic(ctx, legacyProjectId) {
|
|
600
|
+
const directTopic = await tryReadTopicDoc(ctx, legacyProjectId, {
|
|
601
|
+
failureLog: "[topicScope] Failed to load direct project topic",
|
|
602
|
+
idLogKey: "projectId"
|
|
517
603
|
});
|
|
604
|
+
return directTopic ?? tryResolveHostTopicByLegacyScope(ctx, legacyProjectId);
|
|
518
605
|
}
|
|
519
|
-
function
|
|
520
|
-
|
|
521
|
-
return;
|
|
606
|
+
async function tryReadTopicDoc(ctx, id, log) {
|
|
607
|
+
try {
|
|
608
|
+
return await ctx.db.get(id);
|
|
609
|
+
} catch (error) {
|
|
610
|
+
debugGraphPrimitiveFallback(log.failureLog, {
|
|
611
|
+
error,
|
|
612
|
+
[log.idLogKey]: id
|
|
613
|
+
});
|
|
614
|
+
return null;
|
|
522
615
|
}
|
|
523
|
-
throwInvariantError({
|
|
524
|
-
message: "Ontological entities do not use the generic supersede path.",
|
|
525
|
-
invariantCode: "entity.supersede_requires_entity_lifecycle",
|
|
526
|
-
suggestion: "Use entityLifecycle.updateEntityAttributes() to edit an entity in place or entityLifecycle.mergeEntities() to collapse duplicates.",
|
|
527
|
-
details: {
|
|
528
|
-
mutationName: args.mutationName,
|
|
529
|
-
nodeId: args.node._id,
|
|
530
|
-
nodeType: args.node.nodeType
|
|
531
|
-
}
|
|
532
|
-
});
|
|
533
616
|
}
|
|
617
|
+
async function buildTopicScope(ctx, topic, source, options = {}) {
|
|
618
|
+
const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
|
|
619
|
+
const mapped = asMappedProjectId(topic);
|
|
620
|
+
return {
|
|
621
|
+
topicId: topic._id,
|
|
622
|
+
...mapped || options.fallbackProjectId ? { projectId: mapped ?? options.fallbackProjectId } : {},
|
|
623
|
+
tenantId: inherited.tenantId,
|
|
624
|
+
workspaceId: inherited.workspaceId,
|
|
625
|
+
source
|
|
626
|
+
};
|
|
627
|
+
}
|
|
628
|
+
var optionalScopeArgs = {
|
|
629
|
+
projectId: v.optional(v.string()),
|
|
630
|
+
topicId: v.optional(v.string())
|
|
631
|
+
};
|
|
534
632
|
function normalizeScopeValue2(value) {
|
|
535
633
|
if (typeof value !== "string") {
|
|
536
634
|
return;
|
|
@@ -569,7 +667,7 @@ function assertWorkspaceScopedEpistemicNodeScope(args) {
|
|
|
569
667
|
});
|
|
570
668
|
}
|
|
571
669
|
function resolveRuntimePackMutationContext(args) {
|
|
572
|
-
if (!args.runtimeToolName
|
|
670
|
+
if (!(args.runtimeToolName || args.runtimePackKey || args.runtimePackInstallScope)) {
|
|
573
671
|
return;
|
|
574
672
|
}
|
|
575
673
|
return {
|
|
@@ -602,121 +700,116 @@ function assertTenantPackWorkspaceMutationAllowed(args) {
|
|
|
602
700
|
});
|
|
603
701
|
}
|
|
604
702
|
|
|
605
|
-
// src/epistemicNodes.
|
|
606
|
-
|
|
607
|
-
|
|
703
|
+
// src/epistemicNodes.mutations.ts
|
|
704
|
+
var optionalNodeScopeArgs = optionalScopeArgs;
|
|
705
|
+
var EPISTEMIC_LAYERS = /* @__PURE__ */ new Set([
|
|
706
|
+
"L4",
|
|
707
|
+
"L3",
|
|
708
|
+
"L2",
|
|
709
|
+
"L1",
|
|
710
|
+
"ontological",
|
|
711
|
+
"organizational"
|
|
712
|
+
]);
|
|
713
|
+
function readOptionalString(value) {
|
|
714
|
+
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
608
715
|
}
|
|
609
|
-
function
|
|
610
|
-
return
|
|
611
|
-
success: true,
|
|
612
|
-
effectiveStatus: "archived"
|
|
613
|
-
};
|
|
716
|
+
function readOptionalNumber(value) {
|
|
717
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
614
718
|
}
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
)
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
)
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
);
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
)
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
);
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
);
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
v.literal("human_verified"),
|
|
709
|
-
v.literal("ai_verified"),
|
|
710
|
-
v.literal("contradicted"),
|
|
711
|
-
v.literal("outdated")
|
|
712
|
-
);
|
|
713
|
-
async function insertEpistemicNode(ctx, doc) {
|
|
714
|
-
assertUuidV7Identity("epistemicNodes", doc.globalId);
|
|
715
|
-
return ctx.db.insert("epistemicNodes", doc);
|
|
719
|
+
function readConvexId(value) {
|
|
720
|
+
const normalized = readOptionalString(value);
|
|
721
|
+
return normalized ? normalized : null;
|
|
722
|
+
}
|
|
723
|
+
function readRecord(value) {
|
|
724
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
725
|
+
}
|
|
726
|
+
function readStringArray(value) {
|
|
727
|
+
return Array.isArray(value) && value.every((item) => typeof item === "string") ? value : void 0;
|
|
728
|
+
}
|
|
729
|
+
function readEpistemicLayer(value) {
|
|
730
|
+
const layer = readOptionalString(value);
|
|
731
|
+
return layer && EPISTEMIC_LAYERS.has(layer) ? layer : void 0;
|
|
732
|
+
}
|
|
733
|
+
function readEpistemicNodeRow(value) {
|
|
734
|
+
const record = readRecord(value);
|
|
735
|
+
if (!record) {
|
|
736
|
+
return null;
|
|
737
|
+
}
|
|
738
|
+
const id = readConvexId(record._id);
|
|
739
|
+
const nodeType = readOptionalString(record.nodeType);
|
|
740
|
+
if (!(id && nodeType)) {
|
|
741
|
+
return null;
|
|
742
|
+
}
|
|
743
|
+
const node = { _id: id, nodeType };
|
|
744
|
+
const canonicalText = readOptionalString(record.canonicalText);
|
|
745
|
+
if (canonicalText !== void 0) {
|
|
746
|
+
node.canonicalText = canonicalText;
|
|
747
|
+
}
|
|
748
|
+
const confidence = readOptionalNumber(record.confidence);
|
|
749
|
+
if (confidence !== void 0) {
|
|
750
|
+
node.confidence = confidence;
|
|
751
|
+
}
|
|
752
|
+
const content = readOptionalString(record.content);
|
|
753
|
+
if (content !== void 0) {
|
|
754
|
+
node.content = content;
|
|
755
|
+
}
|
|
756
|
+
const contentType = readOptionalString(record.contentType);
|
|
757
|
+
if (contentType !== void 0) {
|
|
758
|
+
node.contentType = contentType;
|
|
759
|
+
}
|
|
760
|
+
const createdBy = readOptionalString(record.createdBy);
|
|
761
|
+
if (createdBy !== void 0) {
|
|
762
|
+
node.createdBy = createdBy;
|
|
763
|
+
}
|
|
764
|
+
const epistemicLayer = readEpistemicLayer(record.epistemicLayer);
|
|
765
|
+
if (epistemicLayer !== void 0) {
|
|
766
|
+
node.epistemicLayer = epistemicLayer;
|
|
767
|
+
}
|
|
768
|
+
const metadata = readRecord(record.metadata);
|
|
769
|
+
if (metadata) {
|
|
770
|
+
node.metadata = metadata;
|
|
771
|
+
}
|
|
772
|
+
const projectId = readOptionalString(record.projectId);
|
|
773
|
+
if (projectId !== void 0) {
|
|
774
|
+
node.projectId = projectId;
|
|
775
|
+
}
|
|
776
|
+
const status = readOptionalString(record.status);
|
|
777
|
+
if (status !== void 0) {
|
|
778
|
+
node.status = status;
|
|
779
|
+
}
|
|
780
|
+
const tags = readStringArray(record.tags);
|
|
781
|
+
if (tags !== void 0) {
|
|
782
|
+
node.tags = tags;
|
|
783
|
+
}
|
|
784
|
+
const tenantId = readOptionalString(record.tenantId);
|
|
785
|
+
if (tenantId !== void 0) {
|
|
786
|
+
node.tenantId = tenantId;
|
|
787
|
+
}
|
|
788
|
+
const title = readOptionalString(record.title);
|
|
789
|
+
if (title !== void 0) {
|
|
790
|
+
node.title = title;
|
|
791
|
+
}
|
|
792
|
+
const topicId = readOptionalString(record.topicId);
|
|
793
|
+
if (topicId !== void 0) {
|
|
794
|
+
node.topicId = topicId;
|
|
795
|
+
}
|
|
796
|
+
const verificationStatus = readOptionalString(record.verificationStatus);
|
|
797
|
+
if (verificationStatus !== void 0) {
|
|
798
|
+
node.verificationStatus = verificationStatus;
|
|
799
|
+
}
|
|
800
|
+
const workspaceId = readOptionalString(record.workspaceId);
|
|
801
|
+
if (workspaceId !== void 0) {
|
|
802
|
+
node.workspaceId = workspaceId;
|
|
803
|
+
}
|
|
804
|
+
return node;
|
|
805
|
+
}
|
|
806
|
+
function requireEpistemicNodeRow(value, context) {
|
|
807
|
+
const node = readEpistemicNodeRow(value);
|
|
808
|
+
if (!node) {
|
|
809
|
+
throw new Error(`${context} requires a stored epistemic node.`);
|
|
810
|
+
}
|
|
811
|
+
return node;
|
|
716
812
|
}
|
|
717
|
-
|
|
718
|
-
// src/epistemicNodes.mutations.ts
|
|
719
|
-
var optionalNodeScopeArgs = optionalScopeArgs;
|
|
720
813
|
var create = mutation({
|
|
721
814
|
args: {
|
|
722
815
|
globalId: v.string(),
|
|
@@ -762,8 +855,9 @@ var create = mutation({
|
|
|
762
855
|
mutationName: "epistemicNodes.create"
|
|
763
856
|
});
|
|
764
857
|
const existing = await ctx.db.query("epistemicNodes").withIndex("by_contentHash", (q) => q.eq("contentHash", args.contentHash)).first();
|
|
765
|
-
|
|
766
|
-
|
|
858
|
+
const existingNode = readEpistemicNodeRow(existing);
|
|
859
|
+
if (existingNode?.status === "active") {
|
|
860
|
+
return { nodeId: existingNode._id, isDuplicate: true };
|
|
767
861
|
}
|
|
768
862
|
const epistemicLayer = getNodeLayer(args.nodeType);
|
|
769
863
|
const resolvedScope = args.topicId || args.projectId ? await resolveTopicProjectScope(ctx, {
|
|
@@ -878,10 +972,10 @@ var update = mutation({
|
|
|
878
972
|
returns: permissiveReturn,
|
|
879
973
|
handler: async (ctx, args) => {
|
|
880
974
|
const { nodeId, userId, ...updates } = args;
|
|
881
|
-
const node =
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
975
|
+
const node = requireEpistemicNodeRow(
|
|
976
|
+
await ctx.db.get(nodeId),
|
|
977
|
+
"Update node"
|
|
978
|
+
);
|
|
885
979
|
if (node.projectId && userId) {
|
|
886
980
|
await requireScopeWriteAccess(ctx, node.projectId, userId);
|
|
887
981
|
}
|
|
@@ -910,7 +1004,7 @@ var update = mutation({
|
|
|
910
1004
|
entityId: String(nodeId),
|
|
911
1005
|
changeType: "updated",
|
|
912
1006
|
changedAt: Date.now(),
|
|
913
|
-
changedBy: userId
|
|
1007
|
+
changedBy: userId ?? node.createdBy ?? "system:update",
|
|
914
1008
|
isAgent: false,
|
|
915
1009
|
previousState: {
|
|
916
1010
|
status: node.status,
|
|
@@ -939,10 +1033,10 @@ var supersede = mutation({
|
|
|
939
1033
|
},
|
|
940
1034
|
returns: permissiveReturn,
|
|
941
1035
|
handler: async (ctx, args) => {
|
|
942
|
-
const oldNode =
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
1036
|
+
const oldNode = requireEpistemicNodeRow(
|
|
1037
|
+
await ctx.db.get(args.oldNodeId),
|
|
1038
|
+
"Supersede node"
|
|
1039
|
+
);
|
|
946
1040
|
if (oldNode.projectId) {
|
|
947
1041
|
await requireScopeWriteAccess(ctx, oldNode.projectId, args.createdBy);
|
|
948
1042
|
}
|
|
@@ -974,7 +1068,10 @@ var supersede = mutation({
|
|
|
974
1068
|
verificationStatus: "unverified",
|
|
975
1069
|
// New version needs re-verification
|
|
976
1070
|
status: "active",
|
|
1071
|
+
topicId: oldNode.topicId,
|
|
977
1072
|
projectId: oldNode.projectId,
|
|
1073
|
+
tenantId: oldNode.tenantId,
|
|
1074
|
+
workspaceId: oldNode.workspaceId,
|
|
978
1075
|
createdBy: args.createdBy,
|
|
979
1076
|
createdAt: now,
|
|
980
1077
|
updatedAt: now
|
|
@@ -1015,10 +1112,10 @@ var archive = mutation({
|
|
|
1015
1112
|
},
|
|
1016
1113
|
returns: permissiveReturn,
|
|
1017
1114
|
handler: async (ctx, args) => {
|
|
1018
|
-
const node =
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1115
|
+
const node = requireEpistemicNodeRow(
|
|
1116
|
+
await ctx.db.get(args.nodeId),
|
|
1117
|
+
"Archive node"
|
|
1118
|
+
);
|
|
1022
1119
|
if (node.projectId && args.userId) {
|
|
1023
1120
|
await requireScopeWriteAccess(ctx, node.projectId, args.userId);
|
|
1024
1121
|
}
|
|
@@ -1040,7 +1137,7 @@ var archive = mutation({
|
|
|
1040
1137
|
entityId: String(args.nodeId),
|
|
1041
1138
|
changeType: "archived",
|
|
1042
1139
|
changedAt: Date.now(),
|
|
1043
|
-
changedBy: args.userId
|
|
1140
|
+
changedBy: args.userId ?? node.createdBy ?? "system:archive",
|
|
1044
1141
|
isAgent: false,
|
|
1045
1142
|
previousState: { status: node.status },
|
|
1046
1143
|
newState: { status: "archived" },
|
|
@@ -1059,10 +1156,10 @@ var verify = mutation({
|
|
|
1059
1156
|
},
|
|
1060
1157
|
returns: permissiveReturn,
|
|
1061
1158
|
handler: async (ctx, args) => {
|
|
1062
|
-
const node =
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1159
|
+
const node = requireEpistemicNodeRow(
|
|
1160
|
+
await ctx.db.get(args.nodeId),
|
|
1161
|
+
"Verify node"
|
|
1162
|
+
);
|
|
1066
1163
|
assertBeliefNodeVerifyAllowed({
|
|
1067
1164
|
node,
|
|
1068
1165
|
confidence: args.confidence,
|
|
@@ -1134,7 +1231,7 @@ var batchCreate = mutation({
|
|
|
1134
1231
|
handler: async (ctx, args) => {
|
|
1135
1232
|
const resolveNodeScope = async (node) => {
|
|
1136
1233
|
if (!(node.topicId || node.projectId)) {
|
|
1137
|
-
return
|
|
1234
|
+
return;
|
|
1138
1235
|
}
|
|
1139
1236
|
try {
|
|
1140
1237
|
return await resolveTopicProjectScope(ctx, {
|
|
@@ -1150,7 +1247,7 @@ var batchCreate = mutation({
|
|
|
1150
1247
|
projectId: node.projectId
|
|
1151
1248
|
}
|
|
1152
1249
|
);
|
|
1153
|
-
return
|
|
1250
|
+
return;
|
|
1154
1251
|
}
|
|
1155
1252
|
};
|
|
1156
1253
|
const now = Date.now();
|