@lucern/graph-primitives 1.0.28 → 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 +398 -228
- 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 +857 -515
- 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 +366 -203
- package/dist/epistemicBeliefs.admin.js.map +1 -1
- package/dist/epistemicBeliefs.backfills.d.ts +8 -8
- package/dist/epistemicBeliefs.backfills.js +655 -308
- package/dist/epistemicBeliefs.backfills.js.map +1 -1
- package/dist/epistemicBeliefs.confidence.d.ts +19 -14
- package/dist/epistemicBeliefs.confidence.js +634 -423
- package/dist/epistemicBeliefs.confidence.js.map +1 -1
- package/dist/epistemicBeliefs.core.d.ts +6 -6
- package/dist/epistemicBeliefs.core.js +719 -411
- package/dist/epistemicBeliefs.core.js.map +1 -1
- package/dist/epistemicBeliefs.d.ts +11 -8
- package/dist/epistemicBeliefs.forkEvidence.d.ts +2 -0
- package/dist/epistemicBeliefs.forkEvidence.js +8 -28
- package/dist/epistemicBeliefs.forkEvidence.js.map +1 -1
- package/dist/epistemicBeliefs.helpers.d.ts +69 -74
- package/dist/epistemicBeliefs.helpers.js +359 -248
- package/dist/epistemicBeliefs.helpers.js.map +1 -1
- package/dist/epistemicBeliefs.internal.d.ts +5 -5
- package/dist/epistemicBeliefs.internal.js +1246 -1044
- package/dist/epistemicBeliefs.internal.js.map +1 -1
- package/dist/epistemicBeliefs.js +4922 -3608
- package/dist/epistemicBeliefs.js.map +1 -1
- package/dist/epistemicBeliefs.lifecycle.d.ts +5 -5
- package/dist/epistemicBeliefs.lifecycle.js +1137 -818
- package/dist/epistemicBeliefs.lifecycle.js.map +1 -1
- package/dist/epistemicBeliefs.links.d.ts +7 -7
- package/dist/epistemicBeliefs.links.js +408 -307
- 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 +1063 -613
- package/dist/epistemicContracts.evaluators.js.map +1 -1
- package/dist/epistemicContracts.handlers.d.ts +15 -32
- package/dist/epistemicContracts.handlers.js +2086 -1644
- package/dist/epistemicContracts.handlers.js.map +1 -1
- package/dist/epistemicContracts.js +1131 -672
- 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 +1969 -1205
- package/dist/epistemicEdges.js.map +1 -1
- package/dist/epistemicEdges.mutations.d.ts +7 -7
- package/dist/epistemicEdges.mutations.js +960 -583
- 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 +937 -536
- 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 +844 -696
- 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 +704 -508
- package/dist/epistemicNodes.js.map +1 -1
- package/dist/epistemicNodes.mutations.d.ts +6 -6
- package/dist/epistemicNodes.mutations.js +564 -467
- 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 +352 -312
- 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 +87 -83
- package/dist/index.js +15677 -10594
- 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,16 +1,21 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { requireScopeWriteAccess } from '@lucern/access-control/access';
|
|
2
2
|
import { permissiveReturn } from '@lucern/contracts/schema-helpers/validators';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { v } from 'convex/values';
|
|
4
|
+
import { unsafeConvexAnyApi } from '@lucern/contracts/convex/unsafeAnyApi';
|
|
5
|
+
import { componentsGeneric, mutationGeneric, queryGeneric } from 'convex/server';
|
|
6
6
|
import '@lucern/access-control/audience';
|
|
7
7
|
import { getCurrentUserId } from '@lucern/access-control/auth';
|
|
8
|
+
import { throwStructuredMutationError } from '@lucern/access-control/structuredMutationError';
|
|
9
|
+
import { normalizeTupleContradictionPolicy } from '@lucern/confidence';
|
|
8
10
|
import '@lucern/contracts/schema-helpers/spine/tables/epistemicNodes';
|
|
9
11
|
|
|
10
12
|
// src/epistemicBeliefs.admin.ts
|
|
11
|
-
var
|
|
13
|
+
var unsafeApi = unsafeConvexAnyApi(
|
|
14
|
+
"graph-primitives top-level module bundle lacks a committed Convex _generated/api surface"
|
|
15
|
+
);
|
|
16
|
+
var api = unsafeApi;
|
|
12
17
|
componentsGeneric();
|
|
13
|
-
var internal =
|
|
18
|
+
var internal = unsafeApi;
|
|
14
19
|
var mutation = mutationGeneric;
|
|
15
20
|
var query = queryGeneric;
|
|
16
21
|
|
|
@@ -59,13 +64,15 @@ function asMappedProjectId(topic) {
|
|
|
59
64
|
if (!topic) {
|
|
60
65
|
return;
|
|
61
66
|
}
|
|
62
|
-
const directLegacyProjectId = normalizeScopeValue(
|
|
67
|
+
const directLegacyProjectId = normalizeScopeValue(
|
|
68
|
+
topic[LEGACY_SCOPE_FIELD]
|
|
69
|
+
);
|
|
63
70
|
if (directLegacyProjectId) {
|
|
64
71
|
return directLegacyProjectId;
|
|
65
72
|
}
|
|
66
73
|
const metadata = topic.metadata || {};
|
|
67
74
|
const candidate = metadata[LEGACY_SCOPE_FIELD] || metadata.legacyProjectId || metadata.projectId || metadata.scopeProjectId;
|
|
68
|
-
return candidate ? candidate : void 0;
|
|
75
|
+
return typeof candidate === "string" ? normalizeScopeValue(candidate) : void 0;
|
|
69
76
|
}
|
|
70
77
|
function normalizeScopeValue(value) {
|
|
71
78
|
if (typeof value !== "string") {
|
|
@@ -90,8 +97,9 @@ function pickPrimaryTopic(candidates) {
|
|
|
90
97
|
})[0];
|
|
91
98
|
}
|
|
92
99
|
async function findTopicsByScopeAlias(ctx, scopeId) {
|
|
100
|
+
const query2 = ctx.db.query("topics");
|
|
93
101
|
try {
|
|
94
|
-
return await
|
|
102
|
+
return await query2.withIndex(
|
|
95
103
|
"by_graph_scope_project",
|
|
96
104
|
(q) => q.eq(LEGACY_SCOPE_FIELD, scopeId)
|
|
97
105
|
).collect();
|
|
@@ -103,7 +111,7 @@ async function findTopicsByScopeAlias(ctx, scopeId) {
|
|
|
103
111
|
scopeId
|
|
104
112
|
}
|
|
105
113
|
);
|
|
106
|
-
const topics = await
|
|
114
|
+
const topics = await query2.collect();
|
|
107
115
|
return topics.filter((topic) => {
|
|
108
116
|
const normalizedGlobalId = normalizeScopeValue(topic.globalId);
|
|
109
117
|
const mappedProjectId = asMappedProjectId(topic);
|
|
@@ -159,137 +167,115 @@ async function resolveInheritedWorkspaceScope(ctx, topic) {
|
|
|
159
167
|
let current = topic;
|
|
160
168
|
for (let i = 0; i < MAX_DEPTH && current?.parentTopicId; i++) {
|
|
161
169
|
current = await ctx.db.get(current.parentTopicId);
|
|
162
|
-
if (!current)
|
|
170
|
+
if (!current) {
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
163
173
|
if (!tenantId) {
|
|
164
174
|
tenantId = normalizeScopeValue(current.tenantId);
|
|
165
175
|
}
|
|
166
176
|
if (!workspaceId) {
|
|
167
177
|
workspaceId = normalizeScopeValue(current.workspaceId);
|
|
168
178
|
}
|
|
169
|
-
if (tenantId && workspaceId)
|
|
179
|
+
if (tenantId && workspaceId) {
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
170
182
|
}
|
|
171
183
|
return { tenantId, workspaceId };
|
|
172
184
|
}
|
|
173
185
|
async function resolveTopicProjectScope(ctx, args) {
|
|
174
186
|
if (args.topicId) {
|
|
175
|
-
|
|
176
|
-
try {
|
|
177
|
-
topic = await ctx.db.get(
|
|
178
|
-
args.topicId
|
|
179
|
-
);
|
|
180
|
-
} catch (error) {
|
|
181
|
-
debugGraphPrimitiveFallback(
|
|
182
|
-
"[topicScope] Failed to load topic by direct id",
|
|
183
|
-
{
|
|
184
|
-
error,
|
|
185
|
-
topicId: args.topicId
|
|
186
|
-
}
|
|
187
|
-
);
|
|
188
|
-
}
|
|
189
|
-
if (!topic) {
|
|
190
|
-
topic = await tryResolveHostTopicById(ctx, String(args.topicId));
|
|
191
|
-
}
|
|
192
|
-
if (!topic) {
|
|
193
|
-
topic = pickPrimaryTopic(
|
|
194
|
-
await findTopicsByScopeAlias(ctx, String(args.topicId))
|
|
195
|
-
) ?? null;
|
|
196
|
-
}
|
|
197
|
-
if (!topic) {
|
|
198
|
-
const nodeScope = await resolveTopicNodeScopeOrNull(
|
|
199
|
-
ctx,
|
|
200
|
-
String(args.topicId)
|
|
201
|
-
);
|
|
202
|
-
if (nodeScope) {
|
|
203
|
-
return nodeScope;
|
|
204
|
-
}
|
|
205
|
-
throw new Error(`Topic not found: ${String(args.topicId)}`);
|
|
206
|
-
}
|
|
207
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
|
|
208
|
-
const mapped = asMappedProjectId(topic);
|
|
209
|
-
if (mapped) {
|
|
210
|
-
return {
|
|
211
|
-
topicId: topic._id,
|
|
212
|
-
projectId: mapped,
|
|
213
|
-
tenantId: inherited.tenantId,
|
|
214
|
-
workspaceId: inherited.workspaceId,
|
|
215
|
-
source: "topic"
|
|
216
|
-
};
|
|
217
|
-
}
|
|
218
|
-
return {
|
|
219
|
-
topicId: topic._id,
|
|
220
|
-
tenantId: inherited.tenantId,
|
|
221
|
-
workspaceId: inherited.workspaceId,
|
|
222
|
-
source: "topic"
|
|
223
|
-
};
|
|
187
|
+
return await resolveScopeFromTopicId(ctx, args.topicId);
|
|
224
188
|
}
|
|
225
189
|
if (args.projectId) {
|
|
226
|
-
|
|
227
|
-
try {
|
|
228
|
-
directTopic = await ctx.db.get(
|
|
229
|
-
args.projectId
|
|
230
|
-
);
|
|
231
|
-
} catch (error) {
|
|
232
|
-
debugGraphPrimitiveFallback(
|
|
233
|
-
"[topicScope] Failed to load direct project topic",
|
|
234
|
-
{
|
|
235
|
-
error,
|
|
236
|
-
projectId: args.projectId
|
|
237
|
-
}
|
|
238
|
-
);
|
|
239
|
-
}
|
|
240
|
-
if (directTopic) {
|
|
241
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
|
|
242
|
-
const mapped = asMappedProjectId(directTopic);
|
|
243
|
-
return {
|
|
244
|
-
topicId: directTopic._id,
|
|
245
|
-
projectId: mapped ?? args.projectId,
|
|
246
|
-
tenantId: inherited.tenantId,
|
|
247
|
-
workspaceId: inherited.workspaceId,
|
|
248
|
-
source: "topic_inferred"
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
directTopic = await tryResolveHostTopicByLegacyScope(ctx, args.projectId);
|
|
252
|
-
if (directTopic) {
|
|
253
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
|
|
254
|
-
const mapped = asMappedProjectId(directTopic);
|
|
255
|
-
return {
|
|
256
|
-
topicId: directTopic._id,
|
|
257
|
-
projectId: mapped ?? args.projectId,
|
|
258
|
-
tenantId: inherited.tenantId,
|
|
259
|
-
workspaceId: inherited.workspaceId,
|
|
260
|
-
source: "topic_inferred"
|
|
261
|
-
};
|
|
262
|
-
}
|
|
263
|
-
const topics = await findTopicsByScopeAlias(ctx, args.projectId);
|
|
264
|
-
const primary = pickPrimaryTopic(topics);
|
|
265
|
-
if (primary) {
|
|
266
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, primary);
|
|
267
|
-
return {
|
|
268
|
-
topicId: primary._id,
|
|
269
|
-
projectId: args.projectId,
|
|
270
|
-
tenantId: inherited.tenantId,
|
|
271
|
-
workspaceId: inherited.workspaceId,
|
|
272
|
-
source: "project_mapped_topic"
|
|
273
|
-
};
|
|
274
|
-
}
|
|
275
|
-
const nodeScope = await resolveTopicNodeScopeOrNull(
|
|
276
|
-
ctx,
|
|
277
|
-
String(args.projectId)
|
|
278
|
-
);
|
|
279
|
-
if (nodeScope) {
|
|
280
|
-
return {
|
|
281
|
-
...nodeScope,
|
|
282
|
-
projectId: nodeScope.projectId ?? String(args.projectId)
|
|
283
|
-
};
|
|
284
|
-
}
|
|
285
|
-
throw new Error(
|
|
286
|
-
`Legacy project scope ${String(args.projectId)} has no mapped topic.`
|
|
287
|
-
);
|
|
190
|
+
return await resolveScopeFromLegacyProjectId(ctx, args.projectId);
|
|
288
191
|
}
|
|
289
192
|
throw new Error(
|
|
290
193
|
"Missing scope: provide topicId (preferred) or legacy projectId alias."
|
|
291
194
|
);
|
|
292
195
|
}
|
|
196
|
+
async function resolveScopeFromTopicId(ctx, topicId) {
|
|
197
|
+
const topic = await resolveTopicDocFromTopicId(ctx, topicId);
|
|
198
|
+
if (topic) {
|
|
199
|
+
return await buildTopicScope(ctx, topic, "topic");
|
|
200
|
+
}
|
|
201
|
+
const nodeScope = await resolveTopicNodeScopeOrNull(ctx, String(topicId));
|
|
202
|
+
if (nodeScope) {
|
|
203
|
+
return nodeScope;
|
|
204
|
+
}
|
|
205
|
+
throw new Error(`Topic not found: ${String(topicId)}`);
|
|
206
|
+
}
|
|
207
|
+
async function resolveTopicDocFromTopicId(ctx, topicId) {
|
|
208
|
+
const direct = await tryReadTopicDoc(ctx, topicId, {
|
|
209
|
+
failureLog: "[topicScope] Failed to load topic by direct id",
|
|
210
|
+
idLogKey: "topicId"
|
|
211
|
+
});
|
|
212
|
+
if (direct) {
|
|
213
|
+
return direct;
|
|
214
|
+
}
|
|
215
|
+
const hostTopic = await tryResolveHostTopicById(ctx, String(topicId));
|
|
216
|
+
if (hostTopic) {
|
|
217
|
+
return hostTopic;
|
|
218
|
+
}
|
|
219
|
+
return pickPrimaryTopic(await findTopicsByScopeAlias(ctx, String(topicId))) ?? null;
|
|
220
|
+
}
|
|
221
|
+
async function resolveScopeFromLegacyProjectId(ctx, legacyProjectId) {
|
|
222
|
+
const directTopic = await resolveDirectLegacyProjectTopic(
|
|
223
|
+
ctx,
|
|
224
|
+
legacyProjectId
|
|
225
|
+
);
|
|
226
|
+
if (directTopic) {
|
|
227
|
+
return await buildTopicScope(ctx, directTopic, "topic_inferred", {
|
|
228
|
+
fallbackProjectId: legacyProjectId
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
const primary = pickPrimaryTopic(
|
|
232
|
+
await findTopicsByScopeAlias(ctx, legacyProjectId)
|
|
233
|
+
);
|
|
234
|
+
if (primary) {
|
|
235
|
+
return await buildTopicScope(ctx, primary, "project_mapped_topic", {
|
|
236
|
+
fallbackProjectId: legacyProjectId
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
const nodeScope = await resolveTopicNodeScopeOrNull(ctx, legacyProjectId);
|
|
240
|
+
if (nodeScope) {
|
|
241
|
+
return {
|
|
242
|
+
...nodeScope,
|
|
243
|
+
projectId: nodeScope.projectId ?? legacyProjectId
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
throw new Error(
|
|
247
|
+
`Legacy project scope ${legacyProjectId} has no mapped topic.`
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
async function resolveDirectLegacyProjectTopic(ctx, legacyProjectId) {
|
|
251
|
+
const directTopic = await tryReadTopicDoc(ctx, legacyProjectId, {
|
|
252
|
+
failureLog: "[topicScope] Failed to load direct project topic",
|
|
253
|
+
idLogKey: "projectId"
|
|
254
|
+
});
|
|
255
|
+
return directTopic ?? tryResolveHostTopicByLegacyScope(ctx, legacyProjectId);
|
|
256
|
+
}
|
|
257
|
+
async function tryReadTopicDoc(ctx, id, log) {
|
|
258
|
+
try {
|
|
259
|
+
return await ctx.db.get(id);
|
|
260
|
+
} catch (error) {
|
|
261
|
+
debugGraphPrimitiveFallback(log.failureLog, {
|
|
262
|
+
error,
|
|
263
|
+
[log.idLogKey]: id
|
|
264
|
+
});
|
|
265
|
+
return null;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
async function buildTopicScope(ctx, topic, source, options = {}) {
|
|
269
|
+
const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
|
|
270
|
+
const mapped = asMappedProjectId(topic);
|
|
271
|
+
return {
|
|
272
|
+
topicId: topic._id,
|
|
273
|
+
...mapped || options.fallbackProjectId ? { projectId: mapped ?? options.fallbackProjectId } : {},
|
|
274
|
+
tenantId: inherited.tenantId,
|
|
275
|
+
workspaceId: inherited.workspaceId,
|
|
276
|
+
source
|
|
277
|
+
};
|
|
278
|
+
}
|
|
293
279
|
var optionalScopeArgs = {
|
|
294
280
|
projectId: v.optional(v.string()),
|
|
295
281
|
topicId: v.optional(v.string())
|
|
@@ -324,8 +310,6 @@ function nodeMatchesWorkspaceReasoningScope(node, scope) {
|
|
|
324
310
|
}
|
|
325
311
|
return scopeWorkspaceId === nodeWorkspaceId;
|
|
326
312
|
}
|
|
327
|
-
|
|
328
|
-
// src/epistemicBeliefs.helpers.ts
|
|
329
313
|
v.id("epistemicNodes");
|
|
330
314
|
var DEFAULT_PROJECT_BELIEF_LIMIT = 250;
|
|
331
315
|
var MAX_PROJECT_BELIEF_LIMIT = 1e3;
|
|
@@ -333,25 +317,119 @@ var optionalBeliefScopeArgs = optionalScopeArgs;
|
|
|
333
317
|
({
|
|
334
318
|
tupleContradiction: normalizeTupleContradictionPolicy()
|
|
335
319
|
});
|
|
336
|
-
function
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
320
|
+
function readFiniteNumber(value) {
|
|
321
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
322
|
+
}
|
|
323
|
+
function isRecord(value) {
|
|
324
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
325
|
+
}
|
|
326
|
+
function readOptionalString(value) {
|
|
327
|
+
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
328
|
+
}
|
|
329
|
+
function readStringArray(value) {
|
|
330
|
+
if (!Array.isArray(value)) {
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
const strings = value.filter(
|
|
334
|
+
(item) => typeof item === "string" && item.length > 0
|
|
348
335
|
);
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
336
|
+
return strings.length === value.length ? strings : void 0;
|
|
337
|
+
}
|
|
338
|
+
function readRecord(value) {
|
|
339
|
+
return isRecord(value) ? value : void 0;
|
|
340
|
+
}
|
|
341
|
+
function readBeliefNodeView(value) {
|
|
342
|
+
if (!isRecord(value)) {
|
|
343
|
+
return null;
|
|
344
|
+
}
|
|
345
|
+
const id = readOptionalString(value._id);
|
|
346
|
+
const nodeType = readOptionalString(value.nodeType);
|
|
347
|
+
if (!(id && nodeType === "belief")) {
|
|
348
|
+
return null;
|
|
349
|
+
}
|
|
350
|
+
const node = {
|
|
351
|
+
_id: id,
|
|
352
|
+
nodeType
|
|
353
|
+
};
|
|
354
|
+
const creationTime = readFiniteNumber(value._creationTime);
|
|
355
|
+
if (creationTime !== void 0) {
|
|
356
|
+
node._creationTime = creationTime;
|
|
357
|
+
}
|
|
358
|
+
const metadata = readRecord(value.metadata);
|
|
359
|
+
if (metadata !== void 0) {
|
|
360
|
+
node.metadata = metadata;
|
|
361
|
+
}
|
|
362
|
+
const opinionA = readFiniteNumber(value.opinion_a);
|
|
363
|
+
if (opinionA !== void 0) {
|
|
364
|
+
node.opinion_a = opinionA;
|
|
365
|
+
}
|
|
366
|
+
const opinionB = readFiniteNumber(value.opinion_b);
|
|
367
|
+
if (opinionB !== void 0) {
|
|
368
|
+
node.opinion_b = opinionB;
|
|
369
|
+
}
|
|
370
|
+
const opinionD = readFiniteNumber(value.opinion_d);
|
|
371
|
+
if (opinionD !== void 0) {
|
|
372
|
+
node.opinion_d = opinionD;
|
|
373
|
+
}
|
|
374
|
+
const opinionU = readFiniteNumber(value.opinion_u);
|
|
375
|
+
if (opinionU !== void 0) {
|
|
376
|
+
node.opinion_u = opinionU;
|
|
377
|
+
}
|
|
378
|
+
const tupleContradicted = typeof value.tupleContradicted === "boolean" ? value.tupleContradicted : void 0;
|
|
379
|
+
if (tupleContradicted !== void 0) {
|
|
380
|
+
node.tupleContradicted = tupleContradicted;
|
|
381
|
+
}
|
|
382
|
+
const stringFields = {
|
|
383
|
+
anonymizationClass: value.anonymizationClass,
|
|
384
|
+
audienceLabel: value.audienceLabel,
|
|
385
|
+
canonicalText: value.canonicalText,
|
|
386
|
+
createdBy: value.createdBy,
|
|
387
|
+
epistemicLayer: value.epistemicLayer,
|
|
388
|
+
exportClass: value.exportClass,
|
|
389
|
+
globalId: value.globalId,
|
|
390
|
+
projectId: value.projectId,
|
|
391
|
+
publicationStatus: value.publicationStatus,
|
|
392
|
+
sensitivityTier: value.sensitivityTier,
|
|
393
|
+
status: value.status,
|
|
394
|
+
tenantId: value.tenantId,
|
|
395
|
+
topicId: value.topicId,
|
|
396
|
+
userId: value.userId,
|
|
397
|
+
workspaceId: value.workspaceId
|
|
398
|
+
};
|
|
399
|
+
for (const [field, fieldValue] of Object.entries(stringFields)) {
|
|
400
|
+
const normalized = readOptionalString(fieldValue);
|
|
401
|
+
if (normalized !== void 0) {
|
|
402
|
+
node[field] = normalized;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
const createdAt = readFiniteNumber(value.createdAt);
|
|
406
|
+
if (createdAt !== void 0) {
|
|
407
|
+
node.createdAt = createdAt;
|
|
408
|
+
}
|
|
409
|
+
const updatedAt = readFiniteNumber(value.updatedAt);
|
|
410
|
+
if (updatedAt !== void 0) {
|
|
411
|
+
node.updatedAt = updatedAt;
|
|
412
|
+
}
|
|
413
|
+
if (value.beliefStatus !== void 0) {
|
|
414
|
+
node.beliefStatus = value.beliefStatus;
|
|
415
|
+
}
|
|
416
|
+
if (value.confidence !== void 0) {
|
|
417
|
+
node.confidence = value.confidence;
|
|
418
|
+
}
|
|
419
|
+
if (value.predictionMeta !== void 0) {
|
|
420
|
+
node.predictionMeta = value.predictionMeta;
|
|
421
|
+
}
|
|
422
|
+
const policyTags = readStringArray(value.policyTags);
|
|
423
|
+
if (policyTags !== void 0) {
|
|
424
|
+
node.policyTags = policyTags;
|
|
425
|
+
}
|
|
426
|
+
return node;
|
|
427
|
+
}
|
|
428
|
+
function readBeliefNodeViews(values) {
|
|
429
|
+
return values.flatMap((value) => {
|
|
430
|
+
const node = readBeliefNodeView(value);
|
|
431
|
+
return node ? [node] : [];
|
|
432
|
+
});
|
|
355
433
|
}
|
|
356
434
|
function buildBeliefStatusSuccessResult() {
|
|
357
435
|
return { success: true };
|
|
@@ -366,7 +444,7 @@ function clampBeliefLimit(limit, fallback = DEFAULT_PROJECT_BELIEF_LIMIT) {
|
|
|
366
444
|
);
|
|
367
445
|
}
|
|
368
446
|
async function resolveBeliefScopeOrNull(ctx, args) {
|
|
369
|
-
if (!args.projectId
|
|
447
|
+
if (!(args.projectId || args.topicId)) {
|
|
370
448
|
return null;
|
|
371
449
|
}
|
|
372
450
|
try {
|
|
@@ -391,14 +469,17 @@ async function getBeliefNodesForScope(ctx, scope, args) {
|
|
|
391
469
|
"by_topic_type",
|
|
392
470
|
(q) => q.eq("topicId", scope.topicId).eq("nodeType", "belief")
|
|
393
471
|
);
|
|
394
|
-
const
|
|
472
|
+
const rows = typeof args?.scanLimit === "number" ? await baseQuery.order("desc").take(args.scanLimit) : await baseQuery.collect();
|
|
473
|
+
const nodes = readBeliefNodeViews(rows);
|
|
395
474
|
const scopedNodes = nodes.filter(
|
|
396
475
|
(node) => nodeMatchesWorkspaceReasoningScope(node, scope)
|
|
397
476
|
);
|
|
398
477
|
if (!args?.status) {
|
|
399
478
|
return scopedNodes;
|
|
400
479
|
}
|
|
401
|
-
return scopedNodes.filter(
|
|
480
|
+
return scopedNodes.filter(
|
|
481
|
+
(node) => node.status === args.status
|
|
482
|
+
);
|
|
402
483
|
}
|
|
403
484
|
async function requireAuthenticatedUserId(ctx) {
|
|
404
485
|
const userId = await getCurrentUserId(
|
|
@@ -415,25 +496,105 @@ async function requireAuthenticatedUserId(ctx) {
|
|
|
415
496
|
}
|
|
416
497
|
return userId;
|
|
417
498
|
}
|
|
418
|
-
async function requireProjectWriteAccess(ctx, projectId, userId) {
|
|
419
|
-
const hasAccess = await checkProjectAccess(
|
|
420
|
-
ctx,
|
|
421
|
-
projectId,
|
|
422
|
-
userId
|
|
423
|
-
);
|
|
424
|
-
if (!hasAccess) {
|
|
425
|
-
throwStructuredMutationError({
|
|
426
|
-
message: `Project write access denied for topic ${projectId}.`,
|
|
427
|
-
status: 403,
|
|
428
|
-
code: "PROJECT_ACCESS_DENIED",
|
|
429
|
-
invariantCode: "policy.scope_required",
|
|
430
|
-
suggestion: "The acting principal lacks project-write access to this topic. Request a topic grant (or, if the principal created this topic, run the creator-grant backfill) and retry.",
|
|
431
|
-
details: { topicId: projectId, principalId: userId }
|
|
432
|
-
});
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
499
|
|
|
436
500
|
// src/epistemicBeliefs.admin.ts
|
|
501
|
+
function worktreeId(value) {
|
|
502
|
+
return value;
|
|
503
|
+
}
|
|
504
|
+
function isRecord2(value) {
|
|
505
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
506
|
+
}
|
|
507
|
+
function readConvexId(value) {
|
|
508
|
+
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
509
|
+
}
|
|
510
|
+
function readOptionalNumber(value) {
|
|
511
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
512
|
+
}
|
|
513
|
+
function readOptionalString2(value) {
|
|
514
|
+
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
515
|
+
}
|
|
516
|
+
function readRecord2(value) {
|
|
517
|
+
return isRecord2(value) ? value : void 0;
|
|
518
|
+
}
|
|
519
|
+
function readBeliefAdminNode(value) {
|
|
520
|
+
if (!isRecord2(value)) {
|
|
521
|
+
return null;
|
|
522
|
+
}
|
|
523
|
+
const id = readConvexId(value._id);
|
|
524
|
+
if (!id) {
|
|
525
|
+
return null;
|
|
526
|
+
}
|
|
527
|
+
const node = { _id: id };
|
|
528
|
+
const metadata = readRecord2(value.metadata);
|
|
529
|
+
const nodeType = readOptionalString2(value.nodeType);
|
|
530
|
+
const projectId = readOptionalString2(value.projectId);
|
|
531
|
+
const status = readOptionalString2(value.status);
|
|
532
|
+
if (metadata !== void 0) {
|
|
533
|
+
node.metadata = metadata;
|
|
534
|
+
}
|
|
535
|
+
if (nodeType !== void 0) {
|
|
536
|
+
node.nodeType = nodeType;
|
|
537
|
+
}
|
|
538
|
+
if (projectId !== void 0) {
|
|
539
|
+
node.projectId = projectId;
|
|
540
|
+
}
|
|
541
|
+
if (status !== void 0) {
|
|
542
|
+
node.status = status;
|
|
543
|
+
}
|
|
544
|
+
return node;
|
|
545
|
+
}
|
|
546
|
+
function readBeliefAdminEdge(value) {
|
|
547
|
+
if (!isRecord2(value)) {
|
|
548
|
+
return null;
|
|
549
|
+
}
|
|
550
|
+
const id = readConvexId(value._id);
|
|
551
|
+
if (!id) {
|
|
552
|
+
return null;
|
|
553
|
+
}
|
|
554
|
+
const edge = { _id: id };
|
|
555
|
+
const context = readOptionalString2(value.context);
|
|
556
|
+
const edgeType = readOptionalString2(value.edgeType);
|
|
557
|
+
const fromNodeId = readConvexId(value.fromNodeId);
|
|
558
|
+
const globalId = readOptionalString2(value.globalId);
|
|
559
|
+
const projectId = readOptionalString2(value.projectId);
|
|
560
|
+
const toNodeId = readConvexId(value.toNodeId);
|
|
561
|
+
const weight = readOptionalNumber(value.weight);
|
|
562
|
+
if (context !== void 0) {
|
|
563
|
+
edge.context = context;
|
|
564
|
+
}
|
|
565
|
+
if (edgeType !== void 0) {
|
|
566
|
+
edge.edgeType = edgeType;
|
|
567
|
+
}
|
|
568
|
+
if (fromNodeId !== void 0) {
|
|
569
|
+
edge.fromNodeId = fromNodeId;
|
|
570
|
+
}
|
|
571
|
+
if (globalId !== void 0) {
|
|
572
|
+
edge.globalId = globalId;
|
|
573
|
+
}
|
|
574
|
+
if (projectId !== void 0) {
|
|
575
|
+
edge.projectId = projectId;
|
|
576
|
+
}
|
|
577
|
+
if (toNodeId !== void 0) {
|
|
578
|
+
edge.toNodeId = toNodeId;
|
|
579
|
+
}
|
|
580
|
+
if (weight !== void 0) {
|
|
581
|
+
edge.weight = weight;
|
|
582
|
+
}
|
|
583
|
+
return edge;
|
|
584
|
+
}
|
|
585
|
+
function readWorktreeBeliefClusterLink(value) {
|
|
586
|
+
if (!isRecord2(value)) {
|
|
587
|
+
return null;
|
|
588
|
+
}
|
|
589
|
+
const beliefId = readConvexId(value.beliefId);
|
|
590
|
+
return beliefId ? { beliefId } : null;
|
|
591
|
+
}
|
|
592
|
+
function readRowList(values, reader) {
|
|
593
|
+
return values.flatMap((value) => {
|
|
594
|
+
const row = reader(value);
|
|
595
|
+
return row ? [row] : [];
|
|
596
|
+
});
|
|
597
|
+
}
|
|
437
598
|
var deleteRelationship = mutation({
|
|
438
599
|
args: {
|
|
439
600
|
edgeId: v.id("epistemicEdges"),
|
|
@@ -443,26 +604,26 @@ var deleteRelationship = mutation({
|
|
|
443
604
|
handler: async (ctx, args) => {
|
|
444
605
|
const authenticatedUserId = await requireAuthenticatedUserId(ctx);
|
|
445
606
|
const now = Date.now();
|
|
446
|
-
const edge = await ctx.db.get(args.edgeId);
|
|
607
|
+
const edge = readBeliefAdminEdge(await ctx.db.get(args.edgeId));
|
|
447
608
|
if (!edge) {
|
|
448
609
|
throw new Error("Edge not found");
|
|
449
610
|
}
|
|
450
611
|
if (!edge.projectId) {
|
|
451
612
|
throw new Error("Edge has no project scope");
|
|
452
613
|
}
|
|
453
|
-
await
|
|
614
|
+
await requireScopeWriteAccess(ctx, edge.projectId, authenticatedUserId);
|
|
454
615
|
const previousState = {
|
|
455
616
|
fromNodeId: edge.fromNodeId,
|
|
456
617
|
toNodeId: edge.toNodeId,
|
|
457
618
|
edgeType: edge.edgeType
|
|
458
619
|
};
|
|
459
620
|
await ctx.scheduler.runAfter(0, internal.neo4jEdgeAPI.deleteEdge, {
|
|
460
|
-
globalId: edge.globalId
|
|
621
|
+
globalId: edge.globalId ?? String(args.edgeId)
|
|
461
622
|
});
|
|
462
623
|
await ctx.db.delete(args.edgeId);
|
|
463
624
|
await ctx.db.insert("epistemicAudit", {
|
|
464
625
|
entityType: "edge",
|
|
465
|
-
entityId: edge.globalId,
|
|
626
|
+
entityId: edge.globalId ?? String(args.edgeId),
|
|
466
627
|
changeType: "edge_removed",
|
|
467
628
|
previousState,
|
|
468
629
|
newState: null,
|
|
@@ -490,15 +651,15 @@ var updateCriticality = mutation({
|
|
|
490
651
|
handler: async (ctx, args) => {
|
|
491
652
|
const authenticatedUserId = await requireAuthenticatedUserId(ctx);
|
|
492
653
|
const now = Date.now();
|
|
493
|
-
const node = await ctx.db.get(args.nodeId);
|
|
494
|
-
if (
|
|
654
|
+
const node = readBeliefAdminNode(await ctx.db.get(args.nodeId));
|
|
655
|
+
if (node?.nodeType !== "belief") {
|
|
495
656
|
throw new Error("Belief not found");
|
|
496
657
|
}
|
|
497
658
|
if (!node.projectId) {
|
|
498
659
|
throw new Error("Belief has no project scope");
|
|
499
660
|
}
|
|
500
|
-
await
|
|
501
|
-
const metadata = node.metadata
|
|
661
|
+
await requireScopeWriteAccess(ctx, node.projectId, authenticatedUserId);
|
|
662
|
+
const metadata = node.metadata ?? {};
|
|
502
663
|
const previousCriticality = metadata.criticality;
|
|
503
664
|
await ctx.db.patch(args.nodeId, {
|
|
504
665
|
metadata: {
|
|
@@ -557,8 +718,8 @@ var batchUpdateCriticality = mutation({
|
|
|
557
718
|
const results = [];
|
|
558
719
|
for (const update of args.updates) {
|
|
559
720
|
try {
|
|
560
|
-
const node = await ctx.db.get(update.beliefId);
|
|
561
|
-
if (
|
|
721
|
+
const node = readBeliefAdminNode(await ctx.db.get(update.beliefId));
|
|
722
|
+
if (node?.nodeType !== "belief") {
|
|
562
723
|
results.push({ beliefId: update.beliefId, success: false });
|
|
563
724
|
continue;
|
|
564
725
|
}
|
|
@@ -566,12 +727,8 @@ var batchUpdateCriticality = mutation({
|
|
|
566
727
|
results.push({ beliefId: update.beliefId, success: false });
|
|
567
728
|
continue;
|
|
568
729
|
}
|
|
569
|
-
await
|
|
570
|
-
|
|
571
|
-
node.projectId,
|
|
572
|
-
authenticatedUserId
|
|
573
|
-
);
|
|
574
|
-
const metadata = node.metadata || {};
|
|
730
|
+
await requireScopeWriteAccess(ctx, node.projectId, authenticatedUserId);
|
|
731
|
+
const metadata = node.metadata ?? {};
|
|
575
732
|
const previousCriticality = metadata.criticality;
|
|
576
733
|
await ctx.db.patch(node._id, {
|
|
577
734
|
metadata: {
|
|
@@ -600,11 +757,11 @@ var batchUpdateCriticality = mutation({
|
|
|
600
757
|
changedAt: now,
|
|
601
758
|
projectId: node.projectId
|
|
602
759
|
});
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
760
|
+
results.push({
|
|
761
|
+
beliefId: update.beliefId,
|
|
762
|
+
nodeId: node._id,
|
|
763
|
+
success: true
|
|
764
|
+
});
|
|
608
765
|
} catch (error) {
|
|
609
766
|
debugGraphPrimitiveFallback(
|
|
610
767
|
"[epistemicBeliefs] Failed to update belief criticality",
|
|
@@ -613,10 +770,7 @@ var batchUpdateCriticality = mutation({
|
|
|
613
770
|
beliefId: update.beliefId
|
|
614
771
|
}
|
|
615
772
|
);
|
|
616
|
-
|
|
617
|
-
result.beliefId = update.beliefId;
|
|
618
|
-
result.success = false;
|
|
619
|
-
results.push(result);
|
|
773
|
+
results.push({ beliefId: update.beliefId, success: false });
|
|
620
774
|
}
|
|
621
775
|
}
|
|
622
776
|
return { results, updatedCount: results.filter((r) => r.success).length };
|
|
@@ -641,7 +795,7 @@ var getByCriticality = query({
|
|
|
641
795
|
}
|
|
642
796
|
const nodes = await getBeliefNodesForScope(ctx, scope);
|
|
643
797
|
return nodes.filter((n) => {
|
|
644
|
-
const metadata = n.metadata;
|
|
798
|
+
const metadata = readRecord2(n.metadata);
|
|
645
799
|
return metadata?.criticality === args.criticality && n.status === "active";
|
|
646
800
|
});
|
|
647
801
|
}
|
|
@@ -660,7 +814,7 @@ var getUnanalyzed = query({
|
|
|
660
814
|
}
|
|
661
815
|
const nodes = await getBeliefNodesForScope(ctx, scope);
|
|
662
816
|
const unanalyzed = nodes.filter((n) => {
|
|
663
|
-
const metadata = n.metadata;
|
|
817
|
+
const metadata = readRecord2(n.metadata);
|
|
664
818
|
return !metadata?.criticality && n.status === "active";
|
|
665
819
|
});
|
|
666
820
|
return unanalyzed.slice(0, limit);
|
|
@@ -722,7 +876,7 @@ var getByPillar = query({
|
|
|
722
876
|
},
|
|
723
877
|
returns: permissiveReturn,
|
|
724
878
|
handler: async (ctx, args) => {
|
|
725
|
-
if (!args.projectId
|
|
879
|
+
if (!(args.projectId || args.topicId)) {
|
|
726
880
|
return [];
|
|
727
881
|
}
|
|
728
882
|
let scope;
|
|
@@ -742,10 +896,13 @@ var getByPillar = query({
|
|
|
742
896
|
);
|
|
743
897
|
return [];
|
|
744
898
|
}
|
|
745
|
-
const nodes =
|
|
746
|
-
"
|
|
747
|
-
|
|
748
|
-
|
|
899
|
+
const nodes = readRowList(
|
|
900
|
+
await ctx.db.query("epistemicNodes").withIndex(
|
|
901
|
+
"by_topic_type",
|
|
902
|
+
(q) => q.eq("topicId", scope.topicId).eq("nodeType", "belief")
|
|
903
|
+
).collect(),
|
|
904
|
+
readBeliefAdminNode
|
|
905
|
+
);
|
|
749
906
|
return nodes.filter((n) => {
|
|
750
907
|
const metadata = n.metadata;
|
|
751
908
|
const matchesPillar = metadata?.pillar === args.pillar;
|
|
@@ -761,24 +918,30 @@ var getWorktreeCluster = query({
|
|
|
761
918
|
},
|
|
762
919
|
returns: permissiveReturn,
|
|
763
920
|
handler: async (ctx, args) => {
|
|
764
|
-
const worktree = await ctx.db.get(args.worktreeId);
|
|
921
|
+
const worktree = await ctx.db.get(worktreeId(args.worktreeId));
|
|
765
922
|
if (!worktree) {
|
|
766
923
|
return { beliefs: [], edges: [], beliefCount: 0 };
|
|
767
924
|
}
|
|
768
|
-
const clusterLinks =
|
|
925
|
+
const clusterLinks = readRowList(
|
|
926
|
+
await ctx.db.query("worktreeBeliefCluster").withIndex("by_worktree", (q) => q.eq("worktreeId", args.worktreeId)).collect(),
|
|
927
|
+
readWorktreeBeliefClusterLink
|
|
928
|
+
);
|
|
769
929
|
const beliefIds = new Set(clusterLinks.map((l) => String(l.beliefId)));
|
|
770
930
|
const beliefs = [];
|
|
771
931
|
for (const link of clusterLinks) {
|
|
772
|
-
const node = await ctx.db.get(link.beliefId);
|
|
773
|
-
if (node)
|
|
932
|
+
const node = readBeliefAdminNode(await ctx.db.get(link.beliefId));
|
|
933
|
+
if (node) {
|
|
934
|
+
beliefs.push(node);
|
|
935
|
+
}
|
|
774
936
|
}
|
|
775
937
|
const clusterEdges = [];
|
|
776
938
|
for (const beliefId of beliefIds) {
|
|
777
|
-
const outEdges =
|
|
778
|
-
(q) => q.eq(q.field("fromNodeId"), beliefId)
|
|
779
|
-
|
|
939
|
+
const outEdges = readRowList(
|
|
940
|
+
await ctx.db.query("epistemicEdges").filter((q) => q.eq(q.field("fromNodeId"), beliefId)).collect(),
|
|
941
|
+
readBeliefAdminEdge
|
|
942
|
+
);
|
|
780
943
|
for (const edge of outEdges) {
|
|
781
|
-
if (beliefIds.has(String(edge.toNodeId))) {
|
|
944
|
+
if (edge.fromNodeId && edge.toNodeId && edge.edgeType && beliefIds.has(String(edge.toNodeId))) {
|
|
782
945
|
clusterEdges.push({
|
|
783
946
|
fromNodeId: String(edge.fromNodeId),
|
|
784
947
|
toNodeId: String(edge.toNodeId),
|