@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,16 @@
|
|
|
1
|
-
import { v } from 'convex/values';
|
|
2
1
|
import { requireScopeWriteAccess, checkScopeAccess } from '@lucern/access-control/access';
|
|
3
2
|
import { assertSchemaEnumValue } from '@lucern/contracts/schema-helpers/enumValidation';
|
|
4
3
|
import { permissiveReturn } from '@lucern/contracts/schema-helpers/validators';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
4
|
+
import { v } from 'convex/values';
|
|
5
|
+
import { unsafeConvexAnyApi } from '@lucern/contracts/convex/unsafeAnyApi';
|
|
6
|
+
import { componentsGeneric, mutationGeneric, queryGeneric } from 'convex/server';
|
|
8
7
|
import '@lucern/access-control/audience';
|
|
9
8
|
import { getCurrentUserId } from '@lucern/access-control/auth';
|
|
9
|
+
import { throwStructuredMutationError } from '@lucern/access-control/structuredMutationError';
|
|
10
|
+
import { normalizeTupleContradictionPolicy, createInheritedContractRecord, confidenceFromSL } from '@lucern/confidence';
|
|
10
11
|
import { isNodeType, getLayerForNodeType } from '@lucern/contracts/schema-helpers/spine/tables/epistemicNodes';
|
|
11
|
-
import { generateGlobalId, assertUuidV7Identity, generateUuidV7, assertStorageEdgeVocabulary, assertUuidShapedEdgeEndpoint } from '@lucern/contracts/ids';
|
|
12
12
|
import { assertEdgePolicyAllowed, edgePolicyManifest } from '@lucern/contracts';
|
|
13
|
+
import { generateGlobalId, assertUuidV7Identity, generateUuidV7, assertStorageEdgeVocabulary, assertUuidShapedEdgeEndpoint } from '@lucern/contracts/ids';
|
|
13
14
|
|
|
14
15
|
// src/epistemicBeliefs.core.ts
|
|
15
16
|
|
|
@@ -123,9 +124,12 @@ function resolveBeliefLifecycleStatus(opts) {
|
|
|
123
124
|
function isPreValidationBeliefStatus(status) {
|
|
124
125
|
return status === "assumption" || status === "hypothesis";
|
|
125
126
|
}
|
|
126
|
-
var
|
|
127
|
+
var unsafeApi = unsafeConvexAnyApi(
|
|
128
|
+
"graph-primitives top-level module bundle lacks a committed Convex _generated/api surface"
|
|
129
|
+
);
|
|
130
|
+
var api = unsafeApi;
|
|
127
131
|
componentsGeneric();
|
|
128
|
-
var internal =
|
|
132
|
+
var internal = unsafeApi;
|
|
129
133
|
var mutation = mutationGeneric;
|
|
130
134
|
var query = queryGeneric;
|
|
131
135
|
|
|
@@ -141,6 +145,32 @@ function debugGraphPrimitiveFallback(message, context) {
|
|
|
141
145
|
console.debug(message, context ?? {});
|
|
142
146
|
}
|
|
143
147
|
|
|
148
|
+
// src/embeddingTrigger.ts
|
|
149
|
+
var embeddingActionRef = "embeddingActions:generateEpistemicNodeEmbedding";
|
|
150
|
+
async function scheduleEmbeddingGeneration(args) {
|
|
151
|
+
try {
|
|
152
|
+
await args.ctx.scheduler.runAfter(0, embeddingActionRef, {
|
|
153
|
+
nodeId: args.nodeId,
|
|
154
|
+
projectId: args.projectId ? String(args.projectId) : void 0,
|
|
155
|
+
topicId: args.topicId ? String(args.topicId) : void 0,
|
|
156
|
+
createdBy: args.createdBy,
|
|
157
|
+
nodeType: args.nodeType,
|
|
158
|
+
text: args.text.slice(0, 2e4),
|
|
159
|
+
hasAnswer: args.hasAnswer,
|
|
160
|
+
confidence: args.confidence
|
|
161
|
+
});
|
|
162
|
+
} catch (error) {
|
|
163
|
+
debugGraphPrimitiveFallback(
|
|
164
|
+
"[embeddingTrigger] Failed to schedule embedding generation",
|
|
165
|
+
{
|
|
166
|
+
error,
|
|
167
|
+
nodeId: String(args.nodeId),
|
|
168
|
+
nodeType: args.nodeType
|
|
169
|
+
}
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
144
174
|
// src/topicProjectOverlay.ts
|
|
145
175
|
var LEGACY_SCOPE_FIELD = "graphScopeProjectId";
|
|
146
176
|
function readNonEmptyString(value) {
|
|
@@ -159,6 +189,10 @@ function readStringArray(value) {
|
|
|
159
189
|
function readMetadata(topic) {
|
|
160
190
|
return topic.metadata && typeof topic.metadata === "object" ? topic.metadata : {};
|
|
161
191
|
}
|
|
192
|
+
function omitMetadataKey(metadata, key) {
|
|
193
|
+
const { [key]: _omitted, ...rest } = metadata;
|
|
194
|
+
return rest;
|
|
195
|
+
}
|
|
162
196
|
function readLegacyProjectId(value) {
|
|
163
197
|
if (!value) {
|
|
164
198
|
return;
|
|
@@ -239,9 +273,12 @@ async function resolveTopicDoc(ctx, scopeId) {
|
|
|
239
273
|
);
|
|
240
274
|
}
|
|
241
275
|
try {
|
|
242
|
-
const topic = await ctx.runQuery(
|
|
243
|
-
|
|
244
|
-
|
|
276
|
+
const topic = await ctx.runQuery(
|
|
277
|
+
api.topics.getByLegacyScopeId,
|
|
278
|
+
{
|
|
279
|
+
projectId: String(scopeId)
|
|
280
|
+
}
|
|
281
|
+
);
|
|
245
282
|
if (topic?.name !== void 0 && topic?.type !== void 0) {
|
|
246
283
|
return topic;
|
|
247
284
|
}
|
|
@@ -261,8 +298,18 @@ function materializeTopicProjectOverlay(topic, idMode = "legacy") {
|
|
|
261
298
|
const outwardId = idMode === "topic" ? topicId : storageProjectId;
|
|
262
299
|
const visibility = coerceVisibility(topic.visibility) || coerceVisibility(metadata.visibility) || "private";
|
|
263
300
|
const status = coerceStatus(topic.status) || coerceStatus(metadata.status) || "active";
|
|
264
|
-
|
|
265
|
-
|
|
301
|
+
let createdAt = 0;
|
|
302
|
+
if (typeof topic.createdAt === "number") {
|
|
303
|
+
createdAt = topic.createdAt;
|
|
304
|
+
} else if (typeof topic._creationTime === "number") {
|
|
305
|
+
createdAt = topic._creationTime;
|
|
306
|
+
}
|
|
307
|
+
let updatedAt = createdAt;
|
|
308
|
+
if (typeof topic.updatedAt === "number") {
|
|
309
|
+
updatedAt = topic.updatedAt;
|
|
310
|
+
} else if (typeof metadata.updatedAt === "number") {
|
|
311
|
+
updatedAt = metadata.updatedAt;
|
|
312
|
+
}
|
|
266
313
|
return {
|
|
267
314
|
...metadata,
|
|
268
315
|
_id: outwardId,
|
|
@@ -331,90 +378,113 @@ async function patchTopicProjectOverlay(ctx, scopeId, value) {
|
|
|
331
378
|
if (!topic) {
|
|
332
379
|
return null;
|
|
333
380
|
}
|
|
334
|
-
const
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
381
|
+
const plan = buildTopicProjectOverlayPatchPlan(topic, value);
|
|
382
|
+
await applyTopicProjectOverlayPatch(ctx, topic, plan);
|
|
383
|
+
return materializeTopicProjectOverlay({
|
|
384
|
+
...topic,
|
|
385
|
+
...plan.patch,
|
|
386
|
+
metadata: plan.nextMetadata
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
function buildTopicProjectOverlayPatchPlan(topic, value) {
|
|
390
|
+
const plan = {
|
|
391
|
+
nextMetadata: { ...readMetadata(topic) },
|
|
392
|
+
patch: {},
|
|
393
|
+
topicUpdateArgs: {
|
|
394
|
+
id: String(topic._id)
|
|
395
|
+
}
|
|
338
396
|
};
|
|
339
397
|
for (const [key, rawValue] of Object.entries(value)) {
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
398
|
+
applyTopicProjectOverlayPatchEntry(plan, key, rawValue);
|
|
399
|
+
}
|
|
400
|
+
plan.patch.updatedAt = Date.now();
|
|
401
|
+
plan.patch.metadata = plan.nextMetadata;
|
|
402
|
+
plan.topicUpdateArgs.metadata = plan.nextMetadata;
|
|
403
|
+
return plan;
|
|
404
|
+
}
|
|
405
|
+
function applyTopicProjectOverlayPatchEntry(plan, key, rawValue) {
|
|
406
|
+
switch (key) {
|
|
407
|
+
case "_id":
|
|
408
|
+
case "projectId":
|
|
409
|
+
case "topicId":
|
|
410
|
+
case "legacyProjectId":
|
|
411
|
+
case "storageProjectId":
|
|
412
|
+
case "updatedAt":
|
|
413
|
+
case "createdAt":
|
|
414
|
+
return;
|
|
415
|
+
case "name":
|
|
416
|
+
case "description":
|
|
417
|
+
plan.patch[key] = rawValue;
|
|
418
|
+
plan.topicUpdateArgs[key] = rawValue;
|
|
419
|
+
return;
|
|
420
|
+
case "tenantId":
|
|
421
|
+
case "workspaceId":
|
|
422
|
+
case "ownerId":
|
|
423
|
+
throw new Error(
|
|
424
|
+
`patchTopicProjectOverlay cannot mutate ${key} via component-owned topics`
|
|
425
|
+
);
|
|
426
|
+
case "status":
|
|
427
|
+
applyTopicStatusPatch(plan, rawValue);
|
|
428
|
+
return;
|
|
429
|
+
case "visibility":
|
|
430
|
+
applyTopicVisibilityPatch(plan, rawValue);
|
|
431
|
+
return;
|
|
432
|
+
case "type":
|
|
433
|
+
applyTopicProjectTypePatch(plan, rawValue);
|
|
434
|
+
return;
|
|
435
|
+
default:
|
|
436
|
+
applyTopicMetadataPatch(plan, key, rawValue);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
function applyTopicStatusPatch(plan, rawValue) {
|
|
440
|
+
const status = coerceStatus(rawValue);
|
|
441
|
+
if (status) {
|
|
442
|
+
plan.patch.status = status;
|
|
443
|
+
plan.topicUpdateArgs.status = status;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
function applyTopicVisibilityPatch(plan, rawValue) {
|
|
447
|
+
const visibility = coerceVisibility(rawValue);
|
|
448
|
+
if (visibility) {
|
|
449
|
+
plan.patch.visibility = visibility;
|
|
450
|
+
plan.topicUpdateArgs.visibility = visibility;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
function applyTopicProjectTypePatch(plan, rawValue) {
|
|
454
|
+
const projectType = readNonEmptyString(rawValue);
|
|
455
|
+
if (projectType) {
|
|
456
|
+
plan.nextMetadata.projectType = projectType;
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
plan.nextMetadata = omitMetadataKey(plan.nextMetadata, "projectType");
|
|
460
|
+
}
|
|
461
|
+
function applyTopicMetadataPatch(plan, key, rawValue) {
|
|
462
|
+
if (rawValue === void 0) {
|
|
463
|
+
plan.nextMetadata = omitMetadataKey(plan.nextMetadata, key);
|
|
464
|
+
return;
|
|
393
465
|
}
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
466
|
+
plan.nextMetadata[key] = rawValue;
|
|
467
|
+
}
|
|
468
|
+
async function applyTopicProjectOverlayPatch(ctx, topic, plan) {
|
|
397
469
|
if (typeof ctx.runMutation === "function") {
|
|
398
470
|
try {
|
|
399
|
-
await ctx.runMutation(api.topics.update, topicUpdateArgs);
|
|
471
|
+
await ctx.runMutation(api.topics.update, plan.topicUpdateArgs);
|
|
400
472
|
} catch (error) {
|
|
401
|
-
if (!
|
|
473
|
+
if (!canPatchTopicViaLocalDb(ctx, error)) {
|
|
402
474
|
throw error;
|
|
403
475
|
}
|
|
404
|
-
await ctx.db.patch(
|
|
476
|
+
await ctx.db.patch(topic._id, plan.patch);
|
|
405
477
|
}
|
|
406
478
|
} else if (ctx?.db && typeof ctx.db.patch === "function") {
|
|
407
|
-
await ctx.db.patch(
|
|
479
|
+
await ctx.db.patch(topic._id, plan.patch);
|
|
408
480
|
} else {
|
|
409
481
|
throw new Error(
|
|
410
482
|
"Cannot patch topic without component adapter (ctx.runMutation unavailable)"
|
|
411
483
|
);
|
|
412
484
|
}
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
metadata: nextMetadata
|
|
417
|
-
});
|
|
485
|
+
}
|
|
486
|
+
function canPatchTopicViaLocalDb(ctx, error) {
|
|
487
|
+
return isMissingLucernChildComponentError(error) && Boolean(ctx?.db) && typeof ctx.db?.patch === "function";
|
|
418
488
|
}
|
|
419
489
|
|
|
420
490
|
// src/resolvers.ts
|
|
@@ -442,7 +512,7 @@ async function patchProjectWithTolerance(ctx, projectId, value) {
|
|
|
442
512
|
try {
|
|
443
513
|
await patchTopicProjectOverlay(ctx, projectId, value);
|
|
444
514
|
} catch (error) {
|
|
445
|
-
if (!isAdvisoryTopicPatch(value)
|
|
515
|
+
if (!(isAdvisoryTopicPatch(value) && isMissingLucernChildComponentError2(error))) {
|
|
446
516
|
throw error;
|
|
447
517
|
}
|
|
448
518
|
console.warn(
|
|
@@ -509,13 +579,15 @@ function asMappedProjectId(topic) {
|
|
|
509
579
|
if (!topic) {
|
|
510
580
|
return;
|
|
511
581
|
}
|
|
512
|
-
const directLegacyProjectId = normalizeScopeValue(
|
|
582
|
+
const directLegacyProjectId = normalizeScopeValue(
|
|
583
|
+
topic[LEGACY_SCOPE_FIELD2]
|
|
584
|
+
);
|
|
513
585
|
if (directLegacyProjectId) {
|
|
514
586
|
return directLegacyProjectId;
|
|
515
587
|
}
|
|
516
588
|
const metadata = topic.metadata || {};
|
|
517
589
|
const candidate = metadata[LEGACY_SCOPE_FIELD2] || metadata.legacyProjectId || metadata.projectId || metadata.scopeProjectId;
|
|
518
|
-
return candidate ? candidate : void 0;
|
|
590
|
+
return typeof candidate === "string" ? normalizeScopeValue(candidate) : void 0;
|
|
519
591
|
}
|
|
520
592
|
function normalizeScopeValue(value) {
|
|
521
593
|
if (typeof value !== "string") {
|
|
@@ -540,8 +612,9 @@ function pickPrimaryTopic(candidates) {
|
|
|
540
612
|
})[0];
|
|
541
613
|
}
|
|
542
614
|
async function findTopicsByScopeAlias(ctx, scopeId) {
|
|
615
|
+
const query2 = ctx.db.query("topics");
|
|
543
616
|
try {
|
|
544
|
-
return await
|
|
617
|
+
return await query2.withIndex(
|
|
545
618
|
"by_graph_scope_project",
|
|
546
619
|
(q) => q.eq(LEGACY_SCOPE_FIELD2, scopeId)
|
|
547
620
|
).collect();
|
|
@@ -553,7 +626,7 @@ async function findTopicsByScopeAlias(ctx, scopeId) {
|
|
|
553
626
|
scopeId
|
|
554
627
|
}
|
|
555
628
|
);
|
|
556
|
-
const topics = await
|
|
629
|
+
const topics = await query2.collect();
|
|
557
630
|
return topics.filter((topic) => {
|
|
558
631
|
const normalizedGlobalId = normalizeScopeValue(topic.globalId);
|
|
559
632
|
const mappedProjectId = asMappedProjectId(topic);
|
|
@@ -609,137 +682,115 @@ async function resolveInheritedWorkspaceScope(ctx, topic) {
|
|
|
609
682
|
let current = topic;
|
|
610
683
|
for (let i = 0; i < MAX_DEPTH && current?.parentTopicId; i++) {
|
|
611
684
|
current = await ctx.db.get(current.parentTopicId);
|
|
612
|
-
if (!current)
|
|
685
|
+
if (!current) {
|
|
686
|
+
break;
|
|
687
|
+
}
|
|
613
688
|
if (!tenantId) {
|
|
614
689
|
tenantId = normalizeScopeValue(current.tenantId);
|
|
615
690
|
}
|
|
616
691
|
if (!workspaceId) {
|
|
617
692
|
workspaceId = normalizeScopeValue(current.workspaceId);
|
|
618
693
|
}
|
|
619
|
-
if (tenantId && workspaceId)
|
|
694
|
+
if (tenantId && workspaceId) {
|
|
695
|
+
break;
|
|
696
|
+
}
|
|
620
697
|
}
|
|
621
698
|
return { tenantId, workspaceId };
|
|
622
699
|
}
|
|
623
700
|
async function resolveTopicProjectScope(ctx, args) {
|
|
624
701
|
if (args.topicId) {
|
|
625
|
-
|
|
626
|
-
try {
|
|
627
|
-
topic = await ctx.db.get(
|
|
628
|
-
args.topicId
|
|
629
|
-
);
|
|
630
|
-
} catch (error) {
|
|
631
|
-
debugGraphPrimitiveFallback(
|
|
632
|
-
"[topicScope] Failed to load topic by direct id",
|
|
633
|
-
{
|
|
634
|
-
error,
|
|
635
|
-
topicId: args.topicId
|
|
636
|
-
}
|
|
637
|
-
);
|
|
638
|
-
}
|
|
639
|
-
if (!topic) {
|
|
640
|
-
topic = await tryResolveHostTopicById(ctx, String(args.topicId));
|
|
641
|
-
}
|
|
642
|
-
if (!topic) {
|
|
643
|
-
topic = pickPrimaryTopic(
|
|
644
|
-
await findTopicsByScopeAlias(ctx, String(args.topicId))
|
|
645
|
-
) ?? null;
|
|
646
|
-
}
|
|
647
|
-
if (!topic) {
|
|
648
|
-
const nodeScope = await resolveTopicNodeScopeOrNull(
|
|
649
|
-
ctx,
|
|
650
|
-
String(args.topicId)
|
|
651
|
-
);
|
|
652
|
-
if (nodeScope) {
|
|
653
|
-
return nodeScope;
|
|
654
|
-
}
|
|
655
|
-
throw new Error(`Topic not found: ${String(args.topicId)}`);
|
|
656
|
-
}
|
|
657
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
|
|
658
|
-
const mapped = asMappedProjectId(topic);
|
|
659
|
-
if (mapped) {
|
|
660
|
-
return {
|
|
661
|
-
topicId: topic._id,
|
|
662
|
-
projectId: mapped,
|
|
663
|
-
tenantId: inherited.tenantId,
|
|
664
|
-
workspaceId: inherited.workspaceId,
|
|
665
|
-
source: "topic"
|
|
666
|
-
};
|
|
667
|
-
}
|
|
668
|
-
return {
|
|
669
|
-
topicId: topic._id,
|
|
670
|
-
tenantId: inherited.tenantId,
|
|
671
|
-
workspaceId: inherited.workspaceId,
|
|
672
|
-
source: "topic"
|
|
673
|
-
};
|
|
702
|
+
return await resolveScopeFromTopicId(ctx, args.topicId);
|
|
674
703
|
}
|
|
675
704
|
if (args.projectId) {
|
|
676
|
-
|
|
677
|
-
try {
|
|
678
|
-
directTopic = await ctx.db.get(
|
|
679
|
-
args.projectId
|
|
680
|
-
);
|
|
681
|
-
} catch (error) {
|
|
682
|
-
debugGraphPrimitiveFallback(
|
|
683
|
-
"[topicScope] Failed to load direct project topic",
|
|
684
|
-
{
|
|
685
|
-
error,
|
|
686
|
-
projectId: args.projectId
|
|
687
|
-
}
|
|
688
|
-
);
|
|
689
|
-
}
|
|
690
|
-
if (directTopic) {
|
|
691
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
|
|
692
|
-
const mapped = asMappedProjectId(directTopic);
|
|
693
|
-
return {
|
|
694
|
-
topicId: directTopic._id,
|
|
695
|
-
projectId: mapped ?? args.projectId,
|
|
696
|
-
tenantId: inherited.tenantId,
|
|
697
|
-
workspaceId: inherited.workspaceId,
|
|
698
|
-
source: "topic_inferred"
|
|
699
|
-
};
|
|
700
|
-
}
|
|
701
|
-
directTopic = await tryResolveHostTopicByLegacyScope(ctx, args.projectId);
|
|
702
|
-
if (directTopic) {
|
|
703
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
|
|
704
|
-
const mapped = asMappedProjectId(directTopic);
|
|
705
|
-
return {
|
|
706
|
-
topicId: directTopic._id,
|
|
707
|
-
projectId: mapped ?? args.projectId,
|
|
708
|
-
tenantId: inherited.tenantId,
|
|
709
|
-
workspaceId: inherited.workspaceId,
|
|
710
|
-
source: "topic_inferred"
|
|
711
|
-
};
|
|
712
|
-
}
|
|
713
|
-
const topics = await findTopicsByScopeAlias(ctx, args.projectId);
|
|
714
|
-
const primary = pickPrimaryTopic(topics);
|
|
715
|
-
if (primary) {
|
|
716
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, primary);
|
|
717
|
-
return {
|
|
718
|
-
topicId: primary._id,
|
|
719
|
-
projectId: args.projectId,
|
|
720
|
-
tenantId: inherited.tenantId,
|
|
721
|
-
workspaceId: inherited.workspaceId,
|
|
722
|
-
source: "project_mapped_topic"
|
|
723
|
-
};
|
|
724
|
-
}
|
|
725
|
-
const nodeScope = await resolveTopicNodeScopeOrNull(
|
|
726
|
-
ctx,
|
|
727
|
-
String(args.projectId)
|
|
728
|
-
);
|
|
729
|
-
if (nodeScope) {
|
|
730
|
-
return {
|
|
731
|
-
...nodeScope,
|
|
732
|
-
projectId: nodeScope.projectId ?? String(args.projectId)
|
|
733
|
-
};
|
|
734
|
-
}
|
|
735
|
-
throw new Error(
|
|
736
|
-
`Legacy project scope ${String(args.projectId)} has no mapped topic.`
|
|
737
|
-
);
|
|
705
|
+
return await resolveScopeFromLegacyProjectId(ctx, args.projectId);
|
|
738
706
|
}
|
|
739
707
|
throw new Error(
|
|
740
708
|
"Missing scope: provide topicId (preferred) or legacy projectId alias."
|
|
741
709
|
);
|
|
742
710
|
}
|
|
711
|
+
async function resolveScopeFromTopicId(ctx, topicId) {
|
|
712
|
+
const topic = await resolveTopicDocFromTopicId(ctx, topicId);
|
|
713
|
+
if (topic) {
|
|
714
|
+
return await buildTopicScope(ctx, topic, "topic");
|
|
715
|
+
}
|
|
716
|
+
const nodeScope = await resolveTopicNodeScopeOrNull(ctx, String(topicId));
|
|
717
|
+
if (nodeScope) {
|
|
718
|
+
return nodeScope;
|
|
719
|
+
}
|
|
720
|
+
throw new Error(`Topic not found: ${String(topicId)}`);
|
|
721
|
+
}
|
|
722
|
+
async function resolveTopicDocFromTopicId(ctx, topicId) {
|
|
723
|
+
const direct = await tryReadTopicDoc(ctx, topicId, {
|
|
724
|
+
failureLog: "[topicScope] Failed to load topic by direct id",
|
|
725
|
+
idLogKey: "topicId"
|
|
726
|
+
});
|
|
727
|
+
if (direct) {
|
|
728
|
+
return direct;
|
|
729
|
+
}
|
|
730
|
+
const hostTopic = await tryResolveHostTopicById(ctx, String(topicId));
|
|
731
|
+
if (hostTopic) {
|
|
732
|
+
return hostTopic;
|
|
733
|
+
}
|
|
734
|
+
return pickPrimaryTopic(await findTopicsByScopeAlias(ctx, String(topicId))) ?? null;
|
|
735
|
+
}
|
|
736
|
+
async function resolveScopeFromLegacyProjectId(ctx, legacyProjectId) {
|
|
737
|
+
const directTopic = await resolveDirectLegacyProjectTopic(
|
|
738
|
+
ctx,
|
|
739
|
+
legacyProjectId
|
|
740
|
+
);
|
|
741
|
+
if (directTopic) {
|
|
742
|
+
return await buildTopicScope(ctx, directTopic, "topic_inferred", {
|
|
743
|
+
fallbackProjectId: legacyProjectId
|
|
744
|
+
});
|
|
745
|
+
}
|
|
746
|
+
const primary = pickPrimaryTopic(
|
|
747
|
+
await findTopicsByScopeAlias(ctx, legacyProjectId)
|
|
748
|
+
);
|
|
749
|
+
if (primary) {
|
|
750
|
+
return await buildTopicScope(ctx, primary, "project_mapped_topic", {
|
|
751
|
+
fallbackProjectId: legacyProjectId
|
|
752
|
+
});
|
|
753
|
+
}
|
|
754
|
+
const nodeScope = await resolveTopicNodeScopeOrNull(ctx, legacyProjectId);
|
|
755
|
+
if (nodeScope) {
|
|
756
|
+
return {
|
|
757
|
+
...nodeScope,
|
|
758
|
+
projectId: nodeScope.projectId ?? legacyProjectId
|
|
759
|
+
};
|
|
760
|
+
}
|
|
761
|
+
throw new Error(
|
|
762
|
+
`Legacy project scope ${legacyProjectId} has no mapped topic.`
|
|
763
|
+
);
|
|
764
|
+
}
|
|
765
|
+
async function resolveDirectLegacyProjectTopic(ctx, legacyProjectId) {
|
|
766
|
+
const directTopic = await tryReadTopicDoc(ctx, legacyProjectId, {
|
|
767
|
+
failureLog: "[topicScope] Failed to load direct project topic",
|
|
768
|
+
idLogKey: "projectId"
|
|
769
|
+
});
|
|
770
|
+
return directTopic ?? tryResolveHostTopicByLegacyScope(ctx, legacyProjectId);
|
|
771
|
+
}
|
|
772
|
+
async function tryReadTopicDoc(ctx, id, log) {
|
|
773
|
+
try {
|
|
774
|
+
return await ctx.db.get(id);
|
|
775
|
+
} catch (error) {
|
|
776
|
+
debugGraphPrimitiveFallback(log.failureLog, {
|
|
777
|
+
error,
|
|
778
|
+
[log.idLogKey]: id
|
|
779
|
+
});
|
|
780
|
+
return null;
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
async function buildTopicScope(ctx, topic, source, options = {}) {
|
|
784
|
+
const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
|
|
785
|
+
const mapped = asMappedProjectId(topic);
|
|
786
|
+
return {
|
|
787
|
+
topicId: topic._id,
|
|
788
|
+
...mapped || options.fallbackProjectId ? { projectId: mapped ?? options.fallbackProjectId } : {},
|
|
789
|
+
tenantId: inherited.tenantId,
|
|
790
|
+
workspaceId: inherited.workspaceId,
|
|
791
|
+
source
|
|
792
|
+
};
|
|
793
|
+
}
|
|
743
794
|
var optionalScopeArgs = {
|
|
744
795
|
projectId: v.optional(v.string()),
|
|
745
796
|
topicId: v.optional(v.string())
|
|
@@ -804,8 +855,6 @@ function nodeMatchesWorkspaceReasoningScope(node, scope) {
|
|
|
804
855
|
}
|
|
805
856
|
return scopeWorkspaceId === nodeWorkspaceId;
|
|
806
857
|
}
|
|
807
|
-
|
|
808
|
-
// src/epistemicBeliefs.helpers.ts
|
|
809
858
|
v.id("epistemicNodes");
|
|
810
859
|
var DEFAULT_PROJECT_BELIEF_LIMIT = 250;
|
|
811
860
|
var MAX_PROJECT_BELIEF_LIMIT = 1e3;
|
|
@@ -897,7 +946,7 @@ function normalizePillar(pillar) {
|
|
|
897
946
|
async function markBeliefGraphDirty(ctx, scope) {
|
|
898
947
|
const projectId = typeof scope.projectId === "string" && scope.projectId.trim().length > 0 ? scope.projectId : void 0;
|
|
899
948
|
const topicId = typeof scope.topicId === "string" && scope.topicId.trim().length > 0 ? scope.topicId : void 0;
|
|
900
|
-
if (!projectId
|
|
949
|
+
if (!(projectId || topicId)) {
|
|
901
950
|
return;
|
|
902
951
|
}
|
|
903
952
|
if (projectId) {
|
|
@@ -914,9 +963,15 @@ async function markBeliefGraphDirty(ctx, scope) {
|
|
|
914
963
|
{ topicId }
|
|
915
964
|
);
|
|
916
965
|
}
|
|
966
|
+
const activityScopeId = topicId ?? projectId;
|
|
967
|
+
if (!activityScopeId) {
|
|
968
|
+
throw new Error(
|
|
969
|
+
"Expected belief graph dirty scope to include a topic or project id."
|
|
970
|
+
);
|
|
971
|
+
}
|
|
917
972
|
await resolveGraphPrimitivesAppResolvers().patchProject(
|
|
918
973
|
ctx,
|
|
919
|
-
|
|
974
|
+
activityScopeId,
|
|
920
975
|
{
|
|
921
976
|
lastActivityAt: Date.now()
|
|
922
977
|
}
|
|
@@ -924,7 +979,10 @@ async function markBeliefGraphDirty(ctx, scope) {
|
|
|
924
979
|
}
|
|
925
980
|
async function getActiveConfidencePolicy(ctx) {
|
|
926
981
|
try {
|
|
927
|
-
const activeConfig = await ctx.db.query("logicSprintScoring").withIndex(
|
|
982
|
+
const activeConfig = await ctx.db.query("logicSprintScoring").withIndex(
|
|
983
|
+
"by_active",
|
|
984
|
+
(q) => q.eq("isActive", true)
|
|
985
|
+
).first();
|
|
928
986
|
return {
|
|
929
987
|
scoringMode: activeConfig?.confidencePolicy === "always" ? "always" : DEFAULT_CONFIDENCE_POLICY.scoringMode,
|
|
930
988
|
tupleContradiction: normalizeTupleContradictionPolicy(
|
|
@@ -969,7 +1027,7 @@ function normalizeForkTriggerRelation(value) {
|
|
|
969
1027
|
}
|
|
970
1028
|
async function resolveForkTriggerEvidence(ctx, args) {
|
|
971
1029
|
const evidence = await ctx.db.get(args.triggeringEvidenceId);
|
|
972
|
-
if (
|
|
1030
|
+
if (evidence?.nodeType !== "evidence") {
|
|
973
1031
|
throwStructuredMutationError({
|
|
974
1032
|
message: "Fork requires an existing evidence node.",
|
|
975
1033
|
status: 400,
|
|
@@ -1008,16 +1066,16 @@ async function resolveForkTriggerEvidence(ctx, args) {
|
|
|
1008
1066
|
].filter(Boolean)
|
|
1009
1067
|
);
|
|
1010
1068
|
let relation = null;
|
|
1011
|
-
const linkedBeliefNodeId = String(
|
|
1012
|
-
evidenceMetadata.linkedBeliefNodeId ?? ""
|
|
1013
|
-
);
|
|
1069
|
+
const linkedBeliefNodeId = String(evidenceMetadata.linkedBeliefNodeId ?? "");
|
|
1014
1070
|
if (linkedBeliefNodeId && parentRefs.has(linkedBeliefNodeId)) {
|
|
1015
1071
|
relation = normalizeForkTriggerRelation(evidenceMetadata.evidenceRelation);
|
|
1016
1072
|
}
|
|
1017
1073
|
if (!relation) {
|
|
1018
1074
|
for (const parentRef of parentRefs) {
|
|
1019
1075
|
const links = await ctx.db.query("beliefEvidenceLinks").withIndex("by_beliefId", (q) => q.eq("beliefId", parentRef)).collect();
|
|
1020
|
-
const matched = links.find(
|
|
1076
|
+
const matched = links.find(
|
|
1077
|
+
(link) => evidenceRefs.has(String(link.insightId))
|
|
1078
|
+
);
|
|
1021
1079
|
if (matched) {
|
|
1022
1080
|
relation = normalizeForkTriggerRelation(matched.relation);
|
|
1023
1081
|
break;
|
|
@@ -1053,13 +1111,16 @@ async function resolveForkTriggerEvidence(ctx, args) {
|
|
|
1053
1111
|
}
|
|
1054
1112
|
return { evidenceNodeId: args.triggeringEvidenceId, relation };
|
|
1055
1113
|
}
|
|
1056
|
-
|
|
1114
|
+
function insertEpistemicNode(ctx, doc) {
|
|
1057
1115
|
assertUuidV7Identity("epistemicNodes", doc.globalId);
|
|
1058
1116
|
return ctx.db.insert("epistemicNodes", doc);
|
|
1059
1117
|
}
|
|
1060
1118
|
async function assertExistingNodeEndpoint(ctx, endpointRole, endpoint) {
|
|
1061
1119
|
assertUuidShapedEdgeEndpoint(endpointRole, endpoint);
|
|
1062
|
-
const node = await ctx.db.query("epistemicNodes").withIndex(
|
|
1120
|
+
const node = await ctx.db.query("epistemicNodes").withIndex(
|
|
1121
|
+
"by_globalId",
|
|
1122
|
+
(q) => q.eq("globalId", endpoint)
|
|
1123
|
+
).first();
|
|
1063
1124
|
if (!node) {
|
|
1064
1125
|
throw new Error(
|
|
1065
1126
|
`edge_endpoint_not_canonical: epistemicEdges insert requires ${endpointRole} to be the globalId of an existing epistemicNodes row, received ${endpoint} (no node with that globalId)`
|
|
@@ -1125,7 +1186,7 @@ async function resolveRequiredTopicAnchor(ctx, topicRef) {
|
|
|
1125
1186
|
if (direct?.nodeType === "topic" && cleanString(direct.globalId)) {
|
|
1126
1187
|
return direct;
|
|
1127
1188
|
}
|
|
1128
|
-
} catch
|
|
1189
|
+
} catch {
|
|
1129
1190
|
}
|
|
1130
1191
|
const byGlobalId = await ctx.db.query("epistemicNodes").withIndex("by_globalId", (q) => q.eq("globalId", candidate)).first();
|
|
1131
1192
|
if (byGlobalId?.nodeType === "topic" && cleanString(byGlobalId.globalId)) {
|
|
@@ -1210,33 +1271,278 @@ async function createRequiredBeliefTopicEdge(ctx, args) {
|
|
|
1210
1271
|
});
|
|
1211
1272
|
}
|
|
1212
1273
|
|
|
1213
|
-
// src/
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1274
|
+
// src/epistemicBeliefs.core.ts
|
|
1275
|
+
var CONTRACT_CONDITION_TYPES = /* @__PURE__ */ new Set(["assertion", "temporal", "evidential", "threshold", "composite"]);
|
|
1276
|
+
var CONTRACT_DIRECTIONS = /* @__PURE__ */ new Set([
|
|
1277
|
+
"confirms",
|
|
1278
|
+
"falsifies"
|
|
1279
|
+
]);
|
|
1280
|
+
var CONTRACT_LINEAGE_SOURCES = /* @__PURE__ */ new Set(["declared", "inherited"]);
|
|
1281
|
+
var CONTRACT_SCHEDULES = /* @__PURE__ */ new Set([
|
|
1282
|
+
"on_demand",
|
|
1283
|
+
"on_evidence",
|
|
1284
|
+
"periodic",
|
|
1285
|
+
"event_driven"
|
|
1286
|
+
]);
|
|
1287
|
+
var CONTRACT_STATUSES = /* @__PURE__ */ new Set([
|
|
1288
|
+
"active",
|
|
1289
|
+
"satisfied",
|
|
1290
|
+
"violated",
|
|
1291
|
+
"expired",
|
|
1292
|
+
"suspended",
|
|
1293
|
+
"archived"
|
|
1294
|
+
]);
|
|
1295
|
+
function isRecord(value) {
|
|
1296
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
1297
|
+
}
|
|
1298
|
+
function readConvexId(value) {
|
|
1299
|
+
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
1300
|
+
}
|
|
1301
|
+
function readOptionalBoolean(value) {
|
|
1302
|
+
return typeof value === "boolean" ? value : void 0;
|
|
1303
|
+
}
|
|
1304
|
+
function readOptionalNumber(value) {
|
|
1305
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
1306
|
+
}
|
|
1307
|
+
function readOptionalString(value) {
|
|
1308
|
+
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
1309
|
+
}
|
|
1310
|
+
function readRecord(value) {
|
|
1311
|
+
return isRecord(value) ? value : void 0;
|
|
1312
|
+
}
|
|
1313
|
+
function readStringList(value) {
|
|
1314
|
+
if (!Array.isArray(value)) {
|
|
1315
|
+
return;
|
|
1316
|
+
}
|
|
1317
|
+
const strings = value.filter(
|
|
1318
|
+
(item) => typeof item === "string" && item.length > 0
|
|
1319
|
+
);
|
|
1320
|
+
return strings.length === value.length ? strings : void 0;
|
|
1321
|
+
}
|
|
1322
|
+
function readEnumValue(value, allowed) {
|
|
1323
|
+
return typeof value === "string" && allowed.has(value) ? value : void 0;
|
|
1324
|
+
}
|
|
1325
|
+
function readContractCondition(value) {
|
|
1326
|
+
const record = readRecord(value);
|
|
1327
|
+
const evaluator = readOptionalString(record?.evaluator);
|
|
1328
|
+
const expression = readOptionalString(record?.expression);
|
|
1329
|
+
if (!(record && evaluator && expression)) {
|
|
1330
|
+
return;
|
|
1331
|
+
}
|
|
1332
|
+
return {
|
|
1333
|
+
evaluator,
|
|
1334
|
+
expression,
|
|
1335
|
+
evaluatorConfig: record.evaluatorConfig
|
|
1336
|
+
};
|
|
1337
|
+
}
|
|
1338
|
+
function readContractModulation(value) {
|
|
1339
|
+
const record = readRecord(value);
|
|
1340
|
+
const onConfirmed = readRecord(record?.onConfirmed);
|
|
1341
|
+
const onDisconfirmed = readRecord(record?.onDisconfirmed);
|
|
1342
|
+
const confirmedDelta = readOptionalNumber(onConfirmed?.delta);
|
|
1343
|
+
const disconfirmedDelta = readOptionalNumber(onDisconfirmed?.delta);
|
|
1344
|
+
if (!(record && onConfirmed && onDisconfirmed)) {
|
|
1345
|
+
return;
|
|
1346
|
+
}
|
|
1347
|
+
if (confirmedDelta === void 0 || disconfirmedDelta === void 0) {
|
|
1348
|
+
return;
|
|
1349
|
+
}
|
|
1350
|
+
const modulation = {
|
|
1351
|
+
onConfirmed: { delta: confirmedDelta },
|
|
1352
|
+
onDisconfirmed: { delta: disconfirmedDelta }
|
|
1353
|
+
};
|
|
1354
|
+
const confirmedCeiling = readOptionalNumber(onConfirmed.ceiling);
|
|
1355
|
+
if (confirmedCeiling !== void 0) {
|
|
1356
|
+
modulation.onConfirmed.ceiling = confirmedCeiling;
|
|
1357
|
+
}
|
|
1358
|
+
const disconfirmedFloor = readOptionalNumber(onDisconfirmed.floor);
|
|
1359
|
+
if (disconfirmedFloor !== void 0) {
|
|
1360
|
+
modulation.onDisconfirmed.floor = disconfirmedFloor;
|
|
1361
|
+
}
|
|
1362
|
+
const onExpired = readRecord(record.onExpired);
|
|
1363
|
+
const expiredDelta = readOptionalNumber(onExpired?.delta);
|
|
1364
|
+
if (expiredDelta !== void 0) {
|
|
1365
|
+
modulation.onExpired = { delta: expiredDelta };
|
|
1366
|
+
}
|
|
1367
|
+
const onPartial = readRecord(record.onPartial);
|
|
1368
|
+
const partialDelta = readOptionalNumber(onPartial?.delta);
|
|
1369
|
+
const partialThreshold = readOptionalNumber(onPartial?.threshold);
|
|
1370
|
+
if (partialDelta !== void 0 && partialThreshold !== void 0) {
|
|
1371
|
+
modulation.onPartial = {
|
|
1372
|
+
delta: partialDelta,
|
|
1373
|
+
threshold: partialThreshold
|
|
1374
|
+
};
|
|
1375
|
+
}
|
|
1376
|
+
return modulation;
|
|
1377
|
+
}
|
|
1378
|
+
function readBeliefNodeDoc(value) {
|
|
1379
|
+
if (!isRecord(value)) {
|
|
1380
|
+
return null;
|
|
1381
|
+
}
|
|
1382
|
+
const id = readConvexId(value._id);
|
|
1383
|
+
const nodeType = readOptionalString(value.nodeType);
|
|
1384
|
+
const projectId = readOptionalString(value.projectId);
|
|
1385
|
+
if (!(id && nodeType === "belief" && projectId)) {
|
|
1386
|
+
return null;
|
|
1387
|
+
}
|
|
1388
|
+
const node = { _id: id, nodeType, projectId };
|
|
1389
|
+
const canonicalText = readOptionalString(value.canonicalText);
|
|
1390
|
+
const confidence = readOptionalNumber(value.confidence);
|
|
1391
|
+
const content = readOptionalString(value.content);
|
|
1392
|
+
const epistemicLayer = readOptionalString(value.epistemicLayer);
|
|
1393
|
+
const globalId = readOptionalString(value.globalId);
|
|
1394
|
+
const metadata = readRecord(value.metadata);
|
|
1395
|
+
const predictionMeta = readRecord(value.predictionMeta);
|
|
1396
|
+
const sourceType = readOptionalString(value.sourceType);
|
|
1397
|
+
const status = readOptionalString(value.status);
|
|
1398
|
+
const tenantId = readOptionalString(value.tenantId);
|
|
1399
|
+
const title = readOptionalString(value.title);
|
|
1400
|
+
const topicId = readConvexId(value.topicId);
|
|
1401
|
+
const tupleContradicted = readOptionalBoolean(value.tupleContradicted);
|
|
1402
|
+
const workspaceId = readOptionalString(value.workspaceId);
|
|
1403
|
+
if (canonicalText !== void 0) {
|
|
1404
|
+
node.canonicalText = canonicalText;
|
|
1405
|
+
}
|
|
1406
|
+
if (confidence !== void 0) {
|
|
1407
|
+
node.confidence = confidence;
|
|
1408
|
+
}
|
|
1409
|
+
if (content !== void 0) {
|
|
1410
|
+
node.content = content;
|
|
1411
|
+
}
|
|
1412
|
+
if (epistemicLayer !== void 0) {
|
|
1413
|
+
node.epistemicLayer = epistemicLayer;
|
|
1414
|
+
}
|
|
1415
|
+
if (globalId !== void 0) {
|
|
1416
|
+
node.globalId = globalId;
|
|
1417
|
+
}
|
|
1418
|
+
if (metadata !== void 0) {
|
|
1419
|
+
node.metadata = metadata;
|
|
1420
|
+
}
|
|
1421
|
+
if (predictionMeta !== void 0) {
|
|
1422
|
+
node.predictionMeta = predictionMeta;
|
|
1423
|
+
}
|
|
1424
|
+
if (sourceType !== void 0) {
|
|
1425
|
+
node.sourceType = sourceType;
|
|
1426
|
+
}
|
|
1427
|
+
if (status !== void 0) {
|
|
1428
|
+
node.status = status;
|
|
1429
|
+
}
|
|
1430
|
+
if (tenantId !== void 0) {
|
|
1431
|
+
node.tenantId = tenantId;
|
|
1432
|
+
}
|
|
1433
|
+
if (title !== void 0) {
|
|
1434
|
+
node.title = title;
|
|
1435
|
+
}
|
|
1436
|
+
if (topicId !== void 0) {
|
|
1437
|
+
node.topicId = topicId;
|
|
1438
|
+
}
|
|
1439
|
+
if (tupleContradicted !== void 0) {
|
|
1440
|
+
node.tupleContradicted = tupleContradicted;
|
|
1441
|
+
}
|
|
1442
|
+
if (workspaceId !== void 0) {
|
|
1443
|
+
node.workspaceId = workspaceId;
|
|
1444
|
+
}
|
|
1445
|
+
return node;
|
|
1446
|
+
}
|
|
1447
|
+
function readContractRow(value) {
|
|
1448
|
+
if (!isRecord(value)) {
|
|
1449
|
+
return null;
|
|
1450
|
+
}
|
|
1451
|
+
const beliefNodeId = readConvexId(value.beliefNodeId);
|
|
1452
|
+
const condition = readContractCondition(value.condition);
|
|
1453
|
+
const conditionType = readEnumValue(
|
|
1454
|
+
value.conditionType,
|
|
1455
|
+
CONTRACT_CONDITION_TYPES
|
|
1456
|
+
);
|
|
1457
|
+
const contractId = readOptionalString(value.contractId);
|
|
1458
|
+
const createdAt = readOptionalNumber(value.createdAt);
|
|
1459
|
+
const createdBy = readOptionalString(value.createdBy);
|
|
1460
|
+
const direction = readEnumValue(value.direction, CONTRACT_DIRECTIONS);
|
|
1461
|
+
const evaluationSchedule = readEnumValue(
|
|
1462
|
+
value.evaluationSchedule,
|
|
1463
|
+
CONTRACT_SCHEDULES
|
|
1464
|
+
);
|
|
1465
|
+
const lineageSource = readEnumValue(
|
|
1466
|
+
value.lineageSource,
|
|
1467
|
+
CONTRACT_LINEAGE_SOURCES
|
|
1468
|
+
);
|
|
1469
|
+
const modulation = readContractModulation(value.modulation);
|
|
1470
|
+
const status = readEnumValue(value.status, CONTRACT_STATUSES);
|
|
1471
|
+
const title = readOptionalString(value.title);
|
|
1472
|
+
const updatedAt = readOptionalNumber(value.updatedAt);
|
|
1473
|
+
if (!(beliefNodeId && condition && conditionType && contractId && createdAt !== void 0 && createdBy && direction && evaluationSchedule && lineageSource && modulation && status && title && updatedAt !== void 0)) {
|
|
1474
|
+
return null;
|
|
1475
|
+
}
|
|
1476
|
+
const row = {
|
|
1477
|
+
beliefNodeId,
|
|
1478
|
+
condition,
|
|
1479
|
+
conditionType,
|
|
1480
|
+
contractId,
|
|
1481
|
+
createdAt,
|
|
1482
|
+
createdBy,
|
|
1483
|
+
direction,
|
|
1484
|
+
evaluationSchedule,
|
|
1485
|
+
lineageSource,
|
|
1486
|
+
modulation,
|
|
1487
|
+
status,
|
|
1488
|
+
title,
|
|
1489
|
+
updatedAt
|
|
1490
|
+
};
|
|
1491
|
+
const compositeOf = readStringList(value.compositeOf);
|
|
1492
|
+
if (compositeOf !== void 0) {
|
|
1493
|
+
row.compositeOf = compositeOf;
|
|
1494
|
+
}
|
|
1495
|
+
const compositeOperator = readOptionalString(value.compositeOperator);
|
|
1496
|
+
if (compositeOperator === "all" || compositeOperator === "any" || compositeOperator === "majority") {
|
|
1497
|
+
row.compositeOperator = compositeOperator;
|
|
1498
|
+
}
|
|
1499
|
+
const deadline = readOptionalNumber(value.deadline);
|
|
1500
|
+
if (deadline !== void 0) {
|
|
1501
|
+
row.deadline = deadline;
|
|
1502
|
+
}
|
|
1503
|
+
const description = readOptionalString(value.description);
|
|
1504
|
+
if (description !== void 0) {
|
|
1505
|
+
row.description = description;
|
|
1506
|
+
}
|
|
1507
|
+
const evaluationCount = readOptionalNumber(value.evaluationCount);
|
|
1508
|
+
if (evaluationCount !== void 0) {
|
|
1509
|
+
row.evaluationCount = evaluationCount;
|
|
1510
|
+
}
|
|
1511
|
+
const inheritedAt = readOptionalNumber(value.inheritedAt);
|
|
1512
|
+
if (inheritedAt !== void 0) {
|
|
1513
|
+
row.inheritedAt = inheritedAt;
|
|
1514
|
+
}
|
|
1515
|
+
const inheritedFromBeliefNodeId = readConvexId(
|
|
1516
|
+
value.inheritedFromBeliefNodeId
|
|
1517
|
+
);
|
|
1518
|
+
if (inheritedFromBeliefNodeId !== void 0) {
|
|
1519
|
+
row.inheritedFromBeliefNodeId = inheritedFromBeliefNodeId;
|
|
1520
|
+
}
|
|
1521
|
+
const inheritedFromContractId = readOptionalString(
|
|
1522
|
+
value.inheritedFromContractId
|
|
1523
|
+
);
|
|
1524
|
+
if (inheritedFromContractId !== void 0) {
|
|
1525
|
+
row.inheritedFromContractId = inheritedFromContractId;
|
|
1526
|
+
}
|
|
1527
|
+
const lastEvaluatedAt = readOptionalNumber(value.lastEvaluatedAt);
|
|
1528
|
+
if (lastEvaluatedAt !== void 0) {
|
|
1529
|
+
row.lastEvaluatedAt = lastEvaluatedAt;
|
|
1530
|
+
}
|
|
1531
|
+
const periodicIntervalMs = readOptionalNumber(value.periodicIntervalMs);
|
|
1532
|
+
if (periodicIntervalMs !== void 0) {
|
|
1533
|
+
row.periodicIntervalMs = periodicIntervalMs;
|
|
1534
|
+
}
|
|
1535
|
+
const topicId = readConvexId(value.topicId) ?? readOptionalString(value.topicId);
|
|
1536
|
+
if (topicId !== void 0) {
|
|
1537
|
+
row.topicId = topicId;
|
|
1239
1538
|
}
|
|
1539
|
+
return row;
|
|
1540
|
+
}
|
|
1541
|
+
function readRowList(values, reader) {
|
|
1542
|
+
return values.flatMap((value) => {
|
|
1543
|
+
const row = reader(value);
|
|
1544
|
+
return row ? [row] : [];
|
|
1545
|
+
});
|
|
1240
1546
|
}
|
|
1241
1547
|
var create = mutation({
|
|
1242
1548
|
args: {
|
|
@@ -1287,41 +1593,7 @@ var create = mutation({
|
|
|
1287
1593
|
returns: permissiveReturn,
|
|
1288
1594
|
handler: async (ctx, args) => {
|
|
1289
1595
|
const authenticatedUserId = await requireAuthenticatedUserId(ctx);
|
|
1290
|
-
const
|
|
1291
|
-
if (!topicRef) {
|
|
1292
|
-
throwStructuredMutationError({
|
|
1293
|
-
message: "Belief creation requires an explicit topic epistemic node.",
|
|
1294
|
-
status: 400,
|
|
1295
|
-
code: "INVALID_ARGUMENT",
|
|
1296
|
-
invariantCode: "belief.topic_node_required",
|
|
1297
|
-
suggestion: "Pass topicGlobalId or topicNodeId for a topic in epistemicNodes before creating a belief.",
|
|
1298
|
-
details: {
|
|
1299
|
-
topicId: args.topicId,
|
|
1300
|
-
topicNodeId: args.topicNodeId,
|
|
1301
|
-
topicGlobalId: args.topicGlobalId
|
|
1302
|
-
}
|
|
1303
|
-
});
|
|
1304
|
-
}
|
|
1305
|
-
const topicNode = await resolveRequiredTopicAnchor(ctx, topicRef);
|
|
1306
|
-
const scope = scopeFromTopicAnchor(topicNode);
|
|
1307
|
-
assertWorkspaceScopedEpistemicNodeScope({
|
|
1308
|
-
scope,
|
|
1309
|
-
nodeType: "belief",
|
|
1310
|
-
mutationName: "epistemicBeliefs.create"
|
|
1311
|
-
});
|
|
1312
|
-
const normalizedBeliefType = await assertSchemaEnumValue(ctx, {
|
|
1313
|
-
category: "belief_type",
|
|
1314
|
-
value: args.beliefType,
|
|
1315
|
-
tenantId: scope.tenantId,
|
|
1316
|
-
context: "epistemicBeliefs.create"
|
|
1317
|
-
});
|
|
1318
|
-
if (scope.projectId) {
|
|
1319
|
-
await requireScopeWriteAccess(
|
|
1320
|
-
ctx,
|
|
1321
|
-
scope.projectId,
|
|
1322
|
-
authenticatedUserId
|
|
1323
|
-
);
|
|
1324
|
-
}
|
|
1596
|
+
const { normalizedBeliefType, scope, topicNode } = await resolveCreateBeliefAdmission(ctx, args, authenticatedUserId);
|
|
1325
1597
|
const now = Date.now();
|
|
1326
1598
|
const baseRate = assertBaseRateInRange(args.baseRate ?? 0.5);
|
|
1327
1599
|
const initialBeliefStatus = args.worktreeId ? "hypothesis" : "assumption";
|
|
@@ -1333,7 +1605,7 @@ var create = mutation({
|
|
|
1333
1605
|
opinion_a: baseRate
|
|
1334
1606
|
};
|
|
1335
1607
|
const pillar = normalizePillar(args.pillar);
|
|
1336
|
-
const additionalMeta = args.metadata
|
|
1608
|
+
const additionalMeta = readRecord(args.metadata) ?? {};
|
|
1337
1609
|
const beliefGlobalId = generateGlobalId();
|
|
1338
1610
|
const nodeId = await insertEpistemicNode(ctx, {
|
|
1339
1611
|
globalId: beliefGlobalId,
|
|
@@ -1495,6 +1767,44 @@ Rationale: ${args.rationale}` : args.formulation
|
|
|
1495
1767
|
return { nodeId };
|
|
1496
1768
|
}
|
|
1497
1769
|
});
|
|
1770
|
+
async function resolveCreateBeliefAdmission(ctx, args, authenticatedUserId) {
|
|
1771
|
+
const topicRef = readTopicNodeRef(args);
|
|
1772
|
+
if (!topicRef) {
|
|
1773
|
+
throwStructuredMutationError({
|
|
1774
|
+
message: "Belief creation requires an explicit topic epistemic node.",
|
|
1775
|
+
status: 400,
|
|
1776
|
+
code: "INVALID_ARGUMENT",
|
|
1777
|
+
invariantCode: "belief.topic_node_required",
|
|
1778
|
+
suggestion: "Pass topicGlobalId or topicNodeId for a topic in epistemicNodes before creating a belief.",
|
|
1779
|
+
details: {
|
|
1780
|
+
topicId: args.topicId,
|
|
1781
|
+
topicNodeId: args.topicNodeId,
|
|
1782
|
+
topicGlobalId: args.topicGlobalId
|
|
1783
|
+
}
|
|
1784
|
+
});
|
|
1785
|
+
}
|
|
1786
|
+
const topicNode = await resolveRequiredTopicAnchor(ctx, topicRef);
|
|
1787
|
+
const anchoredScope = scopeFromTopicAnchor(topicNode);
|
|
1788
|
+
const scope = {
|
|
1789
|
+
...anchoredScope,
|
|
1790
|
+
topicId: anchoredScope.topicId
|
|
1791
|
+
};
|
|
1792
|
+
assertWorkspaceScopedEpistemicNodeScope({
|
|
1793
|
+
scope,
|
|
1794
|
+
nodeType: "belief",
|
|
1795
|
+
mutationName: "epistemicBeliefs.create"
|
|
1796
|
+
});
|
|
1797
|
+
const normalizedBeliefType = await assertSchemaEnumValue(ctx, {
|
|
1798
|
+
category: "belief_type",
|
|
1799
|
+
value: args.beliefType,
|
|
1800
|
+
tenantId: scope.tenantId,
|
|
1801
|
+
context: "epistemicBeliefs.create"
|
|
1802
|
+
});
|
|
1803
|
+
if (scope.projectId) {
|
|
1804
|
+
await requireScopeWriteAccess(ctx, scope.projectId, authenticatedUserId);
|
|
1805
|
+
}
|
|
1806
|
+
return { normalizedBeliefType, scope, topicNode };
|
|
1807
|
+
}
|
|
1498
1808
|
var getById = query({
|
|
1499
1809
|
args: {
|
|
1500
1810
|
nodeId: v.optional(v.id("epistemicNodes")),
|
|
@@ -1506,8 +1816,8 @@ var getById = query({
|
|
|
1506
1816
|
if (!id) {
|
|
1507
1817
|
return null;
|
|
1508
1818
|
}
|
|
1509
|
-
const node = await ctx.db.get(id);
|
|
1510
|
-
if (!node
|
|
1819
|
+
const node = readBeliefNodeDoc(await ctx.db.get(id));
|
|
1820
|
+
if (!node) {
|
|
1511
1821
|
return null;
|
|
1512
1822
|
}
|
|
1513
1823
|
return node;
|
|
@@ -1525,48 +1835,8 @@ var refineBelief = mutation({
|
|
|
1525
1835
|
handler: async (ctx, args) => {
|
|
1526
1836
|
const authenticatedUserId = await requireAuthenticatedUserId(ctx);
|
|
1527
1837
|
const now = Date.now();
|
|
1528
|
-
const node = await ctx
|
|
1529
|
-
if (!node) {
|
|
1530
|
-
throwStructuredMutationError({
|
|
1531
|
-
message: "Belief not found.",
|
|
1532
|
-
status: 404,
|
|
1533
|
-
code: "NOT_FOUND",
|
|
1534
|
-
invariantCode: "belief.exists",
|
|
1535
|
-
suggestion: "Verify nodeId points to an existing belief before refining.",
|
|
1536
|
-
details: { nodeId: args.nodeId }
|
|
1537
|
-
});
|
|
1538
|
-
}
|
|
1539
|
-
if (node.nodeType !== "belief") {
|
|
1540
|
-
throwStructuredMutationError({
|
|
1541
|
-
message: `refineBelief only applies to belief nodes. Received nodeType "${node.nodeType}".`,
|
|
1542
|
-
status: 400,
|
|
1543
|
-
code: "INVALID_ARGUMENT",
|
|
1544
|
-
invariantCode: "entity.no_refine",
|
|
1545
|
-
suggestion: "Use entityLifecycle.updateEntityAttributes for entity mutations.",
|
|
1546
|
-
details: { nodeId: args.nodeId, nodeType: node.nodeType }
|
|
1547
|
-
});
|
|
1548
|
-
}
|
|
1549
|
-
if (!node.projectId) {
|
|
1550
|
-
throwStructuredMutationError({
|
|
1551
|
-
message: "Belief has no project scope.",
|
|
1552
|
-
status: 400,
|
|
1553
|
-
code: "MISSING_SCOPE",
|
|
1554
|
-
invariantCode: "belief.project_required",
|
|
1555
|
-
suggestion: "Belief must have a projectId to refine.",
|
|
1556
|
-
details: { nodeId: args.nodeId }
|
|
1557
|
-
});
|
|
1558
|
-
}
|
|
1838
|
+
const node = await requireRefinableBelief(ctx, args.nodeId);
|
|
1559
1839
|
await requireScopeWriteAccess(ctx, node.projectId, authenticatedUserId);
|
|
1560
|
-
if (typeof node.confidence === "number" && Number.isFinite(node.confidence)) {
|
|
1561
|
-
throwStructuredMutationError({
|
|
1562
|
-
message: "Scored beliefs are immutable. Use forkBelief to evolve a scored belief.",
|
|
1563
|
-
status: 409,
|
|
1564
|
-
code: "CONFLICT",
|
|
1565
|
-
invariantCode: "belief.versioning.scored_immutable",
|
|
1566
|
-
suggestion: "Use forkBelief() to create a new version instead of refining in place.",
|
|
1567
|
-
details: { nodeId: args.nodeId, confidence: node.confidence }
|
|
1568
|
-
});
|
|
1569
|
-
}
|
|
1570
1840
|
const nextText = typeof args.canonicalText === "string" && args.canonicalText.trim().length > 0 ? args.canonicalText.trim() : void 0;
|
|
1571
1841
|
const nextTitle = typeof args.title === "string" && args.title.trim().length > 0 ? args.title.trim() : void 0;
|
|
1572
1842
|
const patch = { updatedAt: now };
|
|
@@ -1627,6 +1897,110 @@ Rationale: ${args.rationale}` : nextText
|
|
|
1627
1897
|
return { nodeId: args.nodeId };
|
|
1628
1898
|
}
|
|
1629
1899
|
});
|
|
1900
|
+
async function requireRefinableBelief(ctx, nodeId) {
|
|
1901
|
+
const node = await ctx.db.get(nodeId);
|
|
1902
|
+
if (!node) {
|
|
1903
|
+
throwStructuredMutationError({
|
|
1904
|
+
message: "Belief not found.",
|
|
1905
|
+
status: 404,
|
|
1906
|
+
code: "NOT_FOUND",
|
|
1907
|
+
invariantCode: "belief.exists",
|
|
1908
|
+
suggestion: "Verify nodeId points to an existing belief before refining.",
|
|
1909
|
+
details: { nodeId }
|
|
1910
|
+
});
|
|
1911
|
+
}
|
|
1912
|
+
const nodeType = isRecord(node) ? readOptionalString(node.nodeType) : void 0;
|
|
1913
|
+
if (nodeType !== "belief") {
|
|
1914
|
+
throwStructuredMutationError({
|
|
1915
|
+
message: `refineBelief only applies to belief nodes. Received nodeType "${nodeType}".`,
|
|
1916
|
+
status: 400,
|
|
1917
|
+
code: "INVALID_ARGUMENT",
|
|
1918
|
+
invariantCode: "entity.no_refine",
|
|
1919
|
+
suggestion: "Use entityLifecycle.updateEntityAttributes for entity mutations.",
|
|
1920
|
+
details: { nodeId, nodeType }
|
|
1921
|
+
});
|
|
1922
|
+
}
|
|
1923
|
+
const projectId = isRecord(node) ? readOptionalString(node.projectId) : void 0;
|
|
1924
|
+
if (!projectId) {
|
|
1925
|
+
throwStructuredMutationError({
|
|
1926
|
+
message: "Belief has no project scope.",
|
|
1927
|
+
status: 400,
|
|
1928
|
+
code: "MISSING_SCOPE",
|
|
1929
|
+
invariantCode: "belief.project_required",
|
|
1930
|
+
suggestion: "Belief must have a projectId to refine.",
|
|
1931
|
+
details: { nodeId }
|
|
1932
|
+
});
|
|
1933
|
+
}
|
|
1934
|
+
const confidence = isRecord(node) ? readOptionalNumber(node.confidence) : void 0;
|
|
1935
|
+
if (confidence !== void 0) {
|
|
1936
|
+
throwStructuredMutationError({
|
|
1937
|
+
message: "Scored beliefs are immutable. Use forkBelief to evolve a scored belief.",
|
|
1938
|
+
status: 409,
|
|
1939
|
+
code: "CONFLICT",
|
|
1940
|
+
invariantCode: "belief.versioning.scored_immutable",
|
|
1941
|
+
suggestion: "Use forkBelief() to create a new version instead of refining in place.",
|
|
1942
|
+
details: { nodeId, confidence }
|
|
1943
|
+
});
|
|
1944
|
+
}
|
|
1945
|
+
const beliefNode = readBeliefNodeDoc(node);
|
|
1946
|
+
if (!beliefNode) {
|
|
1947
|
+
throwStructuredMutationError({
|
|
1948
|
+
message: "Belief row is missing required typed fields.",
|
|
1949
|
+
status: 400,
|
|
1950
|
+
code: "MISSING_SCOPE",
|
|
1951
|
+
invariantCode: "belief.typed_row_required",
|
|
1952
|
+
suggestion: "Backfill belief project/topic/global scope before refining.",
|
|
1953
|
+
details: { nodeId }
|
|
1954
|
+
});
|
|
1955
|
+
}
|
|
1956
|
+
return beliefNode;
|
|
1957
|
+
}
|
|
1958
|
+
async function requireForkParentAdmission(ctx, args, authenticatedUserId) {
|
|
1959
|
+
const parentRaw = await ctx.db.get(args.parentNodeId);
|
|
1960
|
+
if (!parentRaw) {
|
|
1961
|
+
throwStructuredMutationError({
|
|
1962
|
+
message: "Parent node not found.",
|
|
1963
|
+
status: 404,
|
|
1964
|
+
code: "NOT_FOUND",
|
|
1965
|
+
invariantCode: "belief.exists",
|
|
1966
|
+
suggestion: "Verify parentNodeId points to an existing node before forking.",
|
|
1967
|
+
details: { parentNodeId: args.parentNodeId }
|
|
1968
|
+
});
|
|
1969
|
+
}
|
|
1970
|
+
const parent = readBeliefNodeDoc(parentRaw);
|
|
1971
|
+
const parentNodeType = isRecord(parentRaw) ? readOptionalString(parentRaw.nodeType) : void 0;
|
|
1972
|
+
if (!parent) {
|
|
1973
|
+
throwStructuredMutationError({
|
|
1974
|
+
message: `forkBelief only applies to fully scoped belief nodes. Received nodeType "${parentNodeType}". Entity nodes (company, person, investor, etc.) are mutable \u2014 use entityLifecycle.updateEntityAttributes instead of forking.`,
|
|
1975
|
+
status: 400,
|
|
1976
|
+
code: "INVALID_ARGUMENT",
|
|
1977
|
+
invariantCode: "entity.no_fork",
|
|
1978
|
+
suggestion: "Use entityLifecycle.updateEntityAttributes for entity mutations. forkBelief is for belief nodes only, and parent beliefs must carry project scope.",
|
|
1979
|
+
details: {
|
|
1980
|
+
parentNodeId: args.parentNodeId,
|
|
1981
|
+
nodeType: parentNodeType
|
|
1982
|
+
}
|
|
1983
|
+
});
|
|
1984
|
+
}
|
|
1985
|
+
const parentGlobalId = parent.globalId;
|
|
1986
|
+
if (!parentGlobalId) {
|
|
1987
|
+
throwStructuredMutationError({
|
|
1988
|
+
message: "Parent belief has no globalId for lineage edge creation.",
|
|
1989
|
+
status: 400,
|
|
1990
|
+
code: "INVALID_ARGUMENT",
|
|
1991
|
+
invariantCode: "belief.global_id_required",
|
|
1992
|
+
suggestion: "Backfill parent belief globalId before forking so Neo4j lineage edges can use canonical endpoints.",
|
|
1993
|
+
details: { parentNodeId: args.parentNodeId }
|
|
1994
|
+
});
|
|
1995
|
+
}
|
|
1996
|
+
await requireScopeWriteAccess(ctx, parent.projectId, authenticatedUserId);
|
|
1997
|
+
return {
|
|
1998
|
+
metadata: parent.metadata,
|
|
1999
|
+
parent,
|
|
2000
|
+
parentGlobalId,
|
|
2001
|
+
parentRaw
|
|
2002
|
+
};
|
|
2003
|
+
}
|
|
1630
2004
|
var getByProject = query({
|
|
1631
2005
|
args: {
|
|
1632
2006
|
...optionalBeliefScopeArgs,
|
|
@@ -1642,7 +2016,7 @@ var getByProject = query({
|
|
|
1642
2016
|
},
|
|
1643
2017
|
returns: permissiveReturn,
|
|
1644
2018
|
handler: async (ctx, args) => {
|
|
1645
|
-
if (!args.projectId
|
|
2019
|
+
if (!(args.projectId || args.topicId)) {
|
|
1646
2020
|
return [];
|
|
1647
2021
|
}
|
|
1648
2022
|
const pageSize = clampBeliefLimit(args.limit);
|
|
@@ -1674,11 +2048,14 @@ var getByProject = query({
|
|
|
1674
2048
|
return [];
|
|
1675
2049
|
}
|
|
1676
2050
|
}
|
|
1677
|
-
const
|
|
2051
|
+
const query2 = ctx.db.query("epistemicNodes").withIndex(
|
|
1678
2052
|
"by_topic_type",
|
|
1679
2053
|
(q) => q.eq("topicId", scope.topicId).eq("nodeType", "belief")
|
|
1680
2054
|
);
|
|
1681
|
-
const nodes =
|
|
2055
|
+
const nodes = readRowList(
|
|
2056
|
+
await query2.order("desc").take(scanLimit),
|
|
2057
|
+
readBeliefNodeDoc
|
|
2058
|
+
);
|
|
1682
2059
|
const scopedNodes = nodes.filter(
|
|
1683
2060
|
(node) => nodeMatchesWorkspaceReasoningScope(node, scope)
|
|
1684
2061
|
);
|
|
@@ -1708,11 +2085,14 @@ var getByTopic = query({
|
|
|
1708
2085
|
const scope = await resolveTopicProjectScope(ctx, {
|
|
1709
2086
|
topicId: args.topicId
|
|
1710
2087
|
});
|
|
1711
|
-
const
|
|
2088
|
+
const query2 = ctx.db.query("epistemicNodes").withIndex(
|
|
1712
2089
|
"by_topic_type",
|
|
1713
2090
|
(q) => q.eq("topicId", args.topicId).eq("nodeType", "belief")
|
|
1714
2091
|
);
|
|
1715
|
-
const nodes =
|
|
2092
|
+
const nodes = readRowList(
|
|
2093
|
+
await query2.order("desc").take(scanLimit),
|
|
2094
|
+
readBeliefNodeDoc
|
|
2095
|
+
);
|
|
1716
2096
|
const scopedNodes = nodes.filter(
|
|
1717
2097
|
(node) => nodeMatchesWorkspaceReasoningScope(node, {
|
|
1718
2098
|
tenantId: scope.tenantId,
|
|
@@ -1745,44 +2125,12 @@ var forkBelief = mutation({
|
|
|
1745
2125
|
const authenticatedUserId = await requireAuthenticatedUserId(ctx);
|
|
1746
2126
|
const now = Date.now();
|
|
1747
2127
|
await getActiveConfidencePolicy(ctx);
|
|
1748
|
-
const parent = await ctx
|
|
1749
|
-
if (!parent) {
|
|
1750
|
-
throwStructuredMutationError({
|
|
1751
|
-
message: "Parent node not found.",
|
|
1752
|
-
status: 404,
|
|
1753
|
-
code: "NOT_FOUND",
|
|
1754
|
-
invariantCode: "belief.exists",
|
|
1755
|
-
suggestion: "Verify parentNodeId points to an existing node before forking.",
|
|
1756
|
-
details: { parentNodeId: args.parentNodeId }
|
|
1757
|
-
});
|
|
1758
|
-
}
|
|
1759
|
-
if (parent.nodeType !== "belief") {
|
|
1760
|
-
throwStructuredMutationError({
|
|
1761
|
-
message: `forkBelief only applies to belief nodes. Received nodeType "${parent.nodeType}". Entity nodes (company, person, investor, etc.) are mutable \u2014 use entityLifecycle.updateEntityAttributes instead of forking.`,
|
|
1762
|
-
status: 400,
|
|
1763
|
-
code: "INVALID_ARGUMENT",
|
|
1764
|
-
invariantCode: "entity.no_fork",
|
|
1765
|
-
suggestion: "Use entityLifecycle.updateEntityAttributes for entity mutations. forkBelief is for belief nodes only.",
|
|
1766
|
-
details: { parentNodeId: args.parentNodeId, nodeType: parent.nodeType }
|
|
1767
|
-
});
|
|
1768
|
-
}
|
|
1769
|
-
if (!parent.projectId) {
|
|
1770
|
-
throwStructuredMutationError({
|
|
1771
|
-
message: "Parent belief has no project scope.",
|
|
1772
|
-
status: 400,
|
|
1773
|
-
code: "MISSING_SCOPE",
|
|
1774
|
-
invariantCode: "belief.project_required",
|
|
1775
|
-
suggestion: "Belief must have a projectId to fork.",
|
|
1776
|
-
details: { parentNodeId: args.parentNodeId }
|
|
1777
|
-
});
|
|
1778
|
-
}
|
|
1779
|
-
await requireScopeWriteAccess(ctx, parent.projectId, authenticatedUserId);
|
|
1780
|
-
const metadata = parent.metadata;
|
|
2128
|
+
const { metadata, parent, parentGlobalId, parentRaw } = await requireForkParentAdmission(ctx, args, authenticatedUserId);
|
|
1781
2129
|
const forkBeliefStatus = "hypothesis";
|
|
1782
2130
|
const forkMode = args.forkMode ?? "supersede";
|
|
1783
2131
|
const triggerEvidence = await resolveForkTriggerEvidence(ctx, {
|
|
1784
2132
|
parentNodeId: args.parentNodeId,
|
|
1785
|
-
parent,
|
|
2133
|
+
parent: parentRaw,
|
|
1786
2134
|
triggeringEvidenceId: args.triggeringEvidenceId,
|
|
1787
2135
|
forkMode
|
|
1788
2136
|
});
|
|
@@ -1829,7 +2177,7 @@ var forkBelief = mutation({
|
|
|
1829
2177
|
tupleContradicted: false
|
|
1830
2178
|
},
|
|
1831
2179
|
beliefStatus: forkBeliefStatus,
|
|
1832
|
-
sourceType: parent.sourceType,
|
|
2180
|
+
sourceType: parent.sourceType ?? "human",
|
|
1833
2181
|
confidence: void 0,
|
|
1834
2182
|
tupleContradicted: false,
|
|
1835
2183
|
verificationStatus: "unverified",
|
|
@@ -1861,23 +2209,21 @@ var forkBelief = mutation({
|
|
|
1861
2209
|
operation: "upsert"
|
|
1862
2210
|
});
|
|
1863
2211
|
}
|
|
1864
|
-
const inheritedContracts =
|
|
1865
|
-
"by_belief",
|
|
1866
|
-
|
|
1867
|
-
)
|
|
2212
|
+
const inheritedContracts = readRowList(
|
|
2213
|
+
await ctx.db.query("epistemicContracts").withIndex("by_belief", (q) => q.eq("beliefNodeId", args.parentNodeId)).collect(),
|
|
2214
|
+
readContractRow
|
|
2215
|
+
);
|
|
1868
2216
|
for (const contract of inheritedContracts) {
|
|
1869
2217
|
if (contract.status === "archived") {
|
|
1870
2218
|
continue;
|
|
1871
2219
|
}
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
})
|
|
1880
|
-
);
|
|
2220
|
+
const inheritedContract = createInheritedContractRecord(contract, {
|
|
2221
|
+
beliefNodeId: newNodeId,
|
|
2222
|
+
topicId: parent.topicId,
|
|
2223
|
+
createdBy: authenticatedUserId,
|
|
2224
|
+
now
|
|
2225
|
+
});
|
|
2226
|
+
await ctx.db.insert("epistemicContracts", { ...inheritedContract });
|
|
1881
2227
|
}
|
|
1882
2228
|
await ctx.scheduler.runAfter(0, internal.neo4jSync.syncNodeToNeo4j, {
|
|
1883
2229
|
nodeId: newNodeId,
|
|
@@ -1886,7 +2232,7 @@ var forkBelief = mutation({
|
|
|
1886
2232
|
await ctx.scheduler.runAfter(5e3, internal.neo4jEdgeAPI.createEdge, {
|
|
1887
2233
|
globalId: generateGlobalId(),
|
|
1888
2234
|
fromGlobalId: newBeliefGlobalId,
|
|
1889
|
-
toGlobalId:
|
|
2235
|
+
toGlobalId: parentGlobalId,
|
|
1890
2236
|
edgeType: forkMode === "supersede" ? "supersedes" : "derived_from",
|
|
1891
2237
|
context: `Fork reason: ${args.forkReason}; triggering evidence: ${triggerEvidence.evidenceNodeId}`,
|
|
1892
2238
|
createdBy: authenticatedUserId,
|