@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
package/dist/contradictions.js
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
import { v } from 'convex/values';
|
|
2
|
-
import { componentsGeneric, anyApi, queryGeneric, mutationGeneric } from 'convex/server';
|
|
3
1
|
import { checkProjectAccess, requireScopeWriteAccess } from '@lucern/access-control/access';
|
|
4
2
|
import { permissiveReturn } from '@lucern/contracts/schema-helpers/validators';
|
|
3
|
+
import { v } from 'convex/values';
|
|
4
|
+
import { unsafeConvexAnyApi } from '@lucern/contracts/convex/unsafeAnyApi';
|
|
5
|
+
import { componentsGeneric, queryGeneric, mutationGeneric } from 'convex/server';
|
|
5
6
|
|
|
6
7
|
// src/contradictions.ts
|
|
7
|
-
var
|
|
8
|
+
var unsafeApi = unsafeConvexAnyApi(
|
|
9
|
+
"graph-primitives top-level module bundle lacks a committed Convex _generated/api surface"
|
|
10
|
+
);
|
|
11
|
+
var api = unsafeApi;
|
|
8
12
|
componentsGeneric();
|
|
9
|
-
var internal =
|
|
13
|
+
var internal = unsafeApi;
|
|
10
14
|
var mutation = mutationGeneric;
|
|
11
15
|
var query = queryGeneric;
|
|
12
16
|
|
|
@@ -21,8 +25,6 @@ function debugGraphPrimitiveFallback(message, context) {
|
|
|
21
25
|
}
|
|
22
26
|
console.debug(message, context ?? {});
|
|
23
27
|
}
|
|
24
|
-
|
|
25
|
-
// src/topicScope.ts
|
|
26
28
|
var LEGACY_SCOPE_FIELD = "graphScopeProjectId";
|
|
27
29
|
async function resolveTopicNodeScopeOrNull(ctx, ref) {
|
|
28
30
|
if (!ctx?.db || typeof ctx.db.query !== "function") {
|
|
@@ -57,13 +59,15 @@ function asMappedProjectId(topic) {
|
|
|
57
59
|
if (!topic) {
|
|
58
60
|
return;
|
|
59
61
|
}
|
|
60
|
-
const directLegacyProjectId = normalizeScopeValue(
|
|
62
|
+
const directLegacyProjectId = normalizeScopeValue(
|
|
63
|
+
topic[LEGACY_SCOPE_FIELD]
|
|
64
|
+
);
|
|
61
65
|
if (directLegacyProjectId) {
|
|
62
66
|
return directLegacyProjectId;
|
|
63
67
|
}
|
|
64
68
|
const metadata = topic.metadata || {};
|
|
65
69
|
const candidate = metadata[LEGACY_SCOPE_FIELD] || metadata.legacyProjectId || metadata.projectId || metadata.scopeProjectId;
|
|
66
|
-
return candidate ? candidate : void 0;
|
|
70
|
+
return typeof candidate === "string" ? normalizeScopeValue(candidate) : void 0;
|
|
67
71
|
}
|
|
68
72
|
function normalizeScopeValue(value) {
|
|
69
73
|
if (typeof value !== "string") {
|
|
@@ -88,8 +92,9 @@ function pickPrimaryTopic(candidates) {
|
|
|
88
92
|
})[0];
|
|
89
93
|
}
|
|
90
94
|
async function findTopicsByScopeAlias(ctx, scopeId) {
|
|
95
|
+
const query2 = ctx.db.query("topics");
|
|
91
96
|
try {
|
|
92
|
-
return await
|
|
97
|
+
return await query2.withIndex(
|
|
93
98
|
"by_graph_scope_project",
|
|
94
99
|
(q) => q.eq(LEGACY_SCOPE_FIELD, scopeId)
|
|
95
100
|
).collect();
|
|
@@ -101,7 +106,7 @@ async function findTopicsByScopeAlias(ctx, scopeId) {
|
|
|
101
106
|
scopeId
|
|
102
107
|
}
|
|
103
108
|
);
|
|
104
|
-
const topics = await
|
|
109
|
+
const topics = await query2.collect();
|
|
105
110
|
return topics.filter((topic) => {
|
|
106
111
|
const normalizedGlobalId = normalizeScopeValue(topic.globalId);
|
|
107
112
|
const mappedProjectId = asMappedProjectId(topic);
|
|
@@ -157,137 +162,115 @@ async function resolveInheritedWorkspaceScope(ctx, topic) {
|
|
|
157
162
|
let current = topic;
|
|
158
163
|
for (let i = 0; i < MAX_DEPTH && current?.parentTopicId; i++) {
|
|
159
164
|
current = await ctx.db.get(current.parentTopicId);
|
|
160
|
-
if (!current)
|
|
165
|
+
if (!current) {
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
161
168
|
if (!tenantId) {
|
|
162
169
|
tenantId = normalizeScopeValue(current.tenantId);
|
|
163
170
|
}
|
|
164
171
|
if (!workspaceId) {
|
|
165
172
|
workspaceId = normalizeScopeValue(current.workspaceId);
|
|
166
173
|
}
|
|
167
|
-
if (tenantId && workspaceId)
|
|
174
|
+
if (tenantId && workspaceId) {
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
168
177
|
}
|
|
169
178
|
return { tenantId, workspaceId };
|
|
170
179
|
}
|
|
171
180
|
async function resolveTopicProjectScope(ctx, args) {
|
|
172
181
|
if (args.topicId) {
|
|
173
|
-
|
|
174
|
-
try {
|
|
175
|
-
topic = await ctx.db.get(
|
|
176
|
-
args.topicId
|
|
177
|
-
);
|
|
178
|
-
} catch (error) {
|
|
179
|
-
debugGraphPrimitiveFallback(
|
|
180
|
-
"[topicScope] Failed to load topic by direct id",
|
|
181
|
-
{
|
|
182
|
-
error,
|
|
183
|
-
topicId: args.topicId
|
|
184
|
-
}
|
|
185
|
-
);
|
|
186
|
-
}
|
|
187
|
-
if (!topic) {
|
|
188
|
-
topic = await tryResolveHostTopicById(ctx, String(args.topicId));
|
|
189
|
-
}
|
|
190
|
-
if (!topic) {
|
|
191
|
-
topic = pickPrimaryTopic(
|
|
192
|
-
await findTopicsByScopeAlias(ctx, String(args.topicId))
|
|
193
|
-
) ?? null;
|
|
194
|
-
}
|
|
195
|
-
if (!topic) {
|
|
196
|
-
const nodeScope = await resolveTopicNodeScopeOrNull(
|
|
197
|
-
ctx,
|
|
198
|
-
String(args.topicId)
|
|
199
|
-
);
|
|
200
|
-
if (nodeScope) {
|
|
201
|
-
return nodeScope;
|
|
202
|
-
}
|
|
203
|
-
throw new Error(`Topic not found: ${String(args.topicId)}`);
|
|
204
|
-
}
|
|
205
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
|
|
206
|
-
const mapped = asMappedProjectId(topic);
|
|
207
|
-
if (mapped) {
|
|
208
|
-
return {
|
|
209
|
-
topicId: topic._id,
|
|
210
|
-
projectId: mapped,
|
|
211
|
-
tenantId: inherited.tenantId,
|
|
212
|
-
workspaceId: inherited.workspaceId,
|
|
213
|
-
source: "topic"
|
|
214
|
-
};
|
|
215
|
-
}
|
|
216
|
-
return {
|
|
217
|
-
topicId: topic._id,
|
|
218
|
-
tenantId: inherited.tenantId,
|
|
219
|
-
workspaceId: inherited.workspaceId,
|
|
220
|
-
source: "topic"
|
|
221
|
-
};
|
|
182
|
+
return await resolveScopeFromTopicId(ctx, args.topicId);
|
|
222
183
|
}
|
|
223
184
|
if (args.projectId) {
|
|
224
|
-
|
|
225
|
-
try {
|
|
226
|
-
directTopic = await ctx.db.get(
|
|
227
|
-
args.projectId
|
|
228
|
-
);
|
|
229
|
-
} catch (error) {
|
|
230
|
-
debugGraphPrimitiveFallback(
|
|
231
|
-
"[topicScope] Failed to load direct project topic",
|
|
232
|
-
{
|
|
233
|
-
error,
|
|
234
|
-
projectId: args.projectId
|
|
235
|
-
}
|
|
236
|
-
);
|
|
237
|
-
}
|
|
238
|
-
if (directTopic) {
|
|
239
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
|
|
240
|
-
const mapped = asMappedProjectId(directTopic);
|
|
241
|
-
return {
|
|
242
|
-
topicId: directTopic._id,
|
|
243
|
-
projectId: mapped ?? args.projectId,
|
|
244
|
-
tenantId: inherited.tenantId,
|
|
245
|
-
workspaceId: inherited.workspaceId,
|
|
246
|
-
source: "topic_inferred"
|
|
247
|
-
};
|
|
248
|
-
}
|
|
249
|
-
directTopic = await tryResolveHostTopicByLegacyScope(ctx, args.projectId);
|
|
250
|
-
if (directTopic) {
|
|
251
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, directTopic);
|
|
252
|
-
const mapped = asMappedProjectId(directTopic);
|
|
253
|
-
return {
|
|
254
|
-
topicId: directTopic._id,
|
|
255
|
-
projectId: mapped ?? args.projectId,
|
|
256
|
-
tenantId: inherited.tenantId,
|
|
257
|
-
workspaceId: inherited.workspaceId,
|
|
258
|
-
source: "topic_inferred"
|
|
259
|
-
};
|
|
260
|
-
}
|
|
261
|
-
const topics = await findTopicsByScopeAlias(ctx, args.projectId);
|
|
262
|
-
const primary = pickPrimaryTopic(topics);
|
|
263
|
-
if (primary) {
|
|
264
|
-
const inherited = await resolveInheritedWorkspaceScope(ctx, primary);
|
|
265
|
-
return {
|
|
266
|
-
topicId: primary._id,
|
|
267
|
-
projectId: args.projectId,
|
|
268
|
-
tenantId: inherited.tenantId,
|
|
269
|
-
workspaceId: inherited.workspaceId,
|
|
270
|
-
source: "project_mapped_topic"
|
|
271
|
-
};
|
|
272
|
-
}
|
|
273
|
-
const nodeScope = await resolveTopicNodeScopeOrNull(
|
|
274
|
-
ctx,
|
|
275
|
-
String(args.projectId)
|
|
276
|
-
);
|
|
277
|
-
if (nodeScope) {
|
|
278
|
-
return {
|
|
279
|
-
...nodeScope,
|
|
280
|
-
projectId: nodeScope.projectId ?? String(args.projectId)
|
|
281
|
-
};
|
|
282
|
-
}
|
|
283
|
-
throw new Error(
|
|
284
|
-
`Legacy project scope ${String(args.projectId)} has no mapped topic.`
|
|
285
|
-
);
|
|
185
|
+
return await resolveScopeFromLegacyProjectId(ctx, args.projectId);
|
|
286
186
|
}
|
|
287
187
|
throw new Error(
|
|
288
188
|
"Missing scope: provide topicId (preferred) or legacy projectId alias."
|
|
289
189
|
);
|
|
290
190
|
}
|
|
191
|
+
async function resolveScopeFromTopicId(ctx, topicId) {
|
|
192
|
+
const topic = await resolveTopicDocFromTopicId(ctx, topicId);
|
|
193
|
+
if (topic) {
|
|
194
|
+
return await buildTopicScope(ctx, topic, "topic");
|
|
195
|
+
}
|
|
196
|
+
const nodeScope = await resolveTopicNodeScopeOrNull(ctx, String(topicId));
|
|
197
|
+
if (nodeScope) {
|
|
198
|
+
return nodeScope;
|
|
199
|
+
}
|
|
200
|
+
throw new Error(`Topic not found: ${String(topicId)}`);
|
|
201
|
+
}
|
|
202
|
+
async function resolveTopicDocFromTopicId(ctx, topicId) {
|
|
203
|
+
const direct = await tryReadTopicDoc(ctx, topicId, {
|
|
204
|
+
failureLog: "[topicScope] Failed to load topic by direct id",
|
|
205
|
+
idLogKey: "topicId"
|
|
206
|
+
});
|
|
207
|
+
if (direct) {
|
|
208
|
+
return direct;
|
|
209
|
+
}
|
|
210
|
+
const hostTopic = await tryResolveHostTopicById(ctx, String(topicId));
|
|
211
|
+
if (hostTopic) {
|
|
212
|
+
return hostTopic;
|
|
213
|
+
}
|
|
214
|
+
return pickPrimaryTopic(await findTopicsByScopeAlias(ctx, String(topicId))) ?? null;
|
|
215
|
+
}
|
|
216
|
+
async function resolveScopeFromLegacyProjectId(ctx, legacyProjectId) {
|
|
217
|
+
const directTopic = await resolveDirectLegacyProjectTopic(
|
|
218
|
+
ctx,
|
|
219
|
+
legacyProjectId
|
|
220
|
+
);
|
|
221
|
+
if (directTopic) {
|
|
222
|
+
return await buildTopicScope(ctx, directTopic, "topic_inferred", {
|
|
223
|
+
fallbackProjectId: legacyProjectId
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
const primary = pickPrimaryTopic(
|
|
227
|
+
await findTopicsByScopeAlias(ctx, legacyProjectId)
|
|
228
|
+
);
|
|
229
|
+
if (primary) {
|
|
230
|
+
return await buildTopicScope(ctx, primary, "project_mapped_topic", {
|
|
231
|
+
fallbackProjectId: legacyProjectId
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
const nodeScope = await resolveTopicNodeScopeOrNull(ctx, legacyProjectId);
|
|
235
|
+
if (nodeScope) {
|
|
236
|
+
return {
|
|
237
|
+
...nodeScope,
|
|
238
|
+
projectId: nodeScope.projectId ?? legacyProjectId
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
throw new Error(
|
|
242
|
+
`Legacy project scope ${legacyProjectId} has no mapped topic.`
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
async function resolveDirectLegacyProjectTopic(ctx, legacyProjectId) {
|
|
246
|
+
const directTopic = await tryReadTopicDoc(ctx, legacyProjectId, {
|
|
247
|
+
failureLog: "[topicScope] Failed to load direct project topic",
|
|
248
|
+
idLogKey: "projectId"
|
|
249
|
+
});
|
|
250
|
+
return directTopic ?? tryResolveHostTopicByLegacyScope(ctx, legacyProjectId);
|
|
251
|
+
}
|
|
252
|
+
async function tryReadTopicDoc(ctx, id, log) {
|
|
253
|
+
try {
|
|
254
|
+
return await ctx.db.get(id);
|
|
255
|
+
} catch (error) {
|
|
256
|
+
debugGraphPrimitiveFallback(log.failureLog, {
|
|
257
|
+
error,
|
|
258
|
+
[log.idLogKey]: id
|
|
259
|
+
});
|
|
260
|
+
return null;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
async function buildTopicScope(ctx, topic, source, options = {}) {
|
|
264
|
+
const inherited = await resolveInheritedWorkspaceScope(ctx, topic);
|
|
265
|
+
const mapped = asMappedProjectId(topic);
|
|
266
|
+
return {
|
|
267
|
+
topicId: topic._id,
|
|
268
|
+
...mapped || options.fallbackProjectId ? { projectId: mapped ?? options.fallbackProjectId } : {},
|
|
269
|
+
tenantId: inherited.tenantId,
|
|
270
|
+
workspaceId: inherited.workspaceId,
|
|
271
|
+
source
|
|
272
|
+
};
|
|
273
|
+
}
|
|
291
274
|
var optionalScopeArgs = {
|
|
292
275
|
projectId: v.optional(v.string()),
|
|
293
276
|
topicId: v.optional(v.string())
|
|
@@ -305,7 +288,7 @@ function normalizeScopeValue2(value) {
|
|
|
305
288
|
async function resolveScope(ctx, args) {
|
|
306
289
|
const topicId = normalizeScopeValue2(args.topicId);
|
|
307
290
|
const projectId = normalizeScopeValue2(args.projectId);
|
|
308
|
-
if (!topicId
|
|
291
|
+
if (!(topicId || projectId)) {
|
|
309
292
|
return null;
|
|
310
293
|
}
|
|
311
294
|
try {
|
|
@@ -344,10 +327,162 @@ async function resolveScopeSoft(ctx, args) {
|
|
|
344
327
|
...projectId ? { projectId } : {}
|
|
345
328
|
};
|
|
346
329
|
}
|
|
330
|
+
|
|
331
|
+
// src/contradictions.ts
|
|
347
332
|
v.id("epistemicNodes");
|
|
348
333
|
v.id("epistemicNodes");
|
|
349
334
|
var DEFAULT_CONTRADICTION_SOURCE = "evidence_links";
|
|
350
335
|
var TUPLE_SPACE_CONTRADICTION_SOURCE = "tuple_space";
|
|
336
|
+
function isRecord(value) {
|
|
337
|
+
return typeof value === "object" && value !== null;
|
|
338
|
+
}
|
|
339
|
+
function readConvexId(value) {
|
|
340
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
341
|
+
}
|
|
342
|
+
function readOptionalNumber(value) {
|
|
343
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
344
|
+
}
|
|
345
|
+
function readOptionalString(value) {
|
|
346
|
+
return typeof value === "string" ? value : void 0;
|
|
347
|
+
}
|
|
348
|
+
function readIdArray(value) {
|
|
349
|
+
if (!Array.isArray(value)) {
|
|
350
|
+
return [];
|
|
351
|
+
}
|
|
352
|
+
return value.flatMap((entry) => {
|
|
353
|
+
const id = readConvexId(entry);
|
|
354
|
+
return id ? [id] : [];
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
function readContradictionSource(value) {
|
|
358
|
+
if (value === DEFAULT_CONTRADICTION_SOURCE) {
|
|
359
|
+
return DEFAULT_CONTRADICTION_SOURCE;
|
|
360
|
+
}
|
|
361
|
+
if (value === TUPLE_SPACE_CONTRADICTION_SOURCE) {
|
|
362
|
+
return TUPLE_SPACE_CONTRADICTION_SOURCE;
|
|
363
|
+
}
|
|
364
|
+
return null;
|
|
365
|
+
}
|
|
366
|
+
function readContradictionStatus(value) {
|
|
367
|
+
return value === "unresolved" || value === "investigating" || value === "resolved_support" || value === "resolved_contra" || value === "belief_forked" ? value : null;
|
|
368
|
+
}
|
|
369
|
+
function readContradictionSeverity(value) {
|
|
370
|
+
return value === "critical" || value === "significant" || value === "minor" ? value : null;
|
|
371
|
+
}
|
|
372
|
+
function readAiAnalysis(value) {
|
|
373
|
+
if (!isRecord(value)) {
|
|
374
|
+
return null;
|
|
375
|
+
}
|
|
376
|
+
if (typeof value.summary !== "string" || typeof value.likelyExplanation !== "string" || typeof value.suggestedResolution !== "string" || typeof value.confidenceInAnalysis !== "number" || typeof value.analyzedAt !== "number") {
|
|
377
|
+
return null;
|
|
378
|
+
}
|
|
379
|
+
return {
|
|
380
|
+
analyzedAt: value.analyzedAt,
|
|
381
|
+
confidenceInAnalysis: value.confidenceInAnalysis,
|
|
382
|
+
likelyExplanation: value.likelyExplanation,
|
|
383
|
+
suggestedResolution: value.suggestedResolution,
|
|
384
|
+
summary: value.summary
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
function readBeliefRecord(value) {
|
|
388
|
+
if (!isRecord(value)) {
|
|
389
|
+
return null;
|
|
390
|
+
}
|
|
391
|
+
const id = readConvexId(value._id);
|
|
392
|
+
const canonicalText = readOptionalString(value.canonicalText) ?? readOptionalString(value.belief);
|
|
393
|
+
const status = readOptionalString(value.status);
|
|
394
|
+
if (!(id && canonicalText && status)) {
|
|
395
|
+
return null;
|
|
396
|
+
}
|
|
397
|
+
return {
|
|
398
|
+
_id: id,
|
|
399
|
+
canonicalText,
|
|
400
|
+
criticality: readOptionalString(value.criticality) ?? null,
|
|
401
|
+
status
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
function readEvidenceLink(value) {
|
|
405
|
+
if (!isRecord(value)) {
|
|
406
|
+
return null;
|
|
407
|
+
}
|
|
408
|
+
const insightId = readConvexId(value.insightId);
|
|
409
|
+
if (!insightId || value.relation !== "supports" && value.relation !== "contradicts") {
|
|
410
|
+
return null;
|
|
411
|
+
}
|
|
412
|
+
return {
|
|
413
|
+
insightId,
|
|
414
|
+
relation: value.relation
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
function readContradictionRow(value) {
|
|
418
|
+
if (!isRecord(value)) {
|
|
419
|
+
return null;
|
|
420
|
+
}
|
|
421
|
+
const id = readConvexId(value._id);
|
|
422
|
+
const beliefId = readConvexId(value.beliefId);
|
|
423
|
+
const severity = readContradictionSeverity(value.severity);
|
|
424
|
+
const status = readContradictionStatus(value.status);
|
|
425
|
+
if (!(id && beliefId && severity && status)) {
|
|
426
|
+
return null;
|
|
427
|
+
}
|
|
428
|
+
return {
|
|
429
|
+
_id: id,
|
|
430
|
+
aiAnalysis: readAiAnalysis(value.aiAnalysis),
|
|
431
|
+
beliefBId: readConvexId(value.beliefBId),
|
|
432
|
+
beliefId,
|
|
433
|
+
contradictingInsightIds: readIdArray(
|
|
434
|
+
value.contradictingInsightIds
|
|
435
|
+
),
|
|
436
|
+
createdBy: readOptionalString(value.createdBy),
|
|
437
|
+
description: readOptionalString(value.description) ?? null,
|
|
438
|
+
detectedAt: readOptionalNumber(value.detectedAt),
|
|
439
|
+
detectionMethod: readOptionalString(value.detectionMethod) ?? null,
|
|
440
|
+
projectId: readOptionalString(value.projectId) ?? null,
|
|
441
|
+
resolution: value.resolution,
|
|
442
|
+
resolutionSprintId: readOptionalString(value.resolutionSprintId) ?? null,
|
|
443
|
+
resolvedAt: readOptionalNumber(value.resolvedAt) ?? null,
|
|
444
|
+
severity,
|
|
445
|
+
source: readContradictionSource(value.source),
|
|
446
|
+
status,
|
|
447
|
+
supportingInsightIds: readIdArray(
|
|
448
|
+
value.supportingInsightIds
|
|
449
|
+
),
|
|
450
|
+
topicId: readOptionalString(value.topicId) ?? readOptionalString(value.projectId) ?? ""
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
function readRowList(values, reader) {
|
|
454
|
+
return values.flatMap((value) => {
|
|
455
|
+
const row = reader(value);
|
|
456
|
+
return row ? [row] : [];
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
function getContradictionSeverity(criticality) {
|
|
460
|
+
if (criticality === "blocking") {
|
|
461
|
+
return "critical";
|
|
462
|
+
}
|
|
463
|
+
if (criticality === "supporting") {
|
|
464
|
+
return "minor";
|
|
465
|
+
}
|
|
466
|
+
return "significant";
|
|
467
|
+
}
|
|
468
|
+
function extractContradictionEvidence(evidenceLinks) {
|
|
469
|
+
const supportingInsightIds = [];
|
|
470
|
+
const contradictingInsightIds = [];
|
|
471
|
+
for (const link of evidenceLinks) {
|
|
472
|
+
if (link.relation === "supports") {
|
|
473
|
+
supportingInsightIds.push(link.insightId);
|
|
474
|
+
continue;
|
|
475
|
+
}
|
|
476
|
+
if (link.relation === "contradicts") {
|
|
477
|
+
contradictingInsightIds.push(link.insightId);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
return { supportingInsightIds, contradictingInsightIds };
|
|
481
|
+
}
|
|
482
|
+
function getNewEvidenceIds(existingIds, latestIds) {
|
|
483
|
+
const existing = new Set(existingIds);
|
|
484
|
+
return latestIds.filter((id) => !existing.has(id));
|
|
485
|
+
}
|
|
351
486
|
function contradictionSourceOf(contradiction) {
|
|
352
487
|
return contradiction?.source === TUPLE_SPACE_CONTRADICTION_SOURCE ? TUPLE_SPACE_CONTRADICTION_SOURCE : DEFAULT_CONTRADICTION_SOURCE;
|
|
353
488
|
}
|
|
@@ -363,18 +498,24 @@ var detectContradictions = query({
|
|
|
363
498
|
if (!projectId) {
|
|
364
499
|
return [];
|
|
365
500
|
}
|
|
366
|
-
const beliefs =
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
501
|
+
const beliefs = readRowList(
|
|
502
|
+
await ctx.runQuery(
|
|
503
|
+
internal.epistemicBeliefs.internalGetByProject,
|
|
504
|
+
{
|
|
505
|
+
projectId
|
|
506
|
+
}
|
|
507
|
+
),
|
|
508
|
+
readBeliefRecord
|
|
371
509
|
);
|
|
372
510
|
const contradictionCandidates = [];
|
|
373
511
|
for (const belief of beliefs) {
|
|
374
|
-
const evidenceLinks =
|
|
375
|
-
"
|
|
376
|
-
|
|
377
|
-
|
|
512
|
+
const evidenceLinks = readRowList(
|
|
513
|
+
await ctx.db.query("beliefEvidenceLinks").withIndex(
|
|
514
|
+
"by_beliefId",
|
|
515
|
+
(q) => q.eq("beliefId", belief._id)
|
|
516
|
+
).collect(),
|
|
517
|
+
readEvidenceLink
|
|
518
|
+
);
|
|
378
519
|
const supportingLinks = evidenceLinks.filter(
|
|
379
520
|
(l) => l.relation === "supports"
|
|
380
521
|
);
|
|
@@ -388,10 +529,13 @@ var detectContradictions = query({
|
|
|
388
529
|
const contradictingInsights = await Promise.all(
|
|
389
530
|
contradictingLinks.map((l) => ctx.db.get(l.insightId))
|
|
390
531
|
);
|
|
391
|
-
const existingContradictions =
|
|
392
|
-
"
|
|
393
|
-
|
|
394
|
-
|
|
532
|
+
const existingContradictions = readRowList(
|
|
533
|
+
await ctx.db.query("contradictions").withIndex(
|
|
534
|
+
"by_beliefId",
|
|
535
|
+
(q) => q.eq("beliefId", belief._id)
|
|
536
|
+
).collect(),
|
|
537
|
+
readContradictionRow
|
|
538
|
+
);
|
|
395
539
|
const existingContradiction = existingContradictions.find(
|
|
396
540
|
(candidate) => contradictionSourceOf(candidate) === DEFAULT_CONTRADICTION_SOURCE
|
|
397
541
|
);
|
|
@@ -401,11 +545,10 @@ var detectContradictions = query({
|
|
|
401
545
|
contradictionCandidates.push({
|
|
402
546
|
beliefId: belief._id,
|
|
403
547
|
belief,
|
|
404
|
-
supportingInsights: supportingInsights
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
Boolean
|
|
548
|
+
supportingInsights: readRowList(supportingInsights, readBeliefRecord),
|
|
549
|
+
contradictingInsights: readRowList(
|
|
550
|
+
contradictingInsights,
|
|
551
|
+
readBeliefRecord
|
|
409
552
|
),
|
|
410
553
|
existingContradiction: existingContradiction ?? void 0
|
|
411
554
|
});
|
|
@@ -445,15 +588,21 @@ var getByProject = query({
|
|
|
445
588
|
let contradictions;
|
|
446
589
|
if (args.status) {
|
|
447
590
|
const status = args.status;
|
|
448
|
-
contradictions =
|
|
449
|
-
"
|
|
450
|
-
|
|
451
|
-
|
|
591
|
+
contradictions = readRowList(
|
|
592
|
+
await ctx.db.query("contradictions").withIndex(
|
|
593
|
+
"by_topic_status",
|
|
594
|
+
(q) => q.eq("topicId", String(scope.topicId ?? projectId)).eq("status", status)
|
|
595
|
+
).order("desc").take(scanLimit),
|
|
596
|
+
readContradictionRow
|
|
597
|
+
);
|
|
452
598
|
} else {
|
|
453
|
-
contradictions =
|
|
454
|
-
"
|
|
455
|
-
|
|
456
|
-
|
|
599
|
+
contradictions = readRowList(
|
|
600
|
+
await ctx.db.query("contradictions").withIndex(
|
|
601
|
+
"by_topicId",
|
|
602
|
+
(q) => q.eq("topicId", String(scope.topicId ?? projectId))
|
|
603
|
+
).order("desc").take(scanLimit),
|
|
604
|
+
readContradictionRow
|
|
605
|
+
);
|
|
457
606
|
}
|
|
458
607
|
const enriched = await Promise.all(
|
|
459
608
|
contradictions.slice(0, pageSize).map(async (c) => {
|
|
@@ -491,10 +640,13 @@ var getUnresolvedCount = query({
|
|
|
491
640
|
minor: 0
|
|
492
641
|
};
|
|
493
642
|
}
|
|
494
|
-
const contradictions =
|
|
495
|
-
"
|
|
496
|
-
|
|
497
|
-
|
|
643
|
+
const contradictions = readRowList(
|
|
644
|
+
await ctx.db.query("contradictions").withIndex(
|
|
645
|
+
"by_topic_status",
|
|
646
|
+
(q) => q.eq("topicId", String(scope.topicId ?? projectId)).eq("status", "unresolved")
|
|
647
|
+
).collect(),
|
|
648
|
+
readContradictionRow
|
|
649
|
+
);
|
|
498
650
|
const critical = contradictions.filter(
|
|
499
651
|
(c) => c.severity === "critical"
|
|
500
652
|
).length;
|
|
@@ -514,7 +666,9 @@ var getById = query({
|
|
|
514
666
|
args: { contradictionId: v.id("contradictions") },
|
|
515
667
|
returns: permissiveReturn,
|
|
516
668
|
handler: async (ctx, args) => {
|
|
517
|
-
const contradiction =
|
|
669
|
+
const contradiction = readContradictionRow(
|
|
670
|
+
await ctx.db.get(args.contradictionId)
|
|
671
|
+
);
|
|
518
672
|
if (!contradiction) {
|
|
519
673
|
return null;
|
|
520
674
|
}
|
|
@@ -547,10 +701,7 @@ var create = mutation({
|
|
|
547
701
|
v.literal("minor")
|
|
548
702
|
),
|
|
549
703
|
source: v.optional(
|
|
550
|
-
v.union(
|
|
551
|
-
v.literal("evidence_links"),
|
|
552
|
-
v.literal("tuple_space")
|
|
553
|
-
)
|
|
704
|
+
v.union(v.literal("evidence_links"), v.literal("tuple_space"))
|
|
554
705
|
),
|
|
555
706
|
description: v.optional(v.string()),
|
|
556
707
|
detectionMethod: v.optional(
|
|
@@ -584,7 +735,13 @@ var create = mutation({
|
|
|
584
735
|
}
|
|
585
736
|
const now = Date.now();
|
|
586
737
|
const source = args.source ?? DEFAULT_CONTRADICTION_SOURCE;
|
|
587
|
-
const existingRows =
|
|
738
|
+
const existingRows = readRowList(
|
|
739
|
+
await ctx.db.query("contradictions").withIndex(
|
|
740
|
+
"by_beliefId",
|
|
741
|
+
(q) => q.eq("beliefId", args.beliefId)
|
|
742
|
+
).collect(),
|
|
743
|
+
readContradictionRow
|
|
744
|
+
);
|
|
588
745
|
const existing = existingRows.find(
|
|
589
746
|
(row) => contradictionSourceOf(row) === source && (args.beliefBId ? String(row.beliefBId ?? "") === String(args.beliefBId) : true)
|
|
590
747
|
);
|
|
@@ -646,7 +803,9 @@ var updateStatus = mutation({
|
|
|
646
803
|
},
|
|
647
804
|
returns: permissiveReturn,
|
|
648
805
|
handler: async (ctx, args) => {
|
|
649
|
-
const existing =
|
|
806
|
+
const existing = readContradictionRow(
|
|
807
|
+
await ctx.db.get(args.contradictionId)
|
|
808
|
+
);
|
|
650
809
|
if (!existing) {
|
|
651
810
|
throw new Error("Contradiction not found");
|
|
652
811
|
}
|
|
@@ -697,7 +856,9 @@ var resolve = mutation({
|
|
|
697
856
|
},
|
|
698
857
|
returns: permissiveReturn,
|
|
699
858
|
handler: async (ctx, args) => {
|
|
700
|
-
const existing =
|
|
859
|
+
const existing = readContradictionRow(
|
|
860
|
+
await ctx.db.get(args.contradictionId)
|
|
861
|
+
);
|
|
701
862
|
if (!existing) {
|
|
702
863
|
throw new Error("Contradiction not found");
|
|
703
864
|
}
|
|
@@ -756,7 +917,9 @@ var updateSeverity = mutation({
|
|
|
756
917
|
},
|
|
757
918
|
returns: permissiveReturn,
|
|
758
919
|
handler: async (ctx, args) => {
|
|
759
|
-
const existing =
|
|
920
|
+
const existing = readContradictionRow(
|
|
921
|
+
await ctx.db.get(args.contradictionId)
|
|
922
|
+
);
|
|
760
923
|
if (!existing) {
|
|
761
924
|
throw new Error("Contradiction not found");
|
|
762
925
|
}
|
|
@@ -814,75 +977,82 @@ var scanAndCreateContradictions = mutation({
|
|
|
814
977
|
return { created: 0, updated: 0 };
|
|
815
978
|
}
|
|
816
979
|
const now = Date.now();
|
|
817
|
-
const beliefs =
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
980
|
+
const beliefs = readRowList(
|
|
981
|
+
await ctx.runQuery(
|
|
982
|
+
internal.epistemicBeliefs.internalGetByProject,
|
|
983
|
+
{
|
|
984
|
+
projectId
|
|
985
|
+
}
|
|
986
|
+
),
|
|
987
|
+
readBeliefRecord
|
|
822
988
|
);
|
|
823
989
|
let created = 0;
|
|
824
990
|
let updated = 0;
|
|
825
991
|
for (const belief of beliefs) {
|
|
826
|
-
const evidenceLinks =
|
|
827
|
-
"
|
|
828
|
-
(q) => q.eq("beliefId", belief._id)
|
|
829
|
-
).collect();
|
|
830
|
-
const supportingIds = evidenceLinks.filter((l) => l.relation === "supports").map((l) => l.insightId);
|
|
831
|
-
const contradictingIds = evidenceLinks.filter((l) => l.relation === "contradicts").map((l) => l.insightId);
|
|
832
|
-
if (supportingIds.length > 0 && contradictingIds.length > 0) {
|
|
833
|
-
const existingRows = await ctx.db.query("contradictions").withIndex(
|
|
992
|
+
const evidenceLinks = readRowList(
|
|
993
|
+
await ctx.db.query("beliefEvidenceLinks").withIndex(
|
|
834
994
|
"by_beliefId",
|
|
835
995
|
(q) => q.eq("beliefId", belief._id)
|
|
836
|
-
).collect()
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
severity = "critical";
|
|
843
|
-
} else if (belief.criticality === "supporting") {
|
|
844
|
-
severity = "minor";
|
|
845
|
-
}
|
|
846
|
-
if (existing) {
|
|
847
|
-
const newSupporting = supportingIds.filter(
|
|
848
|
-
(id) => !existing.supportingInsightIds.includes(id)
|
|
849
|
-
);
|
|
850
|
-
const newContradicting = contradictingIds.filter(
|
|
851
|
-
(id) => !existing.contradictingInsightIds.includes(id)
|
|
852
|
-
);
|
|
853
|
-
if (newSupporting.length > 0 || newContradicting.length > 0) {
|
|
854
|
-
await ctx.db.patch(existing._id, {
|
|
855
|
-
supportingInsightIds: [
|
|
856
|
-
...existing.supportingInsightIds,
|
|
857
|
-
...newSupporting
|
|
858
|
-
],
|
|
859
|
-
contradictingInsightIds: [
|
|
860
|
-
...existing.contradictingInsightIds,
|
|
861
|
-
...newContradicting
|
|
862
|
-
],
|
|
863
|
-
severity
|
|
864
|
-
});
|
|
865
|
-
updated++;
|
|
866
|
-
}
|
|
867
|
-
} else {
|
|
868
|
-
await ctx.db.insert("contradictions", {
|
|
869
|
-
projectId,
|
|
870
|
-
topicId: String(scope.topicId ?? projectId),
|
|
871
|
-
beliefId: belief._id,
|
|
872
|
-
supportingInsightIds: supportingIds,
|
|
873
|
-
contradictingInsightIds: contradictingIds,
|
|
874
|
-
source: DEFAULT_CONTRADICTION_SOURCE,
|
|
875
|
-
resolutionStatus: "unresolved",
|
|
876
|
-
// Lucern: required field
|
|
877
|
-
status: "unresolved",
|
|
878
|
-
// Legacy: kept for backward compat
|
|
879
|
-
severity,
|
|
880
|
-
detectedAt: now,
|
|
881
|
-
createdBy: args.createdBy
|
|
882
|
-
});
|
|
883
|
-
created++;
|
|
884
|
-
}
|
|
996
|
+
).collect(),
|
|
997
|
+
readEvidenceLink
|
|
998
|
+
);
|
|
999
|
+
const { supportingInsightIds, contradictingInsightIds } = extractContradictionEvidence(evidenceLinks);
|
|
1000
|
+
if (supportingInsightIds.length === 0 || contradictingInsightIds.length === 0) {
|
|
1001
|
+
continue;
|
|
885
1002
|
}
|
|
1003
|
+
const existingRows = readRowList(
|
|
1004
|
+
await ctx.db.query("contradictions").withIndex(
|
|
1005
|
+
"by_beliefId",
|
|
1006
|
+
(q) => q.eq("beliefId", belief._id)
|
|
1007
|
+
).collect(),
|
|
1008
|
+
readContradictionRow
|
|
1009
|
+
);
|
|
1010
|
+
const existing = existingRows.find(
|
|
1011
|
+
(candidate) => contradictionSourceOf(candidate) === DEFAULT_CONTRADICTION_SOURCE
|
|
1012
|
+
);
|
|
1013
|
+
const severity = getContradictionSeverity(belief.criticality);
|
|
1014
|
+
if (!existing) {
|
|
1015
|
+
await ctx.db.insert("contradictions", {
|
|
1016
|
+
projectId,
|
|
1017
|
+
topicId: String(scope.topicId ?? projectId),
|
|
1018
|
+
beliefId: belief._id,
|
|
1019
|
+
supportingInsightIds,
|
|
1020
|
+
contradictingInsightIds,
|
|
1021
|
+
source: DEFAULT_CONTRADICTION_SOURCE,
|
|
1022
|
+
resolutionStatus: "unresolved",
|
|
1023
|
+
// Lucern: required field
|
|
1024
|
+
status: "unresolved",
|
|
1025
|
+
// Legacy: kept for backward compat
|
|
1026
|
+
severity,
|
|
1027
|
+
detectedAt: now,
|
|
1028
|
+
createdBy: args.createdBy
|
|
1029
|
+
});
|
|
1030
|
+
created++;
|
|
1031
|
+
continue;
|
|
1032
|
+
}
|
|
1033
|
+
const newSupporting = getNewEvidenceIds(
|
|
1034
|
+
existing.supportingInsightIds,
|
|
1035
|
+
supportingInsightIds
|
|
1036
|
+
);
|
|
1037
|
+
const newContradicting = getNewEvidenceIds(
|
|
1038
|
+
existing.contradictingInsightIds,
|
|
1039
|
+
contradictingInsightIds
|
|
1040
|
+
);
|
|
1041
|
+
if (newSupporting.length === 0 && newContradicting.length === 0) {
|
|
1042
|
+
continue;
|
|
1043
|
+
}
|
|
1044
|
+
await ctx.db.patch(existing._id, {
|
|
1045
|
+
supportingInsightIds: [
|
|
1046
|
+
...existing.supportingInsightIds,
|
|
1047
|
+
...newSupporting
|
|
1048
|
+
],
|
|
1049
|
+
contradictingInsightIds: [
|
|
1050
|
+
...existing.contradictingInsightIds,
|
|
1051
|
+
...newContradicting
|
|
1052
|
+
],
|
|
1053
|
+
severity
|
|
1054
|
+
});
|
|
1055
|
+
updated++;
|
|
886
1056
|
}
|
|
887
1057
|
return { created, updated };
|
|
888
1058
|
}
|